|
|
@ -12,6 +12,7 @@ var kScrollbarPadding = 40; |
|
|
|
var kMinScale = 0.25; |
|
|
|
var kMinScale = 0.25; |
|
|
|
var kMaxScale = 4.0; |
|
|
|
var kMaxScale = 4.0; |
|
|
|
var kImageDirectory = './images/'; |
|
|
|
var kImageDirectory = './images/'; |
|
|
|
|
|
|
|
var kSettingsMemory = 20; |
|
|
|
|
|
|
|
|
|
|
|
var Cache = function cacheCache(size) { |
|
|
|
var Cache = function cacheCache(size) { |
|
|
|
var data = []; |
|
|
|
var data = []; |
|
|
@ -25,13 +26,126 @@ var Cache = function cacheCache(size) { |
|
|
|
}; |
|
|
|
}; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var RenderingQueue = (function RenderingQueueClosure() { |
|
|
|
|
|
|
|
function RenderingQueue() { |
|
|
|
|
|
|
|
this.items = []; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RenderingQueue.prototype = { |
|
|
|
|
|
|
|
enqueueDraw: function RenderingQueueEnqueueDraw(item) { |
|
|
|
|
|
|
|
if ('rendering' in item) |
|
|
|
|
|
|
|
return; // is already in the queue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
item.rendering = true; |
|
|
|
|
|
|
|
this.items.push(item); |
|
|
|
|
|
|
|
if (this.items.length > 1) |
|
|
|
|
|
|
|
return; // not first item
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
item.draw(this.continueExecution.bind(this)); |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
continueExecution: function RenderingQueueContinueExecution() { |
|
|
|
|
|
|
|
var item = this.items.shift(); |
|
|
|
|
|
|
|
delete item.rendering; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this.items.length == 0) |
|
|
|
|
|
|
|
return; // queue is empty
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
item = this.items[0]; |
|
|
|
|
|
|
|
item.draw(this.continueExecution.bind(this)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return RenderingQueue; |
|
|
|
|
|
|
|
})(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Settings Manager - This is a utility for saving settings
|
|
|
|
|
|
|
|
// First we see if localStorage is available, FF bug #495747
|
|
|
|
|
|
|
|
// If not, we use FUEL in FF
|
|
|
|
|
|
|
|
var Settings = (function SettingsClosure() { |
|
|
|
|
|
|
|
var isLocalStorageEnabled = (function localStorageEnabledTest() { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
localStorage; |
|
|
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
})(); |
|
|
|
|
|
|
|
var extPrefix = 'extensions.uriloader@pdf.js'; |
|
|
|
|
|
|
|
var isExtension = location.protocol == 'chrome:' && !isLocalStorageEnabled; |
|
|
|
|
|
|
|
var inPrivateBrowsing = false; |
|
|
|
|
|
|
|
if (isExtension) { |
|
|
|
|
|
|
|
var pbs = Components.classes['@mozilla.org/privatebrowsing;1'] |
|
|
|
|
|
|
|
.getService(Components.interfaces.nsIPrivateBrowsingService); |
|
|
|
|
|
|
|
inPrivateBrowsing = pbs.privateBrowsingEnabled; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function Settings(fingerprint) { |
|
|
|
|
|
|
|
var database = null; |
|
|
|
|
|
|
|
var index; |
|
|
|
|
|
|
|
if (inPrivateBrowsing) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
else if (isExtension) |
|
|
|
|
|
|
|
database = Application.prefs.getValue(extPrefix + '.database', '{}'); |
|
|
|
|
|
|
|
else if (isLocalStorageEnabled) |
|
|
|
|
|
|
|
database = localStorage.getItem('database') || '{}'; |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
database = JSON.parse(database); |
|
|
|
|
|
|
|
if (!('files' in database)) |
|
|
|
|
|
|
|
database.files = []; |
|
|
|
|
|
|
|
if (database.files.length >= kSettingsMemory) |
|
|
|
|
|
|
|
database.files.shift(); |
|
|
|
|
|
|
|
for (var i = 0, length = database.files.length; i < length; i++) { |
|
|
|
|
|
|
|
var branch = database.files[i]; |
|
|
|
|
|
|
|
if (branch.fingerprint == fingerprint) { |
|
|
|
|
|
|
|
index = i; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (typeof index != 'number') |
|
|
|
|
|
|
|
index = database.files.push({fingerprint: fingerprint}) - 1; |
|
|
|
|
|
|
|
this.file = database.files[index]; |
|
|
|
|
|
|
|
this.database = database; |
|
|
|
|
|
|
|
if (isExtension) |
|
|
|
|
|
|
|
Application.prefs.setValue(extPrefix + '.database', |
|
|
|
|
|
|
|
JSON.stringify(database)); |
|
|
|
|
|
|
|
else if (isLocalStorageEnabled) |
|
|
|
|
|
|
|
localStorage.setItem('database', JSON.stringify(database)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Settings.prototype = { |
|
|
|
|
|
|
|
set: function settingsSet(name, val) { |
|
|
|
|
|
|
|
if (inPrivateBrowsing) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
var file = this.file; |
|
|
|
|
|
|
|
file[name] = val; |
|
|
|
|
|
|
|
if (isExtension) |
|
|
|
|
|
|
|
Application.prefs.setValue(extPrefix + '.database', |
|
|
|
|
|
|
|
JSON.stringify(this.database)); |
|
|
|
|
|
|
|
else if (isLocalStorageEnabled) |
|
|
|
|
|
|
|
localStorage.setItem('database', JSON.stringify(this.database)); |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get: function settingsGet(name, defaultValue) { |
|
|
|
|
|
|
|
if (inPrivateBrowsing) |
|
|
|
|
|
|
|
return defaultValue; |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
return this.file[name] || defaultValue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return Settings; |
|
|
|
|
|
|
|
})(); |
|
|
|
|
|
|
|
|
|
|
|
var cache = new Cache(kCacheSize); |
|
|
|
var cache = new Cache(kCacheSize); |
|
|
|
|
|
|
|
var renderingQueue = new RenderingQueue(); |
|
|
|
var currentPageNumber = 1; |
|
|
|
var currentPageNumber = 1; |
|
|
|
|
|
|
|
|
|
|
|
var PDFView = { |
|
|
|
var PDFView = { |
|
|
|
pages: [], |
|
|
|
pages: [], |
|
|
|
thumbnails: [], |
|
|
|
thumbnails: [], |
|
|
|
currentScale: kDefaultScale, |
|
|
|
currentScale: 0, |
|
|
|
initialBookmark: document.location.hash.substring(1), |
|
|
|
initialBookmark: document.location.hash.substring(1), |
|
|
|
|
|
|
|
|
|
|
|
setScale: function pdfViewSetScale(val, resetAutoSettings) { |
|
|
|
setScale: function pdfViewSetScale(val, resetAutoSettings) { |
|
|
@ -272,8 +386,20 @@ var PDFView = { |
|
|
|
this.error('An error occurred while reading the PDF.', e); |
|
|
|
this.error('An error occurred while reading the PDF.', e); |
|
|
|
} |
|
|
|
} |
|
|
|
var pagesCount = pdf.numPages; |
|
|
|
var pagesCount = pdf.numPages; |
|
|
|
|
|
|
|
var id = pdf.fingerprint; |
|
|
|
|
|
|
|
var storedHash = null; |
|
|
|
document.getElementById('numPages').innerHTML = pagesCount; |
|
|
|
document.getElementById('numPages').innerHTML = pagesCount; |
|
|
|
document.getElementById('pageNumber').max = pagesCount; |
|
|
|
document.getElementById('pageNumber').max = pagesCount; |
|
|
|
|
|
|
|
PDFView.documentFingerprint = id; |
|
|
|
|
|
|
|
var store = PDFView.store = new Settings(id); |
|
|
|
|
|
|
|
if (store.get('exists', false)) { |
|
|
|
|
|
|
|
var page = store.get('page', '1'); |
|
|
|
|
|
|
|
var zoom = store.get('zoom', PDFView.currentScale); |
|
|
|
|
|
|
|
var left = store.get('scrollLeft', '0'); |
|
|
|
|
|
|
|
var top = store.get('scrollTop', '0'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
storedHash = 'page=' + page + '&zoom=' + zoom + ',' + left + ',' + top; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var pages = this.pages = []; |
|
|
|
var pages = this.pages = []; |
|
|
|
var pagesRefMap = {}; |
|
|
|
var pagesRefMap = {}; |
|
|
@ -294,7 +420,6 @@ var PDFView = { |
|
|
|
|
|
|
|
|
|
|
|
this.pagesRefMap = pagesRefMap; |
|
|
|
this.pagesRefMap = pagesRefMap; |
|
|
|
this.destinations = pdf.catalog.destinations; |
|
|
|
this.destinations = pdf.catalog.destinations; |
|
|
|
this.setScale(scale || kDefaultScale, true); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (pdf.catalog.documentOutline) { |
|
|
|
if (pdf.catalog.documentOutline) { |
|
|
|
this.outline = new DocumentOutlineView(pdf.catalog.documentOutline); |
|
|
|
this.outline = new DocumentOutlineView(pdf.catalog.documentOutline); |
|
|
@ -307,8 +432,12 @@ var PDFView = { |
|
|
|
this.setHash(this.initialBookmark); |
|
|
|
this.setHash(this.initialBookmark); |
|
|
|
this.initialBookmark = null; |
|
|
|
this.initialBookmark = null; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else if (storedHash) |
|
|
|
|
|
|
|
this.setHash(storedHash); |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
this.setScale(scale || kDefaultScale, true); |
|
|
|
this.page = 1; |
|
|
|
this.page = 1; |
|
|
|
|
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
setHash: function pdfViewSetHash(hash) { |
|
|
|
setHash: function pdfViewSetHash(hash) { |
|
|
@ -334,7 +463,7 @@ var PDFView = { |
|
|
|
if ('zoom' in params) { |
|
|
|
if ('zoom' in params) { |
|
|
|
var zoomArgs = params.zoom.split(','); // scale,left,top
|
|
|
|
var zoomArgs = params.zoom.split(','); // scale,left,top
|
|
|
|
// building destination array
|
|
|
|
// building destination array
|
|
|
|
var dest = [null, new Name('XYZ'), (zoomArgs[1] | 0), |
|
|
|
var dest = [null, {name: 'XYZ'}, (zoomArgs[1] | 0), |
|
|
|
(zoomArgs[2] | 0), (zoomArgs[0] | 0) / 100]; |
|
|
|
(zoomArgs[2] | 0), (zoomArgs[0] | 0) / 100]; |
|
|
|
var currentPage = this.pages[pageNumber - 1]; |
|
|
|
var currentPage = this.pages[pageNumber - 1]; |
|
|
|
currentPage.scrollIntoView(dest); |
|
|
|
currentPage.scrollIntoView(dest); |
|
|
@ -609,10 +738,11 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight, |
|
|
|
}, 0); |
|
|
|
}, 0); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
this.draw = function pageviewDraw() { |
|
|
|
this.draw = function pageviewDraw(callback) { |
|
|
|
if (div.hasChildNodes()) { |
|
|
|
if (div.hasChildNodes()) { |
|
|
|
this.updateStats(); |
|
|
|
this.updateStats(); |
|
|
|
return false; |
|
|
|
callback(); |
|
|
|
|
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var canvas = document.createElement('canvas'); |
|
|
|
var canvas = document.createElement('canvas'); |
|
|
@ -644,13 +774,14 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight, |
|
|
|
this.updateStats(); |
|
|
|
this.updateStats(); |
|
|
|
if (this.onAfterDraw) |
|
|
|
if (this.onAfterDraw) |
|
|
|
this.onAfterDraw(); |
|
|
|
this.onAfterDraw(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cache.push(this); |
|
|
|
|
|
|
|
callback(); |
|
|
|
}).bind(this), textLayer |
|
|
|
}).bind(this), textLayer |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
setupAnnotations(this.content, this.scale); |
|
|
|
setupAnnotations(this.content, this.scale); |
|
|
|
div.setAttribute('data-loaded', true); |
|
|
|
div.setAttribute('data-loaded', true); |
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
this.updateStats = function pageViewUpdateStats() { |
|
|
|
this.updateStats = function pageViewUpdateStats() { |
|
|
@ -717,12 +848,16 @@ var ThumbnailView = function thumbnailView(container, page, id, pageRatio) { |
|
|
|
return ctx; |
|
|
|
return ctx; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.draw = function thumbnailViewDraw() { |
|
|
|
this.draw = function thumbnailViewDraw(callback) { |
|
|
|
if (this.hasImage) |
|
|
|
if (this.hasImage) { |
|
|
|
|
|
|
|
callback(); |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var ctx = getPageDrawContext(); |
|
|
|
var ctx = getPageDrawContext(); |
|
|
|
page.startRendering(ctx, function thumbnailViewDrawStartRendering() {}); |
|
|
|
page.startRendering(ctx, function thumbnailViewDrawStartRendering() { |
|
|
|
|
|
|
|
callback(); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
this.hasImage = true; |
|
|
|
this.hasImage = true; |
|
|
|
}; |
|
|
|
}; |
|
|
@ -805,8 +940,7 @@ function updateViewarea() { |
|
|
|
var visiblePages = PDFView.getVisiblePages(); |
|
|
|
var visiblePages = PDFView.getVisiblePages(); |
|
|
|
for (var i = 0; i < visiblePages.length; i++) { |
|
|
|
for (var i = 0; i < visiblePages.length; i++) { |
|
|
|
var page = visiblePages[i]; |
|
|
|
var page = visiblePages[i]; |
|
|
|
if (PDFView.pages[page.id - 1].draw()) |
|
|
|
renderingQueue.enqueueDraw(PDFView.pages[page.id - 1]); |
|
|
|
cache.push(page.view); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!visiblePages.length) |
|
|
|
if (!visiblePages.length) |
|
|
@ -826,6 +960,14 @@ function updateViewarea() { |
|
|
|
var topLeft = currentPage.getPagePoint(window.pageXOffset, |
|
|
|
var topLeft = currentPage.getPagePoint(window.pageXOffset, |
|
|
|
window.pageYOffset - firstPage.y - kViewerTopMargin); |
|
|
|
window.pageYOffset - firstPage.y - kViewerTopMargin); |
|
|
|
pdfOpenParams += ',' + Math.round(topLeft.x) + ',' + Math.round(topLeft.y); |
|
|
|
pdfOpenParams += ',' + Math.round(topLeft.x) + ',' + Math.round(topLeft.y); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var store = PDFView.store; |
|
|
|
|
|
|
|
store.set('exists', true); |
|
|
|
|
|
|
|
store.set('page', pageNumber); |
|
|
|
|
|
|
|
store.set('zoom', Math.round(PDFView.currentScale * 100)); |
|
|
|
|
|
|
|
store.set('scrollLeft', Math.round(topLeft.x)); |
|
|
|
|
|
|
|
store.set('scrollTop', Math.round(topLeft.y)); |
|
|
|
|
|
|
|
|
|
|
|
document.getElementById('viewBookmark').href = pdfOpenParams; |
|
|
|
document.getElementById('viewBookmark').href = pdfOpenParams; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -848,7 +990,7 @@ function updateThumbViewArea() { |
|
|
|
var visibleThumbs = PDFView.getVisibleThumbs(); |
|
|
|
var visibleThumbs = PDFView.getVisibleThumbs(); |
|
|
|
for (var i = 0; i < visibleThumbs.length; i++) { |
|
|
|
for (var i = 0; i < visibleThumbs.length; i++) { |
|
|
|
var thumb = visibleThumbs[i]; |
|
|
|
var thumb = visibleThumbs[i]; |
|
|
|
PDFView.thumbnails[thumb.id - 1].draw(); |
|
|
|
renderingQueue.enqueueDraw(PDFView.thumbnails[thumb.id - 1]); |
|
|
|
} |
|
|
|
} |
|
|
|
}, delay); |
|
|
|
}, delay); |
|
|
|
} |
|
|
|
} |
|
|
@ -888,7 +1030,6 @@ window.addEventListener('change', function webViewerChange(evt) { |
|
|
|
// implemented in Firefox.
|
|
|
|
// implemented in Firefox.
|
|
|
|
var file = files[0]; |
|
|
|
var file = files[0]; |
|
|
|
fileReader.readAsBinaryString(file); |
|
|
|
fileReader.readAsBinaryString(file); |
|
|
|
|
|
|
|
|
|
|
|
document.title = file.name; |
|
|
|
document.title = file.name; |
|
|
|
|
|
|
|
|
|
|
|
// URL does not reflect proper document location - hiding some icons.
|
|
|
|
// URL does not reflect proper document location - hiding some icons.
|
|
|
|