mirror of
				https://github.com/mozilla/gecko-dev.git
				synced 2025-11-04 02:09:05 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			256 lines
		
	
	
	
		
			8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			256 lines
		
	
	
	
		
			8 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.
 | 
						|
 */
 | 
						|
 | 
						|
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() {
 | 
						|
    this.checkIsDefault();
 | 
						|
  },
 | 
						|
};
 | 
						|
 | 
						|
XPCOMUtils.defineLazyPreferenceGetter(
 | 
						|
  PdfJs,
 | 
						|
  "_prefDisabled",
 | 
						|
  PREF_DISABLED,
 | 
						|
  false,
 | 
						|
  () => PdfJs.checkIsDefault()
 | 
						|
);
 |