]> git.parisson.com Git - pdf.js.git/commitdiff
Switch to stream converter for extension.
authorBrendan Dahl <brendan.dahl@gmail.com>
Tue, 24 Jan 2012 00:50:45 +0000 (16:50 -0800)
committerBrendan Dahl <brendan.dahl@gmail.com>
Tue, 24 Jan 2012 00:50:45 +0000 (16:50 -0800)
Makefile
extensions/firefox/bootstrap.js
extensions/firefox/chrome.manifest
extensions/firefox/components/pdfContentHandler.js
src/core.js
web/viewer-snippet-firefox-extension.html [new file with mode: 0644]
web/viewer.html
web/viewer.js

index fe5a3fc425e81ec71da167be597659666ef9fda5..eaaa3e81fc3fc90abbaf8d7e93e3d5983da0652d 100644 (file)
--- 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
index e51df28f8bd2a56202830169819c7a0e9ccde804..bbc53195ee6403239f7bc01c2107830ecaf6b846 100644 (file)
@@ -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');
 }
 
index d7db20b3870afefe0045acac3978090394cfbf25..ec7c9a9649847e9aa7903ca73fb6b39e08488931 100644 (file)
@@ -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}
 
index 67459b75929a19ca59e1c06a08a8461682cd8218..fa9f329fca66c9728ac39a80a1bcbd7b1241e2eb 100644 (file)
@@ -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]);
-
index 7a9f3ee03094d12bb12c64af2bd946e7ecf7502f..3e3d991a918bb58c15e2a9f829499bbabd6c69d7 100644 (file)
@@ -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 (file)
index 0000000..a3d3502
--- /dev/null
@@ -0,0 +1,14 @@
+<!-- This snippet is used in firefox extension, see Makefile -->
+<base href="resource://pdf.js/web/" />
+<script type="text/javascript" id="PDFJS_SCRIPT_TAG">
+<!--
+// pdf.js is inlined here because resource:// urls won't work
+// for loading workers.
+/* PDFJSSCRIPT_INCLUDE_BUNDLE */
+-->
+</script>
+<script type="text/javascript">
+  // This specifies the location of the pdf.js file.
+  PDFJS.isFirefoxExtension = true;
+  PDFJS.workerSrc = 'none';
+</script>
index 40e99004fde4eef53f99d163adbe4cd6b3e0f5b2..f395292f98d356b87b0a03f712b6bb3f768fbd36 100644 (file)
@@ -2,9 +2,11 @@
 <html>
     <head>
         <title>Simple pdf.js page viewer</title>
+        <!-- PDFJSSCRIPT_INCLUDE_FIREFOX_EXTENSION -->
+
         <link rel="stylesheet" href="viewer.css"/>
 
-        <script type="text/javascript" src="compatibility.js"></script>
+        <script type="text/javascript" src="compatibility.js"></script> <!-- PDFJSSCRIPT_REMOVE_FIREFOX_EXTENSION -->
 
         <!-- PDFJSSCRIPT_INCLUDE_BUILD -->
         <script type="text/javascript" src="../src/core.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
index 6c72df3d07bd84f82fea5d2dba97664744fd989a..f65c754340b581b7fe834d7c1935236d16039ab0 100644 (file)
@@ -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');