summaryrefslogtreecommitdiffstats
path: root/toolkit/components/pdfjs/content/PdfJs.sys.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/pdfjs/content/PdfJs.sys.mjs')
-rw-r--r--toolkit/components/pdfjs/content/PdfJs.sys.mjs256
1 files changed, 256 insertions, 0 deletions
diff --git a/toolkit/components/pdfjs/content/PdfJs.sys.mjs b/toolkit/components/pdfjs/content/PdfJs.sys.mjs
new file mode 100644
index 0000000000..fd6757737e
--- /dev/null
+++ b/toolkit/components/pdfjs/content/PdfJs.sys.mjs
@@ -0,0 +1,256 @@
+/* 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.
+ */
+
+const PREF_DISABLED = "pdfjs.disabled";
+const PREF_MIGRATION_VERSION = "pdfjs.migrationVersion";
+const PREF_PREVIOUS_ACTION = "pdfjs.previousHandler.preferredAction";
+const PREF_PREVIOUS_ASK = "pdfjs.previousHandler.alwaysAskBeforeHandling";
+const PREF_ISDEFAULT_CACHE_STATE = "pdfjs.enabledCache.state";
+const TOPIC_PDFJS_HANDLER_CHANGED = "pdfjs:handlerChanged";
+const PDF_CONTENT_TYPE = "application/pdf";
+
+import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
+
+var Svc = {};
+XPCOMUtils.defineLazyServiceGetter(
+ Svc,
+ "mime",
+ "@mozilla.org/mime;1",
+ "nsIMIMEService"
+);
+XPCOMUtils.defineLazyServiceGetter(
+ Svc,
+ "handlerService",
+ "@mozilla.org/uriloader/handler-service;1",
+ "nsIHandlerService"
+);
+const lazy = {};
+ChromeUtils.defineESModuleGetters(lazy, {
+ PdfJsDefaultPreferences: "resource://pdf.js/PdfJsDefaultPreferences.sys.mjs",
+});
+
+function initializeDefaultPreferences() {
+ var defaultBranch = Services.prefs.getDefaultBranch("pdfjs.");
+ var defaultValue;
+ for (var key in lazy.PdfJsDefaultPreferences) {
+ // Skip prefs that are already defined, so we can enable/disable things
+ // in all.js.
+ let prefType = defaultBranch.getPrefType(key);
+ if (prefType !== Ci.nsIPrefBranch.PREF_INVALID) {
+ continue;
+ }
+ defaultValue = lazy.PdfJsDefaultPreferences[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;
+ }
+ }
+}
+
+// We're supposed to get this type of thing from the OS, and generally we do.
+// But doing so is expensive, so on startup paths we can use this to make the
+// handler service get and store the Right Thing (it just goes into a JSON
+// file) and avoid the performance issues.
+const gPdfFakeHandlerInfo = {
+ QueryInterface: ChromeUtils.generateQI(["nsIMIMEInfo"]),
+ getFileExtensions() {
+ return ["pdf"];
+ },
+ possibleApplicationHandlers: Cc["@mozilla.org/array;1"].createInstance(
+ Ci.nsIMutableArray
+ ),
+ extensionExists(ext) {
+ return ext == "pdf";
+ },
+ alwaysAskBeforeHandling: false,
+ preferredAction: Ci.nsIHandlerInfo.handleInternally,
+ type: PDF_CONTENT_TYPE,
+};
+
+export var PdfJs = {
+ QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
+ _initialized: false,
+ _cachedIsDefault: true,
+
+ init: function init(isNewProfile) {
+ if (
+ Services.appinfo.processType !== Services.appinfo.PROCESS_TYPE_DEFAULT
+ ) {
+ throw new Error(
+ "PdfJs.init should only get called in the parent process."
+ );
+ }
+ this.initPrefs();
+ this.checkIsDefault(isNewProfile);
+ },
+
+ initPrefs: function initPrefs() {
+ if (this._initialized) {
+ return;
+ }
+ this._initialized = true;
+
+ if (this._prefDisabled) {
+ this._unbecomeHandler();
+ } else {
+ this._migrate();
+ }
+
+ // Listen for when a different pdf handler is chosen.
+ Services.obs.addObserver(this, TOPIC_PDFJS_HANDLER_CHANGED);
+
+ initializeDefaultPreferences();
+ },
+
+ uninit: function uninit() {
+ if (this._initialized) {
+ Services.obs.removeObserver(this, TOPIC_PDFJS_HANDLER_CHANGED);
+ this._initialized = false;
+ }
+ },
+
+ _migrate: function migrate() {
+ const VERSION = 2;
+ var currentVersion = Services.prefs.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("pdfjs.database");
+ }
+ Services.prefs.setIntPref(PREF_MIGRATION_VERSION, VERSION);
+ },
+
+ _becomeHandler: function _becomeHandler() {
+ // Normally, this happens in the first run at some point, where the
+ // handler service doesn't have any info on user preferences yet.
+ // Don't bother storing old defaults in this case, as they're
+ // meaningless anyway.
+ if (!Svc.handlerService.exists(gPdfFakeHandlerInfo)) {
+ // Store the requisite info into the DB, and nothing else:
+ Svc.handlerService.store(gPdfFakeHandlerInfo);
+ } else {
+ let handlerInfo = Svc.mime.getFromTypeAndExtension(
+ PDF_CONTENT_TYPE,
+ "pdf"
+ );
+ let prefs = Services.prefs;
+ if (
+ handlerInfo.preferredAction !== Ci.nsIHandlerInfo.handleInternally &&
+ handlerInfo.alwaysAskBeforeHandling !== 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
+ );
+ }
+
+ // Change and save mime handler settings.
+ handlerInfo.alwaysAskBeforeHandling = false;
+ handlerInfo.preferredAction = Ci.nsIHandlerInfo.handleInternally;
+ Svc.handlerService.store(handlerInfo);
+ }
+ },
+
+ _unbecomeHandler: function _unbecomeHandler() {
+ let handlerInfo = Svc.mime.getFromTypeAndExtension(PDF_CONTENT_TYPE, "pdf");
+ if (handlerInfo.preferredAction === Ci.nsIHandlerInfo.handleInternally) {
+ // If PDFJS is disabled, but we're still marked to handleInternally,
+ // either put it back to what it was, or remove it.
+ if (Services.prefs.prefHasUserValue(PREF_PREVIOUS_ACTION)) {
+ handlerInfo.preferredAction =
+ Services.prefs.getIntPref(PREF_PREVIOUS_ACTION);
+ handlerInfo.alwaysAskBeforeHandling =
+ Services.prefs.getBoolPref(PREF_PREVIOUS_ASK);
+ Svc.handlerService.store(handlerInfo);
+ } else {
+ Svc.handlerService.remove(handlerInfo);
+ // Clear migration pref so the handler comes back if reenabled
+ Services.prefs.clearUserPref(PREF_MIGRATION_VERSION);
+ }
+ }
+ },
+
+ /**
+ * @param isNewProfile used to decide whether we need to check the
+ * handler service to see if the user configured
+ * pdfs differently. If we're on a new profile,
+ * there's no need to check.
+ */
+ _isDefault(isNewProfile) {
+ let { processType, PROCESS_TYPE_DEFAULT } = Services.appinfo;
+ if (processType !== PROCESS_TYPE_DEFAULT) {
+ throw new Error(
+ "isDefault should only get called in the parent process."
+ );
+ }
+
+ if (this._prefDisabled) {
+ return false;
+ }
+
+ // Don't bother with the handler service on a new profile:
+ if (isNewProfile) {
+ return true;
+ }
+ // Check if the 'application/pdf' preview handler is configured properly.
+ let handlerInfo = Svc.mime.getFromTypeAndExtension(PDF_CONTENT_TYPE, "pdf");
+ return (
+ !handlerInfo.alwaysAskBeforeHandling &&
+ handlerInfo.preferredAction == Ci.nsIHandlerInfo.handleInternally
+ );
+ },
+
+ checkIsDefault(isNewProfile) {
+ this._cachedIsDefault = this._isDefault(isNewProfile);
+ Services.prefs.setBoolPref(
+ PREF_ISDEFAULT_CACHE_STATE,
+ this._cachedIsDefault
+ );
+ },
+
+ cachedIsDefault() {
+ return this._cachedIsDefault;
+ },
+
+ // nsIObserver
+ observe(aSubject, aTopic, aData) {
+ this.checkIsDefault();
+ },
+};
+
+XPCOMUtils.defineLazyPreferenceGetter(
+ PdfJs,
+ "_prefDisabled",
+ PREF_DISABLED,
+ false,
+ () => PdfJs.checkIsDefault()
+);