From edc632e4696c460ea4f76b079187177f2d91c3cd Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Fri, 20 Jan 2012 14:48:57 -0800 Subject: [PATCH 01/12] Fix innerHtml warnings. Remove compatibility.js from the extension. --- Makefile | 7 +++---- web/viewer.js | 20 ++++++++++++++------ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index c9de61c1c..fe5a3fc42 100644 --- a/Makefile +++ b/Makefile @@ -207,9 +207,8 @@ pages-repo: | $(BUILD_DIR) # copy of the pdf.js source. CONTENT_DIR := content BUILD_NUMBER := `git log --format=oneline $(EXTENSION_BASE_VERSION).. | wc -l | awk '{print $$1}'` -PDF_WEB_FILES = \ +EXTENSION_WEB_FILES = \ web/images \ - web/compatibility.js \ web/viewer.css \ web/viewer.js \ web/viewer-production.html \ @@ -249,7 +248,7 @@ extension: | production @cd extensions/firefox; cp -r $(FIREFOX_EXTENSION_FILES_TO_COPY) ../../$(FIREFOX_BUILD_DIR)/ # Copy a standalone version of pdf.js inside the content directory @cp $(BUILD_TARGET) $(FIREFOX_BUILD_CONTENT)/$(BUILD_DIR)/ - @cp -r $(PDF_WEB_FILES) $(FIREFOX_BUILD_CONTENT)/web/ + @cp -r $(EXTENSION_WEB_FILES) $(FIREFOX_BUILD_CONTENT)/web/ @mv -f $(FIREFOX_BUILD_CONTENT)/web/viewer-production.html $(FIREFOX_BUILD_CONTENT)/web/viewer.html # Update the build version number @sed -i.bak "s/PDFJSSCRIPT_BUILD/$(BUILD_NUMBER)/" $(FIREFOX_BUILD_DIR)/install.rdf @@ -272,7 +271,7 @@ extension: | production @cp -R $(CHROME_EXTENSION_FILES) $(CHROME_BUILD_DIR)/ # Copy a standalone version of pdf.js inside the content directory @cp $(BUILD_TARGET) $(CHROME_BUILD_CONTENT)/$(BUILD_DIR)/ - @cp -r $(PDF_WEB_FILES) $(CHROME_BUILD_CONTENT)/web/ + @cp -r $(EXTENSION_WEB_FILES) $(CHROME_BUILD_CONTENT)/web/ @mv -f $(CHROME_BUILD_CONTENT)/web/viewer-production.html $(CHROME_BUILD_CONTENT)/web/viewer.html # Create the crx diff --git a/web/viewer.js b/web/viewer.js index ac3fbff0c..6c72df3d0 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -257,7 +257,7 @@ var PDFView = { }, error: function getPdfError(e) { var loadingIndicator = document.getElementById('loading'); - loadingIndicator.innerHTML = 'Error'; + loadingIndicator.textContent = 'Error'; var moreInfo = { message: 'Unexpected server response of ' + e.target.status + '.' }; @@ -327,7 +327,7 @@ var PDFView = { errorWrapper.removeAttribute('hidden'); var errorMessage = document.getElementById('errorMessage'); - errorMessage.innerHTML = message; + errorMessage.textContent = message; var closeButton = document.getElementById('errorClose'); closeButton.onclick = function() { @@ -362,7 +362,7 @@ var PDFView = { progress: function pdfViewProgress(level) { var percent = Math.round(level * 100); var loadingIndicator = document.getElementById('loading'); - loadingIndicator.innerHTML = 'Loading... ' + percent + '%'; + loadingIndicator.textContent = 'Loading... ' + percent + '%'; }, load: function pdfViewLoad(data, scale) { @@ -402,7 +402,7 @@ var PDFView = { var pagesCount = pdf.numPages; var id = pdf.fingerprint; var storedHash = null; - document.getElementById('numPages').innerHTML = pagesCount; + document.getElementById('numPages').textContent = pagesCount; document.getElementById('pageNumber').max = pagesCount; PDFView.documentFingerprint = id; var store = PDFView.store = new Settings(id); @@ -648,7 +648,15 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight, if (!item.content) { content.setAttribute('hidden', true); } else { - text.innerHTML = item.content.replace('\n', '
'); + var e = document.createElement('span'); + var lines = item.content.split('\n'); + for (var i = 0, ii = lines.length; i < ii; ++i) { + var line = lines[i]; + e.appendChild(document.createTextNode(line)); + if (i < (ii - 1)) + e.appendChild(document.createElement('br')); + } + text.appendChild(e); image.addEventListener('mouseover', function annotationImageOver() { this.nextSibling.removeAttribute('hidden'); }, false); @@ -822,7 +830,7 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight, var t1 = stats.compile, t2 = stats.fonts, t3 = stats.render; var str = 'Time to compile/fonts/render: ' + (t1 - stats.begin) + '/' + (t2 - t1) + '/' + (t3 - t2) + ' ms'; - document.getElementById('info').innerHTML = str; + document.getElementById('info').textContent = str; }; }; From 178b89342af2185de7771fba8112cb92cd6dfaa9 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Mon, 23 Jan 2012 16:50:45 -0800 Subject: [PATCH 02/12] Switch to stream converter for extension. --- Makefile | 14 ++- extensions/firefox/bootstrap.js | 3 - extensions/firefox/chrome.manifest | 4 +- .../firefox/components/pdfContentHandler.js | 89 ++++++++++++------- src/core.js | 20 ++++- web/viewer-snippet-firefox-extension.html | 14 +++ web/viewer.html | 4 +- web/viewer.js | 35 ++------ 8 files changed, 113 insertions(+), 70 deletions(-) create mode 100644 web/viewer-snippet-firefox-extension.html diff --git a/Makefile b/Makefile index fe5a3fc42..eaaa3e81f 100644 --- a/Makefile +++ b/Makefile @@ -211,6 +211,7 @@ EXTENSION_WEB_FILES = \ web/images \ web/viewer.css \ web/viewer.js \ + web/viewer.html \ web/viewer-production.html \ $(NULL) @@ -249,7 +250,18 @@ extension: | production # Copy a standalone version of pdf.js inside the content directory @cp $(BUILD_TARGET) $(FIREFOX_BUILD_CONTENT)/$(BUILD_DIR)/ @cp -r $(EXTENSION_WEB_FILES) $(FIREFOX_BUILD_CONTENT)/web/ - @mv -f $(FIREFOX_BUILD_CONTENT)/web/viewer-production.html $(FIREFOX_BUILD_CONTENT)/web/viewer.html + @rm $(FIREFOX_BUILD_CONTENT)/web/viewer-production.html + # Copy over the firefox extension snippet so we can inline pdf.js in it + cp web/viewer-snippet-firefox-extension.html $(FIREFOX_BUILD_CONTENT)/web/ + # Modify the viewer so it does all the extension only stuff. + cd $(FIREFOX_BUILD_CONTENT)/web; \ + sed -i.bak '/PDFJSSCRIPT_INCLUDE_BUNDLE/ r ../build/pdf.js' viewer-snippet-firefox-extension.html; \ + sed -i.bak '/PDFJSSCRIPT_REMOVE/d' viewer.html; \ + sed -i.bak '/PDFJSSCRIPT_REMOVE_FIREFOX_EXTENSION/d' viewer.html; \ + sed -i.bak '/PDFJSSCRIPT_INCLUDE_FIREFOX_EXTENSION/ r viewer-snippet-firefox-extension.html' viewer.html; \ + rm -f *.bak; + # We don't need pdf.js anymore since its inlined + rm -Rf $(FIREFOX_BUILD_CONTENT)/$(BUILD_DIR)/; # Update the build version number @sed -i.bak "s/PDFJSSCRIPT_BUILD/$(BUILD_NUMBER)/" $(FIREFOX_BUILD_DIR)/install.rdf @sed -i.bak "s/PDFJSSCRIPT_BUILD/$(BUILD_NUMBER)/" $(FIREFOX_BUILD_DIR)/update.rdf diff --git a/extensions/firefox/bootstrap.js b/extensions/firefox/bootstrap.js index e51df28f8..bbc53195e 100644 --- a/extensions/firefox/bootstrap.js +++ b/extensions/firefox/bootstrap.js @@ -34,13 +34,10 @@ function shutdown(aData, aReason) { } function install(aData, aReason) { - let url = 'chrome://pdf.js/content/web/viewer.html?file=%s'; - Services.prefs.setCharPref('extensions.pdf.js.url', url); Services.prefs.setBoolPref('extensions.pdf.js.active', false); } function uninstall(aData, aReason) { - Services.prefs.clearUserPref('extensions.pdf.js.url'); Services.prefs.clearUserPref('extensions.pdf.js.active'); } diff --git a/extensions/firefox/chrome.manifest b/extensions/firefox/chrome.manifest index d7db20b38..ec7c9a964 100644 --- a/extensions/firefox/chrome.manifest +++ b/extensions/firefox/chrome.manifest @@ -1,5 +1,5 @@ -content pdf.js content/ +resource pdf.js content/ component {2278dfd0-b75c-11e0-8257-1ba3d93c9f1a} components/pdfContentHandler.js -contract @mozilla.org/uriloader/content-handler;1?type=application/pdf {2278dfd0-b75c-11e0-8257-1ba3d93c9f1a} +contract @mozilla.org/streamconv;1?from=application/pdf&to=*/* {2278dfd0-b75c-11e0-8257-1ba3d93c9f1a} diff --git a/extensions/firefox/components/pdfContentHandler.js b/extensions/firefox/components/pdfContentHandler.js index 67459b759..fa9f329fc 100644 --- a/extensions/firefox/components/pdfContentHandler.js +++ b/extensions/firefox/components/pdfContentHandler.js @@ -21,47 +21,74 @@ function log(aMsg) { } const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001; + function pdfContentHandler() { -} +}; pdfContentHandler.prototype = { - handleContent: function handleContent(aMimetype, aContext, aRequest) { - if (aMimetype != PDF_CONTENT_TYPE) - throw NS_ERROR_WONT_HANDLE_CONTENT; - - if (!(aRequest instanceof Ci.nsIChannel)) - throw NS_ERROR_WONT_HANDLE_CONTENT; - - if (!Services.prefs.getBoolPref('extensions.pdf.js.active')) - throw NS_ERROR_WONT_HANDLE_CONTENT; - - let window = null; - let callbacks = aRequest.notificationCallbacks || - aRequest.loadGroup.notificationCallbacks; - if (!callbacks) - return; - window = callbacks.getInterface(Ci.nsIDOMWindow); + // properties required for XPCOM registration: + classID: Components.ID('{2278dfd0-b75c-11e0-8257-1ba3d93c9f1a}'), + classDescription: 'pdf.js Component', + contractID: '@mozilla.org/streamconv;1?from=application/pdf&to=*/*', + + QueryInterface: XPCOMUtils.generateQI([ + Ci.nsISupports, + Ci.nsIStreamConverter, + Ci.nsIStreamListener, + Ci.nsIRequestObserver + ]), + + /* + * This component works as such: + * 1. asyncConvertData stores the listener + * 2. onStartRequest creates a new channel, streams the viewer and cancels + * the request so pdf.js can do the request + * Since the request is cancelled onDataAvailable should not be called. The + * onStopRequest does nothing. The convert function just returns the stream, + * it's just the synchronous version of asyncConvertData. + */ + + // nsIStreamConverter::convert + convert: function (aFromStream, aFromType, aToType, aCtxt) { + return aFromStream; + }, - let url = null; - try { - url = Services.prefs.getCharPref('extensions.pdf.js.url'); - } catch (e) { - log('Error retrieving the pdf.js base url - ' + e); - throw NS_ERROR_WONT_HANDLE_CONTENT; - } + // nsIStreamConverter::asyncConvertData + asyncConvertData: function (aFromType, aToType, aListener, aCtxt) { + // Store the listener passed to us + this.listener = aListener; + }, - let targetUrl = aRequest.URI.spec; - if (targetUrl.indexOf('#pdfjs.action=download') >= 0) - throw NS_ERROR_WONT_HANDLE_CONTENT; + // nsIStreamListener::onDataAvailable + onDataAvailable: function (aRequest, aContext, aInputStream, aOffset, aCount) { + // Do nothing since all the data loading is handled by the viewer. + log("SANITY CHECK: onDataAvailable SHOULD NOT BE CALLED!"); + }, + // nsIRequestObserver::onStartRequest + onStartRequest: function (aRequest, aContext) { + // Setup the request so we can use it below. + aRequest.QueryInterface(Ci.nsIChannel); + + // Create a new channel that is viewer loaded as a resource. + var ioService = Cc["@mozilla.org/network/io-service;1"] + .getService(Ci.nsIIOService); + var channel = ioService.newChannel( + 'resource://pdf.js/web/viewer.html', null, null); + // Keep the URL the same so the browser sees it as the same. + channel.originalURI = aRequest.originalURI; + channel.asyncOpen(this.listener, aContext); + + // Cancel the request so the viewer can handle it. aRequest.cancel(Cr.NS_BINDING_ABORTED); - window.location = url.replace('%s', encodeURIComponent(targetUrl)); }, - classID: Components.ID('{2278dfd0-b75c-11e0-8257-1ba3d93c9f1a}'), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentHandler]) + // nsIRequestObserver::onStopRequest + onStopRequest: function (aRequest, aContext, aStatusCode) { + // Do nothing. + return; + } }; var NSGetFactory = XPCOMUtils.generateNSGetFactory([pdfContentHandler]); - diff --git a/src/core.js b/src/core.js index 7a9f3ee03..3e3d991a9 100644 --- a/src/core.js +++ b/src/core.js @@ -624,9 +624,19 @@ var PDFDoc = (function PDFDocClosure() { } try { - // Some versions of FF can't create a worker on localhost, see: - // https://bugzilla.mozilla.org/show_bug.cgi?id=683280 - var worker = new Worker(workerSrc); + var worker; + if (PDFJS.isFirefoxExtension) { + // The firefox extension can't load the worker from the resource:// + // url so we have to inline the script and then use the blob loader. + var bb = new MozBlobBuilder(); + bb.append(document.querySelector('#PDFJS_SCRIPT_TAG').textContent); + var blobUrl = window.URL.createObjectURL(bb.getBlob()); + worker = new Worker(blobUrl); + } else { + // Some versions of FF can't create a worker on localhost, see: + // https://bugzilla.mozilla.org/show_bug.cgi?id=683280 + worker = new Worker(workerSrc); + } var messageHandler = new MessageHandler('main', worker); @@ -645,7 +655,9 @@ var PDFDoc = (function PDFDocClosure() { // serializing the typed array. messageHandler.send('test', testObj); return; - } catch (e) {} + } catch (e) { + warn('The worker has been disabled.') + } } // Either workers are disabled, not supported or have thrown an exception. // Thus, we fallback to a faked worker. diff --git a/web/viewer-snippet-firefox-extension.html b/web/viewer-snippet-firefox-extension.html new file mode 100644 index 000000000..a3d3502a8 --- /dev/null +++ b/web/viewer-snippet-firefox-extension.html @@ -0,0 +1,14 @@ + + + + diff --git a/web/viewer.html b/web/viewer.html index 40e99004f..f395292f9 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -2,9 +2,11 @@ Simple pdf.js page viewer + + - + diff --git a/web/viewer.js b/web/viewer.js index 6c72df3d0..f65c75434 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -73,23 +73,11 @@ var Settings = (function SettingsClosure() { } 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) + if (isLocalStorageEnabled) database = localStorage.getItem('database') || '{}'; else return false; @@ -110,31 +98,20 @@ var Settings = (function SettingsClosure() { 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) + 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) + 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 this.file[name] || defaultValue; } }; @@ -1011,7 +988,9 @@ window.addEventListener('load', function webViewerLoad(evt) { } var scale = ('scale' in params) ? params.scale : 0; - PDFView.open(params.file || kDefaultURL, parseFloat(scale)); + var file = PDFJS.isFirefoxExtension ? + window.location.toString() : params.file || kDefaultURL; + PDFView.open(file, parseFloat(scale)); if (!window.File || !window.FileReader || !window.FileList || !window.Blob) document.getElementById('fileInput').setAttribute('hidden', 'true'); From 4d3057aba747ffc2cc6ca54ca475504aac57608e Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Mon, 23 Jan 2012 17:52:53 -0800 Subject: [PATCH 03/12] Fix lint. --- .../firefox/components/pdfContentHandler.js | 18 +++++++++--------- src/core.js | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/extensions/firefox/components/pdfContentHandler.js b/extensions/firefox/components/pdfContentHandler.js index fa9f329fc..fc42b9260 100644 --- a/extensions/firefox/components/pdfContentHandler.js +++ b/extensions/firefox/components/pdfContentHandler.js @@ -23,7 +23,7 @@ function log(aMsg) { const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001; function pdfContentHandler() { -}; +} pdfContentHandler.prototype = { @@ -31,7 +31,7 @@ pdfContentHandler.prototype = { classID: Components.ID('{2278dfd0-b75c-11e0-8257-1ba3d93c9f1a}'), classDescription: 'pdf.js Component', contractID: '@mozilla.org/streamconv;1?from=application/pdf&to=*/*', - + QueryInterface: XPCOMUtils.generateQI([ Ci.nsISupports, Ci.nsIStreamConverter, @@ -50,29 +50,29 @@ pdfContentHandler.prototype = { */ // nsIStreamConverter::convert - convert: function (aFromStream, aFromType, aToType, aCtxt) { + convert: function(aFromStream, aFromType, aToType, aCtxt) { return aFromStream; }, // nsIStreamConverter::asyncConvertData - asyncConvertData: function (aFromType, aToType, aListener, aCtxt) { + asyncConvertData: function(aFromType, aToType, aListener, aCtxt) { // Store the listener passed to us this.listener = aListener; }, // nsIStreamListener::onDataAvailable - onDataAvailable: function (aRequest, aContext, aInputStream, aOffset, aCount) { + onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) { // Do nothing since all the data loading is handled by the viewer. - log("SANITY CHECK: onDataAvailable SHOULD NOT BE CALLED!"); + log('SANITY CHECK: onDataAvailable SHOULD NOT BE CALLED!'); }, // nsIRequestObserver::onStartRequest - onStartRequest: function (aRequest, aContext) { + onStartRequest: function(aRequest, aContext) { // Setup the request so we can use it below. aRequest.QueryInterface(Ci.nsIChannel); // Create a new channel that is viewer loaded as a resource. - var ioService = Cc["@mozilla.org/network/io-service;1"] + var ioService = Cc['@mozilla.org/network/io-service;1'] .getService(Ci.nsIIOService); var channel = ioService.newChannel( 'resource://pdf.js/web/viewer.html', null, null); @@ -85,7 +85,7 @@ pdfContentHandler.prototype = { }, // nsIRequestObserver::onStopRequest - onStopRequest: function (aRequest, aContext, aStatusCode) { + onStopRequest: function(aRequest, aContext, aStatusCode) { // Do nothing. return; } diff --git a/src/core.js b/src/core.js index 3e3d991a9..93dde00ed 100644 --- a/src/core.js +++ b/src/core.js @@ -656,7 +656,7 @@ var PDFDoc = (function PDFDocClosure() { messageHandler.send('test', testObj); return; } catch (e) { - warn('The worker has been disabled.') + warn('The worker has been disabled.'); } } // Either workers are disabled, not supported or have thrown an exception. From 23bf35d5ef34039fd181b3f25b973a4d30f1720d Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Tue, 24 Jan 2012 14:55:07 -0800 Subject: [PATCH 04/12] Fix anchor links. --- web/viewer.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/web/viewer.js b/web/viewer.js index f65c75434..1ed9019ff 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -269,15 +269,18 @@ var PDFView = { }, getDestinationHash: function pdfViewGetDestinationHash(dest) { + // We add the full url for the extension so the anchor links don't come up + // as resource:// urls and so open in new tab/window works. + var url = PDFJS.isFirefoxExtension ? this.url.split('#')[0] : ''; if (typeof dest === 'string') - return '#' + escape(dest); + return url + '#' + escape(dest); if (dest instanceof Array) { var destRef = dest[0]; // see navigateTo method for dest format var pageNumber = destRef instanceof Object ? this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] : (destRef + 1); if (pageNumber) { - var pdfOpenParams = '#page=' + pageNumber; + var pdfOpenParams = url + '#page=' + pageNumber; var destKind = dest[1]; if ('name' in destKind && destKind.name == 'XYZ') { var scale = (dest[4] || this.currentScale); From f3b2a03de63b4216790a00c3ebc95b7e449211e6 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Tue, 24 Jan 2012 15:13:50 -0800 Subject: [PATCH 05/12] Hide the browse bar for the ff extension. --- web/viewer.css | 2 +- web/viewer.html | 2 +- web/viewer.js | 8 ++++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/web/viewer.css b/web/viewer.css index e355f7fc2..b9fd3e9e4 100644 --- a/web/viewer.css +++ b/web/viewer.css @@ -9,7 +9,7 @@ body { } [hidden] { - display: none; + display: none !important; } /* === Toolbar === */ diff --git a/web/viewer.html b/web/viewer.html index f395292f9..ad9d1189e 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -92,7 +92,7 @@ -
+
Bookmark diff --git a/web/viewer.js b/web/viewer.js index 1ed9019ff..131d12b42 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -995,10 +995,14 @@ window.addEventListener('load', function webViewerLoad(evt) { window.location.toString() : params.file || kDefaultURL; PDFView.open(file, parseFloat(scale)); - if (!window.File || !window.FileReader || !window.FileList || !window.Blob) + if (PDFJS.isFirefoxExtension || !window.File || !window.FileReader || + !window.FileList || !window.Blob) { document.getElementById('fileInput').setAttribute('hidden', 'true'); - else + document.getElementById('fileInputSeperator') + .setAttribute('hidden', 'true'); + } else { document.getElementById('fileInput').value = null; + } if ('disableWorker' in params) PDFJS.disableWorker = (params['disableWorker'] === 'true'); From dd8c39d8e14d283777f8c4e5788ada2c719d9542 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Tue, 24 Jan 2012 15:46:53 -0800 Subject: [PATCH 06/12] Fix the bookmark button and redo the anchor prefix. --- web/viewer.js | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/web/viewer.js b/web/viewer.js index 131d12b42..b784e6f5a 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -269,18 +269,15 @@ var PDFView = { }, getDestinationHash: function pdfViewGetDestinationHash(dest) { - // We add the full url for the extension so the anchor links don't come up - // as resource:// urls and so open in new tab/window works. - var url = PDFJS.isFirefoxExtension ? this.url.split('#')[0] : ''; if (typeof dest === 'string') - return url + '#' + escape(dest); + return PDFView.getAnchorUrl('#' + escape(dest)); if (dest instanceof Array) { var destRef = dest[0]; // see navigateTo method for dest format var pageNumber = destRef instanceof Object ? this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] : (destRef + 1); if (pageNumber) { - var pdfOpenParams = url + '#page=' + pageNumber; + var pdfOpenParams = PDFView.getAnchorUrl('#page=' + pageNumber); var destKind = dest[1]; if ('name' in destKind && destKind.name == 'XYZ') { var scale = (dest[4] || this.currentScale); @@ -295,6 +292,17 @@ var PDFView = { return ''; }, + /** + * For the firefox extension we prefix the full url on anchor links so they + * don't come up as resource:// urls and so open in new tab/window works. + * @param {String} anchor The anchor hash include the #. + */ + getAnchorUrl: function getAnchorUrl(anchor) { + if (PDFJS.isFirefoxExtension) + return this.url.split('#')[0] + anchor; + return anchor; + }, + /** * Show the error box. * @param {String} message A message that is human readable. @@ -1087,8 +1095,8 @@ function updateViewarea() { store.set('zoom', normalizedScaleValue); store.set('scrollLeft', Math.round(topLeft.x)); store.set('scrollTop', Math.round(topLeft.y)); - - document.getElementById('viewBookmark').href = pdfOpenParams; + var href = PDFView.getAnchorUrl(pdfOpenParams); + document.getElementById('viewBookmark').href = href; } window.addEventListener('scroll', function webViewerScroll(evt) { From 858aab008f236f4cfdba79be62d22677b9699e60 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Tue, 24 Jan 2012 21:33:03 -0800 Subject: [PATCH 07/12] Fix the download button. --- extensions/firefox/components/pdfContentHandler.js | 14 +++++++++++--- web/viewer.js | 9 ++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/extensions/firefox/components/pdfContentHandler.js b/extensions/firefox/components/pdfContentHandler.js index fc42b9260..320d69d30 100644 --- a/extensions/firefox/components/pdfContentHandler.js +++ b/extensions/firefox/components/pdfContentHandler.js @@ -70,6 +70,17 @@ pdfContentHandler.prototype = { onStartRequest: function(aRequest, aContext) { // Setup the request so we can use it below. aRequest.QueryInterface(Ci.nsIChannel); + // Cancel the request so the viewer can handle it. + aRequest.cancel(Cr.NS_BINDING_ABORTED); + + // Check if we should download. + var targetUrl = aRequest.originalURI.spec; + var downloadHash = targetUrl.indexOf('?#pdfjs.action=download'); + if (downloadHash >= 0) { + targetUrl = targetUrl.substring(0, downloadHash); + Services.wm.getMostRecentWindow("navigator:browser").saveURL(targetUrl); + return; + } // Create a new channel that is viewer loaded as a resource. var ioService = Cc['@mozilla.org/network/io-service;1'] @@ -79,9 +90,6 @@ pdfContentHandler.prototype = { // Keep the URL the same so the browser sees it as the same. channel.originalURI = aRequest.originalURI; channel.asyncOpen(this.listener, aContext); - - // Cancel the request so the viewer can handle it. - aRequest.cancel(Cr.NS_BINDING_ABORTED); }, // nsIRequestObserver::onStopRequest diff --git a/web/viewer.js b/web/viewer.js index b784e6f5a..55d0a595c 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -249,7 +249,14 @@ var PDFView = { }, download: function pdfViewDownload() { - window.open(this.url + '#pdfjs.action=download', '_parent'); + var url = this.url.split('#')[0]; + // For the extension we add an extra '?' to force the page to reload, its + // stripped off by the extension. + if (PDFJS.isFirefoxExtension) + url += '?#pdfjs.action=download'; + else + url += '#pdfjs.action=download', '_parent'; + window.open(url, '_parent'); }, navigateTo: function pdfViewNavigateTo(dest) { From 0d839c1c597b8054cb259d469c02300543023fca Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Wed, 25 Jan 2012 17:40:08 -0800 Subject: [PATCH 08/12] Fix how we're storing settings and change how the save pdf works. --- extensions/firefox/bootstrap.js | 152 +++++++++++++++++- .../firefox/components/pdfContentHandler.js | 15 +- web/viewer.js | 49 ++++-- 3 files changed, 195 insertions(+), 21 deletions(-) diff --git a/extensions/firefox/bootstrap.js b/extensions/firefox/bootstrap.js index bbc53195e..06fcf182f 100644 --- a/extensions/firefox/bootstrap.js +++ b/extensions/firefox/bootstrap.js @@ -3,17 +3,155 @@ 'use strict'; +const EXT_PREFIX = 'extensions.uriloader@pdf.js'; +const PDFJS_EVENT_ID = 'pdf.js.message'; let Cc = Components.classes; let Ci = Components.interfaces; let Cm = Components.manager; let Cu = Components.utils; +let application = Cc['@mozilla.org/fuel/application;1'] + .getService(Ci.fuelIApplication); +let privateBrowsing = Cc['@mozilla.org/privatebrowsing;1'] + .getService(Ci.nsIPrivateBrowsingService); Cu.import('resource://gre/modules/Services.jsm'); function log(str) { dump(str + '\n'); } +// watchWindows() and unload() are from Ed Lee's examples at +// https://github.com/Mardak/restartless/blob/watchWindows/bootstrap.js +/** + * Apply a callback to each open and new browser windows. + * + * @param {function} callback 1-parameter function that gets a browser window. + */ +function watchWindows(callback) { + // Wrap the callback in a function that ignores failures + function watcher(window) { + try { + // Now that the window has loaded, only handle browser windows + let {documentElement} = window.document; + if (documentElement.getAttribute('windowtype') == 'navigator:browser') + callback(window); + } + catch (ex) {} + } + + // Wait for the window to finish loading before running the callback + function runOnLoad(window) { + // Listen for one load event before checking the window type + window.addEventListener('load', function runOnce() { + window.removeEventListener('load', runOnce, false); + watcher(window); + }, false); + } + + // Add functionality to existing windows + let windows = Services.wm.getEnumerator(null); + while (windows.hasMoreElements()) { + // Only run the watcher immediately if the window is completely loaded + let window = windows.getNext(); + if (window.document.readyState == 'complete') + watcher(window); + // Wait for the window to load before continuing + else + runOnLoad(window); + } + + // Watch for new browser windows opening then wait for it to load + function windowWatcher(subject, topic) { + if (topic == 'domwindowopened') + runOnLoad(subject); + } + Services.ww.registerNotification(windowWatcher); + + // Make sure to stop watching for windows if we're unloading + unload(function() Services.ww.unregisterNotification(windowWatcher)); +} + +/** + * Save callbacks to run when unloading. Optionally scope the callback to a + * container, e.g., window. Provide a way to run all the callbacks. + * + * @param {function} callback 0-parameter function to call on unload. + * @param {node} container Remove the callback when this container unloads. + * @return {function} A 0-parameter function that undoes adding the callback. + */ +function unload(callback, container) { + // Initialize the array of unloaders on the first usage + let unloaders = unload.unloaders; + if (unloaders == null) + unloaders = unload.unloaders = []; + + // Calling with no arguments runs all the unloader callbacks + if (callback == null) { + unloaders.slice().forEach(function(unloader) unloader()); + unloaders.length = 0; + return; + } + + // The callback is bound to the lifetime of the container if we have one + if (container != null) { + // Remove the unloader when the container unloads + container.addEventListener('unload', removeUnloader, false); + // Wrap the callback to additionally remove the unload listener + let origCallback = callback; + callback = function() { + container.removeEventListener('unload', removeUnloader, false); + origCallback(); + } + } + + // Wrap the callback in a function that ignores failures + function unloader() { + try { + callback(); + } + catch (ex) {} + } + unloaders.push(unloader); + + // Provide a way to remove the unloader + function removeUnloader() { + let index = unloaders.indexOf(unloader); + if (index != -1) + unloaders.splice(index, 1); + } + return removeUnloader; +} + +function messageCallback(event) { + log(event.target.ownerDocument.currentScript); + var message = event.target, doc = message.ownerDocument; + var inPrivateBrowswing = privateBrowsing.privateBrowsingEnabled; + // Verify the message came from a PDF. + // TODO + var action = message.getUserData('action'); + var data = message.getUserData('data'); + switch (action) { + case 'download': + Services.wm.getMostRecentWindow('navigator:browser').saveURL(data); + break; + case 'setDatabase': + if (inPrivateBrowswing) + return; + application.prefs.setValue(EXT_PREFIX + '.database', data); + break; + case 'getDatabase': + var response; + if (inPrivateBrowswing) + response = '{}'; + else + response = application.prefs.getValue(EXT_PREFIX + '.database', '{}'); + message.setUserData('response', response, null); + break; + } +} + + +// All the boostrap functions: function startup(aData, aReason) { let manifestPath = 'chrome.manifest'; let manifest = Cc['@mozilla.org/file/local;1'] @@ -26,11 +164,22 @@ function startup(aData, aReason) { } catch (e) { log(e); } + + watchWindows(function(window) { + window.addEventListener(PDFJS_EVENT_ID, messageCallback, false, true); + unload(function() { + window.removeEventListener(PDFJS_EVENT_ID, messageCallback, false, true); + }); + }); } function shutdown(aData, aReason) { - if (Services.prefs.getBoolPref('extensions.pdf.js.active')) + if (Services.prefs.getBoolPref('extensions.pdf.js.active')) { Services.prefs.setBoolPref('extensions.pdf.js.active', false); + // Clean up with unloaders when we're deactivating + if (aReason != APP_SHUTDOWN) + unload(); + } } function install(aData, aReason) { @@ -39,5 +188,6 @@ function install(aData, aReason) { function uninstall(aData, aReason) { Services.prefs.clearUserPref('extensions.pdf.js.active'); + application.prefs.setValue(EXT_PREFIX + '.database', '{}'); } diff --git a/extensions/firefox/components/pdfContentHandler.js b/extensions/firefox/components/pdfContentHandler.js index 320d69d30..edd8ee3e0 100644 --- a/extensions/firefox/components/pdfContentHandler.js +++ b/extensions/firefox/components/pdfContentHandler.js @@ -20,7 +20,7 @@ function log(aMsg) { dump(msg + '\n'); } -const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001; +const NS_ERROR_NOT_IMPLEMENTED = 0x80004001; function pdfContentHandler() { } @@ -51,11 +51,13 @@ pdfContentHandler.prototype = { // nsIStreamConverter::convert convert: function(aFromStream, aFromType, aToType, aCtxt) { - return aFromStream; + return aFromStream; }, // nsIStreamConverter::asyncConvertData asyncConvertData: function(aFromType, aToType, aListener, aCtxt) { + if (!Services.prefs.getBoolPref('extensions.pdf.js.active')) + throw NS_ERROR_NOT_IMPLEMENTED; // Store the listener passed to us this.listener = aListener; }, @@ -73,15 +75,6 @@ pdfContentHandler.prototype = { // Cancel the request so the viewer can handle it. aRequest.cancel(Cr.NS_BINDING_ABORTED); - // Check if we should download. - var targetUrl = aRequest.originalURI.spec; - var downloadHash = targetUrl.indexOf('?#pdfjs.action=download'); - if (downloadHash >= 0) { - targetUrl = targetUrl.substring(0, downloadHash); - Services.wm.getMostRecentWindow("navigator:browser").saveURL(targetUrl); - return; - } - // Create a new channel that is viewer loaded as a resource. var ioService = Cc['@mozilla.org/network/io-service;1'] .getService(Ci.nsIIOService); diff --git a/web/viewer.js b/web/viewer.js index 55d0a595c..790b5ae63 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -61,6 +61,31 @@ var RenderingQueue = (function RenderingQueueClosure() { return RenderingQueue; })(); +var FirefoxCom = (function FirefoxComClosure() { + return { + /** + * Creates an event that hopefully the extension is listening for and will + * synchronously respond to. + * @param {String} action The action to trigger. + * @param {String} data Optional data to send. + * @return {*} The response. + */ + request: function(action, data) { + var request = document.createTextNode(''); + request.setUserData('action', action, null); + request.setUserData('data', data, null); + document.documentElement.appendChild(request); + + var sender = document.createEvent('Events'); + sender.initEvent('pdf.js.message', true, false); + request.dispatchEvent(sender); + var response = request.getUserData('response'); + document.documentElement.removeChild(request); + return response; + } + }; +})(); + // 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 @@ -74,10 +99,14 @@ var Settings = (function SettingsClosure() { return true; })(); + var isFirefoxExtension = PDFJS.isFirefoxExtension; + function Settings(fingerprint) { var database = null; var index; - if (isLocalStorageEnabled) + if (isFirefoxExtension) + database = FirefoxCom.request('getDatabase', null); + else if (isLocalStorageEnabled) database = localStorage.getItem('database') || '{}'; else return false; @@ -106,8 +135,11 @@ var Settings = (function SettingsClosure() { set: function settingsSet(name, val) { var file = this.file; file[name] = val; - if (isLocalStorageEnabled) - localStorage.setItem('database', JSON.stringify(this.database)); + var database = JSON.stringify(this.database); + if (isFirefoxExtension) + FirefoxCom.request('setDatabase', database); + else if (isLocalStorageEnabled) + localStorage.setItem('database', database); }, get: function settingsGet(name, defaultValue) { @@ -250,13 +282,12 @@ var PDFView = { download: function pdfViewDownload() { var url = this.url.split('#')[0]; - // For the extension we add an extra '?' to force the page to reload, its - // stripped off by the extension. - if (PDFJS.isFirefoxExtension) - url += '?#pdfjs.action=download'; - else + if (PDFJS.isFirefoxExtension) { + FirefoxCom.request('download', url); + } else { url += '#pdfjs.action=download', '_parent'; - window.open(url, '_parent'); + window.open(url, '_parent'); + } }, navigateTo: function pdfViewNavigateTo(dest) { From e7a0a2e1291fb744cdfa769fa3a8409d246078da Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Fri, 27 Jan 2012 10:53:07 -0800 Subject: [PATCH 09/12] Better way to listen to events and verify them. --- extensions/firefox/bootstrap.js | 148 +----------------- .../firefox/components/pdfContentHandler.js | 70 ++++++++- 2 files changed, 68 insertions(+), 150 deletions(-) diff --git a/extensions/firefox/bootstrap.js b/extensions/firefox/bootstrap.js index 06fcf182f..f1a712c0c 100644 --- a/extensions/firefox/bootstrap.js +++ b/extensions/firefox/bootstrap.js @@ -9,149 +9,14 @@ let Cc = Components.classes; let Ci = Components.interfaces; let Cm = Components.manager; let Cu = Components.utils; -let application = Cc['@mozilla.org/fuel/application;1'] - .getService(Ci.fuelIApplication); -let privateBrowsing = Cc['@mozilla.org/privatebrowsing;1'] - .getService(Ci.nsIPrivateBrowsingService); Cu.import('resource://gre/modules/Services.jsm'); function log(str) { dump(str + '\n'); } -// watchWindows() and unload() are from Ed Lee's examples at -// https://github.com/Mardak/restartless/blob/watchWindows/bootstrap.js -/** - * Apply a callback to each open and new browser windows. - * - * @param {function} callback 1-parameter function that gets a browser window. - */ -function watchWindows(callback) { - // Wrap the callback in a function that ignores failures - function watcher(window) { - try { - // Now that the window has loaded, only handle browser windows - let {documentElement} = window.document; - if (documentElement.getAttribute('windowtype') == 'navigator:browser') - callback(window); - } - catch (ex) {} - } - - // Wait for the window to finish loading before running the callback - function runOnLoad(window) { - // Listen for one load event before checking the window type - window.addEventListener('load', function runOnce() { - window.removeEventListener('load', runOnce, false); - watcher(window); - }, false); - } - // Add functionality to existing windows - let windows = Services.wm.getEnumerator(null); - while (windows.hasMoreElements()) { - // Only run the watcher immediately if the window is completely loaded - let window = windows.getNext(); - if (window.document.readyState == 'complete') - watcher(window); - // Wait for the window to load before continuing - else - runOnLoad(window); - } - // Watch for new browser windows opening then wait for it to load - function windowWatcher(subject, topic) { - if (topic == 'domwindowopened') - runOnLoad(subject); - } - Services.ww.registerNotification(windowWatcher); - - // Make sure to stop watching for windows if we're unloading - unload(function() Services.ww.unregisterNotification(windowWatcher)); -} - -/** - * Save callbacks to run when unloading. Optionally scope the callback to a - * container, e.g., window. Provide a way to run all the callbacks. - * - * @param {function} callback 0-parameter function to call on unload. - * @param {node} container Remove the callback when this container unloads. - * @return {function} A 0-parameter function that undoes adding the callback. - */ -function unload(callback, container) { - // Initialize the array of unloaders on the first usage - let unloaders = unload.unloaders; - if (unloaders == null) - unloaders = unload.unloaders = []; - - // Calling with no arguments runs all the unloader callbacks - if (callback == null) { - unloaders.slice().forEach(function(unloader) unloader()); - unloaders.length = 0; - return; - } - - // The callback is bound to the lifetime of the container if we have one - if (container != null) { - // Remove the unloader when the container unloads - container.addEventListener('unload', removeUnloader, false); - - // Wrap the callback to additionally remove the unload listener - let origCallback = callback; - callback = function() { - container.removeEventListener('unload', removeUnloader, false); - origCallback(); - } - } - - // Wrap the callback in a function that ignores failures - function unloader() { - try { - callback(); - } - catch (ex) {} - } - unloaders.push(unloader); - - // Provide a way to remove the unloader - function removeUnloader() { - let index = unloaders.indexOf(unloader); - if (index != -1) - unloaders.splice(index, 1); - } - return removeUnloader; -} - -function messageCallback(event) { - log(event.target.ownerDocument.currentScript); - var message = event.target, doc = message.ownerDocument; - var inPrivateBrowswing = privateBrowsing.privateBrowsingEnabled; - // Verify the message came from a PDF. - // TODO - var action = message.getUserData('action'); - var data = message.getUserData('data'); - switch (action) { - case 'download': - Services.wm.getMostRecentWindow('navigator:browser').saveURL(data); - break; - case 'setDatabase': - if (inPrivateBrowswing) - return; - application.prefs.setValue(EXT_PREFIX + '.database', data); - break; - case 'getDatabase': - var response; - if (inPrivateBrowswing) - response = '{}'; - else - response = application.prefs.getValue(EXT_PREFIX + '.database', '{}'); - message.setUserData('response', response, null); - break; - } -} - - -// All the boostrap functions: function startup(aData, aReason) { let manifestPath = 'chrome.manifest'; let manifest = Cc['@mozilla.org/file/local;1'] @@ -164,22 +29,11 @@ function startup(aData, aReason) { } catch (e) { log(e); } - - watchWindows(function(window) { - window.addEventListener(PDFJS_EVENT_ID, messageCallback, false, true); - unload(function() { - window.removeEventListener(PDFJS_EVENT_ID, messageCallback, false, true); - }); - }); } function shutdown(aData, aReason) { - if (Services.prefs.getBoolPref('extensions.pdf.js.active')) { + if (Services.prefs.getBoolPref('extensions.pdf.js.active')) Services.prefs.setBoolPref('extensions.pdf.js.active', false); - // Clean up with unloaders when we're deactivating - if (aReason != APP_SHUTDOWN) - unload(); - } } function install(aData, aReason) { diff --git a/extensions/firefox/components/pdfContentHandler.js b/extensions/firefox/components/pdfContentHandler.js index edd8ee3e0..1c6c72c81 100644 --- a/extensions/firefox/components/pdfContentHandler.js +++ b/extensions/firefox/components/pdfContentHandler.js @@ -7,8 +7,10 @@ const Cc = Components.classes; const Ci = Components.interfaces; const Cr = Components.results; const Cu = Components.utils; - +const PDFJS_EVENT_ID = 'pdf.js.message'; const PDF_CONTENT_TYPE = 'application/pdf'; +const NS_ERROR_NOT_IMPLEMENTED = 0x80004001; +const EXT_PREFIX = 'extensions.uriloader@pdf.js'; Cu.import('resource://gre/modules/XPCOMUtils.jsm'); Cu.import('resource://gre/modules/Services.jsm'); @@ -19,8 +21,50 @@ function log(aMsg) { .logStringMessage(msg); dump(msg + '\n'); } +let application = Cc['@mozilla.org/fuel/application;1'] + .getService(Ci.fuelIApplication); +let privateBrowsing = Cc['@mozilla.org/privatebrowsing;1'] + .getService(Ci.nsIPrivateBrowsingService); +let inPrivateBrowswing = privateBrowsing.privateBrowsingEnabled; + +// All the priviledged actions. +function ChromeActions() { + this.inPrivateBrowswing = privateBrowsing.privateBrowsingEnabled; +} +ChromeActions.prototype = { + download: function(data) { + Services.wm.getMostRecentWindow('navigator:browser').saveURL(data); + }, + setDatabase: function() { + if (this.inPrivateBrowswing) + return; + application.prefs.setValue(EXT_PREFIX + '.database', data); + }, + getDatabase: function() { + if (this.inPrivateBrowswing) + return '{}'; + return application.prefs.getValue(EXT_PREFIX + '.database', '{}'); + } +}; + +// Event listener to trigger chrome privedged code. +function RequestListener(actions) { + this.actions = actions; +} +// Recieves an event and synchronously responds. +RequestListener.prototype.recieve = function(event) { + var message = event.target; + var action = message.getUserData('action'); + var data = message.getUserData('data'); + var actions = this.actions; + if (!(action in actions)) { + log('Unknown action: ' + action); + return; + } + var response = actions[action].call(this.actions, data); + message.setUserData('response', response, null); +}; -const NS_ERROR_NOT_IMPLEMENTED = 0x80004001; function pdfContentHandler() { } @@ -70,6 +114,7 @@ pdfContentHandler.prototype = { // nsIRequestObserver::onStartRequest onStartRequest: function(aRequest, aContext) { + // Setup the request so we can use it below. aRequest.QueryInterface(Ci.nsIChannel); // Cancel the request so the viewer can handle it. @@ -80,15 +125,34 @@ pdfContentHandler.prototype = { .getService(Ci.nsIIOService); var channel = ioService.newChannel( 'resource://pdf.js/web/viewer.html', null, null); + // Keep the URL the same so the browser sees it as the same. channel.originalURI = aRequest.originalURI; channel.asyncOpen(this.listener, aContext); + + // Setup a global listener waiting for the next DOM to be created and verfiy + // that its the one we want by its URL. When the correct DOM is found create + // an event listener on that window for the pdf.js events that require + // chrome priviledges. + var url = aRequest.originalURI.spec; + var gb = Services.wm.getMostRecentWindow('navigator:browser'); + var domListener = function domListener(event) { + var doc = event.originalTarget; + var win = doc.defaultView; + if (doc.location.href === url) { + gb.removeEventListener('DOMContentLoaded', domListener); + var requestListener = new RequestListener(new ChromeActions()); + win.addEventListener(PDFJS_EVENT_ID, function(event) { + requestListener.recieve(event); + }, false, true); + } + }; + gb.addEventListener('DOMContentLoaded', domListener, false); }, // nsIRequestObserver::onStopRequest onStopRequest: function(aRequest, aContext, aStatusCode) { // Do nothing. - return; } }; From 337806deed4f75ba7d93bd14963264588c11b72e Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Fri, 27 Jan 2012 10:53:37 -0800 Subject: [PATCH 10/12] Fix url for thumbnail. (still not working 100) --- web/viewer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/viewer.js b/web/viewer.js index 790b5ae63..3431e18c4 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -862,7 +862,7 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight, var ThumbnailView = function thumbnailView(container, page, id, pageRatio) { var anchor = document.createElement('a'); - anchor.href = '#' + id; + anchor.href = PDFView.getAnchorUrl('#page=' + id); anchor.onclick = function stopNivigation() { PDFView.page = id; return false; From f46b0474ce4bad106f3c6dd813f23af8459e1479 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Fri, 27 Jan 2012 11:02:27 -0800 Subject: [PATCH 11/12] Change name to reflect what it is now. Change GUID. --- extensions/firefox/chrome.manifest | 4 ++-- .../{pdfContentHandler.js => PdfStreamConverter.js} | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) rename extensions/firefox/components/{pdfContentHandler.js => PdfStreamConverter.js} (95%) diff --git a/extensions/firefox/chrome.manifest b/extensions/firefox/chrome.manifest index ec7c9a964..5351257e7 100644 --- a/extensions/firefox/chrome.manifest +++ b/extensions/firefox/chrome.manifest @@ -1,5 +1,5 @@ resource pdf.js content/ -component {2278dfd0-b75c-11e0-8257-1ba3d93c9f1a} components/pdfContentHandler.js -contract @mozilla.org/streamconv;1?from=application/pdf&to=*/* {2278dfd0-b75c-11e0-8257-1ba3d93c9f1a} +component {6457a96b-2d68-439a-bcfa-44465fbcdbb1} components/PdfStreamConverter.js +contract @mozilla.org/streamconv;1?from=application/pdf&to=*/* {6457a96b-2d68-439a-bcfa-44465fbcdbb1} diff --git a/extensions/firefox/components/pdfContentHandler.js b/extensions/firefox/components/PdfStreamConverter.js similarity index 95% rename from extensions/firefox/components/pdfContentHandler.js rename to extensions/firefox/components/PdfStreamConverter.js index 1c6c72c81..83c930d51 100644 --- a/extensions/firefox/components/pdfContentHandler.js +++ b/extensions/firefox/components/PdfStreamConverter.js @@ -16,7 +16,7 @@ Cu.import('resource://gre/modules/XPCOMUtils.jsm'); Cu.import('resource://gre/modules/Services.jsm'); function log(aMsg) { - let msg = 'pdfContentHandler.js: ' + (aMsg.join ? aMsg.join('') : aMsg); + let msg = 'PdfStreamConverter.js: ' + (aMsg.join ? aMsg.join('') : aMsg); Cc['@mozilla.org/consoleservice;1'].getService(Ci.nsIConsoleService) .logStringMessage(msg); dump(msg + '\n'); @@ -66,13 +66,13 @@ RequestListener.prototype.recieve = function(event) { }; -function pdfContentHandler() { +function PdfStreamConverter() { } -pdfContentHandler.prototype = { +PdfStreamConverter.prototype = { // properties required for XPCOM registration: - classID: Components.ID('{2278dfd0-b75c-11e0-8257-1ba3d93c9f1a}'), + classID: Components.ID('{6457a96b-2d68-439a-bcfa-44465fbcdbb1}'), classDescription: 'pdf.js Component', contractID: '@mozilla.org/streamconv;1?from=application/pdf&to=*/*', @@ -156,4 +156,4 @@ pdfContentHandler.prototype = { } }; -var NSGetFactory = XPCOMUtils.generateNSGetFactory([pdfContentHandler]); +var NSGetFactory = XPCOMUtils.generateNSGetFactory([PdfStreamConverter]); From 6cf3109329f122996d7343a67b4c67ebf7981ff9 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Tue, 31 Jan 2012 17:53:42 -0800 Subject: [PATCH 12/12] Address review concerns. --- Makefile | 6 +++--- extensions/firefox/components/PdfStreamConverter.js | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index eaaa3e81f..adeb91b12 100644 --- a/Makefile +++ b/Makefile @@ -252,16 +252,16 @@ extension: | production @cp -r $(EXTENSION_WEB_FILES) $(FIREFOX_BUILD_CONTENT)/web/ @rm $(FIREFOX_BUILD_CONTENT)/web/viewer-production.html # Copy over the firefox extension snippet so we can inline pdf.js in it - cp web/viewer-snippet-firefox-extension.html $(FIREFOX_BUILD_CONTENT)/web/ + @cp web/viewer-snippet-firefox-extension.html $(FIREFOX_BUILD_CONTENT)/web/ # Modify the viewer so it does all the extension only stuff. - cd $(FIREFOX_BUILD_CONTENT)/web; \ + @cd $(FIREFOX_BUILD_CONTENT)/web; \ sed -i.bak '/PDFJSSCRIPT_INCLUDE_BUNDLE/ r ../build/pdf.js' viewer-snippet-firefox-extension.html; \ sed -i.bak '/PDFJSSCRIPT_REMOVE/d' viewer.html; \ sed -i.bak '/PDFJSSCRIPT_REMOVE_FIREFOX_EXTENSION/d' viewer.html; \ sed -i.bak '/PDFJSSCRIPT_INCLUDE_FIREFOX_EXTENSION/ r viewer-snippet-firefox-extension.html' viewer.html; \ rm -f *.bak; # We don't need pdf.js anymore since its inlined - rm -Rf $(FIREFOX_BUILD_CONTENT)/$(BUILD_DIR)/; + @rm -Rf $(FIREFOX_BUILD_CONTENT)/$(BUILD_DIR)/; # Update the build version number @sed -i.bak "s/PDFJSSCRIPT_BUILD/$(BUILD_NUMBER)/" $(FIREFOX_BUILD_DIR)/install.rdf @sed -i.bak "s/PDFJSSCRIPT_BUILD/$(BUILD_NUMBER)/" $(FIREFOX_BUILD_DIR)/update.rdf diff --git a/extensions/firefox/components/PdfStreamConverter.js b/extensions/firefox/components/PdfStreamConverter.js index 83c930d51..984915d23 100644 --- a/extensions/firefox/components/PdfStreamConverter.js +++ b/extensions/firefox/components/PdfStreamConverter.js @@ -35,7 +35,7 @@ ChromeActions.prototype = { download: function(data) { Services.wm.getMostRecentWindow('navigator:browser').saveURL(data); }, - setDatabase: function() { + setDatabase: function(data) { if (this.inPrivateBrowswing) return; application.prefs.setValue(EXT_PREFIX + '.database', data); @@ -51,8 +51,8 @@ ChromeActions.prototype = { function RequestListener(actions) { this.actions = actions; } -// Recieves an event and synchronously responds. -RequestListener.prototype.recieve = function(event) { +// Receive an event and synchronously responds. +RequestListener.prototype.receive = function(event) { var message = event.target; var action = message.getUserData('action'); var data = message.getUserData('data'); @@ -143,7 +143,7 @@ PdfStreamConverter.prototype = { gb.removeEventListener('DOMContentLoaded', domListener); var requestListener = new RequestListener(new ChromeActions()); win.addEventListener(PDFJS_EVENT_ID, function(event) { - requestListener.recieve(event); + requestListener.receive(event); }, false, true); } };