From c5f9193777ad319903d9f5b560a62122f2dc8901 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Mon, 17 Apr 2017 13:21:11 +0200 Subject: [PATCH] Convert the `Preferences` to an ES6 class --- web/app.js | 96 +++++++++++++++++++------------------ web/chromecom.js | 81 ++++++++++++++++--------------- web/firefoxcom.js | 36 +++++++------- web/genericcom.js | 22 ++++++++- web/hand_tool.js | 14 +++--- web/preferences.js | 117 +++++++++++++++++---------------------------- 6 files changed, 185 insertions(+), 181 deletions(-) diff --git a/web/app.js b/web/app.js index 6d4cf32af..70622435a 100644 --- a/web/app.js +++ b/web/app.js @@ -42,7 +42,6 @@ import { PDFLinkService } from './pdf_link_service'; import { PDFOutlineViewer } from './pdf_outline_viewer'; import { PDFPresentationMode } from './pdf_presentation_mode'; import { PDFThumbnailViewer } from './pdf_thumbnail_viewer'; -import { Preferences } from './preferences'; import { SecondaryToolbar } from './secondary_toolbar'; import { Toolbar } from './toolbar'; import { ViewHistory } from './view_history'; @@ -75,6 +74,9 @@ var DefaultExternalServices = { createDownloadManager: function () { throw new Error('Not implemented: createDownloadManager'); }, + createPreferences() { + throw new Error('Not implemented: createPreferences'); + }, supportsIntegratedFind: false, supportsDocumentFonts: true, supportsDocumentColors: true, @@ -117,6 +119,8 @@ var PDFViewerApplication = { store: null, /** @type {DownloadManager} */ downloadManager: null, + /** @type {Preferences} */ + preferences: null, /** @type {Toolbar} */ toolbar: null, /** @type {SecondaryToolbar} */ @@ -143,37 +147,34 @@ var PDFViewerApplication = { // called once when the document is loaded initialize: function pdfViewInitialize(appConfig) { - var self = this; - - Preferences.initialize(); - this.preferences = Preferences; + this.preferences = this.externalServices.createPreferences(); configure(PDFJS); this.appConfig = appConfig; - return this._readPreferences().then(function () { - return self._initializeViewerComponents(); - }).then(function () { + return this._readPreferences().then(() => { + return this._initializeViewerComponents(); + }).then(() => { // Bind the various event handlers *after* the viewer has been // initialized, to prevent errors if an event arrives too soon. - self.bindEvents(); - self.bindWindowEvents(); + this.bindEvents(); + this.bindWindowEvents(); if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) { // For backwards compatibility, we dispatch the 'localized' event on // the `eventBus` once the viewer has been initialized. - localized.then(function () { - self.eventBus.dispatch('localized'); + localized.then(() => { + this.eventBus.dispatch('localized'); }); } - if (self.isViewerEmbedded && !PDFJS.isExternalLinkTargetSet()) { + if (this.isViewerEmbedded && !PDFJS.isExternalLinkTargetSet()) { // Prevent external links from "replacing" the viewer, // when it's embedded in e.g. an iframe or an object. PDFJS.externalLinkTarget = PDFJS.LinkTarget.TOP; } - self.initialized = true; + this.initialized = true; }); }, @@ -181,74 +182,74 @@ var PDFViewerApplication = { * @private */ _readPreferences: function () { - var self = this; + var { preferences, viewerPrefs, } = this; return Promise.all([ - Preferences.get('enableWebGL').then(function resolved(value) { + preferences.get('enableWebGL').then(function resolved(value) { PDFJS.disableWebGL = !value; }), - Preferences.get('sidebarViewOnLoad').then(function resolved(value) { - self.viewerPrefs['sidebarViewOnLoad'] = value; + preferences.get('sidebarViewOnLoad').then(function resolved(value) { + viewerPrefs['sidebarViewOnLoad'] = value; }), - Preferences.get('pdfBugEnabled').then(function resolved(value) { - self.viewerPrefs['pdfBugEnabled'] = value; + preferences.get('pdfBugEnabled').then(function resolved(value) { + viewerPrefs['pdfBugEnabled'] = value; }), - Preferences.get('showPreviousViewOnLoad').then(function resolved(value) { - self.viewerPrefs['showPreviousViewOnLoad'] = value; + preferences.get('showPreviousViewOnLoad').then(function resolved(value) { + viewerPrefs['showPreviousViewOnLoad'] = value; }), - Preferences.get('defaultZoomValue').then(function resolved(value) { - self.viewerPrefs['defaultZoomValue'] = value; + preferences.get('defaultZoomValue').then(function resolved(value) { + viewerPrefs['defaultZoomValue'] = value; }), - Preferences.get('enhanceTextSelection').then(function resolved(value) { - self.viewerPrefs['enhanceTextSelection'] = value; + preferences.get('enhanceTextSelection').then(function resolved(value) { + viewerPrefs['enhanceTextSelection'] = value; }), - Preferences.get('disableTextLayer').then(function resolved(value) { + preferences.get('disableTextLayer').then(function resolved(value) { if (PDFJS.disableTextLayer === true) { return; } PDFJS.disableTextLayer = value; }), - Preferences.get('disableRange').then(function resolved(value) { + preferences.get('disableRange').then(function resolved(value) { if (PDFJS.disableRange === true) { return; } PDFJS.disableRange = value; }), - Preferences.get('disableStream').then(function resolved(value) { + preferences.get('disableStream').then(function resolved(value) { if (PDFJS.disableStream === true) { return; } PDFJS.disableStream = value; }), - Preferences.get('disableAutoFetch').then(function resolved(value) { + preferences.get('disableAutoFetch').then(function resolved(value) { PDFJS.disableAutoFetch = value; }), - Preferences.get('disableFontFace').then(function resolved(value) { + preferences.get('disableFontFace').then(function resolved(value) { if (PDFJS.disableFontFace === true) { return; } PDFJS.disableFontFace = value; }), - Preferences.get('useOnlyCssZoom').then(function resolved(value) { + preferences.get('useOnlyCssZoom').then(function resolved(value) { PDFJS.useOnlyCssZoom = value; }), - Preferences.get('externalLinkTarget').then(function resolved(value) { + preferences.get('externalLinkTarget').then(function resolved(value) { if (PDFJS.isExternalLinkTargetSet()) { return; } PDFJS.externalLinkTarget = value; }), - Preferences.get('renderer').then(function resolved(value) { - self.viewerPrefs['renderer'] = value; + preferences.get('renderer').then(function resolved(value) { + viewerPrefs['renderer'] = value; }), - Preferences.get('renderInteractiveForms').then(function resolved(value) { - self.viewerPrefs['renderInteractiveForms'] = value; + preferences.get('renderInteractiveForms').then(function resolved(value) { + viewerPrefs['renderInteractiveForms'] = value; }), - Preferences.get('disablePageLabels').then(function resolved(value) { - self.viewerPrefs['disablePageLabels'] = value; + preferences.get('disablePageLabels').then(function resolved(value) { + viewerPrefs['disablePageLabels'] = value; }), - Preferences.get('enablePrintAutoRotate').then(function resolved(value) { - self.viewerPrefs['enablePrintAutoRotate'] = value; + preferences.get('enablePrintAutoRotate').then(function resolved(value) { + viewerPrefs['enablePrintAutoRotate'] = value; }), ]).catch(function (reason) { }); }, @@ -260,7 +261,7 @@ var PDFViewerApplication = { var self = this; var appConfig = this.appConfig; - return new Promise(function (resolve, reject) { + return new Promise((resolve, reject) => { var eventBus = appConfig.eventBus || getGlobalEventBus(); self.eventBus = eventBus; @@ -337,8 +338,9 @@ var PDFViewerApplication = { self.overlayManager = OverlayManager; self.handTool = new HandTool({ - container: container, - eventBus: eventBus, + container, + eventBus, + preferences: this.preferences, }); self.pdfDocumentProperties = @@ -595,12 +597,12 @@ var PDFViewerApplication = { } if (this.pdfLoadingTask) { // We need to destroy already opened document. - return this.close().then(function () { + return this.close().then(() => { // Reload the preferences if a document was previously opened. - Preferences.reload(); + this.preferences.reload(); // ... and repeat the open() call. return this.open(file, args); - }.bind(this)); + }); } var parameters = Object.create(null), scale; diff --git a/web/chromecom.js b/web/chromecom.js index 332cd2321..108bdf03e 100644 --- a/web/chromecom.js +++ b/web/chromecom.js @@ -15,10 +15,10 @@ /* globals chrome */ import { DefaultExternalServices, PDFViewerApplication } from './app'; +import { BasePreferences } from './preferences'; import { DownloadManager } from './download_manager'; import { OverlayManager } from './overlay_manager'; import { PDFJS } from './pdfjs'; -import { Preferences } from './preferences'; if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('CHROME')) { throw new Error('Module "pdfjs-web/chromecom" shall not be used outside ' + @@ -293,46 +293,48 @@ function setReferer(url, callback) { // chrome.storage.local to chrome.storage.sync when needed. var storageArea = chrome.storage.sync || chrome.storage.local; -Preferences._writeToStorage = function (prefObj) { - return new Promise(function (resolve) { - if (prefObj === Preferences.defaults) { - var keysToRemove = Object.keys(Preferences.defaults); - // If the storage is reset, remove the keys so that the values from - // managed storage are applied again. - storageArea.remove(keysToRemove, function() { - resolve(); - }); - } else { - storageArea.set(prefObj, function() { - resolve(); - }); - } - }); -}; +class ChromePreferences extends BasePreferences { + _writeToStorage(prefObj) { + return new Promise((resolve) => { + if (prefObj === this.defaults) { + var keysToRemove = Object.keys(this.defaults); + // If the storage is reset, remove the keys so that the values from + // managed storage are applied again. + storageArea.remove(keysToRemove, function() { + resolve(); + }); + } else { + storageArea.set(prefObj, function() { + resolve(); + }); + } + }); + } -Preferences._readFromStorage = function (prefObj) { - return new Promise(function (resolve) { - if (chrome.storage.managed) { - // Get preferences as set by the system administrator. - // See extensions/chromium/preferences_schema.json for more information. - // These preferences can be overridden by the user. - chrome.storage.managed.get(Preferences.defaults, getPreferences); - } else { - // Managed storage not supported, e.g. in old Chromium versions. - getPreferences(Preferences.defaults); - } + _readFromStorage(prefObj) { + return new Promise((resolve) => { + var getPreferences = (defaultPrefs) => { + if (chrome.runtime.lastError) { + // Managed storage not supported, e.g. in Opera. + defaultPrefs = this.defaults; + } + storageArea.get(defaultPrefs, function(readPrefs) { + resolve(readPrefs); + }); + }; - function getPreferences(defaultPrefs) { - if (chrome.runtime.lastError) { - // Managed storage not supported, e.g. in Opera. - defaultPrefs = Preferences.defaults; + if (chrome.storage.managed) { + // Get preferences as set by the system administrator. + // See extensions/chromium/preferences_schema.json for more information. + // These preferences can be overridden by the user. + chrome.storage.managed.get(this.defaults, getPreferences); + } else { + // Managed storage not supported, e.g. in old Chromium versions. + getPreferences(this.defaults); } - storageArea.get(defaultPrefs, function(readPrefs) { - resolve(readPrefs); - }); - } - }); -}; + }); + } +} var ChromeExternalServices = Object.create(DefaultExternalServices); ChromeExternalServices.initPassiveLoading = function (callbacks) { @@ -345,6 +347,9 @@ ChromeExternalServices.initPassiveLoading = function (callbacks) { ChromeExternalServices.createDownloadManager = function() { return new DownloadManager(); }; +ChromeExternalServices.createPreferences = function() { + return new ChromePreferences(); +}; PDFViewerApplication.externalServices = ChromeExternalServices; export { diff --git a/web/firefoxcom.js b/web/firefoxcom.js index 015b946aa..b0f020cc8 100644 --- a/web/firefoxcom.js +++ b/web/firefoxcom.js @@ -13,11 +13,9 @@ * limitations under the License. */ -import { - createObjectURL, PDFDataRangeTransport, shadow -} from './pdfjs'; +import { createObjectURL, PDFDataRangeTransport, shadow } from './pdfjs'; +import { BasePreferences } from './preferences'; import { PDFViewerApplication } from './app'; -import { Preferences } from './preferences'; if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { @@ -127,20 +125,22 @@ var DownloadManager = (function DownloadManagerClosure() { return DownloadManager; })(); -Preferences._writeToStorage = function (prefObj) { - return new Promise(function (resolve) { - FirefoxCom.request('setPreferences', prefObj, resolve); - }); -}; +class FirefoxPreferences extends BasePreferences { + _writeToStorage(prefObj) { + return new Promise(function(resolve) { + FirefoxCom.request('setPreferences', prefObj, resolve); + }); + } -Preferences._readFromStorage = function (prefObj) { - return new Promise(function (resolve) { - FirefoxCom.request('getPreferences', prefObj, function (prefStr) { - var readPrefs = JSON.parse(prefStr); - resolve(readPrefs); + _readFromStorage(prefObj) { + return new Promise(function(resolve) { + FirefoxCom.request('getPreferences', prefObj, function (prefStr) { + var readPrefs = JSON.parse(prefStr); + resolve(readPrefs); + }); }); - }); -}; + } +} (function listenFindEvents() { var events = [ @@ -247,6 +247,10 @@ PDFViewerApplication.externalServices = { return new DownloadManager(); }, + createPreferences() { + return new FirefoxPreferences(); + }, + get supportsIntegratedFind() { var support = FirefoxCom.requestSync('supportsIntegratedFind'); return shadow(this, 'supportsIntegratedFind', support); diff --git a/web/genericcom.js b/web/genericcom.js index 599e0a019..b1141c470 100644 --- a/web/genericcom.js +++ b/web/genericcom.js @@ -14,6 +14,7 @@ */ import { DefaultExternalServices, PDFViewerApplication } from './app'; +import { BasePreferences } from './preferences'; import { DownloadManager } from './download_manager'; if (typeof PDFJSDev !== 'undefined' && !PDFJSDev.test('GENERIC')) { @@ -23,10 +24,29 @@ if (typeof PDFJSDev !== 'undefined' && !PDFJSDev.test('GENERIC')) { var GenericCom = {}; +class GenericPreferences extends BasePreferences { + _writeToStorage(prefObj) { + return new Promise(function(resolve) { + localStorage.setItem('pdfjs.preferences', JSON.stringify(prefObj)); + resolve(); + }); + } + + _readFromStorage(prefObj) { + return new Promise(function(resolve) { + var readPrefs = JSON.parse(localStorage.getItem('pdfjs.preferences')); + resolve(readPrefs); + }); + } +} + var GenericExternalServices = Object.create(DefaultExternalServices); -GenericExternalServices.createDownloadManager = function () { +GenericExternalServices.createDownloadManager = function() { return new DownloadManager(); }; +GenericExternalServices.createPreferences = function() { + return new GenericPreferences(); +}; PDFViewerApplication.externalServices = GenericExternalServices; export { diff --git a/web/hand_tool.js b/web/hand_tool.js index eab54d7af..801498ba7 100644 --- a/web/hand_tool.js +++ b/web/hand_tool.js @@ -15,7 +15,6 @@ import { GrabToPan } from './grab_to_pan'; import { localized } from './ui_utils'; -import { Preferences } from './preferences'; /** * @typedef {Object} HandToolOptions @@ -34,6 +33,7 @@ var HandTool = (function HandToolClosure() { function HandTool(options) { this.container = options.container; this.eventBus = options.eventBus; + var preferences = options.preferences; this.wasActive = false; @@ -46,12 +46,12 @@ var HandTool = (function HandToolClosure() { this.eventBus.on('togglehandtool', this.toggle.bind(this)); - Promise.all([localized, Preferences.get('enableHandToolOnLoad')]).then( - function resolved(values) { - if (values[1] === true) { - this.handTool.activate(); - } - }.bind(this)).catch(function rejected(reason) { }); + Promise.all([localized, + preferences.get('enableHandToolOnLoad')]).then((values) => { + if (values[1] === true) { + this.handTool.activate(); + } + }).catch(function rejected(reason) { }); this.eventBus.on('presentationmodechanged', function (e) { if (e.switchInProgress) { diff --git a/web/preferences.js b/web/preferences.js index 137058cc6..9445ab4ba 100644 --- a/web/preferences.js +++ b/web/preferences.js @@ -27,7 +27,7 @@ function getDefaultPreferences() { try { resolve(JSON.parse(xhr.responseText)); } catch (e) { - console.error('Unable to load default preferences: ' + e); + console.error(`Unable to load default preferences: ${e}`); resolve({}); } }; @@ -49,24 +49,18 @@ function cloneObj(obj) { } /** - * Preferences - Utility for storing persistent settings. + * BasePreferences - Abstract base class for storing persistent settings. * Used for settings that should be applied to all opened documents, * or every time the viewer is loaded. */ -var Preferences = { - prefs: null, - isInitializedPromiseResolved: false, - initializedPromise: null, - - /** - * Initialize and fetch the current preference values from storage. - * @return {Promise} A promise that is resolved when the preferences - * have been initialized. - */ - initialize: function preferencesInitialize() { - return this.initializedPromise = getDefaultPreferences().then( - function (defaults) { +class BasePreferences { + constructor() { + if (this.constructor === BasePreferences) { + throw new Error('Cannot initialize BasePreferences.'); + } + this.prefs = null; + this._initializedPromise = getDefaultPreferences().then((defaults) => { Object.defineProperty(this, 'defaults', { value: Object.freeze(defaults), writable: false, @@ -76,62 +70,59 @@ var Preferences = { this.prefs = cloneObj(defaults); return this._readFromStorage(defaults); - }.bind(this)).then(function(prefObj) { - this.isInitializedPromiseResolved = true; + }).then((prefObj) => { if (prefObj) { this.prefs = prefObj; } - }.bind(this)); - }, + }); + } /** * Stub function for writing preferences to storage. - * NOTE: This should be overridden by a build-specific function defined below. * @param {Object} prefObj The preferences that should be written to storage. * @return {Promise} A promise that is resolved when the preference values * have been written. */ - _writeToStorage: function preferences_writeToStorage(prefObj) { - return Promise.resolve(); - }, + _writeToStorage(prefObj) { + return Promise.reject(new Error('Not implemented: _writeToStorage')); + } /** * Stub function for reading preferences from storage. - * NOTE: This should be overridden by a build-specific function defined below. * @param {Object} prefObj The preferences that should be read from storage. * @return {Promise} A promise that is resolved with an {Object} containing * the preferences that have been read. */ - _readFromStorage: function preferences_readFromStorage(prefObj) { - return Promise.resolve(); - }, + _readFromStorage(prefObj) { + return Promise.reject(new Error('Not implemented: _readFromStorage')); + } /** * Reset the preferences to their default values and update storage. * @return {Promise} A promise that is resolved when the preference values * have been reset. */ - reset: function preferencesReset() { - return this.initializedPromise.then(function() { + reset() { + return this._initializedPromise.then(() => { this.prefs = cloneObj(this.defaults); return this._writeToStorage(this.defaults); - }.bind(this)); - }, + }); + } /** * Replace the current preference values with the ones from storage. * @return {Promise} A promise that is resolved when the preference values * have been updated. */ - reload: function preferencesReload() { - return this.initializedPromise.then(function () { - this._readFromStorage(this.defaults).then(function(prefObj) { - if (prefObj) { - this.prefs = prefObj; - } - }.bind(this)); - }.bind(this)); - }, + reload() { + return this._initializedPromise.then(() => { + return this._readFromStorage(this.defaults); + }).then((prefObj) => { + if (prefObj) { + this.prefs = prefObj; + } + }); + } /** * Set the value of a preference. @@ -140,12 +131,12 @@ var Preferences = { * @return {Promise} A promise that is resolved when the value has been set, * provided that the preference exists and the types match. */ - set: function preferencesSet(name, value) { - return this.initializedPromise.then(function () { + set(name, value) { + return this._initializedPromise.then(() => { if (this.defaults[name] === undefined) { - throw new Error('preferencesSet: \'' + name + '\' is undefined.'); + throw new Error(`Set preference: "${name}" is undefined.`); } else if (value === undefined) { - throw new Error('preferencesSet: no value is specified.'); + throw new Error('Set preference: no value is specified.'); } var valueType = typeof value; var defaultType = typeof this.defaults[name]; @@ -154,19 +145,18 @@ var Preferences = { if (valueType === 'number' && defaultType === 'string') { value = value.toString(); } else { - throw new Error('Preferences_set: \'' + value + '\' is a \"' + - valueType + '\", expected \"' + defaultType + '\".'); + throw new Error(`Set preference: "${value}" is a ${valueType}, ` + + `expected a ${defaultType}.`); } } else { if (valueType === 'number' && (value | 0) !== value) { - throw new Error('Preferences_set: \'' + value + - '\' must be an \"integer\".'); + throw new Error(`Set preference: "${value}" must be an integer.`); } } this.prefs[name] = value; return this._writeToStorage(this.prefs); - }.bind(this)); - }, + }); + } /** * Get the value of a preference. @@ -174,12 +164,12 @@ var Preferences = { * @return {Promise} A promise that is resolved with a {boolean|number|string} * containing the value of the preference. */ - get: function preferencesGet(name) { - return this.initializedPromise.then(function () { + get(name) { + return this._initializedPromise.then(() => { var defaultValue = this.defaults[name]; if (defaultValue === undefined) { - throw new Error('preferencesGet: \'' + name + '\' is undefined.'); + throw new Error(`Get preference: "${name}" is undefined.`); } else { var prefValue = this.prefs[name]; @@ -188,27 +178,10 @@ var Preferences = { } } return defaultValue; - }.bind(this)); - } -}; - -if (typeof PDFJSDev === 'undefined' || - !PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) { - Preferences._writeToStorage = function (prefObj) { - return new Promise(function (resolve) { - localStorage.setItem('pdfjs.preferences', JSON.stringify(prefObj)); - resolve(); }); - }; - - Preferences._readFromStorage = function (prefObj) { - return new Promise(function (resolve) { - var readPrefs = JSON.parse(localStorage.getItem('pdfjs.preferences')); - resolve(readPrefs); - }); - }; + } } export { - Preferences, + BasePreferences, };