this.lastDisplayableIndex2up = null;
- // We link to index.php to avoid redirect which breaks back button
// Should be overriden (before init) by custom implmentations.
- this.logoURL = 'http://openlibrary.org';
+ this.logoURL = 'http://www.archive.org';
// Base URL for UI images - should be overriden (before init) by
// custom implementations.
this.twoPage = {
coverInternalPadding: 0, // Width of cover
coverExternalPadding: 0, // Padding outside of cover
- bookSpineDivWidth: 0, // Width of book spine $$$ consider sizing based on book length
+ bookSpineDivWidth: 64, // Width of book spine $$$ consider sizing based on book length
autofit: 'auto'
};
document.title = this.shortTitle(50);
$("#BookReader").empty();
-
+
this.initToolbar(this.mode, this.ui); // Build inside of toolbar div
$("#BookReader").append("<div id='BRcontainer' dir='ltr'></div>");
$("#BRcontainer").append("<div id='BRpageview'></div>");
// We init the nav bar after the params processing so that the nav slider knows where
// it should start (doesn't jump after init)
- this.initNavbar();
+ if (this.ui == "embed") {
+ this.initEmbedNavbar();
+ } else {
+ this.initNavbar();
+ }
this.bindNavigationHandlers();
+
+ // Set strings in the UI
+ this.initUIStrings();
// Start AJAX request for OL data
if (this.getOpenLibraryRecord) {
$('#pagediv'+index).remove();
}
} else {
- /*
- var mRow = this.displayedRows[i];
- var mLeafs = '[' + [leaf.num for each (leaf in leafMap[mRow].leafs)] + ']';
- console.log('NOT Removing row ' + mRow + ' ' + mLeafs);
- */
+ // var mRow = this.displayedRows[i];
+ // var mLeafs = '[' + [leaf.num for each (leaf in leafMap[mRow].leafs)] + ']';
+ // console.log('NOT Removing row ' + mRow + ' ' + mLeafs);
}
}
}).appendTo('#BRtwopageview');
div = document.createElement('div');
- $(div).attr('id', 'BRbookspine').css({
+ $(div).attr('id', 'BRgutter').css({
width: this.twoPage.bookSpineDivWidth+'px',
height: this.twoPage.bookSpineDivHeight+'px',
- left: this.twoPage.bookSpineDivLeft+'px',
+ left: (this.twoPage.gutter - this.twoPage.bookSpineDivWidth*0.5)+'px',
top: this.twoPage.bookSpineDivTop+'px'
}).appendTo('#BRtwopageview');
return spreadSize.reduce;
}
+// twoPageIsZoomedIn
+//______________________________________________________________________________
+// Returns true if the pages extend past the edge of the view
+BookReader.prototype.twoPageIsZoomedIn = function() {
+ var autofitReduce = this.twoPageGetAutofitReduce();
+ var isZoomedIn = false;
+ if (this.twoPage.autofit != 'auto') {
+ if (this.reduce < this.twoPageGetAutofitReduce()) {
+ isZoomedIn = true;
+ }
+ }
+ return isZoomedIn;
+}
+
BookReader.prototype.onePageGetAutofitWidth = function() {
var widthPadding = 20;
return (this.getMedianPageSize().width + 0.0) / ($('#BRcontainer').attr('clientWidth') - widthPadding * 2);
//console.log(' and now leafEdgeTmp to left: gutter+newWidthR ' + (gutter + newWidthR));
$(self.leafEdgeTmp).animate({left: gutter+newWidthR+'px'}, self.flipSpeed, 'easeOutSine');
+
+ $('#BRgutter').css({left: (gutter - self.twoPage.bookSpineDivWidth*0.5)+'px'});
//console.log(' animating newIndexR ' + newIndexR + ' to ' + newWidthR + ' from ' + $(self.prefetchedImgs[newIndexR]).width());
$(self.prefetchedImgs[newIndexR]).animate({width: newWidthR+'px'}, self.flipSpeed, 'easeOutSine', function() {
$(self.twoPage.coverDiv).css({
width: self.twoPageCoverWidth(newWidthL+newWidthR)+'px',
left: gutter-newWidthL-newLeafEdgeWidthL-self.twoPage.coverInternalPadding+'px'
- });
+ });
$(self.leafEdgeTmp).remove();
self.leafEdgeTmp = null;
{
// Update navbar position icon - leads page change animation
this.updateNavIndex(index);
-
}
// flipRightToLeft(nextL, nextR, gutter)
$(this.leafEdgeTmp).animate({left: gutter}, speed, 'easeInSine');
$(this.prefetchedImgs[this.twoPage.currentIndexR]).animate({width: '0px'}, speed, 'easeInSine', function() {
+ $('#BRgutter').css({left: (gutter - self.twoPage.bookSpineDivWidth*0.5)+'px'});
$(self.leafEdgeTmp).animate({left: gutter-newWidthL-leafEdgeTmpW+'px'}, speed, 'easeOutSine');
$(self.prefetchedImgs[newIndexL]).animate({width: newWidthL+'px'}, speed, 'easeOutSine', function() {
$(self.prefetchedImgs[newIndexR]).css('zIndex', 2);
$(self.twoPage.coverDiv).css({
width: self.twoPageCoverWidth(newWidthL+newWidthR)+'px',
left: gutter - newWidthL - newLeafEdgeWidthL - self.twoPage.coverInternalPadding + 'px'
- });
-
+ });
+
$(self.leafEdgeTmp).remove();
self.leafEdgeTmp = null;
function(e) {
if (e.button == 2) {
// right click
- return;
+ return true;
}
-
- var autofitReduce = e.data.self.twoPageGetAutofitReduce();
- // Don't trigger if zoomed in
- if (e.data.self.reduce >= e.data.self.twoPageGetAutofitReduce()) {
+
+ if (! e.data.self.twoPageIsZoomedIn()) {
e.data.self.ttsStop();
e.data.self.left();
}
function(e) {
if (e.button == 2) {
// right click
- return;
+ return true;
}
-
- var autofitReduce = e.data.self.twoPageGetAutofitReduce();
- // Don't trigger if zoomed in
- if (e.data.self.reduce >= e.data.self.twoPageGetAutofitReduce()) {
+
+ if (! e.data.self.twoPageIsZoomedIn()) {
e.data.self.ttsStop();
- e.data.self.right();
+ e.data.self.right();
}
e.preventDefault();
}
//console.log(' prevL.left: ' + (gutter - scaledW) + 'px');
//console.log(' changing prevL ' + prevL + ' to left: ' + (gutter-scaledW) + ' width: ' + scaledW);
- leftCSS = {
+ var leftCSS = {
position: 'absolute',
left: gutter-scaledW+'px',
right: '', // clear right property
top: top+'px',
height: this.twoPage.height,
width: scaledW+'px',
- borderRight: '1px solid black', // XXXmang check
zIndex: 1
}
//console.log(' changing prevR ' + prevR + ' to left: ' + gutter + ' width: 0');
- rightCSS = {
+ var rightCSS = {
position: 'absolute',
left: gutter+'px',
right: '',
top: top+'px',
height: this.twoPage.height,
- borderLeft: '1px solid black', // XXXmang check
width: '0',
zIndex: 2
}
this.removeSearchResults();
this.showProgressPopup('<img id="searchmarker" src="'+this.imagesBaseURL + 'marker_srch-on.png'+'"> Search results will appear below...');
- this.ttsAjax = $.ajax({url:url, dataType:'jsonp', jsonpCallback:'br.BRSearchCallback'});
+ $.ajax({url:url, dataType:'jsonp', jsonpCallback:'br.BRSearchCallback'});
}
// BRSearchCallback()
//console.log(br.searchResults);
if (0 == results.matches.length) {
- $(br.popup).text('No matches were found.');
+ var errStr = 'No matches were found.';
+ var timeout = 1000;
+ if (false === results.indexed) {
+ errStr = "<p>This book isn't in the search engine yet.</p><p>Please <a href='http://openlibrary.org/contact?path=archive.org/stream/"+this.bookId+"/search'>drop us a line</a> so we can fix it. Thanks!</p>";
+ timeout = 5000;
+ }
+ $(br.popup).html(errStr);
setTimeout(function(){
$(br.popup).fadeOut('slow', function() {
br.removeProgressPopup();
})
- },1000);
+ },timeout);
return;
}
return '/bookreader/print.php?' + options;
}
-/* iframe implementation
-BookReader.prototype.getPrintFrameContent = function(index) {
- // We fit the image based on an assumed A4 aspect ratio. A4 is a bit taller aspect than
- // 8.5x11 so we should end up not overflowing on either paper size.
- var paperAspect = 8.5 / 11;
- var imageAspect = this._getPageWidth(index) / this._getPageHeight(index);
-
- var rotate = 0;
-
- // Rotate if possible and appropriate, to get larger image size on printed page
- if (this.canRotatePage(index)) {
- if (imageAspect > 1 && imageAspect > paperAspect) {
- // more wide than square, and more wide than paper
- rotate = 90;
- imageAspect = 1/imageAspect;
- }
- }
-
- var fitAttrs;
- if (imageAspect > paperAspect) {
- // wider than paper, fit width
- fitAttrs = 'width="95%"';
- } else {
- // taller than paper, fit height
- fitAttrs = 'height="95%"';
- }
-
- var imageURL = this._getPageURI(index, 1, rotate);
- var iframeStr = '<html style="padding: 0; border: 0; margin: 0"><head><title>' + this.bookTitle + '</title></head><body style="padding: 0; border:0; margin: 0">';
- iframeStr += '<div style="text-align: center; width: 99%; height: 99%; overflow: hidden;">';
- iframeStr += '<img src="' + imageURL + '" ' + fitAttrs + ' />';
- iframeStr += '</div>';
- iframeStr += '</body></html>';
-
- return iframeStr;
-}
-
-BookReader.prototype.updatePrintFrame = function(delta) {
- var newIndex = this.indexToPrint + delta;
- newIndex = BookReader.util.clamp(newIndex, 0, this.numLeafs - 1);
- if (newIndex == this.indexToPrint) {
- return;
- }
- this.indexToPrint = newIndex;
- var doc = BookReader.util.getIFrameDocument($('#printFrame')[0]);
- $('body', doc).html(this.getPrintFrameContent(this.indexToPrint));
-}
-*/
-
// showEmbedCode()
+//
+// Note: Has been replaced by the share dialog
//______________________________________________________________________________
BookReader.prototype.showEmbedCode = function() {
if (null != this.embedPopup) { // check if already showing
BookReader.prototype.initNavbar = function() {
// Setup nav / chapter / search results bar
- // $$$ should make this work inside the BookReader div (self-contained), rather than after
- $('#BookReader').after(
+ $('#BookReader').append(
'<div id="BRnav">'
+ '<div id="BRpage">' // Page turn buttons
+ '<button class="BRicon onepg"></button>'
+ '</div>'
);
-/*
- <div class="searchChap" style="left:49%;" title="Search result">
- <div class="query">
- A related distinction is between the emotion and the results of the emotion, principally behaviors and <strong><a href="">emotional</a></strong> expressions. People often behave in certain ways as a direct result of their <strong><a href="">emotional</a></strong> state, such as crying, fighting or fleeing. <span>Page 163</span>
- <div class="queryChap">IV. The Witch <span>|</span> Page 163</div>
- </div>
- </div>
-*/
-
- /* $$$mang search results and chapters should automatically coalesce
- $('.searchChap').bt({
- contentSelector: '$(this).find(".query")',
- trigger: 'click',
- closeWhenOthersOpen: true,
- cssStyles: {
- width: '250px',
- padding: '10px 10px 15px',
- backgroundColor: '#fff',
- border: '3px solid #e2dcc5',
- borderBottom: 'none',
- fontFamily: '"Lucida Grande","Arial",sans-serif',
- fontSize: '12px',
- lineHeight: '18px',
- color: '#615132'
- },
- shrinkToFit: false,
- width: '230px',
- padding: 0,
- spikeGirth: 0,
- spikeLength: 0,
- overlap: '10px',
- overlay: false,
- killTitle: true,
- textzIndex: 9999,
- boxzIndex: 9998,
- wrapperzIndex: 9997,
- offsetParent: null,
- positions: ['top'],
- fill: 'white',
- windowMargin: 10,
- strokeWidth: 3,
- strokeStyle: '#e2dcc5',
- cornerRadius: 0,
- centerPointX: 0,
- centerPointY: 0,
- shadow: false
- });
- $('.searchChap').each(function(){
- $(this).hover(function(){
- $(this).addClass('front');
- },function(){
- $(this).removeClass('front');
- });
- });
- */
var self = this;
$('#BRpager').slider({
animate: true,
max: this.numLeafs - 1,
value: this.currentIndex()
})
- .bind('slide', function(event, ui){
+ .bind('slide', function(event, ui) {
self.updateNavPageNum(ui.value);
$("#pagenum").show();
return true;
})
.bind('slidechange', function(event, ui) {
+ self.updateNavPageNum(ui.value); // hiding now but will show later
$("#pagenum").hide();
// recursion prevention for jumpToIndex
.append('<div id="pagenum"><span class="currentpage"></span></div>');
//.wrap('<div class="ui-handle-helper-parent"></div>').parent(); // XXXmang is this used for hiding the tooltip?
- // $$$mang, why are these set both here and in bindNavigationHandlers?
- $('.BRicon.book_left').bind('click', function() {
- self.ttsStop();
- self.left();
- });
- $('.BRicon.book_right').bind('click', function() {
- self.ttsStop();
- self.right();
- });
-
this.updateNavPageNum(this.currentIndex());
$("#BRzoombtn").draggable({axis:'y',containment:'parent'});
- //XXXmang remove once done testing
- //this.addSearchResult("There is a place where the <strong>sidewalk</strong> ends And before the street begins, And there the grass grows soft and white, And there the sun burns crimson bright,And there the moon-bird rests from his flight To cool in the peppermint wind.", "20", 31);
- //this.addSearchResult("There is a place where the <strong>sidewalk</strong> BEGINS And there the moon-bird rests from his flight To cool in the peppermint wind.", "60", 71);
+ /* Initial hiding
+ $('#BRtoolbar').delay(3000).animate({top:-40});
+ $('#BRnav').delay(3000).animate({bottom:-53});
+ changeArrow();
+ $('.BRnavCntl').delay(3000).animate({height:'43px'}).delay(1000).animate({opacity:.25},1000);
+ */
+}
+
+// initEmbedNavbar
+//______________________________________________________________________________
+// Initialize the navigation bar when embedded
+BookReader.prototype.initEmbedNavbar = function() {
+ var thisLink = (window.location + '').replace('?ui=embed',''); // IA-specific
+ $('#BookReader').append(
+ '<div id="BRnav">'
+ + "<span id='BRtoolbarbuttons'>"
+ + '<button class="BRicon full"></button>'
+ + '<button class="BRicon book_left"></button>'
+ + '<button class="BRicon book_right"></button>'
+ + "</span>"
+ + "<span><a class='logo' href='" + this.logoURL + "' 'target='_blank' ></a></span>"
+ + "<span id='BRembedreturn'><a href='" + thisLink + "' target='_blank' ></a></span>"
+ + '</div>'
+ );
+ $('#BRembedreturn a').text(this.bookTitle);
}
BookReader.prototype.updateNavPageNum = function(index) {
}
BookReader.prototype.initToolbar = function(mode, ui) {
+ if (ui == "embed") {
+ return; // No toolbar at top in embed mode
+ }
// $$$mang should be contained within the BookReader div instead of body
var readIcon = '';
if (!navigator.userAgent.match(/mobile/i)) {
readIcon = "<button class='BRicon read modal'></button>";
}
-
- $("body").append(
+
+ $("#BookReader").append(
"<div id='BRtoolbar'>"
+ "<span id='BRtoolbarbuttons'>"
+ "<form action='javascript:br.search($(\"#textSrch\").val());' id='booksearch'><input type='search' id='textSrch' name='textSrch' val='' placeholder='Search inside'/><button type='submit' id='btnSrch' name='btnSrch'>GO</button></form>"
//+ "<button class='BRicon full'></button>"
+ "</span>"
+ "<span><a class='logo' href='" + this.logoURL + "'></a></span>"
- + "<span id='BRreturn'><span>Back to</span><a href='" + this.bookUrl + "'>" + this.bookTitle + "</a></span>"
- + "<div id='BRnavCntlTop' class='BRnavCntl BRup'></div>"
+ + "<span id='BRreturn'><a></a></span>"
+ + "<div id='BRnavCntlTop' class='BRnabrbuvCntl'></div>"
+ "</div>"
/*
+ "<div id='BRzoomer'>"
*/
);
+ // Browser hack - bug with colorbox on iOS 3 see https://bugs.launchpad.net/bookreader/+bug/686220
+ if ( navigator.userAgent.match(/ipad/i) && $.browser.webkit && (parseInt($.browser.version, 10) <= 531) ) {
+ $('#BRtoolbarbuttons .info').hide();
+ $('#BRtoolbarbuttons .share').hide();
+ }
+
+ $('#BRreturn a').attr('href', this.bookUrl).text(this.bookTitle);
+
+ $('#BRtoolbar .BRnavCntl').addClass('BRup');
$('#BRtoolbar .pause').hide();
this.updateToolbarZoom(this.reduce); // Pretty format
// We build in mode 2
jToolbar.append();
-
- // Navigation handlers will be bound after all UI is in place -- makes moving icons between
- // the toolbar and nav bar easier
-
- // Setup tooltips -- later we could load these from a file for i18n
- var titles = { '.logo': 'Go to Archive.org',
- '.zoom_in': 'Zoom in',
- '.zoom_out': 'Zoom out',
- '.onepg': 'One-page view',
- '.twopg': 'Two-page view',
- '.thumb': 'Thumbnail view',
- '.print': 'Print this page',
- '.embed': 'Embed BookReader',
- '.link': 'Link to this book (and page)',
- '.bookmark': 'Bookmark this page',
- '.read': 'Read this book aloud',
- '.full': 'Show fullscreen',
- '.book_left': 'Flip left',
- '.book_right': 'Flip right',
- '.book_up': 'Page up',
- '.book_down': 'Page down',
- '.play': 'Play',
- '.pause': 'Pause',
- '.book_top': 'First page',
- '.book_bottom': 'Last page'
- };
- if ('rl' == this.pageProgression) {
- titles['.book_leftmost'] = 'Last page';
- titles['.book_rightmost'] = 'First page';
- } else { // LTR
- titles['.book_leftmost'] = 'First page';
- titles['.book_rightmost'] = 'Last page';
- }
-
- for (var icon in titles) {
- jToolbar.find(icon).attr('title', titles[icon]);
- }
-
+
// Hide mode buttons and autoplay if 2up is not available
// $$$ if we end up with more than two modes we should show the applicable buttons
if ( !this.canSwitchToMode(this.constMode2up) ) {
jToolbar.find('.one_page_mode').hide();
}
- // $$$ Don't hardcode ids
- jToolbar.find('.share').colorbox({inline: true, opacity: "0.5", href: "#shareThis"});
- jToolbar.find('.info').colorbox({inline: true, opacity: "0.5", href: "#aboutThis"});
-
- $("body").append(
- [
- '<div style="display: none;">',
- this.makeShareDiv(),
- this.makeAboutDiv(),
- '</div>'
- ].join('\n')
- );
-
+ // $$$ Don't hardcode ids
+ var self = this;
+ jToolbar.find('.share').colorbox({inline: true, opacity: "0.5", href: "#BRshare", onLoad: function() { self.autoStop(); self.ttsStop(); } });
+ jToolbar.find('.info').colorbox({inline: true, opacity: "0.5", href: "#BRinfo", onLoad: function() { self.autoStop(); self.ttsStop(); } });
+
+ $('<div style="display: none;"></div>').append(this.blankShareDiv()).append(this.blankInfoDiv()).appendTo($('body'));
+ $('#BRinfo .BRfloatTitle a').attr( {'href': this.bookUrl} ).text(this.bookTitle).addClass('title');
+
+ // These functions can be overridden
+ this.buildInfoDiv($('#BRinfo'));
+ this.buildShareDiv($('#BRshare'));
// Switch to requested mode -- binds other click handlers
//this.switchToolbarMode(mode);
}
+BookReader.prototype.blankInfoDiv = function() {
+ return $([
+ '<div class="BRfloat" id="BRinfo">',
+ '<div class="BRfloatHead">About this book',
+ '<a class="floatShut" href="javascript:;" onclick="$.fn.colorbox.close();"><span class="shift">Close</span></a>',
+ '</div>',
+ '<div class="BRfloatBody">',
+ '<div class="BRfloatCover">',
+ '</div>',
+ '<div class="BRfloatMeta">',
+ '<div class="BRfloatTitle">',
+ '<h2><a/></h2>',
+ '</div>',
+ '</div>',
+ '</div>',
+ '<div class="BRfloatFoot">',
+ '<a href="http://openlibrary.org/dev/docs/bookreader">About the BookReader</a>',
+ '</div>',
+ '</div>'].join('\n')
+ );
+}
+
+BookReader.prototype.blankShareDiv = function() {
+ return $([
+ '<div class="BRfloat" id="BRshare">',
+ '<div class="BRfloatHead">',
+ 'Share',
+ '<a class="floatShut" href="javascript:;" onclick="$.fn.colorbox.close();"><span class="shift">Close</span></a>',
+ '</div>',
+ '</div>'].join('\n')
+ );
+}
+
// switchToolbarMode
//______________________________________________________________________________
});
jIcons.filter('.book_left').click(function(e) {
+ self.ttsStop();
self.left();
return false;
});
jIcons.filter('.book_right').click(function(e) {
+ self.ttsStop();
self.right();
return false;
});
self.printPage();
return false;
});
-
+
+ // Note: Functionality has been replaced by .share
jIcons.filter('.embed').click(function(e) {
self.showEmbedCode();
return false;
return false;
});
+ jIcons.filter('.full').bind('click', function() {
+ if (self.ui == 'embed') {
+ // $$$ bit of a hack, IA-specific
+ var url = (window.location + '').replace("?ui=embed","");
+ window.open(url);
+ }
+
+ // Not implemented
+ });
+
+ $('.BRnavCntl').click(
+ function(){
+ if ($('#BRnavCntlBtm').hasClass('BRdn')) {
+ $('#BRtoolbar').animate({top:-40});
+ $('#BRnav').animate({bottom:-55});
+ $('#BRnavCntlBtm').addClass('BRup').removeClass('BRdn');
+ $('#BRnavCntlTop').addClass('BRdn').removeClass('BRup');
+ $('#BRnavCntlBtm.BRnavCntl').animate({height:'45px'});
+ $('.BRnavCntl').delay(1000).animate({opacity:.25},1000);
+ } else {
+ $('#BRtoolbar').animate({top:0});
+ $('#BRnav').animate({bottom:0});
+ $('#BRnavCntlBtm').addClass('BRdn').removeClass('BRup');
+ $('#BRnavCntlTop').addClass('BRup').removeClass('BRdn');
+ $('#BRnavCntlBtm.BRnavCntl').animate({height:'30px'});
+ $('.BRvavCntl').animate({opacity:1})
+ };
+ }
+ );
+ $('#BRnavCntlBtm').mouseover(function(){
+ if ($(this).hasClass('BRup')) {
+ $('.BRnavCntl').animate({opacity:1},250);
+ };
+ });
+ $('#BRnavCntlBtm').mouseleave(function(){
+ if ($(this).hasClass('BRup')) {
+ $('.BRnavCntl').animate({opacity:.25},250);
+ };
+ });
+ $('#BRnavCntlTop').mouseover(function(){
+ if ($(this).hasClass('BRdn')) {
+ $('.BRnavCntl').animate({opacity:1},250);
+ };
+ });
+ $('#BRnavCntlTop').mouseleave(function(){
+ if ($(this).hasClass('BRdn')) {
+ $('.BRnavCntl').animate({opacity:.25},250);
+ };
+ });
+
+
this.initSwipeData();
$('#BookReader').die('mousemove.navigation').live('mousemove.navigation',
{ 'br': this },
$('.BRpageimage').die('mousedown.swipe').live('mousedown.swipe',
{ 'br': this },
this.swipeMousedownHandler
- )
- .die('mousemove.swipe').live('mousemove.swipe',
- { 'br': this },
- this.swipeMousemoveHandler
- )
- .die('mouseup.swipe').live('mouseup.swipe',
- { 'br': this },
- this.swipeMouseupHandler
);
this.bindMozTouchHandlers();
BookReader.prototype.swipeMousedownHandler = function(event) {
//console.log('swipe mousedown');
//console.log(event);
+
+ // We should be the last bubble point for the page images
+ // Disable image drag and select, but keep right-click
+ if (event.which == 3) {
+ return true;
+ }
var self = event.data['br'];
+
+ $(event.target).bind('mouseout.swipe',
+ { 'br': self},
+ self.swipeMouseupHandler
+ ).bind('mouseup.swipe',
+ { 'br': self},
+ self.swipeMouseupHandler
+ ).bind('mousemove.swipe',
+ { 'br': self },
+ self.swipeMousemoveHandler
+ );
+
self.initSwipeData(event.clientX, event.clientY);
self._swipe.mightBeSwiping = true;
self._swipe.mightBeDragging = true;
- // We should be the last bubble point for the page images
- // Disable image drag and select, but keep right-click
- if ($(event.originalTarget).hasClass('BRpageimage') && event.button != 2) {
- event.preventDefault();
- }
+ event.preventDefault();
+ event.returnValue = false;
+ event.cancelBubble = true;
+ return false;
}
BookReader.prototype.swipeMousemoveHandler = function(event) {
}
_swipe.lastX = event.clientX;
_swipe.lastY = event.clientY;
+
+ event.preventDefault();
+ event.returnValue = false;
+ event.cancelBubble = true;
+ return false;
}
BookReader.prototype.swipeMouseupHandler = function(event) {
var _swipe = event.data['br']._swipe;
//console.log('swipe mouseup - did swipe ' + _swipe.didSwipe);
_swipe.mightBeSwiping = false;
_swipe.mightBeDragging = false;
+
+ $(event.target).unbind('mouseout.swipe').unbind('mouseup.swipe').unbind('mousemove.swipe');
+
if (_swipe.didSwipe || _swipe.didDrag) {
// Swallow event if completed swipe gesture
event.preventDefault();
- event.stopPropagation();
+ event.returnValue = false;
+ event.cancelBubble = true;
+ return false;
}
+ return true;
}
-
BookReader.prototype.bindMozTouchHandlers = function() {
var self = this;
}
}
+// changeArrow
+//______________________________________________________________________________
+// Change the nav bar arrow
+function changeArrow(){
+ setTimeout(function(){
+ $('#BRnavCntlBtm').removeClass('BRdn').addClass('BRup');
+ },3000);
+};
+
+
// firstDisplayableIndex
//______________________________________________________________________________
// Returns the index of the first visible page, dependent on the mode.
if ('undefined' != typeof(params.page)) {
fragments.push('page', params.page);
} else {
- // Don't have page numbering -- use index instead
- fragments.push('page', 'n' + params.index);
+ if ('undefined' != typeof(params.index)) {
+ // Don't have page numbering but we do have the index
+ fragments.push('page', 'n' + params.index);
+ }
}
// $$$ highlight
}
// $$$mang cleanup
- this.bookUrl = 'http://openlibrary.org' + olObject.key;
- $('#BRreturn a').attr('href', this.bookUrl);
+ self.bookUrl = 'http://openlibrary.org' + olObject.key;
+ self.bookTitle = olObject['title'];
+ $('#BRreturn a').attr( {'href': self.bookUrl, 'title': "Go to this book's page on Open Library" } );
+ $('#BRreturn a').text(self.bookTitle);
+
+ $('#BRinfo').remove();
+ $('#BRshare').after(self.blankInfoDiv());
+ self.buildInfoDiv($('#BRinfo'));
}
}
// showProgressPopup
//______________________________________________________________________________
BookReader.prototype.showProgressPopup = function(msg) {
- if (soundManager.debugMode) console.log('showProgressPopup index='+this.ttsIndex+' pos='+this.ttsPosition);
+ //if (soundManager.debugMode) console.log('showProgressPopup index='+this.ttsIndex+' pos='+this.ttsPosition);
if (this.popup) return;
this.popup = document.createElement("div");
self.ttsNextChunk();
},500);
}
-//FADING, ETC.
- function changeArrow(){
- setTimeout(function(){
- $('#BRnavCntlBtm').removeClass('BRdn').addClass('BRup');
- },3000);
- };
- $().ready(function(){
- /*
- $('#BRtoolbar').delay(3000).animate({top:-40});
- $('#BRnav').delay(3000).animate({bottom:-53});
- changeArrow();
- $('.BRnavCntl').delay(3000).animate({height:'43px'}).delay(1000).animate({opacity:.25},1000);
- */
- $('.BRnavCntl').click(
- function(){
- if ($('#BRnavCntlBtm').hasClass('BRdn')) {
- $('#BRtoolbar').animate({top:-40});
- $('#BRnav').animate({bottom:-55});
- $('#BRnavCntlBtm').addClass('BRup').removeClass('BRdn');
- $('#BRnavCntlTop').addClass('BRdn').removeClass('BRup');
- $('#BRnavCntlBtm.BRnavCntl').animate({height:'45px'});
- $('.BRnavCntl').delay(1000).animate({opacity:.25},1000);
- } else {
- $('#BRtoolbar').animate({top:0});
- $('#BRnav').animate({bottom:0});
- $('#BRnavCntlBtm').addClass('BRdn').removeClass('BRup');
- $('#BRnavCntlTop').addClass('BRup').removeClass('BRdn');
- $('#BRnavCntlBtm.BRnavCntl').animate({height:'30px'});
- $('.BRvavCntl').animate({opacity:1})
- };
- }
- );
- $('#BRnavCntlBtm').mouseover(function(){
- if ($(this).hasClass('BRup')) {
- $('.BRnavCntl').animate({opacity:1},250);
- };
- });
- $('#BRnavCntlBtm').mouseleave(function(){
- if ($(this).hasClass('BRup')) {
- $('.BRnavCntl').animate({opacity:.25},250);
- };
- });
- $('#BRnavCntlTop').mouseover(function(){
- if ($(this).hasClass('BRdn')) {
- $('.BRnavCntl').animate({opacity:1},250);
- };
- });
- $('#BRnavCntlTop').mouseleave(function(){
- if ($(this).hasClass('BRdn')) {
- $('.BRnavCntl').animate({opacity:.25},250);
- };
- });
- });
-BookReader.prototype.makeShareDiv = function()
+BookReader.prototype.buildShareDiv = function(jShareDiv)
{
- var html = [
- '<div class="BRfloat" id="shareThis">',
- '<div class="BRfloatHead">',
- 'Share',
- '<a class="floatShut" href="javascript:;" onclick="$.fn.colorbox.close();"><span class="shift">Close</span></a>',
- '</div>',
- '<p>Copy and paste one of these options to share this book elsewhere.</p>',
- '<form method="post" action="">',
- '<fieldset>',
- '<label for="pageview">Link to this page view:</label>',
- '<input type="text" name="pageview" id="pageview" value="http://thisisthelinktothispageview"/>',
- '</fieldset>',
- '<fieldset>',
- '<label for="booklink">Link to the book:</label>',
- '<input type="text" name="booklink" id="booklink" value="http://thisisthelinktothisbook"/>',
- '</fieldset>',
- '<fieldset>',
- '<label for="iframe">Embed a mini Book Reader:</label>',
- '<fieldset class="sub">',
- '<label class="sub">',
- '<input type="radio" name="pages" id="1page" checked="checked"/>',
- '1 page',
- '</label>',
- '<label class="sub">',
- '<input type="radio" name="pages" id="2page"/>',
- '2 pages',
- '</label>',
- '<label class="sub">',
- '<input type="checkbox" name="thispage" id="thispage"/>',
- 'Open to this page?',
- '</label>',
- '</fieldset>',
- '<textarea cols="30" rows="4" name="iframe" id="iframe"><iframe src="http://thisisthestreamlink" width="480" height="480"></iframe></textarea>',
- '<p class="meta"><strong>NOTE:</strong> We\'ve tested EMBED on blogspot.com blogs as well as self-hosted Wordpress blogs. This feature will NOT work on wordpress.com blogs.</p>',
- '</fieldset>',
- '<fieldset class="center">',
- '<button type="button" onclick="$.fn.colorbox.close();">Finished</button>',
+ var pageView = document.location + '';
+ var bookView = (pageView + '').replace(/#.*/,'');
+ var self = this;
+
+ var jForm = $([
+ '<p>Copy and paste one of these options to share this book elsewhere.</p>',
+ '<form method="post" action="">',
+ '<fieldset>',
+ '<label for="pageview">Link to this page view:</label>',
+ '<input type="text" name="pageview" id="pageview" value="' + pageView + '"/>',
+ '</fieldset>',
+ '<fieldset>',
+ '<label for="booklink">Link to the book:</label>',
+ '<input type="text" name="booklink" id="booklink" value="' + bookView + '"/>',
+ '</fieldset>',
+ '<fieldset>',
+ '<label for="iframe">Embed a mini Book Reader:</label>',
+ '<fieldset class="sub">',
+ '<label class="sub">',
+ '<input type="radio" name="pages" value="' + this.constMode1up + '" checked="checked"/>',
+ '1 page',
+ '</label>',
+ '<label class="sub">',
+ '<input type="radio" name="pages" value="' + this.constMode2up + '"/>',
+ '2 pages',
+ '</label>',
+ '<label class="sub">',
+ '<input type="checkbox" name="thispage" value="thispage"/>',
+ 'Open to this page?',
+ '</label>',
'</fieldset>',
- '</form>',
- '</div>'
- ].join('\n');
+ '<textarea cols="30" rows="4" name="iframe" class="BRframeEmbed"></textarea>',
+ '<p class="meta"><strong>NOTE:</strong> We\'ve tested EMBED on blogspot.com blogs as well as self-hosted Wordpress blogs. This feature will NOT work on wordpress.com blogs.</p>',
+ '</fieldset>',
+ '<fieldset class="center">',
+ '<button type="button" onclick="$.fn.colorbox.close();">Finished</button>',
+ '</fieldset>',
+ '</form>'].join('\n'));
+
+ jForm.appendTo(jShareDiv);
+
+ jForm.find('input').bind('change', function() {
+ var form = $(this).parents('form:first');
+ var params = {};
+ params.mode = $(form.find('input[name=pages]:checked')).val();
+ if (form.find('input[name=thispage]').attr('checked')) {
+ params.page = self.getPageNum(self.currentIndex());
+ }
+
+ // $$$ changeable width/height to be added to share UI
+ var frameWidth = "480px";
+ var frameHeight = "430px";
+ form.find('.BRframeEmbed').val(self.getEmbedCode(frameWidth, frameHeight, params));
+ })
+ jForm.find('input[name=thispage]').trigger('change');
+ jForm.find('input, textarea').bind('focus', function() {
+ this.select();
+ });
- return html;
+ jForm.appendTo(jShareDiv);
+ jForm = ''; // closure
+
}
-BookReader.prototype.makeAboutDiv = function()
+// Should be overridden
+BookReader.prototype.buildInfoDiv = function(jInfoDiv)
{
- var html = [
- '<div class="BRfloat" id="aboutThis">',
- '<div class="BRfloatHead">About this book',
- '<a class="floatShut" href="javascript:;" onclick="$.fn.colorbox.close();"><span class="shift">Close</span></a>',
- '</div>',
- '<div class="BRfloatBody">'
- ];
-
- // Use 3rd-party provided function if available
- if (this.getInfoDiv) {
- html.push(this.getInfoDiv());
- } else {
- html = html.concat([
- '<div class="BRfloatMeta">',
- '<div class="BRfloatTitle">',
- '<h2><a href="', br.bookUrl, '" class="title">', BookReader.util.escapeHTML(br.bookTitle), '</a></h2>',
- '</div>',
- '</div>',
- ]);
+ jInfoDiv.find('.BRfloatTitle a').attr({'href': this.bookUrl, 'alt': this.bookTitle}).text(this.bookTitle);
+}
+
+// Can be overriden
+BookReader.prototype.initUIStrings = function()
+{
+ // Navigation handlers will be bound after all UI is in place -- makes moving icons between
+ // the toolbar and nav bar easier
+
+ // Setup tooltips -- later we could load these from a file for i18n
+ var titles = { '.logo': 'Go to Archive.org', // $$$ update after getting OL record
+ '.zoom_in': 'Zoom in',
+ '.zoom_out': 'Zoom out',
+ '.onepg': 'One-page view',
+ '.twopg': 'Two-page view',
+ '.thumb': 'Thumbnail view',
+ '.print': 'Print this page',
+ '.embed': 'Embed BookReader',
+ '.link': 'Link to this book (and page)',
+ '.bookmark': 'Bookmark this page',
+ '.read': 'Read this book aloud',
+ '.share': 'Share this book',
+ '.info': 'About this book',
+ '.full': 'Show fullscreen',
+ '.book_left': 'Flip left',
+ '.book_right': 'Flip right',
+ '.book_up': 'Page up',
+ '.book_down': 'Page down',
+ '.play': 'Play',
+ '.pause': 'Pause',
+ '.BRdn': 'Show/hide nav bar', // Would have to keep updating on state change to have just "Hide nav bar"
+ '.BRup': 'Show/hide nav bar',
+ '.book_top': 'First page',
+ '.book_bottom': 'Last page'
+ };
+ if ('rl' == this.pageProgression) {
+ titles['.book_leftmost'] = 'Last page';
+ titles['.book_rightmost'] = 'First page';
+ } else { // LTR
+ titles['.book_leftmost'] = 'First page';
+ titles['.book_rightmost'] = 'Last page';
}
-
- html = html.concat([
- '</div>', // BRfloatBody
- '<div class="BRfloatFoot">'
- ]);
-
- if (this.getInfoFooter) {
- html.push(this.getInfoFooter());
- } else {
- html.push(
- '<a href="http://openlibrary.org/dev/docs/bookreader">About the BookReader</a>'
- );
+
+ for (var icon in titles) {
+ if (titles.hasOwnProperty(icon)) {
+ $('#BookReader').find(icon).attr('title', titles[icon]);
+ }
}
-
- html = html.concat([
- '</div>', // BRfloatfoot
- '</div>' // BRfloat
- ]);
-
- return html.join('\n');
}