]> git.parisson.com Git - pdf.js.git/commitdiff
Add global pref to enable/disable. Control pdf.js in application preferences. Add...
authorBrendan Dahl <brendan.dahl@gmail.com>
Thu, 31 May 2012 18:16:06 +0000 (11:16 -0700)
committerBrendan Dahl <brendan.dahl@gmail.com>
Thu, 31 May 2012 18:16:06 +0000 (11:16 -0700)
extensions/firefox/.gitignore
extensions/firefox/chrome-mozcentral.manifest
extensions/firefox/components/PdfStreamConverter.js
extensions/firefox/content/PdfJs.jsm [new file with mode: 0644]
make.js
test/mozcentral/Makefile.in
test/mozcentral/browser_pdfjs_main.js
test/mozcentral/browser_pdfjs_savedialog.js [new file with mode: 0644]

index 6eec9a7f275b578ca645c28541f099f4149a9c6d..c64b8b9104a64857d5905584ceaba7386d27174f 100644 (file)
@@ -1,4 +1,3 @@
-content/
 metadata.inc
 chrome.manifest.inc
 locale/
index a2a6757c37030ef8d99fd482a3105aa127c534e6..1c7abc845c3e3adb928797bec7aa368407f06bad 100644 (file)
@@ -1,3 +1,2 @@
 resource pdf.js content/
-component {d0c5195d-e798-49d4-b1d3-9324328b2291} components/PdfStreamConverter.js
-contract @mozilla.org/streamconv;1?from=application/pdf&to=*/* {d0c5195d-e798-49d4-b1d3-9324328b2291}
+resource pdf.js.components components/
index 62d22162b7b903aede61a8363473a1913ff5c9b9..dd8f2c190c516b765e872e7545be41461982f6ee 100644 (file)
@@ -9,6 +9,7 @@ const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 const Cu = Components.utils;
+const MOZ_CENTRAL = PDFJSSCRIPT_MOZ_CENTRAL;
 const PDFJS_EVENT_ID = 'pdf.js.message';
 const PDF_CONTENT_TYPE = 'application/pdf';
 const PREF_PREFIX = 'PDFJSSCRIPT_PREF_PREFIX';
@@ -19,11 +20,12 @@ const SEAMONKEY_ID = '{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}';
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 Cu.import('resource://gre/modules/Services.jsm');
 Cu.import('resource://gre/modules/NetUtil.jsm');
-Cu.import('resource://gre/modules/AddonManager.jsm');
 
 let appInfo = Cc['@mozilla.org/xre/app-info;1']
                   .getService(Ci.nsIXULAppInfo);
 let privateBrowsing, inPrivateBrowsing;
+let mimeService = Cc['@mozilla.org/mime;1']
+                    .getService(Ci.nsIMIMEService);
 
 if (appInfo.ID === FIREFOX_ID) {
   privateBrowsing = Cc['@mozilla.org/privatebrowsing;1']
@@ -71,6 +73,23 @@ function getDOMWindow(aChannel) {
   return win;
 }
 
+function isEnabled() {
+  if (MOZ_CENTRAL) {
+    var enabled = getBoolPref(PREF_PREFIX + '.enabled', false);
+    if (!enabled)
+      return false;
+    // To also be considered enabled the "Preview in Firefox" option must be
+    // selected in the Application preferences.
+    var handlerInfo = mimeService.
+                        getFromTypeAndExtension('application/pdf', 'pdf');
+    return handlerInfo && (handlerInfo.alwaysAskBeforeHandling == false &&
+           handlerInfo.preferredAction == Ci.nsIHandlerInfo.handleInternally);
+  }
+  // Always returns true for the extension since enabling/disabling is handled
+  // by the add-on manager.
+  return true;
+}
+
 function getLocalizedStrings(path) {
   var stringBundle = Cc['@mozilla.org/intl/stringbundle;1'].
       getService(Ci.nsIStringBundleService).
@@ -248,6 +267,8 @@ PdfStreamConverter.prototype = {
 
   // nsIStreamConverter::asyncConvertData
   asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
+    if (!isEnabled())
+      throw Cr.NS_ERROR_NOT_IMPLEMENTED;
     // Ignoring HTTP POST requests -- pdf.js has to repeat the request.
     var skipConversion = false;
     try {
diff --git a/extensions/firefox/content/PdfJs.jsm b/extensions/firefox/content/PdfJs.jsm
new file mode 100644 (file)
index 0000000..2b26fce
--- /dev/null
@@ -0,0 +1,105 @@
+var EXPORTED_SYMBOLS = ["PdfJs"];
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+const Cm = Components.manager;
+const Cu = Components.utils;
+
+const PREF_PREFIX = 'pdfjs';
+const PREF_ENABLED = PREF_PREFIX + '.enabled';
+const PDFJS_HANDLER_CHANGED = 'pdfjs:handlerChanged';
+
+Cu.import('resource://gre/modules/Services.jsm');
+Cu.import('resource://pdf.js.components/PdfStreamConverter.js');
+
+let mimeService = Cc["@mozilla.org/mime;1"]
+                    .getService(Ci.nsIMIMEService);
+
+function getBoolPref(pref, def) {
+  try {
+    return Services.prefs.getBoolPref(pref);
+  } catch (ex) {
+    return def;
+  }
+}
+
+// Register/unregister a class as a component.
+let Factory = {
+  registrar: null,
+  aClass: null,
+  register: function(aClass) {
+    if (this.aClass) {
+      dump('Cannot register more than one class');
+      return;
+    }
+    this.registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
+    this.aClass = aClass;
+    var proto = aClass.prototype;
+    this.registrar.registerFactory(proto.classID, proto.classDescription,
+      proto.contractID, this);
+  },
+  unregister: function() {
+    if (!this.aClass) {
+      dump('Class was never registered.');
+      return;
+    }
+    var proto = this.aClass.prototype;
+    this.registrar.unregisterFactory(proto.classID, this);
+    this.aClass = null;
+  },
+  // nsIFactory::createInstance
+  createInstance: function(outer, iid) {
+    if (outer !== null)
+      throw Cr.NS_ERROR_NO_AGGREGATION;
+    return (new (this.aClass)).QueryInterface(iid);
+  }
+};
+
+let PdfJs = {
+  _registered: false,
+  init: function() {
+    if (this.enabled)
+      this._register();
+    else
+      this._unregister();
+
+    // Listen for when pdf.js is completely disabled or a different pdf handler
+    // is chosen.
+    Services.prefs.addObserver(PREF_ENABLED, this, false);
+    Services.obs.addObserver(this, PDFJS_HANDLER_CHANGED, false);
+  },
+  observe: function(subject, topic, data) {
+    if (topic != 'nsPref:changed' && topic != PDFJS_HANDLER_CHANGED)
+      return;
+
+    if (this.enabled)
+      this._register();
+    else
+      this._unregister();
+  },
+  // pdf.js is only enabled if we're both selected as the pdf viewer and if the 
+  // global switch enabling us is true.
+  get enabled() {
+    var handlerInfo = mimeService.
+                        getFromTypeAndExtension('application/pdf', 'pdf');
+
+    var selectedAsHandler = handlerInfo && (handlerInfo.alwaysAskBeforeHandling == false &&
+           handlerInfo.preferredAction == Ci.nsIHandlerInfo.handleInternally);
+    return getBoolPref(PREF_ENABLED, false) && selectedAsHandler;
+  },
+  _register: function() {
+    if (this._registered)
+      return;
+
+    Factory.register(PdfStreamConverter);
+    this._registered = true;
+  },
+  _unregister: function() {
+    if (!this._registered)
+      return;
+
+    Factory.unregister();
+    this._registered = false;
+  }
+};
diff --git a/make.js b/make.js
index 227abed4be4b684adc4ff3fafedc5fc7f8991edc..62881ae19fbfe35f1efc66dd82ae538ee1a819b3 100755 (executable)
--- a/make.js
+++ b/make.js
@@ -358,6 +358,7 @@ target.firefox = function() {
 
   sed('-i', /PDFJSSCRIPT_STREAM_CONVERTER_ID/, FIREFOX_STREAM_CONVERTER_ID, FIREFOX_BUILD_DIR + 'components/PdfStreamConverter.js');
   sed('-i', /PDFJSSCRIPT_PREF_PREFIX/, FIREFOX_PREF_PREFIX, FIREFOX_BUILD_DIR + 'components/PdfStreamConverter.js');
+  sed('-i', /PDFJSSCRIPT_MOZ_CENTRAL/, 'false', FIREFOX_BUILD_DIR + 'components/PdfStreamConverter.js');
 
   // Update localized metadata
   var localizedMetadata = cat(EXTENSION_SRC_DIR + '/firefox/metadata.inc');
@@ -421,6 +422,8 @@ target.mozcentral = function() {
   mkdir('-p', MOZCENTRAL_CONTENT_DIR + BUILD_DIR);
   mkdir('-p', MOZCENTRAL_CONTENT_DIR + '/web');
 
+  cp(FIREFOX_CONTENT_DIR + 'PdfJs.jsm', MOZCENTRAL_CONTENT_DIR)
+
   // Copy extension files
   cd('extensions/firefox');
   cp('-R', FIREFOX_EXTENSION_FILES_TO_COPY, ROOT_DIR + MOZCENTRAL_EXTENSION_DIR);
@@ -461,6 +464,7 @@ target.mozcentral = function() {
 
   sed('-i', /PDFJSSCRIPT_STREAM_CONVERTER_ID/, MOZCENTRAL_STREAM_CONVERTER_ID, MOZCENTRAL_EXTENSION_DIR + 'components/PdfStreamConverter.js');
   sed('-i', /PDFJSSCRIPT_PREF_PREFIX/, MOZCENTRAL_PREF_PREFIX, MOZCENTRAL_EXTENSION_DIR + 'components/PdfStreamConverter.js');
+  sed('-i', /PDFJSSCRIPT_MOZ_CENTRAL/, 'true', MOZCENTRAL_EXTENSION_DIR + 'components/PdfStreamConverter.js');
 
   // List all files for mozilla-central
   cd(MOZCENTRAL_EXTENSION_DIR);
index 77b7a838d941b72fbf236879a3c86d2dec9c319c..93ec187e28c4de4d2340a64ede6f269cf9feb08e 100644 (file)
@@ -13,6 +13,7 @@ include $(topsrcdir)/config/rules.mk
 
 _BROWSER_TEST_FILES = \
   browser_pdfjs_main.js \
+  browser_pdfjs_savedialog.js \
   file_pdfjs_test.pdf \
   $(NULL)
 
index 884650892d2cc79c47ed102c6c84f90377b3d0aa..23229914be06f78a1b345fbb97524eb82728b14b 100644 (file)
@@ -6,7 +6,17 @@ const RELATIVE_DIR = "browser/extensions/pdfjs/test/";
 const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
 
 function test() {
-  var tab;
+  var tab, oldAction;
+
+  oldAction = changeMimeHandler();
+
+    const Cc = Components.classes;
+  const Ci = Components.interfaces;
+  let handlerService = Cc["@mozilla.org/uriloader/handler-service;1"].getService(Ci.nsIHandlerService);
+  let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
+  let handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
+
+  info('Pref action: ' + handlerInfo.preferredAction);
 
   waitForExplicitFinish();
   registerCleanupFunction(function() {
@@ -23,13 +33,62 @@ function test() {
 
     // Runs tests after all 'load' event handlers have fired off
     setTimeout(function() {
-      runTests(document, window);
+      runTests(document, window, function() {
+        revertMimeHandler(oldAction);
+        finish();
+      });
     }, 0);
   }, true);
 }
 
 
-function runTests(document, window) {
+function changeMimeHandler() {
+  let oldAction;
+
+  const Cc = Components.classes;
+  const Ci = Components.interfaces;
+  let handlerService = Cc["@mozilla.org/uriloader/handler-service;1"].getService(Ci.nsIHandlerService);
+  let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
+  let handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
+
+  oldAction = handlerInfo.preferredAction;
+
+  // Change and save mime handler settings
+  handlerInfo.alwaysAskBeforeHandling = false;
+  handlerInfo.preferredAction = Ci.nsIHandlerInfo.handleInternally;
+  handlerService.store(handlerInfo);
+
+  Services.obs.notifyObservers(null, 'pdfjs:handlerChanged', null);
+
+  // Refresh data
+  mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
+  handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
+
+  //
+  // Test: Mime handler was updated
+  //
+  is(handlerInfo.alwaysAskBeforeHandling, false, 'always-ask prompt change successful');
+  is(handlerInfo.preferredAction, Ci.nsIHandlerInfo.handleInternally, 'mime handler change successful');
+
+  return oldAction;
+}
+
+function revertMimeHandler(oldAction) {
+  const Cc = Components.classes;
+  const Ci = Components.interfaces;
+  let handlerService = Cc["@mozilla.org/uriloader/handler-service;1"].getService(Ci.nsIHandlerService);
+  let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
+  let handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
+
+  // Change and save mime handler settings
+  handlerInfo.alwaysAskBeforeHandling = true;
+  handlerInfo.preferredAction = oldAction;
+  handlerService.store(handlerInfo);
+}
+
+
+function runTests(document, window, callback) {
+
   //
   // Overall sanity tests
   //
@@ -67,5 +126,5 @@ function runTests(document, window) {
   viewBookmark.click();
   ok(viewBookmark.href.length > 0, 'viewBookmark button has href');
 
-  finish();
+  callback();
 }
diff --git a/test/mozcentral/browser_pdfjs_savedialog.js b/test/mozcentral/browser_pdfjs_savedialog.js
new file mode 100644 (file)
index 0000000..1014473
--- /dev/null
@@ -0,0 +1,54 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+const RELATIVE_DIR = "browser/extensions/pdfjs/test/";
+const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
+
+function test() {
+  var tab;
+
+  const Cc = Components.classes;
+  const Ci = Components.interfaces;
+  let handlerService = Cc["@mozilla.org/uriloader/handler-service;1"].getService(Ci.nsIHandlerService);
+  let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
+  let handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
+
+  //
+  // Test: Default mime handler
+  //
+  is(handlerInfo.alwaysAskBeforeHandling, true, 'mime handler: default is always-ask prompt');
+
+  //
+  // Test: "Open with" dialog comes up
+  //
+  addWindowListener('chrome://mozapps/content/downloads/unknownContentType.xul', finish);
+
+  waitForExplicitFinish();
+  registerCleanupFunction(function() {
+    gBrowser.removeTab(tab);
+  });
+
+  tab = gBrowser.addTab(TESTROOT + "file_pdfjs_test.pdf");
+  var newTabBrowser = gBrowser.getBrowserForTab(tab);
+}
+
+
+function addWindowListener(aURL, aCallback) {
+  Services.wm.addListener({
+    onOpenWindow: function(aXULWindow) {
+      info("window opened, waiting for focus");
+      Services.wm.removeListener(this);
+
+      var domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+                                .getInterface(Ci.nsIDOMWindow);
+      waitForFocus(function() {
+        is(domwindow.document.location.href, aURL, "should have seen the right window open");
+        domwindow.close();
+        aCallback();
+      }, domwindow);
+    },
+    onCloseWindow: function(aXULWindow) { },
+    onWindowTitleChange: function(aXULWindow, aNewTitle) { }
+  });
+}