225 lines
7 KiB
JavaScript
225 lines
7 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"
|
|
);
|
|
|
|
// 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);
|
|
},
|
|
|
|
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()
|
|
);
|