X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=BookReader%2FBookReader.js;h=4b3e686c09fbeb55ffb221d28152aa7a9add8525;hb=7b6cc74f09de8011a17f42c952cb3beef54fc812;hp=c35c069c2733ff09fa518c8115ba0e7367b0125d;hpb=e9182ca5b886e9908baac932eeb96934c09e7026;p=bookreader.git diff --git a/BookReader/BookReader.js b/BookReader/BookReader.js index c35c069..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. @@ -93,12 +91,22 @@ function BookReader() { // Zoom levels // $$$ provide finer grained zooming + /* this.reductionFactors = [ {reduce: 0.5, autofit: null}, {reduce: 1, autofit: null}, {reduce: 2, autofit: null}, {reduce: 4, autofit: null}, {reduce: 8, autofit: null}, {reduce: 16, autofit: null} ]; + */ + /* The autofit code ensures that fit to width and fit to height will be available */ + this.reductionFactors = [ {reduce: 0.5, autofit: null}, + {reduce: 1, autofit: null}, + {reduce: 2, autofit: null}, + {reduce: 3, autofit: null}, + {reduce: 4, autofit: null}, + {reduce: 6, autofit: null} ]; + // Object to hold parameters related to 1up mode this.onePage = { @@ -109,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' }; @@ -135,6 +143,7 @@ function BookReader() { return this; }; +(function ($) { // init() //______________________________________________________________________________ BookReader.prototype.init = function() { @@ -143,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 @@ -179,20 +197,11 @@ BookReader.prototype.init = function() { document.title = this.shortTitle(50); $("#BookReader").empty(); - - this.initToolbar(this.mode, this.ui); // Build inside of toolbar div - $("#BookReader").append("
"); + this.initToolbar(this.mode, this.ui); // Build inside of toolbar div + $("#BookReader").append(""); $("#BRcontainer").append(""); - // Autohide nav after showing for awhile - var self = this; - if (this.uiAutoHide) { - $(window).bind('load', function() { - setTimeout(function() { self.hideNavigation(); }, 3000); - }); - }; - $("#BRcontainer").bind('scroll', this, function(e) { e.data.loadLeafs(); }); @@ -202,6 +211,7 @@ BookReader.prototype.init = function() { $(window).bind('resize', this, function(e) { //console.log('resize!'); + if (1 == e.data.mode) { //console.log('centering 1page view'); if (e.data.autofit) { @@ -239,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 @@ -255,9 +280,7 @@ BookReader.prototype.init = function() { this.firstIndex = startIndex; this.prepareThumbnailView(); this.jumpToIndex(startIndex); - } else { - //this.resizePageView(); - + } else { this.displayedIndices=[0]; this.firstIndex = startIndex; this.displayedIndices = [this.firstIndex]; @@ -271,13 +294,21 @@ 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) { this.getOpenLibraryRecord(this.gotOpenLibraryRecord); } + } BookReader.prototype.setupKeyListeners = function() { @@ -465,6 +496,7 @@ BookReader.prototype.drawLeafsOnePage = function() { var img = document.createElement("img"); img.src = this._getPageURI(index, this.reduce, 0); + $(img).addClass('BRnoselect'); $(img).css('width', width+'px'); $(img).css('height', height+'px'); $(div).append(img); @@ -656,10 +688,8 @@ BookReader.prototype.drawLeafsThumbnail = function( seekIndex ) { self.firstIndex = $(this).data('leaf'); self.switchMode(self.constMode1up); event.preventDefault(); - }); - - // $$$ we don't actually go to this URL (click is handled in handler above) - link.href = '#page/' + (this.getPageNum(leaf)) +'/mode/1up' ; + event.stopPropagation(); + }); $(div).append(link); $('#BRpageview').append(div); @@ -694,11 +724,9 @@ BookReader.prototype.drawLeafsThumbnail = function( seekIndex ) { $('#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); } } @@ -785,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 @@ -1219,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; @@ -1353,8 +1403,6 @@ BookReader.prototype.switchMode = function(mode) { // this.twoPage.autofit = null; // Take zoom level from other mode this.twoPageCalculateReductionFactors(); this.reduce = this.quantizeReduce(this.reduce, this.twoPage.reductionFactors); - $('button.thumb').show(); - $('button.twopg').hide(); this.prepareTwoPageView(); this.twoPageCenterView(0.5, 0.5); // $$$ TODO preserve center } @@ -1498,7 +1546,7 @@ BookReader.prototype.prepareTwoPageView = function(centerPercentageX, centerPerc $(this.twoPage.coverDiv).attr('id', 'BRbookcover').css({ width: this.twoPage.bookCoverDivWidth + 'px', height: this.twoPage.bookCoverDivHeight+'px', - visibility: 'visible', + visibility: 'visible' }).appendTo('#BRtwopageview'); this.leafEdgeR = document.createElement('div'); @@ -1520,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'); @@ -1571,7 +1619,7 @@ BookReader.prototype.prepareTwoPageView = function(centerPercentageX, centerPerc //this.indicesToDisplay=[firstLeaf, firstLeaf+1]; //console.log('indicesToDisplay: ' + this.indicesToDisplay[0] + ' ' + this.indicesToDisplay[1]); - + this.drawLeafsTwoPage(); this.updateToolbarZoom(this.reduce); @@ -1666,7 +1714,7 @@ BookReader.prototype.calculateSpreadSize = function() { // set based on reduction factor spreadSize = this.getSpreadSizeFromReduce(firstIndex, secondIndex, this.reduce); } - + // Both pages together this.twoPage.height = spreadSize.height; this.twoPage.width = spreadSize.width; @@ -1738,7 +1786,7 @@ BookReader.prototype.getIdealSpreadSize = function(firstIndex, secondIndex) { height: this._getPageHeight(secondIndex), width: this._getPageWidth(secondIndex) } - + var firstIndexRatio = first.height / first.width; var secondIndexRatio = second.height / second.width; //console.log('firstIndexRatio = ' + firstIndexRatio + ' secondIndexRatio = ' + secondIndexRatio); @@ -1746,10 +1794,8 @@ BookReader.prototype.getIdealSpreadSize = function(firstIndex, secondIndex) { var ratio; if (Math.abs(firstIndexRatio - canon5Dratio) < Math.abs(secondIndexRatio - canon5Dratio)) { ratio = firstIndexRatio; - //console.log('using firstIndexRatio ' + ratio); } else { ratio = secondIndexRatio; - //console.log('using secondIndexRatio ' + ratio); } var totalLeafEdgeWidth = parseInt(this.numLeafs * 0.1); @@ -1807,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); @@ -2176,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 @@ -2197,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; @@ -2276,7 +2342,6 @@ BookReader.prototype.willChangeToIndex = function(index) { // Update navbar position icon - leads page change animation this.updateNavIndex(index); - } // flipRightToLeft(nextL, nextR, gutter) @@ -2325,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', @@ -2338,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; @@ -2377,13 +2447,18 @@ 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; + } + + if (! e.data.self.twoPageIsZoomedIn()) { + e.data.self.ttsStop(); + e.data.self.left(); } - e.data.self.ttsStop(); - e.data.self.left(); - e.preventDefault(); } ); @@ -2391,12 +2466,18 @@ 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; + } + + if (! e.data.self.twoPageIsZoomedIn()) { + e.data.self.ttsStop(); + e.data.self.right(); } - e.data.self.ttsStop(); - e.data.self.right(); e.preventDefault(); } ); @@ -2461,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 } @@ -2478,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 } @@ -2645,8 +2724,11 @@ BookReader.prototype.getPageWidth2UP = function(index) { //______________________________________________________________________________ BookReader.prototype.search = function(term) { //console.log('search called with term=' + term); + + $('#textSrch').blur(); //cause mobile safari to hide the keyboard + var url = 'http://'+this.server.replace(/:.+/, ''); //remove the port and userdir - url += '/~edward/inside_jsonp.php?item_id='+this.bookId; + url += '/fulltext/inside.php?item_id='+this.bookId; url += '&doc='+this.subPrefix; //TODO: test with subitem url += '&path='+this.bookPath.replace(new RegExp('/'+this.subPrefix+'$'), ''); //remove subPrefix from end of path url += '&q='+escape(term); @@ -2657,26 +2739,30 @@ BookReader.prototype.search = function(term) { this.removeSearchResults(); this.showProgressPopup(' Search results will appear below...'); - this.ttsAjax = $.ajax({url:url, dataType:'jsonp', jsonpCallback:'BRSearchCallback'}); + $.ajax({url:url, dataType:'jsonp', jsonpCallback:'br.BRSearchCallback'}); } // BRSearchCallback() //______________________________________________________________________________ -// Unfortunately, we can't pass 'br.searchCallback' to our search service, -// because it can't handle the '.' -function BRSearchCallback(results) { +BookReader.prototype.BRSearchCallback = function(results) { //console.log('got ' + results.matches.length + ' results'); br.removeSearchResults(); br.searchResults = 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; } @@ -2871,9 +2957,10 @@ BookReader.prototype.updateSearchHilites2UP = function() { var i, j; for (i=0; i