[Firefox] Fetch browser preferences/options together with the viewer preferences (bug 1862192)

Currently we *synchronously* fetch a number of browser preferences/options, from the platform code, during the viewer respectively PDF document initialization paths.
This seems unnecessary, and we can re-factor the code to instead include the relevant data when fetching the regular viewer preferences.
This commit is contained in:
Jonas Jenwald 2023-10-31 11:39:04 +01:00
parent 50c0fccda6
commit eebc230cf1
7 changed files with 109 additions and 81 deletions

View File

@ -188,6 +188,9 @@ function createWebpackConfig(
BUNDLE_VERSION: versionInfo.version, BUNDLE_VERSION: versionInfo.version,
BUNDLE_BUILD: versionInfo.commit, BUNDLE_BUILD: versionInfo.commit,
TESTING: defines.TESTING ?? process.env.TESTING === "true", TESTING: defines.TESTING ?? process.env.TESTING === "true",
BROWSER_PREFERENCES: defaultPreferencesDir
? getBrowserPreferences(defaultPreferencesDir)
: {},
DEFAULT_PREFERENCES: defaultPreferencesDir DEFAULT_PREFERENCES: defaultPreferencesDir
? getDefaultPreferences(defaultPreferencesDir) ? getDefaultPreferences(defaultPreferencesDir)
: {}, : {},
@ -811,17 +814,32 @@ async function parseDefaultPreferences(dir) {
"./" + DEFAULT_PREFERENCES_DIR + dir + "app_options.mjs" "./" + DEFAULT_PREFERENCES_DIR + dir + "app_options.mjs"
); );
const browserPrefs = AppOptions.getAll(OptionKind.BROWSER);
if (Object.keys(browserPrefs).length === 0) {
throw new Error("No browser preferences found.");
}
const prefs = AppOptions.getAll(OptionKind.PREFERENCE); const prefs = AppOptions.getAll(OptionKind.PREFERENCE);
if (Object.keys(prefs).length === 0) { if (Object.keys(prefs).length === 0) {
throw new Error("No default preferences found."); throw new Error("No default preferences found.");
} }
fs.writeFileSync(
DEFAULT_PREFERENCES_DIR + dir + "browser_preferences.json",
JSON.stringify(browserPrefs)
);
fs.writeFileSync( fs.writeFileSync(
DEFAULT_PREFERENCES_DIR + dir + "default_preferences.json", DEFAULT_PREFERENCES_DIR + dir + "default_preferences.json",
JSON.stringify(prefs) JSON.stringify(prefs)
); );
} }
function getBrowserPreferences(dir) {
const str = fs
.readFileSync(DEFAULT_PREFERENCES_DIR + dir + "browser_preferences.json")
.toString();
return JSON.parse(str);
}
function getDefaultPreferences(dir) { function getDefaultPreferences(dir) {
const str = fs const str = fs
.readFileSync(DEFAULT_PREFERENCES_DIR + dir + "default_preferences.json") .readFileSync(DEFAULT_PREFERENCES_DIR + dir + "default_preferences.json")
@ -1581,6 +1599,9 @@ function buildLib(defines, dir) {
BUNDLE_VERSION: versionInfo.version, BUNDLE_VERSION: versionInfo.version,
BUNDLE_BUILD: versionInfo.commit, BUNDLE_BUILD: versionInfo.commit,
TESTING: defines.TESTING ?? process.env.TESTING === "true", TESTING: defines.TESTING ?? process.env.TESTING === "true",
BROWSER_PREFERENCES: getBrowserPreferences(
defines.SKIP_BABEL ? "lib/" : "lib-legacy/"
),
DEFAULT_PREFERENCES: getDefaultPreferences( DEFAULT_PREFERENCES: getDefaultPreferences(
defines.SKIP_BABEL ? "lib/" : "lib-legacy/" defines.SKIP_BABEL ? "lib/" : "lib-legacy/"
), ),

View File

@ -120,37 +120,10 @@ class DefaultExternalServices {
throw new Error("Not implemented: createScripting"); throw new Error("Not implemented: createScripting");
} }
static get supportsPinchToZoom() {
return shadow(this, "supportsPinchToZoom", true);
}
static get supportsIntegratedFind() {
return shadow(this, "supportsIntegratedFind", false);
}
static get supportsDocumentFonts() {
return shadow(this, "supportsDocumentFonts", true);
}
static get supportedMouseWheelZoomModifierKeys() {
return shadow(this, "supportedMouseWheelZoomModifierKeys", {
ctrlKey: true,
metaKey: true,
});
}
static get isInAutomation() {
return shadow(this, "isInAutomation", false);
}
static updateEditorStates(data) { static updateEditorStates(data) {
throw new Error("Not implemented: updateEditorStates"); throw new Error("Not implemented: updateEditorStates");
} }
static get canvasMaxAreaInBytes() {
return shadow(this, "canvasMaxAreaInBytes", -1);
}
static getNimbusExperimentData() { static getNimbusExperimentData() {
return shadow(this, "getNimbusExperimentData", Promise.resolve(null)); return shadow(this, "getNimbusExperimentData", Promise.resolve(null));
} }
@ -421,7 +394,7 @@ const PDFViewerApplication = {
async _initializeViewerComponents() { async _initializeViewerComponents() {
const { appConfig, externalServices, l10n } = this; const { appConfig, externalServices, l10n } = this;
const eventBus = externalServices.isInAutomation const eventBus = AppOptions.get("isInAutomation")
? new AutomationEventBus() ? new AutomationEventBus()
: new EventBus(); : new EventBus();
this.eventBus = eventBus; this.eventBus = eventBus;
@ -722,7 +695,7 @@ const PDFViewerApplication = {
}); });
} }
if (!this.supportsDocumentFonts) { if (!AppOptions.get("supportsDocumentFonts")) {
AppOptions.set("disableFontFace", true); AppOptions.set("disableFontFace", true);
this.l10n.get("pdfjs-web-fonts-disabled").then(msg => { this.l10n.get("pdfjs-web-fonts-disabled").then(msg => {
console.warn(msg); console.warn(msg);
@ -825,15 +798,19 @@ const PDFViewerApplication = {
}, },
get supportsPinchToZoom() { get supportsPinchToZoom() {
return this.externalServices.supportsPinchToZoom; return shadow(
this,
"supportsPinchToZoom",
AppOptions.get("supportsPinchToZoom")
);
}, },
get supportsIntegratedFind() { get supportsIntegratedFind() {
return this.externalServices.supportsIntegratedFind; return shadow(
}, this,
"supportsIntegratedFind",
get supportsDocumentFonts() { AppOptions.get("supportsIntegratedFind")
return this.externalServices.supportsDocumentFonts; );
}, },
get loadingBar() { get loadingBar() {
@ -842,8 +819,20 @@ const PDFViewerApplication = {
return shadow(this, "loadingBar", bar); return shadow(this, "loadingBar", bar);
}, },
get supportedMouseWheelZoomModifierKeys() { get supportsMouseWheelZoomCtrlKey() {
return this.externalServices.supportedMouseWheelZoomModifierKeys; return shadow(
this,
"supportsMouseWheelZoomCtrlKey",
AppOptions.get("supportsMouseWheelZoomCtrlKey")
);
},
get supportsMouseWheelZoomMetaKey() {
return shadow(
this,
"supportsMouseWheelZoomMetaKey",
AppOptions.get("supportsMouseWheelZoomMetaKey")
);
}, },
initPassiveLoading(file) { initPassiveLoading(file) {
@ -1034,7 +1023,7 @@ const PDFViewerApplication = {
// Set the necessary API parameters, using all the available options. // Set the necessary API parameters, using all the available options.
const apiParams = AppOptions.getAll(OptionKind.API); const apiParams = AppOptions.getAll(OptionKind.API);
const params = { const params = {
canvasMaxAreaInBytes: this.externalServices.canvasMaxAreaInBytes, canvasMaxAreaInBytes: AppOptions.get("canvasMaxAreaInBytes"),
...apiParams, ...apiParams,
...args, ...args,
}; };
@ -2648,7 +2637,8 @@ function setZoomDisabledTimeout() {
function webViewerWheel(evt) { function webViewerWheel(evt) {
const { const {
pdfViewer, pdfViewer,
supportedMouseWheelZoomModifierKeys, supportsMouseWheelZoomCtrlKey,
supportsMouseWheelZoomMetaKey,
supportsPinchToZoom, supportsPinchToZoom,
} = PDFViewerApplication; } = PDFViewerApplication;
@ -2687,8 +2677,8 @@ function webViewerWheel(evt) {
if ( if (
isPinchToZoom || isPinchToZoom ||
(evt.ctrlKey && supportedMouseWheelZoomModifierKeys.ctrlKey) || (evt.ctrlKey && supportsMouseWheelZoomCtrlKey) ||
(evt.metaKey && supportedMouseWheelZoomModifierKeys.metaKey) (evt.metaKey && supportsMouseWheelZoomMetaKey)
) { ) {
// Only zoom the pages, not the entire viewer. // Only zoom the pages, not the entire viewer.
evt.preventDefault(); evt.preventDefault();

View File

@ -41,6 +41,7 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
} }
const OptionKind = { const OptionKind = {
BROWSER: 0x01,
VIEWER: 0x02, VIEWER: 0x02,
API: 0x04, API: 0x04,
WORKER: 0x08, WORKER: 0x08,
@ -53,6 +54,42 @@ const OptionKind = {
* primitive types and cannot rely on any imported types. * primitive types and cannot rely on any imported types.
*/ */
const defaultOptions = { const defaultOptions = {
canvasMaxAreaInBytes: {
/** @type {number} */
value: -1,
kind: OptionKind.BROWSER,
},
isInAutomation: {
/** @type {boolean} */
value: false,
kind: OptionKind.BROWSER,
},
supportsDocumentFonts: {
/** @type {boolean} */
value: true,
kind: OptionKind.BROWSER,
},
supportsIntegratedFind: {
/** @type {boolean} */
value: false,
kind: OptionKind.BROWSER,
},
supportsMouseWheelZoomCtrlKey: {
/** @type {boolean} */
value: true,
kind: OptionKind.BROWSER,
},
supportsMouseWheelZoomMetaKey: {
/** @type {boolean} */
value: true,
kind: OptionKind.BROWSER,
},
supportsPinchToZoom: {
/** @type {boolean} */
value: true,
kind: OptionKind.BROWSER,
},
annotationEditorMode: { annotationEditorMode: {
/** @type {number} */ /** @type {number} */
value: 0, value: 0,
@ -367,6 +404,9 @@ class AppOptions {
continue; continue;
} }
if (kind === OptionKind.PREFERENCE) { if (kind === OptionKind.PREFERENCE) {
if (defaultOption.kind & OptionKind.BROWSER) {
throw new Error(`Invalid kind for preference: ${name}`);
}
const value = defaultOption.value, const value = defaultOption.value,
valueType = typeof value; valueType = typeof value;

View File

@ -352,7 +352,7 @@ class ChromePreferences extends BasePreferences {
defaultPrefs = this.defaults; defaultPrefs = this.defaults;
} }
storageArea.get(defaultPrefs, function (readPrefs) { storageArea.get(defaultPrefs, function (readPrefs) {
resolve(readPrefs); resolve({ prefs: readPrefs });
}); });
}; };

View File

@ -14,7 +14,7 @@
*/ */
import { DefaultExternalServices, PDFViewerApplication } from "./app.js"; import { DefaultExternalServices, PDFViewerApplication } from "./app.js";
import { isPdfFile, PDFDataRangeTransport, shadow } from "pdfjs-lib"; import { isPdfFile, PDFDataRangeTransport } from "pdfjs-lib";
import { BasePreferences } from "./preferences.js"; import { BasePreferences } from "./preferences.js";
import { DEFAULT_SCALE_VALUE } from "./ui_utils.js"; import { DEFAULT_SCALE_VALUE } from "./ui_utils.js";
import { L10n } from "./l10n.js"; import { L10n } from "./l10n.js";
@ -434,40 +434,6 @@ class FirefoxExternalServices extends DefaultExternalServices {
return FirefoxScripting; return FirefoxScripting;
} }
static get supportsPinchToZoom() {
const support = FirefoxCom.requestSync("supportsPinchToZoom");
return shadow(this, "supportsPinchToZoom", support);
}
static get supportsIntegratedFind() {
const support = FirefoxCom.requestSync("supportsIntegratedFind");
return shadow(this, "supportsIntegratedFind", support);
}
static get supportsDocumentFonts() {
const support = FirefoxCom.requestSync("supportsDocumentFonts");
return shadow(this, "supportsDocumentFonts", support);
}
static get supportedMouseWheelZoomModifierKeys() {
const support = FirefoxCom.requestSync(
"supportedMouseWheelZoomModifierKeys"
);
return shadow(this, "supportedMouseWheelZoomModifierKeys", support);
}
static get isInAutomation() {
// Returns the value of `Cu.isInAutomation`, which is only `true` when e.g.
// various test-suites are running in mozilla-central.
const isInAutomation = FirefoxCom.requestSync("isInAutomation");
return shadow(this, "isInAutomation", isInAutomation);
}
static get canvasMaxAreaInBytes() {
const maxArea = FirefoxCom.requestSync("getCanvasMaxArea");
return shadow(this, "canvasMaxAreaInBytes", maxArea);
}
static async getNimbusExperimentData() { static async getNimbusExperimentData() {
const nimbusData = await FirefoxCom.requestAsync( const nimbusData = await FirefoxCom.requestAsync(
"getNimbusExperimentData", "getNimbusExperimentData",

View File

@ -34,7 +34,7 @@ class GenericPreferences extends BasePreferences {
} }
async _readFromStorage(prefObj) { async _readFromStorage(prefObj) {
return JSON.parse(localStorage.getItem("pdfjs.preferences")); return { prefs: JSON.parse(localStorage.getItem("pdfjs.preferences")) };
} }
} }

View File

@ -45,14 +45,25 @@ class BasePreferences {
} }
this.#initializedPromise = this._readFromStorage(this.#defaults).then( this.#initializedPromise = this._readFromStorage(this.#defaults).then(
prefs => { ({ browserPrefs, prefs }) => {
const BROWSER_PREFS =
typeof PDFJSDev === "undefined"
? AppOptions.getAll(OptionKind.BROWSER)
: PDFJSDev.eval("BROWSER_PREFERENCES");
const options = Object.create(null);
for (const [name, defaultVal] of Object.entries(BROWSER_PREFS)) {
const prefVal = browserPrefs?.[name];
options[name] =
typeof prefVal === typeof defaultVal ? prefVal : defaultVal;
}
for (const [name, defaultVal] of Object.entries(this.#defaults)) { for (const [name, defaultVal] of Object.entries(this.#defaults)) {
const prefVal = prefs?.[name]; const prefVal = prefs?.[name];
// Ignore preferences whose types don't match the default values. // Ignore preferences whose types don't match the default values.
this.#prefs[name] = options[name] = this.#prefs[name] =
typeof prefVal === typeof defaultVal ? prefVal : defaultVal; typeof prefVal === typeof defaultVal ? prefVal : defaultVal;
} }
AppOptions.setAll(this.#prefs, /* init = */ true); AppOptions.setAll(options, /* init = */ true);
} }
); );
} }