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("
'
+ '
' // 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(
"
"
/*
+ "
"
@@ -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.',
+ '
'].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]);
+ }
+ }
+}