browser/extensions/pdfjs/content/PdfJs.jsm

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* Copyright 2012 Mozilla Foundation
     2  *
     3  * Licensed under the Apache License, Version 2.0 (the "License");
     4  * you may not use this file except in compliance with the License.
     5  * You may obtain a copy of the License at
     6  *
     7  *     http://www.apache.org/licenses/LICENSE-2.0
     8  *
     9  * Unless required by applicable law or agreed to in writing, software
    10  * distributed under the License is distributed on an "AS IS" BASIS,
    11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  * See the License for the specific language governing permissions and
    13  * limitations under the License.
    14  */
    16 var EXPORTED_SYMBOLS = ["PdfJs"];
    18 const Cc = Components.classes;
    19 const Ci = Components.interfaces;
    20 const Cr = Components.results;
    21 const Cm = Components.manager;
    22 const Cu = Components.utils;
    24 const PREF_PREFIX = 'pdfjs';
    25 const PREF_DISABLED = PREF_PREFIX + '.disabled';
    26 const PREF_MIGRATION_VERSION = PREF_PREFIX + '.migrationVersion';
    27 const PREF_PREVIOUS_ACTION = PREF_PREFIX + '.previousHandler.preferredAction';
    28 const PREF_PREVIOUS_ASK = PREF_PREFIX + '.previousHandler.alwaysAskBeforeHandling';
    29 const PREF_DISABLED_PLUGIN_TYPES = 'plugin.disable_full_page_plugin_for_types';
    30 const TOPIC_PDFJS_HANDLER_CHANGED = 'pdfjs:handlerChanged';
    31 const TOPIC_PLUGINS_LIST_UPDATED = "plugins-list-updated";
    32 const TOPIC_PLUGIN_INFO_UPDATED = "plugin-info-updated";
    33 const PDF_CONTENT_TYPE = 'application/pdf';
    35 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
    36 Cu.import('resource://gre/modules/Services.jsm');
    38 let Svc = {};
    39 XPCOMUtils.defineLazyServiceGetter(Svc, 'mime',
    40                                    '@mozilla.org/mime;1',
    41                                    'nsIMIMEService');
    42 XPCOMUtils.defineLazyServiceGetter(Svc, 'pluginHost',
    43                                    '@mozilla.org/plugin/host;1',
    44                                    'nsIPluginHost');
    46 function getBoolPref(aPref, aDefaultValue) {
    47   try {
    48     return Services.prefs.getBoolPref(aPref);
    49   } catch (ex) {
    50     return aDefaultValue;
    51   }
    52 }
    54 function getIntPref(aPref, aDefaultValue) {
    55   try {
    56     return Services.prefs.getIntPref(aPref);
    57   } catch (ex) {
    58     return aDefaultValue;
    59   }
    60 }
    62 function initializeDefaultPreferences() {
    64 var DEFAULT_PREFERENCES = {
    65   showPreviousViewOnLoad: true,
    66   defaultZoomValue: '',
    67   ifAvailableShowOutlineOnLoad: false,
    68   enableHandToolOnLoad: false,
    69   enableWebGL: false
    70 };
    73   var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.');
    74   var defaultValue;
    75   for (var key in DEFAULT_PREFERENCES) {
    76     defaultValue = DEFAULT_PREFERENCES[key];
    77     switch (typeof defaultValue) {
    78       case 'boolean':
    79         defaultBranch.setBoolPref(key, defaultValue);
    80         break;
    81       case 'number':
    82         defaultBranch.setIntPref(key, defaultValue);
    83         break;
    84       case 'string':
    85         defaultBranch.setCharPref(key, defaultValue);
    86         break;
    87     }
    88   }
    89 }
    91 // Register/unregister a constructor as a factory.
    92 function Factory() {}
    93 Factory.prototype = {
    94   register: function register(targetConstructor) {
    95     var proto = targetConstructor.prototype;
    96     this._classID = proto.classID;
    98     var factory = XPCOMUtils._getFactory(targetConstructor);
    99     this._factory = factory;
   101     var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
   102     registrar.registerFactory(proto.classID, proto.classDescription,
   103                               proto.contractID, factory);
   104   },
   106   unregister: function unregister() {
   107     var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
   108     registrar.unregisterFactory(this._classID, this._factory);
   109     this._factory = null;
   110   }
   111 };
   113 let PdfJs = {
   114   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
   115   _registered: false,
   117   init: function init() {
   118     if (!getBoolPref(PREF_DISABLED, true)) {
   119       this._migrate();
   120     }
   122     if (this.enabled)
   123       this._ensureRegistered();
   124     else
   125       this._ensureUnregistered();
   127     // Listen for when pdf.js is completely disabled or a different pdf handler
   128     // is chosen.
   129     Services.prefs.addObserver(PREF_DISABLED, this, false);
   130     Services.prefs.addObserver(PREF_DISABLED_PLUGIN_TYPES, this, false);
   131     Services.obs.addObserver(this, TOPIC_PDFJS_HANDLER_CHANGED, false);
   132     Services.obs.addObserver(this, TOPIC_PLUGINS_LIST_UPDATED, false);
   133     Services.obs.addObserver(this, TOPIC_PLUGIN_INFO_UPDATED, false);
   135     initializeDefaultPreferences();
   136   },
   138   _migrate: function migrate() {
   139     const VERSION = 2;
   140     var currentVersion = getIntPref(PREF_MIGRATION_VERSION, 0);
   141     if (currentVersion >= VERSION) {
   142       return;
   143     }
   144     // Make pdf.js the default pdf viewer on the first migration.
   145     if (currentVersion < 1) {
   146       this._becomeHandler();
   147     }
   148     if (currentVersion < 2) {
   149       // cleaning up of unused database preference (see #3994)
   150       Services.prefs.clearUserPref(PREF_PREFIX + '.database');
   151     }
   152     Services.prefs.setIntPref(PREF_MIGRATION_VERSION, VERSION);
   153   },
   155   _becomeHandler: function _becomeHandler() {
   156     let handlerInfo = Svc.mime.getFromTypeAndExtension(PDF_CONTENT_TYPE, 'pdf');
   157     let prefs = Services.prefs;
   158     if (handlerInfo.preferredAction !== Ci.nsIHandlerInfo.handleInternally &&
   159         handlerInfo.preferredAction !== false) {
   160       // Store the previous settings of preferredAction and
   161       // alwaysAskBeforeHandling in case we need to revert them in a hotfix that
   162       // would turn pdf.js off.
   163       prefs.setIntPref(PREF_PREVIOUS_ACTION, handlerInfo.preferredAction);
   164       prefs.setBoolPref(PREF_PREVIOUS_ASK, handlerInfo.alwaysAskBeforeHandling);
   165     }
   167     let handlerService = Cc['@mozilla.org/uriloader/handler-service;1'].
   168                          getService(Ci.nsIHandlerService);
   170     // Change and save mime handler settings.
   171     handlerInfo.alwaysAskBeforeHandling = false;
   172     handlerInfo.preferredAction = Ci.nsIHandlerInfo.handleInternally;
   173     handlerService.store(handlerInfo);
   175     // Also disable any plugins for pdfs.
   176     var stringTypes = '';
   177     var types = [];
   178     if (prefs.prefHasUserValue(PREF_DISABLED_PLUGIN_TYPES)) {
   179       stringTypes = prefs.getCharPref(PREF_DISABLED_PLUGIN_TYPES);
   180     }
   181     if (stringTypes !== '') {
   182       types = stringTypes.split(',');
   183     }
   185     if (types.indexOf(PDF_CONTENT_TYPE) === -1) {
   186       types.push(PDF_CONTENT_TYPE);
   187     }
   188     prefs.setCharPref(PREF_DISABLED_PLUGIN_TYPES, types.join(','));
   190     // Update the category manager in case the plugins are already loaded.
   191     let categoryManager = Cc["@mozilla.org/categorymanager;1"];
   192     categoryManager.getService(Ci.nsICategoryManager).
   193                     deleteCategoryEntry("Gecko-Content-Viewers",
   194                                         PDF_CONTENT_TYPE,
   195                                         false);
   196   },
   198   // nsIObserver
   199   observe: function observe(aSubject, aTopic, aData) {
   200     if (this.enabled)
   201       this._ensureRegistered();
   202     else
   203       this._ensureUnregistered();
   204   },
   206   /**
   207    * pdf.js is only enabled if it is both selected as the pdf viewer and if the 
   208    * global switch enabling it is true.
   209    * @return {boolean} Wether or not it's enabled.
   210    */
   211   get enabled() {
   212     var disabled = getBoolPref(PREF_DISABLED, true);
   213     if (disabled) {
   214       return false;
   215     }
   217     // the 'application/pdf' handler is selected as internal?
   218     var handlerInfo = Svc.mime
   219                          .getFromTypeAndExtension(PDF_CONTENT_TYPE, 'pdf');
   220     if (handlerInfo.alwaysAskBeforeHandling ||
   221         handlerInfo.preferredAction !== Ci.nsIHandlerInfo.handleInternally) {
   222       return false;
   223     }
   225     // Check if we have disabled plugin handling of 'application/pdf' in prefs
   226     if (Services.prefs.prefHasUserValue(PREF_DISABLED_PLUGIN_TYPES)) {
   227       let disabledPluginTypes =
   228         Services.prefs.getCharPref(PREF_DISABLED_PLUGIN_TYPES).split(',');
   229       if (disabledPluginTypes.indexOf(PDF_CONTENT_TYPE) >= 0) {
   230         return true;
   231       }
   232     }
   234     // Check if there is an enabled pdf plugin.
   235     // Note: this check is performed last because getPluginTags() triggers costly
   236     // plugin list initialization (bug 881575)
   237     let tags = Cc["@mozilla.org/plugin/host;1"].
   238                   getService(Ci.nsIPluginHost).
   239                   getPluginTags();
   240     let enabledPluginFound = tags.some(function(tag) {
   241       if (tag.disabled) {
   242         return false;
   243       }
   244       let mimeTypes = tag.getMimeTypes();
   245       return mimeTypes.some(function(mimeType) {
   246         return mimeType === PDF_CONTENT_TYPE;
   247       });
   248     });
   250     // Use pdf.js if pdf plugin is not present or disabled
   251     return !enabledPluginFound;
   252   },
   254   _ensureRegistered: function _ensureRegistered() {
   255     if (this._registered)
   256       return;
   258     this._pdfStreamConverterFactory = new Factory();
   259     Cu.import('resource://pdf.js/PdfStreamConverter.jsm');
   260     this._pdfStreamConverterFactory.register(PdfStreamConverter);
   262     this._pdfRedirectorFactory = new Factory();
   263     Cu.import('resource://pdf.js/PdfRedirector.jsm');
   264     this._pdfRedirectorFactory.register(PdfRedirector);
   266     Svc.pluginHost.registerPlayPreviewMimeType(PDF_CONTENT_TYPE, true,
   267       'data:application/x-moz-playpreview-pdfjs;,');
   269     this._registered = true;
   270   },
   272   _ensureUnregistered: function _ensureUnregistered() {
   273     if (!this._registered)
   274       return;
   276     this._pdfStreamConverterFactory.unregister();
   277     Cu.unload('resource://pdf.js/PdfStreamConverter.jsm');
   278     delete this._pdfStreamConverterFactory;
   280     this._pdfRedirectorFactory.unregister();
   281     Cu.unload('resource://pdf.js/PdfRedirector.jsm');
   282     delete this._pdfRedirectorFactory;
   284     Svc.pluginHost.unregisterPlayPreviewMimeType(PDF_CONTENT_TYPE);
   286     this._registered = false;
   287   }
   288 };

mercurial