Set return tooltip to 'Go to Open Library' if we get an OL record
[bookreader.git] / BookReader / BookReader.js
index 9315999..f1f7196 100644 (file)
@@ -273,6 +273,9 @@ BookReader.prototype.init = function() {
     // it should start (doesn't jump after init)
     this.initNavbar();
     this.bindNavigationHandlers();
+    
+    // Set strings in the UI
+    this.initUIStrings();
 
     // Start AJAX request for OL data
     if (this.getOpenLibraryRecord) {
@@ -694,11 +697,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);
         }
     }
     
@@ -1803,6 +1804,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);
@@ -2375,12 +2390,10 @@ BookReader.prototype.setMouseHandlers2UP = function() {
         function(e) {
             if (e.button == 2) {
                 // right click
-                return;
+                return true;
             }
-            
-            var autofitReduce = e.data.self.twoPageGetAutofitReduce();
-            // Don't trigger if zoomed in
-            if (e.data.self.reduce >= e.data.self.twoPageGetAutofitReduce()) {                
+                        
+             if (! e.data.self.twoPageIsZoomedIn()) {
                 e.data.self.ttsStop();
                 e.data.self.left();                
             }
@@ -2393,14 +2406,12 @@ BookReader.prototype.setMouseHandlers2UP = function() {
         function(e) {
             if (e.button == 2) {
                 // right click
-                return;
+                return true;
             }
-
-            var autofitReduce = e.data.self.twoPageGetAutofitReduce();
-            // Don't trigger if zoomed in
-            if (e.data.self.reduce >= e.data.self.twoPageGetAutofitReduce()) {                
+            
+            if (! e.data.self.twoPageIsZoomedIn()) {
                 e.data.self.ttsStop();
-                e.data.self.right();
+                e.data.self.right();                
             }
             e.preventDefault();
         }
@@ -3274,8 +3285,7 @@ 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(
         '<div id="BRnav">'
         +     '<div id="BRpage">'   // Page turn buttons
         +         '<button class="BRicon onepg"></button>'
@@ -3630,7 +3640,7 @@ BookReader.prototype.initToolbar = function(mode, ui) {
         readIcon = "<button class='BRicon read modal'></button>";
     }
 
-    $("body").append(
+    $("#BookReader").append(
           "<div id='BRtoolbar'>"
         +   "<span id='BRtoolbarbuttons'>"
         +     "<form action='javascript:br.search($(\"#textSrch\").val());' id='booksearch'><input type='search' id='textSrch' name='textSrch' val='' placeholder='Search inside'/><button type='submit' id='btnSrch' name='btnSrch'>GO</button></form>"
@@ -3643,7 +3653,7 @@ BookReader.prototype.initToolbar = function(mode, ui) {
         +   "</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>"
-        +   "<div id='BRnavCntlTop' class='BRnavCntl BRup'></div>"
+        +   "<div id='BRnavCntlTop' class='BRnabrbuvCntl'></div>"
         + "</div>"
         /*
         + "<div id='BRzoomer'>"
@@ -3659,6 +3669,7 @@ BookReader.prototype.initToolbar = function(mode, ui) {
         */
         );
 
+    $('#BRtoolbar .BRnavCntl').addClass('BRup');
     $('#BRtoolbar .pause').hide();    
     
     this.updateToolbarZoom(this.reduce); // Pretty format
@@ -3672,44 +3683,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) ) {
@@ -3724,26 +3698,57 @@ BookReader.prototype.initToolbar = function(mode, ui) {
         jToolbar.find('.one_page_mode').hide();
     }
     
-        // $$$ Don't hardcode ids
-    jToolbar.find('.share').colorbox({inline: true, opacity: "0.5", href: "#shareThis"});
-    jToolbar.find('.info').colorbox({inline: true, opacity: "0.5", href: "#aboutThis"});
-    
-    $("body").append(
-        [
-            '<div style="display: none;">',
-                this.makeShareDiv(),
-                this.makeAboutDiv(),
-            '</div>'
-        ].join('\n')
-    );
-    
+    // $$$ 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(); } });
+
+    $('<div style="display: none;"></div>').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 $([
+        '<div class="BRfloat" id="BRinfo">',
+            '<div class="BRfloatHead">About this book',
+                '<a class="floatShut" href="javascript:;" onclick="$.fn.colorbox.close();"><span class="shift">Close</span></a>',
+            '</div>',
+            '<div class="BRfloatBody">',
+                '<div class="BRfloatCover">',
+                '</div>',
+                '<div class="BRfloatMeta">',
+                    '<div class="BRfloatTitle">',
+                        '<h2><a/></h2>',
+                    '</div>',
+                '</div>',
+            '</div>',
+            '<div class="BRfloatFoot">',
+                '<a href="http://openlibrary.org/dev/docs/bookreader">About the BookReader</a>',
+            '</div>',
+        '</div>'].join('\n')
+    );
+}
+
+BookReader.prototype.blankShareDiv = function() {
+    return $([
+        '<div class="BRfloat" id="BRshare">',
+            '<div class="BRfloatHead">',
+                'Share',
+                '<a class="floatShut" href="javascript:;" onclick="$.fn.colorbox.close();"><span class="shift">Close</span></a>',
+            '</div>',
+        '</div>'].join('\n')
+    );
+}
+
 
 // switchToolbarMode
 //______________________________________________________________________________
@@ -4601,15 +4606,21 @@ 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);
+        //console.log(olObject);
         if (olObject['table_of_contents']) {
             // XXX check here that TOC is valid
             self.updateTOC(olObject['table_of_contents']);
         }
 
         // $$$mang cleanup
-        this.bookUrl = 'http://openlibrary.org' + olObject.key;
+        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'));
     }
 }
 
@@ -5092,97 +5103,120 @@ BookReader.prototype.ttsStartPolling = function () {
     },500);    
 }
 
-BookReader.prototype.makeShareDiv = function()
+BookReader.prototype.buildShareDiv = function(jShareDiv)
 {
     var pageView = document.location + '';
     var bookView = (pageView + '').replace(/#.*/,'');
-    var embedLink = this.getEmbedURL({ 'mode': this.constMode1up } );
+    var self = this;
     
-    var html = [
-        '<div class="BRfloat" id="shareThis">',
-            '<div class="BRfloatHead">',
-                'Share',
-                '<a class="floatShut" href="javascript:;" onclick="$.fn.colorbox.close();"><span class="shift">Close</span></a>',
-            '</div>',
-            '<p>Copy and paste one of these options to share this book elsewhere.</p>',
-            '<form method="post" action="">',
-                '<fieldset>',
-                    '<label for="pageview">Link to this page view:</label>',
-                    '<input type="text" name="pageview" id="pageview" value="' + pageView + '"/>',
+    var jForm = $([
+        '<p>Copy and paste one of these options to share this book elsewhere.</p>',
+        '<form method="post" action="">',
+            '<fieldset>',
+                '<label for="pageview">Link to this page view:</label>',
+                '<input type="text" name="pageview" id="pageview" value="' + pageView + '"/>',
+            '</fieldset>',
+            '<fieldset>',
+                '<label for="booklink">Link to the book:</label>',
+                '<input type="text" name="booklink" id="booklink" value="' + bookView + '"/>',
+            '</fieldset>',
+            '<fieldset>',
+                '<label for="iframe">Embed a mini Book Reader:</label>',
+                '<fieldset class="sub">',
+                    '<label class="sub">',
+                        '<input type="radio" name="pages" value="' + this.constMode1up + '" checked="checked"/>',
+                        '1 page',
+                    '</label>',
+                    '<label class="sub">',
+                        '<input type="radio" name="pages" value="' + this.constMode2up + '"/>',
+                        '2 pages',
+                    '</label>',
+                    '<label class="sub">',
+                        '<input type="checkbox" name="thispage" value="thispage"/>',
+                        'Open to this page?',
+                    '</label>',
                 '</fieldset>',
-                '<fieldset>',
-                    '<label for="booklink">Link to the book:</label>',
-                    '<input type="text" name="booklink" id="booklink" value="' + bookView + '"/>',
-                '</fieldset>',
-                '<fieldset>',
-                    '<label for="iframe">Embed a mini Book Reader:</label>',
-                    '<fieldset class="sub">',
-                        '<label class="sub">',
-                            '<input type="radio" name="pages" id="1page" checked="checked"/>',
-                            '1 page',
-                        '</label>',
-                        '<label class="sub">',
-                            '<input type="radio" name="pages" id="2page"/>',
-                            '2 pages',
-                        '</label>',
-                        '<label class="sub">',
-                            '<input type="checkbox" name="thispage" id="thispage"/>',
-                            'Open to this page?',
-                        '</label>',
-                    '</fieldset>',
-                    '<textarea cols="30" rows="4" name="iframe" id="iframe"><iframe src="' + embedLink + '" width="480" height="480"></iframe></textarea>',
-                    '<p class="meta"><strong>NOTE:</strong> We\'ve tested EMBED on blogspot.com blogs as well as self-hosted Wordpress blogs. This feature will NOT work on wordpress.com blogs.</p>',
-                '</fieldset>',
-                '<fieldset class="center">',
-                    '<button type="button" onclick="$.fn.colorbox.close();">Finished</button>',
-                '</fieldset>',
-            '</form>',
-        '</div>'
-    ].join('\n');
+                '<textarea cols="30" rows="4" name="iframe" class="BRframeEmbed"></textarea>',
+                '<p class="meta"><strong>NOTE:</strong> We\'ve tested EMBED on blogspot.com blogs as well as self-hosted Wordpress blogs. This feature will NOT work on wordpress.com blogs.</p>',
+            '</fieldset>',
+            '<fieldset class="center">',
+                '<button type="button" onclick="$.fn.colorbox.close();">Finished</button>',
+            '</fieldset>',
+        '</form>'].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);
+        var embedLink = self.getEmbedURL( params );    
+        form.find('.BRframeEmbed').val('<iframe src="' + embedLink + '" width="480" height="480"></iframe>');
+    })
+    jForm.find('input[name=thispage]').trigger('change');
+    jForm.find('input, textarea').bind('focus', function() {
+        this.select();
+    });
     
-    return html;
+    jForm.appendTo(jShareDiv);
+    jForm = ''; // closure
+        
 }
 
-BookReader.prototype.makeAboutDiv = function() 
+// Should be overridden
+BookReader.prototype.buildInfoDiv = function(jInfoDiv) 
 {
-    var html = [
-        '<div class="BRfloat" id="aboutThis">',
-            '<div class="BRfloatHead">About this book',
-                '<a class="floatShut" href="javascript:;" onclick="$.fn.colorbox.close();"><span class="shift">Close</span></a>',
-            '</div>',
-            '<div class="BRfloatBody">'
-    ];
-    
-    // Use 3rd-party provided function if available
-    if (this.getInfoDiv) {
-        html.push(this.getInfoDiv());
-    } else {
-        html = html.concat([
-                '<div class="BRfloatMeta">',
-                    '<div class="BRfloatTitle">',
-                        '<h2><a href="', br.bookUrl, '" class="title">', BookReader.util.escapeHTML(br.bookTitle), '</a></h2>',
-                    '</div>',
-                '</div>',
-        ]);
+    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';
     }
-    
-    html = html.concat([
-            '</div>', // BRfloatBody
-            '<div class="BRfloatFoot">'
-    ]);
-    
-    if (this.getInfoFooter) {
-        html.push(this.getInfoFooter());
-    } else {
-        html.push(
-                '<a href="http://openlibrary.org/dev/docs/bookreader">About the BookReader</a>'
-        );
+                  
+    for (var icon in titles) {
+        if (titles.hasOwnProperty(icon)) {
+            $('#BookReader').find(icon).attr('title', titles[icon]);
+        }
     }
-    
-    html = html.concat([
-            '</div>', // BRfloatfoot
-        '</div>' // BRfloat
-    ]);
-    
-    return html.join('\n');
 }