From 381efa8a5069967c976455afa124b31d59dc82d2 Mon Sep 17 00:00:00 2001
From: notmasteryet <async.processingjs@yahoo.com>
Date: Sat, 1 Oct 2011 13:54:37 -0500
Subject: [PATCH 1/2] Making all link bookmark-able (ref #574, #428); removing
 always-changing hash

---
 web/viewer.js | 75 ++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 59 insertions(+), 16 deletions(-)

diff --git a/web/viewer.js b/web/viewer.js
index da41c1d0b..34429eb19 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -21,11 +21,13 @@ var Cache = function(size) {
 };
 
 var cache = new Cache(kCacheSize);
+var currentPageNumber = 1;
 
 var PDFView = {
   pages: [],
   thumbnails: [],
   currentScale: kDefaultScale,
+  initialBookmark: document.location.hash.substring(1),
 
   setScale: function(val, resetAutoSettings) {
     var pages = this.pages;
@@ -33,11 +35,8 @@ var PDFView = {
       pages[i].update(val * kCssUnits);
     this.currentScale = val;
 
-    if (document.location.hash == '#' + this.page)
-      this.pages[this.page - 1].draw();
-    else
-      // Jump the scroll position to the correct page.
-      document.location.hash = this.page;
+    this.pages[this.page - 1].scrollIntoView();
+    this.pages[this.page - 1].draw();
 
     var event = document.createEvent('UIEvents');
     event.initUIEvent('scalechange', false, false, window, 0);
@@ -87,18 +86,18 @@ var PDFView = {
       return;
     }
 
-    document.location.hash = val;
+    currentPageNumber = val;
     document.getElementById('previous').disabled = (val == 1);
     document.getElementById('next').disabled = (val == pages.length);
-    if (input.value == val)
-      return;
+    if (input.value != val) {
+      input.value = val;
+    }
 
-    input.value = val;
-    pages[val - 1].draw();
+    pages[val - 1].scrollIntoView();
   },
 
   get page() {
-    return parseInt(document.location.hash.substring(1), 10) || 1;
+    return currentPageNumber;
   },
 
   open: function(url, scale) {
@@ -137,6 +136,20 @@ var PDFView = {
     }
   },
 
+  getDestinationHash: function(dest) {
+    if (typeof dest === 'string')
+      return '#' + escape(dest);
+    if (dest instanceof Array) {
+      var destRef = dest[0]; // see nevigateTo method for dest format
+      var pageNumber = destRef instanceof Object ?
+        this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] : (destRef + 1);
+      if (pageNumber) {
+        return '#page=' + pageNumber + '&dest=' + dest.slice(1).join(',');
+      }
+    }
+    return '';
+  },
+
   error: function() {
     var loadingIndicator = document.getElementById('loading');
     loadingIndicator.innerHTML = 'Error';
@@ -181,7 +194,7 @@ var PDFView = {
     }
 
     this.setScale(scale || kDefaultScale, true);
-    this.page = parseInt(document.location.hash.substring(1), 10) || 1;
+
     this.pagesRefMap = pagesRefMap;
     this.destinations = pdf.catalog.destinations;
     if (pdf.catalog.documentOutline) {
@@ -190,6 +203,28 @@ var PDFView = {
       outlineSwitchButton.removeAttribute('disabled');
       this.switchSidebarView('outline');
     }
+
+    if (this.initialBookmark) {
+      this.setHash(this.initialBookmark);
+      this.initialBookmark = null;
+    }
+    else
+      this.page = 1;
+  },
+
+  setHash: function(hash) {
+    if (!hash)
+      return;
+
+    if (hash.indexOf('=') >= 0) {
+      // TODO more complex hashes, for now catching page=XX only
+      var m = /\bpage=(\d+)/.exec(hash);
+      if (m && m[1] > 0)
+        this.page = m[1];
+    } else if (/^\d+$/.test(hash)) // page number
+      this.page = hash;
+    else // named destination
+      PDFView.navigateTo(unescape(hash));
   },
 
   switchSidebarView: function(view) {
@@ -274,6 +309,7 @@ var PageView = function(container, content, id, pageWidth, pageHeight,
 
   function setupLinks(content, scale) {
     function bindLink(link, dest) {
+      link.href = PDFView.getDestinationHash(dest);
       link.onclick = function() {
         if (dest)
           PDFView.navigateTo(dest);
@@ -296,6 +332,11 @@ var PageView = function(container, content, id, pageWidth, pageHeight,
   }
 
   this.scrollIntoView = function(dest) {
+      if (!dest) {
+        div.scrollIntoView(true);
+        return;
+      }
+
       var x = 0, y = 0;
       var width = 0, height = 0, widthScale, heightScale;
       var scale = 0;
@@ -405,6 +446,10 @@ var PageView = function(container, content, id, pageWidth, pageHeight,
 var ThumbnailView = function(container, page, id, pageRatio) {
   var anchor = document.createElement('a');
   anchor.href = '#' + id;
+  anchor.onclick = function stopNivigation() {
+    PDFView.page = id;
+    return false;
+  };
 
   var div = document.createElement('div');
   div.id = 'thumbnailContainer' + id;
@@ -452,7 +497,7 @@ var DocumentOutlineView = function(outline) {
   var outlineView = document.getElementById('outlineView');
 
   function bindItemLink(domObj, item) {
-    domObj.href = '';
+    domObj.href = PDFView.getDestinationHash(item.dest);
     domObj.onclick = function(e) {
       PDFView.navigateTo(item.dest);
       return false;
@@ -543,7 +588,7 @@ window.addEventListener('resize', function onscroll(evt) {
 });
 
 window.addEventListener('hashchange', function(evt) {
-  PDFView.page = PDFView.page;
+  PDFView.setHash(document.location.hash.substring(1));
 });
 
 window.addEventListener('change', function(evt) {
@@ -569,7 +614,6 @@ window.addEventListener('change', function(evt) {
   fileReader.readAsBinaryString(file);
 
   document.title = file.name;
-  document.location.hash = 1;
 }, true);
 
 window.addEventListener('transitionend', function(evt) {
@@ -621,7 +665,6 @@ window.addEventListener('scalechange', function scalechange(evt) {
 
 window.addEventListener('pagechange', function pagechange(evt) {
   var page = evt.detail;
-  document.location.hash = page;
   document.getElementById('pageNumber').value = page;
   document.getElementById('previous').disabled = (page == 1);
   document.getElementById('next').disabled = (page == PDFView.pages.length);

From 62f9ab00633472b78cdcec29b4df271bb20bfa1e Mon Sep 17 00:00:00 2001
From: notmasteryet <async.processingjs@yahoo.com>
Date: Sat, 1 Oct 2011 14:03:04 -0500
Subject: [PATCH 2/2] lint warning fix

---
 web/viewer.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/web/viewer.js b/web/viewer.js
index 34429eb19..fabf2ba2c 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -142,7 +142,8 @@ var PDFView = {
     if (dest instanceof Array) {
       var destRef = dest[0]; // see nevigateTo method for dest format
       var pageNumber = destRef instanceof Object ?
-        this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] : (destRef + 1);
+        this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] :
+        (destRef + 1);
       if (pageNumber) {
         return '#page=' + pageNumber + '&dest=' + dest.slice(1).join(',');
       }