From 3f6df90e507d824b43c09905d82c437b7ec18ea8 Mon Sep 17 00:00:00 2001
From: Justin D'Arcangelo <justindarc@gmail.com>
Date: Sun, 26 Jun 2011 01:05:22 -0400
Subject: [PATCH 1/3] Fixed issue #67: zooming in in the multi-page viewer
 makes pages disappear.

---
 multi_page_viewer.js | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/multi_page_viewer.js b/multi_page_viewer.js
index f262734d3..aeb9ea38f 100644
--- a/multi_page_viewer.js
+++ b/multi_page_viewer.js
@@ -132,10 +132,6 @@ var PDFViewer = {
       for (i = 1; i <= PDFViewer.numberOfPages; i++) {
         PDFViewer.createPage(i);
       }
-      
-      if (PDFViewer.numberOfPages > 0) {
-        PDFViewer.drawPage(1);
-      }
     }
     
     for (i = 0; i < PDFViewer.scaleSelect.childNodes; i++) {
@@ -153,6 +149,12 @@ var PDFViewer = {
     }
     
     PDFViewer.scaleSelect.value = Math.floor(PDFViewer.scale * 100) + '%';
+    
+    // Clear the array of the last pages drawn to force a redraw.
+    PDFViewer.lastPagesDrawn = [];
+    
+    // Jump the scroll position to the correct page.
+    PDFViewer.goToPage(PDFViewer.pageNumber);
   },
   
   goToPage: function(num) {

From c40333317be0b8e5573e7344e4e448540ddb1720 Mon Sep 17 00:00:00 2001
From: Justin D'Arcangelo <justindarc@gmail.com>
Date: Sun, 26 Jun 2011 02:14:57 -0400
Subject: [PATCH 2/3] Added experimental slide-out sidebar with page
 thumbnails.

---
 multi_page_viewer.css  | 41 +++++++++++++++++--
 multi_page_viewer.html | 13 +++---
 multi_page_viewer.js   | 90 ++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 132 insertions(+), 12 deletions(-)

diff --git a/multi_page_viewer.css b/multi_page_viewer.css
index b3eaab792..2eaca4870 100644
--- a/multi_page_viewer.css
+++ b/multi_page_viewer.css
@@ -74,6 +74,20 @@ span {
   width: 100%;
 }
 
+.thumbnailPageNumber {
+  color: #fff;
+  font-size: 0.55em;
+  text-align: right;
+  margin: -6px 2px 6px 0px;
+  width: 102px;
+}
+
+.thumbnail {
+  width: 104px;
+  height: 134px;
+  margin: 0px auto 10px;
+}
+
 .page {
   width: 816px;
   height: 1056px;
@@ -163,27 +177,46 @@ span {
 }
 
 #sidebar {
-  background-color: rgba(0, 0, 0, 0.8);
   position: fixed;
-  width: 150px;
+  width: 200px;
   top: 62px;
   bottom: 18px;
+  left: -170px;
+  transition: left 0.25s ease-in-out 1s;
+  -moz-transition: left 0.25s ease-in-out 1s;
+  -webkit-transition: left 0.25s ease-in-out 1s;
+}
+
+#sidebar:hover {
+  left: 0px;
+  transition: left 0.25s ease-in-out 0s;
+  -moz-transition: left 0.25s ease-in-out 0s;
+  -webkit-transition: left 0.25s ease-in-out 0s;
+}
+
+#sidebarBox {
+  background-color: rgba(0, 0, 0, 0.7);
+  width: 150px;
+  height: 100%;
   border-top-right-radius: 8px;
   border-bottom-right-radius: 8px;
   -moz-border-radius-topright: 8px;
   -moz-border-radius-bottomright: 8px;
   -webkit-border-top-right-radius: 8px;
   -webkit-border-bottom-right-radius: 8px;
+  box-shadow: 0px 2px 8px #000;
+  -moz-box-shadow: 0px 2px 8px #000;
+  -webkit-box-shadow: 0px 2px 8px #000;
 }
 
 #sidebarScrollView {
   position: absolute;
   overflow: hidden;
   overflow-y: auto;
-  top: 40px;
-  right: 10px;
+  top: 10px;
   bottom: 10px;
   left: 10px;
+  width: 130px;
 }
 
 #sidebarContentView {
diff --git a/multi_page_viewer.html b/multi_page_viewer.html
index 649e3a7cc..e90606a23 100644
--- a/multi_page_viewer.html
+++ b/multi_page_viewer.html
@@ -40,13 +40,16 @@
       <span class="label">Open File</span>
     </span>
   </div>
-  <!--<div id="sidebar">
-    <div id="sidebarScrollView">
-      <div id="sidebarContentView">
-        
+  
+  <!-- EXPERIMENTAL: Slide-out sidebar with page thumbnails (comment-out to disable) -->
+  <div id="sidebar">
+    <div id="sidebarBox">
+      <div id="sidebarScrollView">
+        <div id="sidebarContentView"></div>
       </div>
     </div>
-  </div>-->
+  </div>
+  
   <div id="viewer"></div>
 </body>
 </html>
diff --git a/multi_page_viewer.js b/multi_page_viewer.js
index aeb9ea38f..4f2bd5197 100644
--- a/multi_page_viewer.js
+++ b/multi_page_viewer.js
@@ -10,6 +10,8 @@ var PDFViewer = {
   
   element: null,
   
+  sidebarContentView: null,
+  
   previousPageButton: null,
   nextPageButton: null,
   pageNumberInput: null,
@@ -52,6 +54,78 @@ var PDFViewer = {
     return pages;
   },
   
+  createThumbnail: function(num) {
+    if (PDFViewer.sidebarContentView) {
+      var anchor = document.createElement('a');
+      anchor.href = '#' + num;
+    
+      var containerDiv = document.createElement('div');
+      containerDiv.id = 'thumbnailContainer' + num;
+      containerDiv.className = 'thumbnail';
+    
+      var pageNumberDiv = document.createElement('div');
+      pageNumberDiv.className = 'thumbnailPageNumber';
+      pageNumberDiv.innerHTML = '' + num;
+    
+      anchor.appendChild(containerDiv);
+      PDFViewer.sidebarContentView.appendChild(anchor);
+      PDFViewer.sidebarContentView.appendChild(pageNumberDiv);
+    }
+  },
+  
+  removeThumbnail: function(num) {
+    var div = document.getElementById('thumbnailContainer' + num);
+    
+    if (div) {
+      while (div.hasChildNodes()) {
+        div.removeChild(div.firstChild);
+      }
+    }
+  },
+  
+  drawThumbnail: function(num) {
+    if (!PDFViewer.pdf)
+      return;
+
+    var div = document.getElementById('thumbnailContainer' + num);
+    
+    if (div && !div.hasChildNodes()) {
+      var page = PDFViewer.pdf.getPage(num);
+      var canvas = document.createElement('canvas');
+      
+      canvas.id = 'thumbnail' + num;
+      canvas.mozOpaque = true;
+
+      // Canvas dimensions must be specified in CSS pixels. CSS pixels
+      // are always 96 dpi. These dimensions are 8.5in x 11in at 96dpi.
+      canvas.width = 104;
+      canvas.height = 134;
+      div.appendChild(canvas);
+
+      var ctx = canvas.getContext('2d');
+      ctx.save();
+      ctx.fillStyle = 'rgb(255, 255, 255)';
+      ctx.fillRect(0, 0, canvas.width, canvas.height);
+      ctx.restore();
+
+      var gfx = new CanvasGraphics(ctx);
+
+      // page.compile will collect all fonts for us, once we have loaded them
+      // we can trigger the actual page rendering with page.display
+      var fonts = [];
+      page.compile(gfx, fonts);
+
+      var loadFont = function() {
+        if (!FontLoader.bind(fonts)) {
+          pageTimeout = window.setTimeout(loadFont, 10);
+          return;
+        }
+        page.display(gfx);
+      }
+      loadFont();
+    }
+  },
+  
   createPage: function(num) {
     var anchor = document.createElement('a');
     anchor.name = '' + num;
@@ -81,11 +155,11 @@ var PDFViewer = {
       return;
 
     var div = document.getElementById('pageContainer' + num);
-    var canvas = document.createElement('canvas');
-
+    
     if (div && !div.hasChildNodes()) {
       var page = PDFViewer.pdf.getPage(num);
-
+      var canvas = document.createElement('canvas');
+      
       canvas.id = 'page' + num;
       canvas.mozOpaque = true;
 
@@ -130,6 +204,7 @@ var PDFViewer = {
     
     if (PDFViewer.pdf) {
       for (i = 1; i <= PDFViewer.numberOfPages; i++) {
+        PDFViewer.createThumbnail(i);
         PDFViewer.createPage(i);
       }
     }
@@ -218,6 +293,13 @@ var PDFViewer = {
     if (PDFViewer.numberOfPages > 0) {
       PDFViewer.drawPage(1);
       document.location.hash = 1;
+      
+      setTimeout(function() {
+        for (var i = 1; i <= PDFViewer.numberOfPages; i++) {
+          PDFViewer.createThumbnail(i);
+          PDFViewer.drawThumbnail(i);
+        }
+      }, 500);
     }
     
     PDFViewer.previousPageButton.className = (PDFViewer.pageNumber === 1) ? 'disabled' : '';
@@ -242,6 +324,8 @@ window.onload = function() {
 
   PDFViewer.element = document.getElementById('viewer');
   
+  PDFViewer.sidebarContentView = document.getElementById('sidebarContentView');
+  
   PDFViewer.pageNumberInput = document.getElementById('pageNumber');
   PDFViewer.pageNumberInput.onkeydown = function(evt) {
     var charCode = evt.charCode || evt.keyCode;

From d307a90ed4fd9b8e80221cad96952a71ec524deb Mon Sep 17 00:00:00 2001
From: Justin D'Arcangelo <justindarc@gmail.com>
Date: Sun, 26 Jun 2011 02:23:18 -0400
Subject: [PATCH 3/3] Minor fix for issues with thumbnails when a new PDF was
 opened from the local filesystem.

---
 multi_page_viewer.js | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/multi_page_viewer.js b/multi_page_viewer.js
index 4f2bd5197..5a94f12ed 100644
--- a/multi_page_viewer.js
+++ b/multi_page_viewer.js
@@ -282,6 +282,10 @@ var PDFViewer = {
       PDFViewer.element.removeChild(PDFViewer.element.firstChild);
     }
     
+    while (PDFViewer.sidebarContentView.hasChildNodes()) {
+      PDFViewer.sidebarContentView.removeChild(PDFViewer.sidebarContentView.firstChild);
+    }
+    
     PDFViewer.pdf = new PDFDoc(new Stream(data));
     PDFViewer.numberOfPages = PDFViewer.pdf.numPages;
     document.getElementById('numPages').innerHTML = PDFViewer.numberOfPages.toString();