function BookReader() {
this.reduce = 4;
- this.padding = 10;
+ this.padding = 0;
this.mode = 1; //1, 2, 3
this.ui = 'full'; // UI mode
// Object to hold parameters related to 2up mode
this.twoPage = {
- coverInternalPadding: 10, // Width of cover
- coverExternalPadding: 10, // Padding outside of cover
- bookSpineDivWidth: 30, // Width of book spine $$$ consider sizing based on book length
+ coverInternalPadding: 0, // Width of cover
+ coverExternalPadding: 0, // Padding outside of cover
+ bookSpineDivWidth: 0, // Width of book spine $$$ consider sizing based on book length
autofit: 'auto'
};
// Find start index and mode if set in location hash
var params = this.paramsFromFragment(window.location.hash);
+
+ // Sanitize/process parameters
+
+ if ( !this.canSwitchToMode( this.mode ) ) {
+ this.mode = this.constMode1up;
+ }
if ('undefined' != typeof(params.index)) {
startIndex = params.index;
} else if ('undefined' != typeof(params.page)) {
startIndex = this.getPageIndex(params.page);
}
-
+
if ('undefined' == typeof(startIndex)) {
if ('undefined' != typeof(this.titleLeaf)) {
- startIndex = this.leafNumToIndex(this.titleLeaf);
+ // title leaf is known - but only use as default if book has a few pages
+ if (this.numLeafs > 2) {
+ startIndex = this.leafNumToIndex(this.titleLeaf);
+ }
}
}
// search engine visibility
document.title = this.shortTitle(50);
- // Sanitize parameters
- if ( !this.canSwitchToMode( this.mode ) ) {
- this.mode = this.constMode1up;
- }
-
$("#BookReader").empty();
this.initToolbar(this.mode, this.ui); // Build inside of toolbar div
top: top+'px',
height: this.twoPage.height +'px', // $$$ height forced the same for both pages
width: this.twoPage.scaledWL + 'px',
- borderRight: '1px solid black',
zIndex: 2
}).appendTo('#BRtwopageview');
top: top+'px',
height: this.twoPage.height + 'px', // $$$ height forced the same for both pages
width: this.twoPage.scaledWR + 'px',
- borderLeft: '1px solid black',
zIndex: 2
}).appendTo('#BRtwopageview');
this.removeSearchHilites();
this.mode = mode;
- this.switchToolbarMode(mode);
+ //this.switchToolbarMode(mode);
// reinstate scale if moving from thumbnail view
if (this.pageScale != this.reduce) {
this.reduce = this.quantizeReduce(this.reduce, this.onePage.reductionFactors);
this.prepareOnePageView();
} else if (3 == mode) {
+ $('button.thumb').hide();
+ $('button.twopg').show();
this.reduce = this.quantizeReduce(this.reduce, this.reductionFactors);
this.prepareThumbnailView();
} else {
// $$$ why don't we save autofit?
- this.twoPage.autofit = null; // Take zoom level from other 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
}
width: this.twoPage.bookCoverDivWidth + 'px',
height: this.twoPage.bookCoverDivHeight+'px',
visibility: 'visible',
- position: 'absolute',
- left: this.twoPage.bookCoverDivLeft + 'px',
- top: this.twoPage.bookCoverDivTop+'px'
}).appendTo('#BRtwopageview');
this.leafEdgeR = document.createElement('div');
this.leafEdgeR.className = 'BRleafEdgeR';
$(this.leafEdgeR).css({
width: this.twoPage.leafEdgeWidthR + 'px',
- height: this.twoPage.height-1 + 'px',
+ height: this.twoPage.height + 'px',
left: this.twoPage.gutter+this.twoPage.scaledWR+'px',
top: this.twoPage.bookCoverDivTop+this.twoPage.coverInternalPadding+'px'
}).appendTo('#BRtwopageview');
this.leafEdgeL.className = 'BRleafEdgeL';
$(this.leafEdgeL).css({
width: this.twoPage.leafEdgeWidthL + 'px',
- height: this.twoPage.height-1 + 'px',
+ height: this.twoPage.height + 'px',
left: this.twoPage.bookCoverDivLeft+this.twoPage.coverInternalPadding+'px',
top: this.twoPage.bookCoverDivTop+this.twoPage.coverInternalPadding+'px'
}).appendTo('#BRtwopageview');
top: this.twoPageFlipAreaTop() + 'px',
cursor: 'w-resize',
zIndex: 100
- }).bind('click', function(e) {
+ }).click(function(e) {
self.left();
}).bind('mousedown', function(e) {
e.preventDefault();
top: this.twoPageFlipAreaTop() + 'px',
cursor: 'e-resize',
zIndex: 100
- }).bind('click', function(e) {
+ }).click(function(e) {
self.right();
}).bind('mousedown', function(e) {
e.preventDefault();
// $$$ TODO: Make sure popup is positioned so that it is in view
// (https://bugs.edge.launchpad.net/gnubook/+bug/327456)
$(e.data.twoPagePopUp).css({
- left: e.pageX- $('#BRcontainer').offset().left + $('#BRcontainer').scrollLeft() + 20 + 'px',
+ left: e.pageX- $('#BRcontainer').offset().left + $('#BRcontainer').scrollLeft() - 100 + 'px',
top: e.pageY - $('#BRcontainer').offset().top + $('#BRcontainer').scrollTop() + 'px'
});
});
// $$$ TODO: Make sure popup is positioned so that it is in view
// (https://bugs.edge.launchpad.net/gnubook/+bug/327456)
$(e.data.twoPagePopUp).css({
- left: e.pageX - $('#BRcontainer').offset().left + $('#BRcontainer').scrollLeft() - $(e.data.twoPagePopUp).width() - 25 + 'px',
+ left: e.pageX - $('#BRcontainer').offset().left + $('#BRcontainer').scrollLeft() - $(e.data.twoPagePopUp).width() + 100 + 'px',
top: e.pageY-$('#BRcontainer').offset().top + $('#BRcontainer').scrollTop() + 'px'
});
});
// Book cover
// The width of the book cover div. The combined width of both pages, twice the width
// of the book cover internal padding (2*10) and the page edges
- this.twoPage.bookCoverDivWidth = this.twoPage.scaledWL + this.twoPage.scaledWR + 2 * this.twoPage.coverInternalPadding + this.twoPage.edgeWidth;
+ this.twoPage.bookCoverDivWidth = this.twoPageCoverWidth(this.twoPage.scaledWL + this.twoPage.scaledWR);
// The height of the book cover div
this.twoPage.bookCoverDivHeight = this.twoPage.height + 2 * this.twoPage.coverInternalPadding;
this.leafEdgeTmp.className = 'BRleafEdgeTmp';
$(this.leafEdgeTmp).css({
width: leafEdgeTmpW + 'px',
- height: this.twoPage.height-1 + 'px',
+ height: this.twoPage.height + 'px',
left: leftEdgeTmpLeft + 'px',
top: top+'px',
zIndex:1000
this.leafEdgeTmp.className = 'BRleafEdgeTmp';
$(this.leafEdgeTmp).css({
width: leafEdgeTmpW + 'px',
- height: this.twoPage.height-1 + 'px',
+ height: this.twoPage.height + 'px',
left: gutter+scaledW+'px',
top: top+'px',
zIndex:1000
top: top+'px',
height: this.twoPage.height,
width: scaledW+'px',
- borderRight: '1px solid black',
+ borderRight: '1px solid black', // XXXmang check
zIndex: 1
}
right: '',
top: top+'px',
height: this.twoPage.height,
- width: '0px',
- borderLeft: '1px solid black',
+ borderLeft: '1px solid black', // XXXmang check
+ width: '0',
zIndex: 2
}
top: top+'px',
height: this.twoPage.height,
width: scaledW+'px',
- borderLeft: '1px solid black',
zIndex: 1
});
top: top+'px',
height: this.twoPage.height,
width: 0+'px', // Start at 0 width, then grow to the left
- borderRight: '1px solid black',
zIndex: 2
});
// showEmbedCode()
//______________________________________________________________________________
BookReader.prototype.showEmbedCode = function() {
- if (null != this.embedPopup) { // check if already showing
- return;
- }
- this.autoStop();
this.embedPopup = document.createElement("div");
$(this.embedPopup).css({
position: 'absolute',
- top: '20px',
+ top: ($('#BRcontainer').attr('clientHeight')-250)/2 + 'px',
left: ($('#BRcontainer').attr('clientWidth')-400)/2 + 'px',
width: '400px',
- padding: "20px",
- border: "3px double #999999",
- zIndex: 3,
- backgroundColor: "#fff"
+ height: '250px',
+ padding: '0',
+ fontSize: '12px',
+ color: '#333',
+ zIndex: 300,
+ border: '10px solid #615132',
+ backgroundColor: "#fff",
+ MozBorderRadius: '8px',
+ MozBoxShadow: '0 0 6px #000',
+ WebkitBorderRadius: '8px',
+ WebkitBoxShadow: '0 0 6px #000'
}).appendTo('#BookReader');
- htmlStr = '<p style="text-align:center;"><b>Embed Bookreader in your blog!</b></p>';
- htmlStr += '<p>The bookreader uses iframes for embedding. It will not work on web hosts that block iframes. The embed feature has been tested on blogspot.com blogs as well as self-hosted Wordpress blogs. This feature will NOT work on wordpress.com blogs.</p>';
- htmlStr += '<p>Embed Code: <input type="text" size="40" value="' + this.getEmbedCode() + '"></p>';
- htmlStr += '<p style="text-align:center;"><a href="" onclick="br.embedPopup = null; $(this.parentNode.parentNode).remove(); return false">Close popup</a></p>';
+ htmlStr = '<h3 style="background:#615132;padding:10px;margin:0 0 10px;color:#fff;">Embed Bookreader</h3>';
+ htmlStr += '<p style="padding:10px;line-height:18px;">The bookreader uses iframes for embedding. It will not work on web hosts that block iframes. The embed feature has been tested on blogspot.com blogs as well as self-hosted Wordpress blogs. This feature will NOT work on wordpress.com blogs.</p>';
+ htmlStr += '<textarea rows="2" cols="40" style="margin-left:10px;width:368px;height:40px;color:#333;font-size:12px;border:2px inset #ccc;background:#efefef;padding:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;">' + this.getEmbedCode() + '</textarea>';
+ htmlStr += '<a href="javascript:;" class="popOff" onclick="$(this.parentNode).remove();$(\'.coverUp\').hide();return false" style="color:#999;"><span>Close</span></a>';
this.embedPopup.innerHTML = htmlStr;
- $(this.embedPopup).find('input').bind('click', function() {
+ $('#BookReader').append('<div class="coverUp" style="position:absolute;z-index:299;width:100%;height:100%;background:#000;opacity:.4;filter:alpha(opacity=40);" onclick="$(\'.popped\').hide();$(this).hide();"></div>');
+ $(this.embedPopup).find('textarea').click(function() {
+ this.select();
+ })
+ $(this.embedPopup).addClass("popped");
+}
+
+// showBookmarkCode()
+//______________________________________________________________________________
+BookReader.prototype.showBookmarkCode = function() {
+ this.bookmarkPopup = document.createElement("div");
+ $(this.bookmarkPopup).css({
+ position: 'absolute',
+ top: ($('#BRcontainer').attr('clientHeight')-250)/2 + 'px',
+ left: ($('#BRcontainer').attr('clientWidth')-400)/2 + 'px',
+ width: '400px',
+ height: '250px',
+ padding: '0',
+ fontSize: '12px',
+ color: '#333',
+ zIndex: 300,
+ border: '10px solid #615132',
+ backgroundColor: "#fff",
+ MozBorderRadius: '8px',
+ MozBoxShadow: '0 0 6px #000',
+ WebkitBorderRadius: '8px',
+ WebkitBoxShadow: '0 0 6px #000'
+ }).appendTo('#BookReader');
+
+ htmlStr = '<h3 style="background:#615132;padding:10px;margin:0 0 10px;color:#fff;">Add a bookmark</h3>';
+ htmlStr += '<p style="padding:10px;line-height:18px;">You can add a bookmark to any page in any book. If you elect to make your bookmark public, other readers will be able to see it. <em>You must be logged in to your <a href="">Open Library account</a> to add bookmarks.</em></p>';
+ htmlStr += '<form name="bookmark" id="bookmark" style="line-height:20px;margin-left:10px;"><label style="padding-bottom"10px;><input type="radio" name="privacy" id="p2" disabled="disabled" checked="checked"/> Make this bookmark public.</label><br/><label style="padding-bottom:10px;"><input type="radio" name="privacy" id="p1" disabled="disabled"/> Keep this bookmark private.</label><br/><br/><button type="submit" style="font-size:20px;" disabled="disabled">Add a bookmark</button></form>';
+ htmlStr += '<a href="javascript:;" class="popOff" onclick="$(this.parentNode).remove();$(\'.coverUp\').hide();return false;" style="color:#999;"><span>Close</span></a>';
+
+ this.bookmarkPopup.innerHTML = htmlStr;
+ $('#BookReader').append('<div class="coverUp" style="position:absolute;z-index:299;width:100%;height:100%;background:#000;opacity:.4;filter:alpha(opacity=40);" onclick="$(\'.popped\').hide();$(this).hide();"></div>');
+ $(this.bookmarkPopup).find('textarea').click(function() {
this.select();
})
+ $(this.bookmarkPopup).addClass("popped");
}
+
// autoToggle()
//______________________________________________________________________________
BookReader.prototype.autoToggle = function() {
BookReader.prototype.initToolbar = function(mode, ui) {
- $("#BookReader").append("<div id='BRtoolbar'>"
- + "<span id='BRtoolbarbuttons' style='float: right'>"
- + "<button class='BRicon print rollover' /> <button class='BRicon rollover embed' />"
- + "<form class='BRpageform' action='javascript:' onsubmit='br.jumpToPage(this.elements[0].value)'> <span class='label'>Page:<input id='BRpagenum' type='text' size='3' onfocus='br.autoStop();'></input></span></form>"
- + "<div class='BRtoolbarmode2' style='display: none'><button class='BRicon rollover book_leftmost' /><button class='BRicon rollover book_left' /><button class='BRicon rollover book_right' /><button class='BRicon rollover book_rightmost' /></div>"
- + "<div class='BRtoolbarmode1' style='display: none'><button class='BRicon rollover book_top' /><button class='BRicon rollover book_up' /> <button class='BRicon rollover book_down' /><button class='BRicon rollover book_bottom' /></div>"
- + "<div class='BRtoolbarmode3' style='display: none'><button class='BRicon rollover book_top' /><button class='BRicon rollover book_up' /> <button class='BRicon rollover book_down' /><button class='BRicon rollover book_bottom' /></div>"
- + "<button class='BRicon rollover play' /><button class='BRicon rollover pause' style='display: none' />"
+ $("body").append("<div id='BRtoolbar'>"
+ + "<span id='BRtoolbarbuttons' style='float:right;'>"
+ + "<button class='BRicon bookmark modal'></button>"
+ + "<button class='BRicon link modal'></button>"
+ + "<button class='BRicon embed modal'></button>"
+ + "<button class='BRicon read modal'></button>"
+ + "<button class='BRicon full'></button>"
+// + "<div class='BRtoolbarmode2' style='display: none'><button class='BRicon book_leftmost'></button><button class='BRicon book_left'></button><button class='BRicon book_right'></button><button class='BRicon book_rightmost'></button></div>"
+// + "<div class='BRtoolbarmode1' style='display: none'><button class='BRicon book_top'></button><button class='BRicon book_up'></button> <button class='BRicon book_down'></button><button class='BRicon book_bottom'></button></div>"
+// + "<div class='BRtoolbarmode3' style='display: none'><button class='BRicon book_top'></button><button class='BRicon book_up'></button> <button class='BRicon book_down'></button><button class='BRicon book_bottom'></button></div>"
+// + "<button class='BRicon play'></button><button class='BRicon pause' style='display: none'></button>"
+ "</span>"
+ "<span>"
- + "<a class='BRicon logo rollover' href='" + this.logoURL + "'> </a>"
- + " <button class='BRicon rollover zoom_out' onclick='br.zoom(-1); return false;'/>"
- + "<button class='BRicon rollover zoom_in' onclick='br.zoom(1); return false;'/>"
- + " <span class='label'>Zoom: <span id='BRzoom'>"+parseInt(100/this.reduce)+"</span></span>"
- + " <button class='BRicon rollover one_page_mode' onclick='br.switchMode(1); return false;'/>"
- + " <button class='BRicon rollover two_page_mode' onclick='br.switchMode(2); return false;'/>"
- + " <button class='BRicon rollover thumbnail_mode' onclick='br.switchMode(3); return false;'/>"
+ + "<a class='logo' href='" + this.logoURL + "'></a>"
+ + "<button class='BRicon glass'></button>"
+ /* XXXmang integrate search */
+ + "<form method='get' id='booksearch'><input type='search' id='textSrch' name='textSrch' val='' placeholder='Search'/><button type='submit' id='btnSrch' name='btnSrch'>GO</button></form>"
+ + "<button class='BRicon fit'></button>"
+ + "<button class='BRicon thumb' onclick='br.switchMode(3); return false;'></button>"
+ + "<button class='BRicon twopg' onclick='br.switchMode(2); return false;'></button>"
+ "</span>"
- + "<span id='#BRbooktitle'>"
- + " <a class='BRblack title' href='"+this.bookUrl+"' target='_blank'>"+this.bookTitle+"</a>"
- + "</span>"
+ "</div>");
this.updateToolbarZoom(this.reduce); // Pretty format
var titles = { '.logo': 'Go to Archive.org',
'.zoom_in': 'Zoom in',
'.zoom_out': 'Zoom out',
- '.one_page_mode': 'One-page view',
- '.two_page_mode': 'Two-page view',
- '.thumbnail_mode': 'Thumbnail view',
+ '.onepg': 'One-page view',
+ '.twopg': 'Two-page view',
+ '.thumb': 'Thumbnail view',
'.print': 'Print this page',
- '.embed': 'Embed bookreader',
+ '.embed': 'Embed BookReader',
+ '.link': 'Link to this book (and page)',
+ '.bookmark': 'Bookmark this page',
+ '.read': 'Allow BookReader to read this aloud',
+ '.full': 'Show fullscreen',
'.book_left': 'Flip left',
'.book_right': 'Flip right',
'.book_up': 'Page up',
// Hide mode buttons and autoplay if 2up is not available
// $$$ if we end up with more than two modes we should show the applicable buttons
if ( !this.canSwitchToMode(this.constMode2up) ) {
- jToolbar.find('.one_page_mode, .two_page_mode, .play, .pause').hide();
+ jToolbar.find('.two_page_mode, .play, .pause').hide();
+ }
+ if ( !this.canSwitchToMode(this.constModeThumb) ) {
+ jToolbar.find('.thumbnail_mode').hide();
+ }
+
+ // Hide one page button if it is the only mode available
+ if ( ! (this.canSwitchToMode(this.constMode2up) || this.canSwitchToMode(this.constModeThumb)) ) {
+ jToolbar.find('.one_page_mode').hide();
}
// Switch to requested mode -- binds other click handlers
- this.switchToolbarMode(mode);
+ //this.switchToolbarMode(mode);
}
var self = this; // closure
- jToolbar.find('.book_left').bind('click', function(e) {
+ jToolbar.find('.book_left').click(function(e) {
self.left();
return false;
});
- jToolbar.find('.book_right').bind('click', function(e) {
+ jToolbar.find('.book_right').click(function(e) {
self.right();
return false;
});
return false;
});
- jToolbar.find('.print').bind('click', function(e) {
+ jToolbar.find('.print').click(function(e) {
self.printPage();
return false;
});
- jToolbar.find('.embed').bind('click', function(e) {
+ jToolbar.find('.embed').click(function(e) {
self.showEmbedCode();
return false;
});
- jToolbar.find('.play').bind('click', function(e) {
+ jToolbar.find('.bookmark').click(function(e) {
+ self.showBookmarkCode();
+ return false;
+ });
+
+ jToolbar.find('.play').click(function(e) {
self.autoToggle();
return false;
});
- jToolbar.find('.pause').bind('click', function(e) {
+ jToolbar.find('.pause').click(function(e) {
self.autoToggle();
return false;
});
- jToolbar.find('.book_top').bind('click', function(e) {
+ jToolbar.find('.book_top').click(function(e) {
self.first();
return false;
});
- jToolbar.find('.book_bottom').bind('click', function(e) {
+ jToolbar.find('.book_bottom').click(function(e) {
self.last();
return false;
});
- jToolbar.find('.book_leftmost').bind('click', function(e) {
+ jToolbar.find('.book_leftmost').click(function(e) {
self.leftmost();
return false;
});
- jToolbar.find('.book_rightmost').bind('click', function(e) {
+ jToolbar.find('.book_rightmost').click(function(e) {
self.rightmost();
return false;
});
//________
// Returns true if we can switch to the requested mode
BookReader.prototype.canSwitchToMode = function(mode) {
- if (mode == this.constMode2up) {
+ if (mode == this.constMode2up || mode == this.constModeThumb) {
// check there are enough pages to display
// $$$ this is a workaround for the mis-feature that we can't display
// short books in 2up mode