Browse Source

Convert the overlay manager to ES6 syntax

Tim van der Meij 8 years ago
parent
commit
e7a04fc82d
No known key found for this signature in database
GPG Key ID: 8C3FD2925A5F2762
  1. 18
      web/app.js
  2. 22
      web/chromecom.js
  3. 107
      web/overlay_manager.js
  4. 11
      web/password_prompt.js
  5. 14
      web/pdf_document_properties.js
  6. 25
      web/pdf_print_service.js

18
web/app.js

@ -119,6 +119,8 @@ var PDFViewerApplication = {
store: null, store: null,
/** @type {DownloadManager} */ /** @type {DownloadManager} */
downloadManager: null, downloadManager: null,
/** @type {OverlayManager} */
overlayManager: null,
/** @type {Preferences} */ /** @type {Preferences} */
preferences: null, preferences: null,
/** @type {Toolbar} */ /** @type {Toolbar} */
@ -261,6 +263,8 @@ var PDFViewerApplication = {
let appConfig = this.appConfig; let appConfig = this.appConfig;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.overlayManager = new OverlayManager();
let eventBus = appConfig.eventBus || getGlobalEventBus(); let eventBus = appConfig.eventBus || getGlobalEventBus();
this.eventBus = eventBus; this.eventBus = eventBus;
@ -329,16 +333,15 @@ var PDFViewerApplication = {
this.pdfViewer.setFindController(this.findController); this.pdfViewer.setFindController(this.findController);
// FIXME better PDFFindBar constructor parameters // TODO: improve `PDFFindBar` constructor parameter passing
let findBarConfig = Object.create(appConfig.findBar); let findBarConfig = Object.create(appConfig.findBar);
findBarConfig.findController = this.findController; findBarConfig.findController = this.findController;
findBarConfig.eventBus = eventBus; findBarConfig.eventBus = eventBus;
this.findBar = new PDFFindBar(findBarConfig); this.findBar = new PDFFindBar(findBarConfig);
this.overlayManager = OverlayManager;
this.pdfDocumentProperties = this.pdfDocumentProperties =
new PDFDocumentProperties(appConfig.documentProperties); new PDFDocumentProperties(appConfig.documentProperties,
this.overlayManager);
this.pdfCursorTools = new PDFCursorTools({ this.pdfCursorTools = new PDFCursorTools({
container, container,
@ -361,7 +364,8 @@ var PDFViewerApplication = {
}); });
} }
this.passwordPrompt = new PasswordPrompt(appConfig.passwordOverlay); this.passwordPrompt = new PasswordPrompt(appConfig.passwordOverlay,
this.overlayManager);
this.pdfOutlineViewer = new PDFOutlineViewer({ this.pdfOutlineViewer = new PDFOutlineViewer({
container: appConfig.sidebar.outlineView, container: appConfig.sidebar.outlineView,
@ -375,7 +379,7 @@ var PDFViewerApplication = {
downloadManager, downloadManager,
}); });
// FIXME better PDFSidebar constructor parameters // TODO: improve `PDFSidebar` constructor parameter passing
let sidebarConfig = Object.create(appConfig.sidebar); let sidebarConfig = Object.create(appConfig.sidebar);
sidebarConfig.pdfViewer = this.pdfViewer; sidebarConfig.pdfViewer = this.pdfViewer;
sidebarConfig.pdfThumbnailViewer = this.pdfThumbnailViewer; sidebarConfig.pdfThumbnailViewer = this.pdfThumbnailViewer;
@ -1911,7 +1915,7 @@ function webViewerClick(evt) {
} }
function webViewerKeyDown(evt) { function webViewerKeyDown(evt) {
if (OverlayManager.active) { if (PDFViewerApplication.overlayManager.active) {
return; return;
} }

22
web/chromecom.js

@ -17,7 +17,6 @@
import { DefaultExternalServices, PDFViewerApplication } from './app'; import { DefaultExternalServices, PDFViewerApplication } from './app';
import { BasePreferences } from './preferences'; import { BasePreferences } from './preferences';
import { DownloadManager } from './download_manager'; import { DownloadManager } from './download_manager';
import { OverlayManager } from './overlay_manager';
import { PDFJS } from './pdfjs'; import { PDFJS } from './pdfjs';
if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('CHROME')) { if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('CHROME')) {
@ -56,10 +55,11 @@ ChromeCom.request = function ChromeCom_request(action, data, callback) {
/** /**
* Resolves a PDF file path and attempts to detects length. * Resolves a PDF file path and attempts to detects length.
* *
* @param {String} file Absolute URL of PDF file. * @param {String} file - Absolute URL of PDF file.
* @param {Function} callback A callback with resolved URL and file length. * @param {OverlayManager} overlayManager - Manager for the viewer overlays.
* @param {Function} callback - A callback with resolved URL and file length.
*/ */
ChromeCom.resolvePDFFile = function ChromeCom_resolvePDFFile(file, callback) { ChromeCom.resolvePDFFile = function(file, overlayManager, callback) {
// Expand drive:-URLs to filesystem URLs (Chrome OS) // Expand drive:-URLs to filesystem URLs (Chrome OS)
file = file.replace(/^drive:/i, file = file.replace(/^drive:/i,
'filesystem:' + location.origin + '/external/'); 'filesystem:' + location.origin + '/external/');
@ -110,7 +110,7 @@ ChromeCom.resolvePDFFile = function ChromeCom_resolvePDFFile(file, callback) {
if (isAllowedAccess) { if (isAllowedAccess) {
callback(file); callback(file);
} else { } else {
requestAccessToLocalFile(file); requestAccessToLocalFile(file, overlayManager);
} }
}); });
}); });
@ -155,7 +155,7 @@ function reloadIfRuntimeIsUnavailable() {
} }
var chromeFileAccessOverlayPromise; var chromeFileAccessOverlayPromise;
function requestAccessToLocalFile(fileUrl) { function requestAccessToLocalFile(fileUrl, overlayManager) {
var onCloseOverlay = null; var onCloseOverlay = null;
if (top !== window) { if (top !== window) {
// When the extension reloads after receiving new permissions, the pages // When the extension reloads after receiving new permissions, the pages
@ -169,11 +169,11 @@ function requestAccessToLocalFile(fileUrl) {
onCloseOverlay = function() { onCloseOverlay = function() {
window.removeEventListener('focus', reloadIfRuntimeIsUnavailable); window.removeEventListener('focus', reloadIfRuntimeIsUnavailable);
reloadIfRuntimeIsUnavailable(); reloadIfRuntimeIsUnavailable();
OverlayManager.close('chromeFileAccessOverlay'); overlayManager.close('chromeFileAccessOverlay');
}; };
} }
if (!chromeFileAccessOverlayPromise) { if (!chromeFileAccessOverlayPromise) {
chromeFileAccessOverlayPromise = OverlayManager.register( chromeFileAccessOverlayPromise = overlayManager.register(
'chromeFileAccessOverlay', 'chromeFileAccessOverlay',
document.getElementById('chromeFileAccessOverlay'), document.getElementById('chromeFileAccessOverlay'),
onCloseOverlay, true); onCloseOverlay, true);
@ -215,7 +215,7 @@ function requestAccessToLocalFile(fileUrl) {
// why this permission request is shown. // why this permission request is shown.
document.getElementById('chrome-url-of-local-file').textContent = fileUrl; document.getElementById('chrome-url-of-local-file').textContent = fileUrl;
OverlayManager.open('chromeFileAccessOverlay'); overlayManager.open('chromeFileAccessOverlay');
}); });
} }
@ -338,8 +338,8 @@ class ChromePreferences extends BasePreferences {
var ChromeExternalServices = Object.create(DefaultExternalServices); var ChromeExternalServices = Object.create(DefaultExternalServices);
ChromeExternalServices.initPassiveLoading = function (callbacks) { ChromeExternalServices.initPassiveLoading = function (callbacks) {
var appConfig = PDFViewerApplication.appConfig; let { appConfig, overlayManager, } = PDFViewerApplication;
ChromeCom.resolvePDFFile(appConfig.defaultUrl, ChromeCom.resolvePDFFile(appConfig.defaultUrl, overlayManager,
function (url, length, originalURL) { function (url, length, originalURL) {
callbacks.onOpenWithURL(url, length, originalURL); callbacks.onOpenWithURL(url, length, originalURL);
}); });

107
web/overlay_manager.js

@ -13,132 +13,137 @@
* limitations under the License. * limitations under the License.
*/ */
var OverlayManager = { class OverlayManager {
overlays: {}, constructor() {
active: null, this._overlays = {};
this._active = null;
this._keyDownBound = this._keyDown.bind(this);
}
get active() {
return this._active;
}
/** /**
* @param {string} name The name of the overlay that is registered. * @param {string} name - The name of the overlay that is registered.
* @param {HTMLDivElement} element The overlay's DOM element. * @param {HTMLDivElement} element - The overlay's DOM element.
* @param {function} callerCloseMethod (optional) The method that, if present, * @param {function} callerCloseMethod - (optional) The method that, if
* will call OverlayManager.close from the Object * present, calls `OverlayManager.close` from the object
* registering the overlay. Access to this method is * registering the overlay. Access to this method is
* necessary in order to run cleanup code when e.g. * necessary in order to run cleanup code when e.g.
* the overlay is force closed. The default is null. * the overlay is force closed. The default is `null`.
* @param {boolean} canForceClose (optional) Indicates if opening the overlay * @param {boolean} canForceClose - (optional) Indicates if opening the
* will close an active overlay. The default is false. * overlay closes an active overlay. The default is `false`.
* @returns {Promise} A promise that is resolved when the overlay has been * @returns {Promise} A promise that is resolved when the overlay has been
* registered. * registered.
*/ */
register(name, element, callerCloseMethod, canForceClose) { register(name, element, callerCloseMethod = null, canForceClose = false) {
return new Promise((resolve) => { return new Promise((resolve) => {
var container; let container;
if (!name || !element || !(container = element.parentNode)) { if (!name || !element || !(container = element.parentNode)) {
throw new Error('Not enough parameters.'); throw new Error('Not enough parameters.');
} else if (this.overlays[name]) { } else if (this._overlays[name]) {
throw new Error('The overlay is already registered.'); throw new Error('The overlay is already registered.');
} }
this.overlays[name] = { this._overlays[name] = {
element, element,
container, container,
callerCloseMethod: (callerCloseMethod || null), callerCloseMethod,
canForceClose: (canForceClose || false), canForceClose,
}; };
resolve(); resolve();
}); });
}, }
/** /**
* @param {string} name The name of the overlay that is unregistered. * @param {string} name - The name of the overlay that is unregistered.
* @returns {Promise} A promise that is resolved when the overlay has been * @returns {Promise} A promise that is resolved when the overlay has been
* unregistered. * unregistered.
*/ */
unregister(name) { unregister(name) {
return new Promise((resolve) => { return new Promise((resolve) => {
if (!this.overlays[name]) { if (!this._overlays[name]) {
throw new Error('The overlay does not exist.'); throw new Error('The overlay does not exist.');
} else if (this.active === name) { } else if (this._active === name) {
throw new Error('The overlay cannot be removed while it is active.'); throw new Error('The overlay cannot be removed while it is active.');
} }
delete this.overlays[name]; delete this._overlays[name];
resolve(); resolve();
}); });
}, }
/** /**
* @param {string} name The name of the overlay that should be opened. * @param {string} name - The name of the overlay that should be opened.
* @returns {Promise} A promise that is resolved when the overlay has been * @returns {Promise} A promise that is resolved when the overlay has been
* opened. * opened.
*/ */
open(name) { open(name) {
return new Promise((resolve) => { return new Promise((resolve) => {
if (!this.overlays[name]) { if (!this._overlays[name]) {
throw new Error('The overlay does not exist.'); throw new Error('The overlay does not exist.');
} else if (this.active) { } else if (this._active) {
if (this.overlays[name].canForceClose) { if (this._overlays[name].canForceClose) {
this._closeThroughCaller(); this._closeThroughCaller();
} else if (this.active === name) { } else if (this._active === name) {
throw new Error('The overlay is already active.'); throw new Error('The overlay is already active.');
} else { } else {
throw new Error('Another overlay is currently active.'); throw new Error('Another overlay is currently active.');
} }
} }
this.active = name; this._active = name;
this.overlays[this.active].element.classList.remove('hidden'); this._overlays[this._active].element.classList.remove('hidden');
this.overlays[this.active].container.classList.remove('hidden'); this._overlays[this._active].container.classList.remove('hidden');
window.addEventListener('keydown', this._keyDown); window.addEventListener('keydown', this._keyDownBound);
resolve(); resolve();
}); });
}, }
/** /**
* @param {string} name The name of the overlay that should be closed. * @param {string} name - The name of the overlay that should be closed.
* @returns {Promise} A promise that is resolved when the overlay has been * @returns {Promise} A promise that is resolved when the overlay has been
* closed. * closed.
*/ */
close(name) { close(name) {
return new Promise((resolve) => { return new Promise((resolve) => {
if (!this.overlays[name]) { if (!this._overlays[name]) {
throw new Error('The overlay does not exist.'); throw new Error('The overlay does not exist.');
} else if (!this.active) { } else if (!this._active) {
throw new Error('The overlay is currently not active.'); throw new Error('The overlay is currently not active.');
} else if (this.active !== name) { } else if (this._active !== name) {
throw new Error('Another overlay is currently active.'); throw new Error('Another overlay is currently active.');
} }
this.overlays[this.active].container.classList.add('hidden'); this._overlays[this._active].container.classList.add('hidden');
this.overlays[this.active].element.classList.add('hidden'); this._overlays[this._active].element.classList.add('hidden');
this.active = null; this._active = null;
window.removeEventListener('keydown', this._keyDown); window.removeEventListener('keydown', this._keyDownBound);
resolve(); resolve();
}); });
}, }
/** /**
* @private * @private
*/ */
_keyDown(evt) { _keyDown(evt) {
var self = OverlayManager; if (this._active && evt.keyCode === 27) { // Esc key.
if (self.active && evt.keyCode === 27) { // Esc key. this._closeThroughCaller();
self._closeThroughCaller();
evt.preventDefault(); evt.preventDefault();
} }
}, }
/** /**
* @private * @private
*/ */
_closeThroughCaller() { _closeThroughCaller() {
if (this.overlays[this.active].callerCloseMethod) { if (this._overlays[this._active].callerCloseMethod) {
this.overlays[this.active].callerCloseMethod(); this._overlays[this._active].callerCloseMethod();
}
if (this._active) {
this.close(this._active);
} }
if (this.active) {
this.close(this.active);
} }
} }
};
export { export {
OverlayManager, OverlayManager,

11
web/password_prompt.js

@ -14,7 +14,6 @@
*/ */
import { mozL10n } from './ui_utils'; import { mozL10n } from './ui_utils';
import { OverlayManager } from './overlay_manager';
import { PasswordResponses } from './pdfjs'; import { PasswordResponses } from './pdfjs';
/** /**
@ -33,14 +32,16 @@ import { PasswordResponses } from './pdfjs';
class PasswordPrompt { class PasswordPrompt {
/** /**
* @param {PasswordPromptOptions} options * @param {PasswordPromptOptions} options
* @param {OverlayManager} overlayManager - Manager for the viewer overlays.
*/ */
constructor(options) { constructor(options, overlayManager) {
this.overlayName = options.overlayName; this.overlayName = options.overlayName;
this.container = options.container; this.container = options.container;
this.label = options.label; this.label = options.label;
this.input = options.input; this.input = options.input;
this.submitButton = options.submitButton; this.submitButton = options.submitButton;
this.cancelButton = options.cancelButton; this.cancelButton = options.cancelButton;
this.overlayManager = overlayManager;
this.updateCallback = null; this.updateCallback = null;
this.reason = null; this.reason = null;
@ -54,12 +55,12 @@ class PasswordPrompt {
} }
}); });
OverlayManager.register(this.overlayName, this.container, this.overlayManager.register(this.overlayName, this.container,
this.close.bind(this), true); this.close.bind(this), true);
} }
open() { open() {
OverlayManager.open(this.overlayName).then(() => { this.overlayManager.open(this.overlayName).then(() => {
this.input.focus(); this.input.focus();
var promptString = mozL10n.get('password_label', null, var promptString = mozL10n.get('password_label', null,
@ -75,7 +76,7 @@ class PasswordPrompt {
} }
close() { close() {
OverlayManager.close(this.overlayName).then(() => { this.overlayManager.close(this.overlayName).then(() => {
this.input.value = ''; this.input.value = '';
}); });
} }

14
web/pdf_document_properties.js

@ -15,7 +15,6 @@
import { cloneObj, getPDFFileNameFromURL, mozL10n } from './ui_utils'; import { cloneObj, getPDFFileNameFromURL, mozL10n } from './ui_utils';
import { createPromiseCapability } from './pdfjs'; import { createPromiseCapability } from './pdfjs';
import { OverlayManager } from './overlay_manager';
const DEFAULT_FIELD_CONTENT = '-'; const DEFAULT_FIELD_CONTENT = '-';
@ -30,18 +29,21 @@ const DEFAULT_FIELD_CONTENT = '-';
class PDFDocumentProperties { class PDFDocumentProperties {
/** /**
* @param {PDFDocumentPropertiesOptions} options * @param {PDFDocumentPropertiesOptions} options
* @param {OverlayManager} overlayManager - Manager for the viewer overlays.
*/ */
constructor({ overlayName, fields, container, closeButton, }) { constructor({ overlayName, fields, container, closeButton, },
overlayManager) {
this.overlayName = overlayName; this.overlayName = overlayName;
this.fields = fields; this.fields = fields;
this.container = container; this.container = container;
this.overlayManager = overlayManager;
this._reset(); this._reset();
if (closeButton) { // Bind the event listener for the Close button. if (closeButton) { // Bind the event listener for the Close button.
closeButton.addEventListener('click', this.close.bind(this)); closeButton.addEventListener('click', this.close.bind(this));
} }
OverlayManager.register(this.overlayName, this.container, this.overlayManager.register(this.overlayName, this.container,
this.close.bind(this)); this.close.bind(this));
} }
@ -58,7 +60,7 @@ class PDFDocumentProperties {
}); });
}; };
Promise.all([OverlayManager.open(this.overlayName), Promise.all([this.overlayManager.open(this.overlayName),
this._dataAvailableCapability.promise]).then(() => { this._dataAvailableCapability.promise]).then(() => {
// If the document properties were previously fetched (for this PDF file), // If the document properties were previously fetched (for this PDF file),
// just update the dialog immediately to avoid redundant lookups. // just update the dialog immediately to avoid redundant lookups.
@ -101,7 +103,7 @@ class PDFDocumentProperties {
* Close the document properties overlay. * Close the document properties overlay.
*/ */
close() { close() {
OverlayManager.close(this.overlayName); this.overlayManager.close(this.overlayName);
} }
/** /**
@ -165,7 +167,7 @@ class PDFDocumentProperties {
} }
return; return;
} }
if (OverlayManager.active !== this.overlayName) { if (this.overlayManager.active !== this.overlayName) {
// Don't bother updating the dialog if has already been closed, // Don't bother updating the dialog if has already been closed,
// since it will be updated the next time `this.open` is called. // since it will be updated the next time `this.open` is called.
return; return;

25
web/pdf_print_service.js

@ -14,11 +14,11 @@
*/ */
import { CSS_UNITS, mozL10n } from './ui_utils'; import { CSS_UNITS, mozL10n } from './ui_utils';
import { OverlayManager } from './overlay_manager'; import { PDFPrintServiceFactory, PDFViewerApplication } from './app';
import { PDFJS } from './pdfjs'; import { PDFJS } from './pdfjs';
import { PDFPrintServiceFactory } from './app';
var activeService = null; let activeService = null;
let overlayManager = null;
// Renders the page to the canvas of the given print service, and returns // Renders the page to the canvas of the given print service, and returns
// the suggested dimensions of the output page. // the suggested dimensions of the output page.
@ -118,10 +118,10 @@ PDFPrintService.prototype = {
this.scratchCanvas = null; this.scratchCanvas = null;
activeService = null; activeService = null;
ensureOverlay().then(function () { ensureOverlay().then(function () {
if (OverlayManager.active !== 'printServiceOverlay') { if (overlayManager.active !== 'printServiceOverlay') {
return; // overlay was already closed return; // overlay was already closed
} }
OverlayManager.close('printServiceOverlay'); overlayManager.close('printServiceOverlay');
}); });
}, },
@ -208,7 +208,7 @@ window.print = function print() {
} }
ensureOverlay().then(function () { ensureOverlay().then(function () {
if (activeService) { if (activeService) {
OverlayManager.open('printServiceOverlay'); overlayManager.open('printServiceOverlay');
} }
}); });
@ -217,9 +217,11 @@ window.print = function print() {
} finally { } finally {
if (!activeService) { if (!activeService) {
console.error('Expected print service to be initialized.'); console.error('Expected print service to be initialized.');
if (OverlayManager.active === 'printServiceOverlay') { ensureOverlay().then(function () {
OverlayManager.close('printServiceOverlay'); if (overlayManager.active === 'printServiceOverlay') {
overlayManager.close('printServiceOverlay');
} }
});
return; // eslint-disable-line no-unsafe-finally return; // eslint-disable-line no-unsafe-finally
} }
var activeServiceOnEntry = activeService; var activeServiceOnEntry = activeService;
@ -310,7 +312,12 @@ if ('onbeforeprint' in window) {
var overlayPromise; var overlayPromise;
function ensureOverlay() { function ensureOverlay() {
if (!overlayPromise) { if (!overlayPromise) {
overlayPromise = OverlayManager.register('printServiceOverlay', overlayManager = PDFViewerApplication.overlayManager;
if (!overlayManager) {
throw new Error('The overlay manager has not yet been initialized.');
}
overlayPromise = overlayManager.register('printServiceOverlay',
document.getElementById('printServiceOverlay'), abort, true); document.getElementById('printServiceOverlay'), abort, true);
document.getElementById('printCancel').onclick = abort; document.getElementById('printCancel').onclick = abort;
} }

Loading…
Cancel
Save