diff --git a/Makefile b/Makefile index 04586bd18..a9cd2793f 100644 --- a/Makefile +++ b/Makefile @@ -166,9 +166,9 @@ PDF_WEB_FILES = \ extension: # Copy a standalone version of pdf.js inside the content directory @rm -Rf $(EXTENSION_SRC)/$(CONTENT_DIR)/ - @mkdir $(EXTENSION_SRC)/$(CONTENT_DIR)/ + @mkdir -p $(EXTENSION_SRC)/$(CONTENT_DIR)/web @cp $(PDF_JS_FILES) $(EXTENSION_SRC)/$(CONTENT_DIR)/ - @cp -r $(PDF_WEB_FILES) $(EXTENSION_SRC)/$(CONTENT_DIR)/ + @cp -r $(PDF_WEB_FILES) $(EXTENSION_SRC)/$(CONTENT_DIR)/web/ # Create the xpi @cd $(EXTENSION_SRC); zip -r $(EXTENSION_NAME) * diff --git a/extensions/firefox/components/pdfContentHandler.js b/extensions/firefox/components/pdfContentHandler.js index 92b663455..e4b6a2a55 100644 --- a/extensions/firefox/components/pdfContentHandler.js +++ b/extensions/firefox/components/pdfContentHandler.js @@ -13,9 +13,6 @@ const PDF_CONTENT_TYPE = 'application/pdf'; Cu.import('resource://gre/modules/XPCOMUtils.jsm'); Cu.import('resource://gre/modules/Services.jsm'); -// TODO -// Add some download progress event - function log(aMsg) { let msg = 'pdfContentHandler.js: ' + (aMsg.join ? aMsg.join('') : aMsg); Cc['@mozilla.org/consoleservice;1'].getService(Ci.nsIConsoleService) @@ -23,33 +20,44 @@ function log(aMsg) { dump(msg + '\n'); } +function fireEventTo(aName, aData, aWindow) { + let window = aWindow.wrappedJSObject; + let evt = window.document.createEvent('CustomEvent'); + evt.initCustomEvent('pdf' + aName, false, false, aData); + window.document.dispatchEvent(evt); +} + function loadDocument(aWindow, aDocumentUrl) { let xhr = Cc['@mozilla.org/xmlextras/xmlhttprequest;1'] .createInstance(Ci.nsIXMLHttpRequest); - xhr.open('GET', aDocumentUrl); - xhr.mozResponseType = xhr.responseType = 'arraybuffer'; - xhr.onreadystatechange = function() { - if (xhr.readyState == 4 && xhr.status == 200) { - let data = (xhr.mozResponseArrayBuffer || xhr.mozResponse || - xhr.responseArrayBuffer || xhr.response); - try { - var view = new Uint8Array(data); + xhr.onprogress = function updateProgress(evt) { + if (evt.lengthComputable) + fireEventTo(evt.type, evt.loaded / evt.total, aWindow); + }; - // I think accessing aWindow.wrappedJSObject returns a - // XPCSafeJSObjectWrapper and so it is safe but mrbkap can confirm that - let window = aWindow.wrappedJSObject; - var arrayBuffer = new window.ArrayBuffer(data.byteLength); - var view2 = new window.Uint8Array(arrayBuffer); - view2.set(view); + xhr.onerror = function error(evt) { + fireEventTo(evt.type, false, aWindow); + }; - let evt = window.document.createEvent('CustomEvent'); - evt.initCustomEvent('pdfloaded', false, false, arrayBuffer); - window.document.dispatchEvent(evt); - } catch (e) { - log('Error - ' + e); - } + xhr.onload = function load(evt) { + let data = (xhr.mozResponseArrayBuffer || xhr.mozResponse || + xhr.responseArrayBuffer || xhr.response); + try { + let view = new Uint8Array(data); + + let window = aWindow.wrappedJSObject; + let arrayBuffer = new window.ArrayBuffer(data.byteLength); + let view2 = new window.Uint8Array(arrayBuffer); + view2.set(view); + + fireEventTo(evt.type, arrayBuffer, aWindow); + } catch (e) { + log('Error - ' + e); } }; + + xhr.open('GET', aDocumentUrl); + xhr.responseType = 'arraybuffer'; xhr.send(null); } @@ -140,7 +148,7 @@ pdfContentHandler.prototype = { url = url.replace('%s', uri.spec); window.location = url; } catch (e) { - log('Error - ' + e); + log('Error retrieving the pdf.js base url - ' + e); } }, diff --git a/pdf.js b/pdf.js index c173166c8..a660118a9 100644 --- a/pdf.js +++ b/pdf.js @@ -116,25 +116,32 @@ function stringToPDFString(str) { // getPdf() // Convenience function to perform binary Ajax GET // Usage: getPdf('http://...', callback) -// getPdf({url:String [,progress:Function]}, callback) +// getPdf({ +// url:String , +// [,progress:Function, error:Function] +// }, +// callback) // function getPdf(arg, callback) { var params = arg; - if (typeof arg === 'string') { - params = {url: arg}; - } + if (typeof arg === 'string') + params = { url: arg }; var xhr = new XMLHttpRequest(); xhr.open('GET', params.url); xhr.mozResponseType = xhr.responseType = 'arraybuffer'; xhr.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200; - xhr.onprogress = params.progress || undefined; + + if ('progress' in params) + xhr.onprogrss = params.progress || undefined; + + if ('error' in params) + xhr.onerror = params.error || undefined; xhr.onreadystatechange = function getPdfOnreadystatechange() { - var data; if (xhr.readyState === 4 && xhr.status === xhr.expected) { - data = (xhr.mozResponseArrayBuffer || xhr.mozResponse || - xhr.responseArrayBuffer || xhr.response); + var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse || + xhr.responseArrayBuffer || xhr.response); callback(data); } }; diff --git a/web/viewer.js b/web/viewer.js index 7515979f2..da41c1d0b 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -107,15 +107,18 @@ var PDFView = { document.title = url; - getPdf({url: url, progress: PDFView.progressLevel}, function(data) { - document.getElementById('loading').style.display = 'none'; - PDFView.load(data, scale); - }); - }, - - progressLevel: function(evt) { - var p = Math.round((evt.loaded / evt.total) * 100); - document.getElementById('loading').innerHTML = 'Loading... ' + p + '%'; + getPdf( + { + url: url, + progress: function getPdfProgress(evt) { + if (evt.lengthComputable) + PDFView.progress(evt.loaded / evt.total); + }, + error: PDFView.error + }, + function getPdfLoad(data) { + PDFView.load(data, scale); + }); }, navigateTo: function(dest) { @@ -134,7 +137,21 @@ var PDFView = { } }, + error: function() { + var loadingIndicator = document.getElementById('loading'); + loadingIndicator.innerHTML = 'Error'; + }, + + progress: function(level) { + var percent = Math.round(level * 100); + var loadingIndicator = document.getElementById('loading'); + loadingIndicator.innerHTML = 'Loading... ' + percent + '%'; + }, + load: function(data, scale) { + var loadingIndicator = document.getElementById('loading'); + loadingIndicator.style.display = 'none'; + var sidebar = document.getElementById('sidebarView'); sidebar.parentNode.scrollTop = 0; @@ -482,10 +499,18 @@ window.addEventListener('load', function(evt) { document.getElementById('fileInput').value = null; }, true); -window.addEventListener('pdfloaded', function(evt) { +window.addEventListener('pdfload', function(evt) { PDFView.load(evt.detail); }, true); +window.addEventListener('pdfprogress', function(evt) { + PDFView.progress(evt.detail); +}, true); + +window.addEventListener('pdferror', function(evt) { + PDFView.error(); +}, true); + function updateViewarea() { var visiblePages = PDFView.getVisiblePages(); for (var i = 0; i < visiblePages.length; i++) {