X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=BookReader%2FBookReader.js;h=161f8c4158baab3744e7b62226cdd8c98b7060af;hb=df3799f1f94a4f8d1d772fa71ee5e5dd771b7033;hp=2069e7fa331e64407f7b65f810254a111d43427f;hpb=7cc9fa40566fa741ec45b52d4e2a2a8799f09923;p=bookreader.git diff --git a/BookReader/BookReader.js b/BookReader/BookReader.js index 2069e7f..161f8c4 100644 --- a/BookReader/BookReader.js +++ b/BookReader/BookReader.js @@ -93,12 +93,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 = { @@ -179,20 +189,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 +203,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) { @@ -255,9 +257,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 +271,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 +473,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 +665,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 +701,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); } } @@ -1496,7 +1501,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'); @@ -1569,7 +1574,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); @@ -1664,7 +1669,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; @@ -1736,7 +1741,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); @@ -1744,10 +1749,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); @@ -1805,6 +1808,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); @@ -2274,7 +2291,6 @@ BookReader.prototype.willChangeToIndex = function(index) { // Update navbar position icon - leads page change animation this.updateNavIndex(index); - } // flipRightToLeft(nextL, nextR, gutter) @@ -2377,11 +2393,13 @@ BookReader.prototype.setMouseHandlers2UP = function() { function(e) { if (e.button == 2) { // right click - return; + 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,10 +2409,13 @@ BookReader.prototype.setMouseHandlers2UP = function() { function(e) { if (e.button == 2) { // right click - return; + 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(); } ); @@ -2644,7 +2665,7 @@ 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 + $('#textSrch').blur(); //cause mobile safari to hide the keyboard var url = 'http://'+this.server.replace(/:.+/, ''); //remove the port and userdir url += '/fulltext/inside.php?item_id='+this.bookId; @@ -2658,7 +2679,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() @@ -2971,56 +2992,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 @@ -3101,6 +3075,8 @@ BookReader.prototype.showBookmarkCode = function() { //______________________________________________________________________________ BookReader.prototype.autoToggle = function() { + this.ttsStop(); + var bComingFrom1up = false; if (2 != this.mode) { bComingFrom1up = true; @@ -3265,14 +3241,14 @@ 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 + '' + '' + '' - + '' + // $$$ not yet implemented + //+ '' + '' + '' + '' @@ -3290,61 +3266,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, @@ -3352,12 +3273,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 @@ -3382,24 +3304,36 @@ BookReader.prototype.initNavbar = function() { .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'}); - //XXXmang remove once done testing - //this.addSearchResult("There is a place where the sidewalk 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 sidewalk 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( + '
' + + "" + + '' + + '' + + '' + + "" + + "" + + "" + + '
' + ); + $('#BRembedreturn a').text(this.bookTitle); } BookReader.prototype.updateNavPageNum = function(index) { @@ -3475,6 +3409,9 @@ BookReader.prototype.addSearchResult = function(queryString, pageIndex) { shadow: false }) .hover( function() { + // remove from other markers then turn on just for this + // XXX should be done when nav slider moves + $('.search,.chapter').removeClass('front'); $(this).addClass('front'); }, function() { $(this).removeClass('front'); @@ -3539,6 +3476,8 @@ BookReader.prototype.addChapter = function(chapterTitle, pageNumber, pageIndex) shadow: false }) .hover( function() { + // remove hover effect from other markers then turn on just for this + $('.search,.chapter').removeClass('front'); $(this).addClass('front'); }, function() { $(this).removeClass('front'); @@ -3606,20 +3545,20 @@ 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( "
" + "" - /* XXXmang integrate search */ + "
" - // XXXmang icons incorrect or handlers wrong + "" + "" + "" @@ -3628,7 +3567,8 @@ BookReader.prototype.initToolbar = function(mode, ui) { //+ "" + "
" + "" - + "Back to" + this.bookTitle + "" + + "Back to" + this.bookTitle + "" // XXX escape + + "
" + "
" /* + "
" @@ -3643,8 +3583,9 @@ BookReader.prototype.initToolbar = function(mode, ui) { + "
" */ ); - - $('#BRtoolbar .pause').hide(); + + $('#BRtoolbar .BRnavCntl').addClass('BRup'); + $('#BRtoolbar .pause').hide(); this.updateToolbarZoom(this.reduce); // Pretty format @@ -3657,44 +3598,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) ) { @@ -3708,12 +3612,58 @@ BookReader.prototype.initToolbar = function(mode, ui) { if ( ! (this.canSwitchToMode(this.constMode2up) || this.canSwitchToMode(this.constModeThumb)) ) { jToolbar.find('.one_page_mode').hide(); } + + // $$$ 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(); } }); + $('
').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', + '
', + '
', + '
', + '
', + '
', + '
', + '

', + '
', + '
', + '
', + '', + '
'].join('\n') + ); +} + +BookReader.prototype.blankShareDiv = function() { + return $([ + '
', + '
', + 'Share', + 'Close', + '
', + '
'].join('\n') + ); +} + // switchToolbarMode //______________________________________________________________________________ @@ -3792,11 +3742,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; }); @@ -3823,7 +3775,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; @@ -3881,13 +3834,57 @@ BookReader.prototype.bindNavigationHandlers = function() { return false; }); - // XXX fix integration - // XXX Mobile safari was not picking up this handler, so - // I explictly set the form action in initToolbar() - // $('#booksearch').bind('submit', function() { - // self.search($('#textSrch').val()); - // }); + 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 }, @@ -3940,9 +3937,14 @@ BookReader.prototype.initSwipeData = function(clientX, clientY) { */ this._swipe = { mightBeSwiping: false, + didSwipe: false, + mightBeDraggin: false, + didDrag: false, startTime: (new Date).getTime(), startX: clientX, startY: clientY, + lastX: clientX, + lastY: clientY, deltaX: 0, deltaY: 0, deltaT: 0 @@ -3956,6 +3958,7 @@ BookReader.prototype.swipeMousedownHandler = function(event) { var self = event.data['br']; 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 @@ -3981,14 +3984,15 @@ BookReader.prototype.swipeMousemoveHandler = function(event) { var absY = Math.abs(_swipe.deltaY); // Minimum distance in the amount of tim to trigger the swipe - var minSwipeLength = Math.max($('#BookReader').width() / 5, 100); - var maxSwipeTime = 1000; + var minSwipeLength = Math.min($('#BookReader').width() / 5, 80); + var maxSwipeTime = 400; // Check for horizontal swipe if (absX > absY && (absX > minSwipeLength) && _swipe.deltaT < maxSwipeTime) { //console.log('swipe! ' + _swipe.deltaX + ',' + _swipe.deltaY + ' ' + _swipe.deltaT + 'ms'); _swipe.mightBeSwiping = false; // only trigger once + _swipe.didSwipe = true; if (event.data['br'].mode == event.data['br'].constMode2up) { if (_swipe.deltaX < 0) { event.data['br'].right(); @@ -3997,11 +4001,29 @@ BookReader.prototype.swipeMousemoveHandler = function(event) { } } } + + if ( _swipe.deltaT > maxSwipeTime && !_swipe.didSwipe) { + if (_swipe.mightBeDragging) { + // Dragging + _swipe.didDrag = true; + $('#BRcontainer') + .scrollTop($('#BRcontainer').scrollTop() - event.clientY + _swipe.lastY) + .scrollLeft($('#BRcontainer').scrollLeft() - event.clientX + _swipe.lastX); + } + } + _swipe.lastX = event.clientX; + _swipe.lastY = event.clientY; } BookReader.prototype.swipeMouseupHandler = function(event) { - //console.log('swipe mouseup'); - //console.log(event); - event.data['br']._swipe.mightBeSwiping = false; + var _swipe = event.data['br']._swipe; + //console.log('swipe mouseup - did swipe ' + _swipe.didSwipe); + _swipe.mightBeSwiping = false; + _swipe.mightBeDragging = false; + if (_swipe.didSwipe || _swipe.didDrag) { + // Swallow event if completed swipe gesture + event.preventDefault(); + event.stopPropagation(); + } } BookReader.prototype.bindMozTouchHandlers = function() { @@ -4009,19 +4031,19 @@ BookReader.prototype.bindMozTouchHandlers = function() { // Currently only want touch handlers in 2up $('#BookReader').bind('MozTouchDown', function(event) { - //console.log('MozTouchDown ' + event.streamId + ' ' + event.clientX + ',' + event.clientY); + //console.log('MozTouchDown ' + event.originalEvent.streamId + ' ' + event.target + ' ' + event.clientX + ',' + event.clientY); if (this.mode == this.constMode2up) { event.preventDefault(); } }) .bind('MozTouchMove', function(event) { - //console.log('MozTouchMove - ' + event.streamId + ' ' + event.clientX + ',' + event.clientY) + //console.log('MozTouchMove - ' + event.originalEvent.streamId + ' ' + event.target + ' ' + event.clientX + ',' + event.clientY) if (this.mode == this.constMode2up) { event.preventDefault(); } }) .bind('MozTouchUp', function(event) { - //console.log('MozTouchUp - ' + event.streamId + ' ' + event.clientX + ',' + event.clientY); + //console.log('MozTouchUp - ' + event.originalEvent.streamId + ' ' + event.target + ' ' + event.clientX + ',' + event.clientY); if (this.mode = this.constMode2up) { event.preventDefault(); } @@ -4066,6 +4088,16 @@ BookReader.prototype.showNavigation = function() { } } +// 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. @@ -4271,8 +4303,10 @@ BookReader.prototype.fragmentFromParams = function(params) { 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 @@ -4500,15 +4534,22 @@ BookReader.prototype._getPageURI = function(index, reduce, rotate) { BookReader.prototype.gotOpenLibraryRecord = function(self, olObject) { // $$$ could refactor this so that 'this' is available if (olObject) { + // console.log(olObject); if (olObject['table_of_contents']) { // XXX check here that TOC is valid self.updateTOC(olObject['table_of_contents']); } - } - - // $$$mang cleanup - $('#BRreturn a').attr('href', 'http://openlibrary.org' + olObject.key); + // $$$mang cleanup + self.bookUrl = 'http://openlibrary.org' + olObject.key; + self.bookTitle = olObject['title']; + $('#BRreturn a').attr('href', this.bookUrl); + $('#BookReader .logo').attr('title', 'Go to Open Library'); // i18n + + $('#BRinfo').remove(); + $('#BRshare').after(self.blankInfoDiv()); + self.buildInfoDiv($('#BRinfo')); + } } // Library functions @@ -4545,6 +4586,15 @@ BookReader.util = { return (outer.document || outer); }, + escapeHTML: function (str) { + return( + str.replace(/&/g,'&'). + replace(/>/g,'>'). + replace(/Copy and paste one of these options to share this book elsewhere.

', + '
', + '
', + '', + '', + '
', + '
', + '', + '', + '
', + '
', + '', + '
', + '', + '', + '', + '
', + '', + '

NOTE: We\'ve tested EMBED on blogspot.com blogs as well as self-hosted Wordpress blogs. This feature will NOT work on wordpress.com blogs.

', + '
', + '
', + '', + '
', + '
'].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()); + } + + // console.log(params); + form.find('.BRframeEmbed').val(self.getEmbedCode()); + }) + jForm.find('input[name=thispage]').trigger('change'); + jForm.find('input, textarea').bind('focus', function() { + this.select(); }); + + jForm.appendTo(jShareDiv); + jForm = ''; // closure + +} + +// Should be overridden +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]); + } + } +}