X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=BookReader%2FBookReader.js;h=4b3e686c09fbeb55ffb221d28152aa7a9add8525;hb=7b6cc74f09de8011a17f42c952cb3beef54fc812;hp=7b7d9ab1db79173fff7bc47c788ea9fc075ade35;hpb=7bf029c8ebe1e358afeba01683835ae3d3c61fef;p=bookreader.git diff --git a/BookReader/BookReader.js b/BookReader/BookReader.js index 7b7d9ab..4b3e686 100644 --- a/BookReader/BookReader.js +++ b/BookReader/BookReader.js @@ -18,7 +18,6 @@ This file is part of BookReader. The BookReader source is hosted at http://github.com/openlibrary/bookreader/ - archive.org cvs $Revision: 1.2 $ $Date: 2009-06-22 18:42:51 $ */ // BookReader() @@ -80,9 +79,8 @@ function BookReader() { 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. @@ -119,7 +117,7 @@ function BookReader() { 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' }; @@ -145,6 +143,7 @@ function BookReader() { return this; }; +(function ($) { // init() //______________________________________________________________________________ BookReader.prototype.init = function() { @@ -153,7 +152,16 @@ BookReader.prototype.init = function() { this.pageScale = this.reduce; // preserve current reduce // Find start index and mode if set in location hash - var params = this.paramsFromFragment(window.location.hash); + var params = {}; + if (window.location.hash) { + // params explicitly set in URL + params = this.paramsFromFragment(window.location.hash); + } else { + // params not explicitly set, use defaults if we have them + if ('defaults' in this) { + params = this.paramsFromFragment(this.defaults); + } + } // Sanitize/process parameters @@ -189,7 +197,7 @@ BookReader.prototype.init = function() { document.title = this.shortTitle(50); $("#BookReader").empty(); - + this.initToolbar(this.mode, this.ui); // Build inside of toolbar div $("#BookReader").append("
"); $("#BRcontainer").append("
"); @@ -241,6 +249,21 @@ BookReader.prototype.init = function() { } }); + if (this.protected) { + $('.BRpagediv1up').live('contextmenu dragstart', this, function(e) { + return false; + }); + + $('.BRpageimage').live('contextmenu dragstart', this, function(e) { + return false; + }); + + $('.BRpagedivthumb').live('contextmenu dragstart', this, function(e) { + return false; + }); + + } + $('.BRpagediv1up').bind('mousedown', this, function(e) { // $$$ the purpose of this is to disable selection of the image (makes it turn blue) // but this also interferes with right-click. See https://bugs.edge.launchpad.net/gnubook/+bug/362626 @@ -271,8 +294,15 @@ BookReader.prototype.init = function() { // 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) { @@ -783,9 +813,17 @@ BookReader.prototype.lazyLoadImage = function (dummyImage) { // Remove class so we no longer count as loading $(this).removeClass('BRlazyloading'); }) - .attr( { width: $(dummyImage).width(), - height: $(dummyImage).height(), - src: $(dummyImage).data('srcURL') + + //the width set with .attr is ignored by Internet Explorer, causing it to show the image at its original size + //but with this one line of css, even IE shows the image at the proper size + .css({ + 'width': $(dummyImage).width()+'px', + 'height': $(dummyImage).height()+'px' + }) + .attr({ + 'width': $(dummyImage).width(), + 'height': $(dummyImage).height(), + 'src': $(dummyImage).data('srcURL') }); // replace with the new img @@ -1217,7 +1255,21 @@ BookReader.prototype._reduceSort = function(a, b) { // Attempts to jump to page. Returns true if page could be found, false otherwise. BookReader.prototype.jumpToPage = function(pageNum) { - var pageIndex = this.getPageIndex(pageNum); + var pageIndex; + + // Check for special "leaf" + var re = new RegExp('^leaf(\\d+)'); + leafMatch = re.exec(pageNum); + if (leafMatch) { + console.log(leafMatch[1]); + pageIndex = this.leafNumToIndex(parseInt(leafMatch[1],10)); + if (pageIndex === null) { + pageIndex = undefined; // to match return type of getPageIndex + } + + } else { + pageIndex = this.getPageIndex(pageNum); + } if ('undefined' != typeof(pageIndex)) { var leafTop = 0; @@ -1516,10 +1568,10 @@ BookReader.prototype.prepareTwoPageView = function(centerPercentageX, centerPerc }).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'); @@ -1801,6 +1853,20 @@ BookReader.prototype.twoPageGetAutofitReduce = function() { 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); @@ -2170,10 +2236,16 @@ BookReader.prototype.flipLeftToRight = function(newIndexL, newIndexR) { //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.prefetchedImgs[newIndexL]).css('zIndex', 2); + + //jquery adds display:block to the element style, which interferes with our print css + $(self.prefetchedImgs[newIndexL]).css('display', ''); + $(self.prefetchedImgs[newIndexR]).css('display', ''); $(self.leafEdgeR).css({ // Moves the right leaf edge @@ -2191,7 +2263,7 @@ BookReader.prototype.flipLeftToRight = function(newIndexL, newIndexR) { $(self.twoPage.coverDiv).css({ width: self.twoPageCoverWidth(newWidthL+newWidthR)+'px', left: gutter-newWidthL-newLeafEdgeWidthL-self.twoPage.coverInternalPadding+'px' - }); + }); $(self.leafEdgeTmp).remove(); self.leafEdgeTmp = null; @@ -2270,7 +2342,6 @@ BookReader.prototype.willChangeToIndex = function(index) { // Update navbar position icon - leads page change animation this.updateNavIndex(index); - } // flipRightToLeft(nextL, nextR, gutter) @@ -2319,9 +2390,14 @@ BookReader.prototype.flipRightToLeft = function(newIndexL, newIndexR) { $(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); + + //jquery adds display:block to the element style, which interferes with our print css + $(self.prefetchedImgs[newIndexL]).css('display', ''); + $(self.prefetchedImgs[newIndexR]).css('display', ''); $(self.leafEdgeL).css({ width: newLeafEdgeWidthL+'px', @@ -2332,8 +2408,8 @@ BookReader.prototype.flipRightToLeft = function(newIndexL, newIndexR) { $(self.twoPage.coverDiv).css({ width: self.twoPageCoverWidth(newWidthL+newWidthR)+'px', left: gutter - newWidthL - newLeafEdgeWidthL - self.twoPage.coverInternalPadding + 'px' - }); - + }); + $(self.leafEdgeTmp).remove(); self.leafEdgeTmp = null; @@ -2371,14 +2447,15 @@ BookReader.prototype.setMouseHandlers2UP = function() { this.setClickHandler2UP( this.prefetchedImgs[this.twoPage.currentIndexL], { self: this }, function(e) { - if (e.button == 2) { + if (e.which == 3) { // right click - return; + if (e.data.self.protected) { + return false; + } + 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(); } @@ -2389,16 +2466,17 @@ BookReader.prototype.setMouseHandlers2UP = function() { this.setClickHandler2UP( this.prefetchedImgs[this.twoPage.currentIndexR], { self: this }, function(e) { - if (e.button == 2) { + if (e.which == 3) { // right click - return; + if (e.data.self.protected) { + return false; + } + 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(); } @@ -2464,14 +2542,13 @@ BookReader.prototype.prepareFlipLeftToRight = function(prevL, prevR) { //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 } @@ -2481,13 +2558,12 @@ BookReader.prototype.prepareFlipLeftToRight = function(prevL, prevR) { //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 } @@ -2663,7 +2739,7 @@ BookReader.prototype.search = function(term) { this.removeSearchResults(); this.showProgressPopup(' Search results will appear below...'); - this.ttsAjax = $.ajax({url:url, dataType:'jsonp', jsonpCallback:'br.BRSearchCallback'}); + $.ajax({url:url, dataType:'jsonp', jsonpCallback:'br.BRSearchCallback'}); } // BRSearchCallback() @@ -2675,12 +2751,18 @@ BookReader.prototype.BRSearchCallback = function(results) { //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 = "

This book hasn't been indexed for searching yet. We've just started indexing it, so search should be available soon. Please try again later. Thanks!

"; + timeout = 5000; + } + $(br.popup).html(errStr); setTimeout(function(){ $(br.popup).fadeOut('slow', function() { br.removeProgressPopup(); }) - },1000); + },timeout); return; } @@ -2976,56 +3058,9 @@ BookReader.prototype.getPrintURI = function() { 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 = '' + this.bookTitle + ''; - iframeStr += '
'; - iframeStr += ''; - iframeStr += '
'; - iframeStr += ''; - - 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 @@ -3272,8 +3307,7 @@ BookReader.prototype.jumpIndexForRightEdgePageX = function(pageX) { 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( '
' + '
' // Page turn buttons + '' @@ -3298,61 +3332,6 @@ BookReader.prototype.initNavbar = function() { + '
' ); -/* -
-
- A related distinction is between the emotion and the results of the emotion, principally behaviors and emotional expressions. People often behave in certain ways as a direct result of their emotional state, such as crying, fighting or fleeing. Page 163 -
IV. The Witch | Page 163
-
-
-*/ - - /* $$$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, @@ -3360,12 +3339,13 @@ BookReader.prototype.initNavbar = function() { 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 @@ -3386,20 +3366,9 @@ BookReader.prototype.initNavbar = function() { //append icon to handle var handleHelper = $('#BRpager .ui-slider-handle') - // $$$mang update logic for setting the page number label -- use page numbers if available .append('
'); //.wrap('
').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'}); @@ -3412,11 +3381,31 @@ BookReader.prototype.initNavbar = function() { */ } +// initEmbedNavbar +//______________________________________________________________________________ +// Initialize the navigation bar when embedded +BookReader.prototype.initEmbedNavbar = function() { + var thisLink = (window.location + '').replace('?ui=embed',''); // IA-specific + + $('#BookReader').append( + '
' + + "" + + '' + + '' + + '' + + "" + + "" + + "" + + '
' + ); + $('#BRembedreturn a').text(this.bookTitle); +} + BookReader.prototype.updateNavPageNum = function(index) { var pageNum = this.getPageNum(index); var pageStr; if (pageNum[0] == 'n') { // funny index - pageStr = index + ' / ' + this.numLeafs; + pageStr = index + 1 + ' / ' + this.numLeafs; // Accessible index starts at 0 (alas) so we add 1 to make human } else { pageStr = 'Page ' + pageNum; } @@ -3621,14 +3610,17 @@ BookReader.prototype.addChapterFromEntry = function(tocEntryObject) { } 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 = ""; } - - $("body").append( + + $("#BookReader").append( "
" + "" + "
" @@ -3640,8 +3632,8 @@ BookReader.prototype.initToolbar = function(mode, ui) { //+ "" + "
" + "" - + "Back to" + this.bookTitle + "" - + "
" + + "" + + "
" + "
" /* + "
" @@ -3657,6 +3649,15 @@ BookReader.prototype.initToolbar = function(mode, ui) { */ ); + // 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 @@ -3670,44 +3671,7 @@ BookReader.prototype.initToolbar = function(mode, ui) { // 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) ) { @@ -3724,16 +3688,24 @@ BookReader.prototype.initToolbar = function(mode, ui) { // $$$ Don't hardcode ids var self = this; - jToolbar.find('.share').colorbox({inline: true, opacity: "0.5", href: "#BRshare", onLoad: function() { self.ttsStop(); } }); - jToolbar.find('.info').colorbox({inline: true, opacity: "0.5", href: "#BRinfo", onLoad: function() { self.ttsStop(); } }); + 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(); } }); - $("body").append(['
', - '
', - '
', - 'Share', - 'Close', - '
', - '
', + $('
').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 $([ '
', '
About this book', 'Close', @@ -3745,24 +3717,24 @@ BookReader.prototype.initToolbar = function(mode, ui) { '
', '

', '
', - - '
', '
', '
', '', - '
'].join('\n')); + '
'].join('\n') + ); +} - $('#BRinfo .BRfloatTitle a').attr( {'href': this.bookUrl} ).text(this.bookTitle).addClass('title').appendTo - - // These functions can be overridden - this.buildInfoDiv($('#BRinfo')); - this.buildShareDiv($('#BRshare')); - - // Switch to requested mode -- binds other click handlers - //this.switchToolbarMode(mode); - +BookReader.prototype.blankShareDiv = function() { + return $([ + '
', + '
', + 'Share', + 'Close', + '
', + '
'].join('\n') + ); } @@ -3843,11 +3815,13 @@ BookReader.prototype.bindNavigationHandlers = function() { }); 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; }); @@ -3874,7 +3848,8 @@ BookReader.prototype.bindNavigationHandlers = function() { self.printPage(); return false; }); - + + // Note: Functionality has been replaced by .share jIcons.filter('.embed').click(function(e) { self.showEmbedCode(); return false; @@ -3932,6 +3907,16 @@ BookReader.prototype.bindNavigationHandlers = function() { 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')) { @@ -3982,14 +3967,6 @@ BookReader.prototype.bindNavigationHandlers = function() { $('.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(); @@ -4042,17 +4019,37 @@ BookReader.prototype.initSwipeData = function(clientX, clientY) { BookReader.prototype.swipeMousedownHandler = function(event) { //console.log('swipe mousedown'); //console.log(event); - + var self = event.data['br']; + + // We should be the last bubble point for the page images + // Disable image drag and select, but keep right-click + if (event.which == 3) { + if (self.protected) { + return false; + } + return true; + } + + $(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) { @@ -4101,19 +4098,29 @@ 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; @@ -4288,7 +4295,7 @@ BookReader.prototype.updateFromParams = function(params) { this.jumpToPage(params.page); } } - + // $$$ process /region // $$$ process /highlight } @@ -4629,31 +4636,44 @@ BookReader.prototype.gotOpenLibraryRecord = function(self, olObject) { } // $$$mang cleanup - self.bookUrl = 'http://openlibrary.org' + olObject.key; + self.bookUrl = self.olHost + olObject.key; self.bookTitle = olObject['title']; - $('#BRreturn a').attr('href', this.bookUrl); + $('#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(['
', - '
About this book', - 'Close', - '
', - '
', - '
', - '
', - '
', - '
', - '

', - '
', - - '
', - '
', - '
', - '
', - 'About the BookReader', - '
', - ''].join('\n')); + $('#BRshare').after(self.blankInfoDiv()); self.buildInfoDiv($('#BRinfo')); + + // Check for borrowed book + if (self.olAuth) { + var returnUrl = self.olHost + olObject.key + '/do_return/borrow'; + var borrowUrl = self.olHost + olObject.key + '/borrow'; + + /* + $('') + .attr('href', borrowUrl) + .text('Return this book') + .click(function(event) { + event.preventDefault(); + $('#BRreturnform').trigger('submit'); + }) + .appendTo('#BRreturn'); + */ + + $('
') + .appendTo('#BRreturn'); + + } else { + $('
').attr( { 'href': self.bookUrl, 'title': 'Go to this book\'s page on Open Library' } ) + .text('On openlibrary.org') + .appendTo('#BRreturn'); + } + + $('#BRreturn').css({ 'line-height': '19px'} ); + $('#BRreturn a').css( {'height': '18px' } ); + + } } @@ -4796,15 +4816,17 @@ BookReader.prototype.ttsStartCB = function (data) { this.showProgressPopup('Loading audio...'); - ///// whileloading: broken on safari - ///// onload fires on safari, but *after* the sound starts playing.. + ///// Many soundManger2 callbacks are broken when using HTML5 audio. + ///// whileloading: broken on safari, worked in FF4, but broken on FireFox 5 + ///// onload: fires on safari, but *after* the sound starts playing, and does not fire in FF or IE9 + ///// onbufferchange: fires in FF5 using HTML5 audio, but not in safari using flash audio + ///// whileplaying: fires everywhere this.ttsPosition = -1; var snd = soundManager.createSound({ id: 'chunk'+this.ttsIndex+'-0', - //url: 'http://home.us.archive.org/~rkumar/arctic.ogg', url: 'http://'+this.server+'/BookReader/BookReaderGetTTS.php?string=' + escape(data[0][0]) + '&format=.'+this.ttsFormat, //the .ogg is to trick SoundManager2 to use the HTML5 audio player - whileloading: function(){if (this.bytesLoaded == this.bytesTotal) this.br.removeProgressPopup();}, //onload never fires in FF... - onload: function(){this.br.removeProgressPopup();} //whileloading never fires in safari... + onload: function(){this.br.removeProgressPopup();}, //fires in safari... + onbufferchange: function(){if (false == this.isBuffering) this.br.removeProgressPopup();} //fires in FF and IE9 }); snd.br = this; snd.load(); @@ -5187,9 +5209,10 @@ BookReader.prototype.buildShareDiv = function(jShareDiv) params.page = self.getPageNum(self.currentIndex()); } - console.log(params); - var embedLink = self.getEmbedURL( params ); - form.find('.BRframeEmbed').val(''); + // $$$ 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() { @@ -5206,3 +5229,51 @@ BookReader.prototype.buildInfoDiv = function(jInfoDiv) { 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'; + } + + for (var icon in titles) { + if (titles.hasOwnProperty(icon)) { + $('#BookReader').find(icon).attr('title', titles[icon]); + } + } +} +})(jQuery);