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>");
}
});
+ 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
// 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
// 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
}).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');
//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
$(self.twoPage.coverDiv).css({
width: self.twoPageCoverWidth(newWidthL+newWidthR)+'px',
left: gutter-newWidthL-newLeafEdgeWidthL-self.twoPage.coverInternalPadding+'px'
- });
+ });
$(self.leafEdgeTmp).remove();
self.leafEdgeTmp = null;
$(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',
$(self.twoPage.coverDiv).css({
width: self.twoPageCoverWidth(newWidthL+newWidthR)+'px',
left: gutter - newWidthL - newLeafEdgeWidthL - self.twoPage.coverInternalPadding + 'px'
- });
-
+ });
+
$(self.leafEdgeTmp).remove();
self.leafEdgeTmp = null;
this.setClickHandler2UP( this.prefetchedImgs[this.twoPage.currentIndexL],
{ self: this },
function(e) {
- if (e.button == 2) {
+ if (e.which == 3) {
// right click
+ if (e.data.self.protected) {
+ return false;
+ }
return true;
}
this.setClickHandler2UP( this.prefetchedImgs[this.twoPage.currentIndexR],
{ self: this },
function(e) {
- if (e.button == 2) {
+ if (e.which == 3) {
// right click
+ if (e.data.self.protected) {
+ return false;
+ }
return true;
}
//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
}
//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 hasn't been indexed for searching yet. We've just started indexing it, so search should be available soon. Please try again later. 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
.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'});
*/
}
+// 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) {
var pageNum = this.getPageNum(index);
var pageStr;
}
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 = '';
//+ "<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>"
+ + "<span id='BRreturn'><a></a></span>"
+ "<div id='BRnavCntlTop' class='BRnabrbuvCntl'></div>"
+ "</div>"
/*
*/
);
+ // 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();
// $$$ 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(); } });
$('<div style="display: none;"></div>').append(this.blankShareDiv()).append(this.blankInfoDiv()).appendTo($('body'));
});
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')) {
$('.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);
-
+
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) {
}
_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;
}
// $$$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);
- $('#BookReader .logo').attr('title', 'Go to Open Library'); // i18n
+ $('#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'));
+
+ // Check for borrowed book
+ if (self.olAuth) {
+ var returnUrl = self.olHost + olObject.key + '/do_return/borrow';
+ var borrowUrl = self.olHost + olObject.key + '/borrow';
+
+ /*
+ $('<a/>')
+ .attr('href', borrowUrl)
+ .text('Return this book')
+ .click(function(event) {
+ event.preventDefault();
+ $('#BRreturnform').trigger('submit');
+ })
+ .appendTo('#BRreturn');
+ */
+
+ $('<form id="BRreturnform" action="' + returnUrl + '" method="post"><input type="submit" value="Return book" onclick="olAuth.deleteCookies();"/><input type="hidden" name="action" value="return" /></form>')
+ .appendTo('#BRreturn');
+
+ } else {
+ $('<a/>').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' } );
+
+
}
}
params.page = self.getPageNum(self.currentIndex());
}
- // console.log(params);
- var embedLink = self.getEmbedURL( params );
- form.find('.BRframeEmbed').val('<iframe src="' + embedLink + '" width="480" height="480"></iframe>');
+ // $$$ 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() {