pdf.js/extensions/firefox/content/PdfJs.jsm
Jonas Jenwald a5d5b970af [Firefox addon] Enforce double quotes, using ESLint, to avoid linting errors in mozilla-central (issue 7957)
Given that this patch causes a lot of churn in the addon code, I wouldn't really mind if we ultimately decide against doing this and just add a rule exception in mozilla-central instead.[1]

---
[1] Note that I used the ESLint `--fix` option, hence writing this commit message actually took longer time than the creation of the patch :-)
2017-01-25 01:14:06 +01:00

332 lines
11 KiB
JavaScript

/* Copyright 2012 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* globals Components, Services, XPCOMUtils, PdfjsChromeUtils,
PdfjsContentUtils, PdfStreamConverter */
"use strict";
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_DISABLED = PREF_PREFIX + ".disabled";
const PREF_MIGRATION_VERSION = PREF_PREFIX + ".migrationVersion";
const PREF_PREVIOUS_ACTION = PREF_PREFIX + ".previousHandler.preferredAction";
const PREF_PREVIOUS_ASK = PREF_PREFIX +
".previousHandler.alwaysAskBeforeHandling";
const PREF_DISABLED_PLUGIN_TYPES = "plugin.disable_full_page_plugin_for_types";
const TOPIC_PDFJS_HANDLER_CHANGED = "pdfjs:handlerChanged";
const TOPIC_PLUGINS_LIST_UPDATED = "plugins-list-updated";
const TOPIC_PLUGIN_INFO_UPDATED = "plugin-info-updated";
const PDF_CONTENT_TYPE = "application/pdf";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
var Svc = {};
XPCOMUtils.defineLazyServiceGetter(Svc, "mime",
"@mozilla.org/mime;1",
"nsIMIMEService");
XPCOMUtils.defineLazyServiceGetter(Svc, "pluginHost",
"@mozilla.org/plugin/host;1",
"nsIPluginHost");
XPCOMUtils.defineLazyModuleGetter(this, "PdfjsChromeUtils",
"resource://pdf.js/PdfjsChromeUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PdfjsContentUtils",
"resource://pdf.js/PdfjsContentUtils.jsm");
function getBoolPref(aPref, aDefaultValue) {
try {
return Services.prefs.getBoolPref(aPref);
} catch (ex) {
return aDefaultValue;
}
}
function getIntPref(aPref, aDefaultValue) {
try {
return Services.prefs.getIntPref(aPref);
} catch (ex) {
return aDefaultValue;
}
}
function isDefaultHandler() {
if (Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_CONTENT) {
return PdfjsContentUtils.isDefaultHandlerApp();
}
return PdfjsChromeUtils.isDefaultHandlerApp();
}
function initializeDefaultPreferences() {
var DEFAULT_PREFERENCES =
//#include ../../../web/default_preferences.json
//#if false
"end of DEFAULT_PREFERENCES";
//#endif
var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + ".");
var defaultValue;
for (var key in DEFAULT_PREFERENCES) {
defaultValue = DEFAULT_PREFERENCES[key];
switch (typeof defaultValue) {
case "boolean":
defaultBranch.setBoolPref(key, defaultValue);
break;
case "number":
defaultBranch.setIntPref(key, defaultValue);
break;
case "string":
defaultBranch.setCharPref(key, defaultValue);
break;
}
}
}
// Register/unregister a constructor as a factory.
function Factory() {}
Factory.prototype = {
register: function register(targetConstructor) {
var proto = targetConstructor.prototype;
this._classID = proto.classID;
var factory = XPCOMUtils._getFactory(targetConstructor);
this._factory = factory;
var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
registrar.registerFactory(proto.classID, proto.classDescription,
proto.contractID, factory);
if (proto.classID2) {
this._classID2 = proto.classID2;
registrar.registerFactory(proto.classID2, proto.classDescription,
proto.contractID2, factory);
}
},
unregister: function unregister() {
var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
registrar.unregisterFactory(this._classID, this._factory);
if (this._classID2) {
registrar.unregisterFactory(this._classID2, this._factory);
}
this._factory = null;
}
};
var PdfJs = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
_registered: false,
_initialized: false,
init: function init(remote) {
if (Services.appinfo.processType !==
Services.appinfo.PROCESS_TYPE_DEFAULT) {
throw new Error("PdfJs.init should only get called " +
"in the parent process.");
}
PdfjsChromeUtils.init();
if (!remote) {
PdfjsContentUtils.init();
}
this.initPrefs();
this.updateRegistration();
},
initPrefs: function initPrefs() {
if (this._initialized) {
return;
}
this._initialized = true;
if (!getBoolPref(PREF_DISABLED, true)) {
this._migrate();
}
// Listen for when pdf.js is completely disabled or a different pdf handler
// is chosen.
Services.prefs.addObserver(PREF_DISABLED, this, false);
Services.prefs.addObserver(PREF_DISABLED_PLUGIN_TYPES, this, false);
Services.obs.addObserver(this, TOPIC_PDFJS_HANDLER_CHANGED, false);
Services.obs.addObserver(this, TOPIC_PLUGINS_LIST_UPDATED, false);
Services.obs.addObserver(this, TOPIC_PLUGIN_INFO_UPDATED, false);
initializeDefaultPreferences();
},
updateRegistration: function updateRegistration() {
if (this.enabled) {
this._ensureRegistered();
} else {
this._ensureUnregistered();
}
},
uninit: function uninit() {
if (this._initialized) {
Services.prefs.removeObserver(PREF_DISABLED, this);
Services.prefs.removeObserver(PREF_DISABLED_PLUGIN_TYPES, this);
Services.obs.removeObserver(this, TOPIC_PDFJS_HANDLER_CHANGED);
Services.obs.removeObserver(this, TOPIC_PLUGINS_LIST_UPDATED);
Services.obs.removeObserver(this, TOPIC_PLUGIN_INFO_UPDATED);
this._initialized = false;
}
this._ensureUnregistered();
},
_migrate: function migrate() {
const VERSION = 2;
var currentVersion = getIntPref(PREF_MIGRATION_VERSION, 0);
if (currentVersion >= VERSION) {
return;
}
// Make pdf.js the default pdf viewer on the first migration.
if (currentVersion < 1) {
this._becomeHandler();
}
if (currentVersion < 2) {
// cleaning up of unused database preference (see #3994)
Services.prefs.clearUserPref(PREF_PREFIX + ".database");
}
Services.prefs.setIntPref(PREF_MIGRATION_VERSION, VERSION);
},
_becomeHandler: function _becomeHandler() {
let handlerInfo = Svc.mime.getFromTypeAndExtension(PDF_CONTENT_TYPE, "pdf");
let prefs = Services.prefs;
if (handlerInfo.preferredAction !== Ci.nsIHandlerInfo.handleInternally &&
handlerInfo.preferredAction !== false) {
// Store the previous settings of preferredAction and
// alwaysAskBeforeHandling in case we need to revert them in a hotfix that
// would turn pdf.js off.
prefs.setIntPref(PREF_PREVIOUS_ACTION, handlerInfo.preferredAction);
prefs.setBoolPref(PREF_PREVIOUS_ASK, handlerInfo.alwaysAskBeforeHandling);
}
let handlerService = Cc["@mozilla.org/uriloader/handler-service;1"].
getService(Ci.nsIHandlerService);
// Change and save mime handler settings.
handlerInfo.alwaysAskBeforeHandling = false;
handlerInfo.preferredAction = Ci.nsIHandlerInfo.handleInternally;
handlerService.store(handlerInfo);
// Also disable any plugins for pdfs.
var stringTypes = "";
var types = [];
if (prefs.prefHasUserValue(PREF_DISABLED_PLUGIN_TYPES)) {
stringTypes = prefs.getCharPref(PREF_DISABLED_PLUGIN_TYPES);
}
if (stringTypes !== "") {
types = stringTypes.split(",");
}
if (types.indexOf(PDF_CONTENT_TYPE) === -1) {
types.push(PDF_CONTENT_TYPE);
}
prefs.setCharPref(PREF_DISABLED_PLUGIN_TYPES, types.join(","));
// Update the category manager in case the plugins are already loaded.
let categoryManager = Cc["@mozilla.org/categorymanager;1"];
categoryManager.getService(Ci.nsICategoryManager).
deleteCategoryEntry("Gecko-Content-Viewers",
PDF_CONTENT_TYPE,
false);
},
// nsIObserver
observe: function observe(aSubject, aTopic, aData) {
this.updateRegistration();
if (Services.appinfo.processType ===
Services.appinfo.PROCESS_TYPE_DEFAULT) {
let jsm = "resource://pdf.js/PdfjsChromeUtils.jsm";
let PdfjsChromeUtils = Components.utils.import(jsm, {}).PdfjsChromeUtils;
PdfjsChromeUtils.notifyChildOfSettingsChange();
}
},
/**
* pdf.js is only enabled if it is both selected as the pdf viewer and if the
* global switch enabling it is true.
* @return {boolean} Whether or not it's enabled.
*/
get enabled() {
var disabled = getBoolPref(PREF_DISABLED, true);
if (disabled) {
return false;
}
// Check if the 'application/pdf' preview handler is configured properly.
if (!isDefaultHandler()) {
return false;
}
// Check if we have disabled plugin handling of 'application/pdf' in prefs
if (Services.prefs.prefHasUserValue(PREF_DISABLED_PLUGIN_TYPES)) {
let disabledPluginTypes =
Services.prefs.getCharPref(PREF_DISABLED_PLUGIN_TYPES).split(",");
if (disabledPluginTypes.indexOf(PDF_CONTENT_TYPE) >= 0) {
return true;
}
}
// Check if there is an enabled pdf plugin.
// Note: this check is performed last because getPluginTags() triggers
// costly plugin list initialization (bug 881575)
let tags = Cc["@mozilla.org/plugin/host;1"].
getService(Ci.nsIPluginHost).
getPluginTags();
let enabledPluginFound = tags.some(function(tag) {
if (tag.disabled) {
return false;
}
let mimeTypes = tag.getMimeTypes();
return mimeTypes.some(function(mimeType) {
return mimeType === PDF_CONTENT_TYPE;
});
});
// Use pdf.js if pdf plugin is not present or disabled
return !enabledPluginFound;
},
_ensureRegistered: function _ensureRegistered() {
if (this._registered) {
return;
}
this._pdfStreamConverterFactory = new Factory();
Cu.import("resource://pdf.js/PdfStreamConverter.jsm");
this._pdfStreamConverterFactory.register(PdfStreamConverter);
this._registered = true;
},
_ensureUnregistered: function _ensureUnregistered() {
if (!this._registered) {
return;
}
this._pdfStreamConverterFactory.unregister();
Cu.unload("resource://pdf.js/PdfStreamConverter.jsm");
delete this._pdfStreamConverterFactory;
this._registered = false;
}
};