Merge pull request #9995 from Snuffleupagus/async-web

Refactor code in the `web/` folder to use `async`/`await`
This commit is contained in:
Tim van der Meij 2018-09-08 21:40:20 +02:00 committed by GitHub
commit 510f1c84d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 414 additions and 473 deletions

View File

@ -133,44 +133,42 @@ let PDFViewerApplication = {
contentDispositionFilename: null,
// Called once when the document is loaded.
initialize(appConfig) {
async initialize(appConfig) {
this.preferences = this.externalServices.createPreferences();
this.appConfig = appConfig;
return this._readPreferences().then(() => {
return this._parseHashParameters();
}).then(() => {
return this._initializeL10n();
}).then(() => {
if (this.isViewerEmbedded &&
AppOptions.get('externalLinkTarget') === LinkTarget.NONE) {
// Prevent external links from "replacing" the viewer,
// when it's embedded in e.g. an <iframe> or an <object>.
AppOptions.set('externalLinkTarget', LinkTarget.TOP);
}
return this._initializeViewerComponents();
}).then(() => {
// Bind the various event handlers *after* the viewer has been
// initialized, to prevent errors if an event arrives too soon.
this.bindEvents();
this.bindWindowEvents();
await this._readPreferences();
await this._parseHashParameters();
await this._initializeL10n();
// We can start UI localization now.
let appContainer = appConfig.appContainer || document.documentElement;
this.l10n.translate(appContainer).then(() => {
// Dispatch the 'localized' event on the `eventBus` once the viewer
// has been fully initialized and translated.
this.eventBus.dispatch('localized', { source: this, });
});
if (this.isViewerEmbedded &&
AppOptions.get('externalLinkTarget') === LinkTarget.NONE) {
// Prevent external links from "replacing" the viewer,
// when it's embedded in e.g. an <iframe> or an <object>.
AppOptions.set('externalLinkTarget', LinkTarget.TOP);
}
await this._initializeViewerComponents();
this.initialized = true;
// Bind the various event handlers *after* the viewer has been
// initialized, to prevent errors if an event arrives too soon.
this.bindEvents();
this.bindWindowEvents();
// We can start UI localization now.
let appContainer = appConfig.appContainer || document.documentElement;
this.l10n.translate(appContainer).then(() => {
// Dispatch the 'localized' event on the `eventBus` once the viewer
// has been fully initialized and translated.
this.eventBus.dispatch('localized', { source: this, });
});
this.initialized = true;
},
/**
* @private
*/
_readPreferences() {
async _readPreferences() {
// A subset of the Preferences that `AppOptions`, for compatibility reasons,
// is allowed to override if the `AppOptions` values matches the ones below.
const OVERRIDES = {
@ -180,89 +178,89 @@ let PDFViewerApplication = {
textLayerMode: TextLayerMode.DISABLE,
};
return this.preferences.getAll().then(function(prefs) {
try {
const prefs = await this.preferences.getAll();
for (let name in prefs) {
if ((name in OVERRIDES) && AppOptions.get(name) === OVERRIDES[name]) {
continue;
}
AppOptions.set(name, prefs[name]);
}
}, function(reason) { });
} catch (reason) { }
},
/**
* @private
*/
_parseHashParameters() {
async _parseHashParameters() {
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('PRODUCTION') &&
!AppOptions.get('pdfBugEnabled')) {
return;
}
const waitOn = [];
if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION') ||
AppOptions.get('pdfBugEnabled')) {
// Special debugging flags in the hash section of the URL.
let hash = document.location.hash.substring(1);
let hashParams = parseQueryString(hash);
// Special debugging flags in the hash section of the URL.
let hash = document.location.hash.substring(1);
let hashParams = parseQueryString(hash);
if ('disableworker' in hashParams &&
hashParams['disableworker'] === 'true') {
waitOn.push(loadFakeWorker());
}
if ('disablerange' in hashParams) {
AppOptions.set('disableRange', hashParams['disablerange'] === 'true');
}
if ('disablestream' in hashParams) {
AppOptions.set('disableStream', hashParams['disablestream'] === 'true');
}
if ('disableautofetch' in hashParams) {
AppOptions.set('disableAutoFetch',
hashParams['disableautofetch'] === 'true');
}
if ('disablefontface' in hashParams) {
AppOptions.set('disableFontFace',
hashParams['disablefontface'] === 'true');
}
if ('disablehistory' in hashParams) {
AppOptions.set('disableHistory',
hashParams['disablehistory'] === 'true');
}
if ('webgl' in hashParams) {
AppOptions.set('enableWebGL', hashParams['webgl'] === 'true');
}
if ('useonlycsszoom' in hashParams) {
AppOptions.set('useOnlyCssZoom',
hashParams['useonlycsszoom'] === 'true');
}
if ('verbosity' in hashParams) {
AppOptions.set('verbosity', hashParams['verbosity'] | 0);
}
if ((typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) &&
hashParams['disablebcmaps'] === 'true') {
AppOptions.set('cMapUrl', '../external/cmaps/');
AppOptions.set('cMapPacked', false);
}
if ('textlayer' in hashParams) {
switch (hashParams['textlayer']) {
case 'off':
AppOptions.set('textLayerMode', TextLayerMode.DISABLE);
break;
case 'visible':
case 'shadow':
case 'hover':
let viewer = this.appConfig.viewerContainer;
viewer.classList.add('textLayer-' + hashParams['textlayer']);
break;
}
}
if ('pdfbug' in hashParams) {
AppOptions.set('pdfBug', true);
let enabled = hashParams['pdfbug'].split(',');
waitOn.push(loadAndEnablePDFBug(enabled));
}
// It is not possible to change locale for the (various) extension builds.
if ((typeof PDFJSDev === 'undefined' ||
PDFJSDev.test('!PRODUCTION || GENERIC')) && 'locale' in hashParams) {
AppOptions.set('locale', hashParams['locale']);
if ('disableworker' in hashParams &&
hashParams['disableworker'] === 'true') {
waitOn.push(loadFakeWorker());
}
if ('disablerange' in hashParams) {
AppOptions.set('disableRange', hashParams['disablerange'] === 'true');
}
if ('disablestream' in hashParams) {
AppOptions.set('disableStream', hashParams['disablestream'] === 'true');
}
if ('disableautofetch' in hashParams) {
AppOptions.set('disableAutoFetch',
hashParams['disableautofetch'] === 'true');
}
if ('disablefontface' in hashParams) {
AppOptions.set('disableFontFace',
hashParams['disablefontface'] === 'true');
}
if ('disablehistory' in hashParams) {
AppOptions.set('disableHistory', hashParams['disablehistory'] === 'true');
}
if ('webgl' in hashParams) {
AppOptions.set('enableWebGL', hashParams['webgl'] === 'true');
}
if ('useonlycsszoom' in hashParams) {
AppOptions.set('useOnlyCssZoom', hashParams['useonlycsszoom'] === 'true');
}
if ('verbosity' in hashParams) {
AppOptions.set('verbosity', hashParams['verbosity'] | 0);
}
if ((typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) &&
hashParams['disablebcmaps'] === 'true') {
AppOptions.set('cMapUrl', '../external/cmaps/');
AppOptions.set('cMapPacked', false);
}
if ('textlayer' in hashParams) {
switch (hashParams['textlayer']) {
case 'off':
AppOptions.set('textLayerMode', TextLayerMode.DISABLE);
break;
case 'visible':
case 'shadow':
case 'hover':
let viewer = this.appConfig.viewerContainer;
viewer.classList.add('textLayer-' + hashParams['textlayer']);
break;
}
}
if ('pdfbug' in hashParams) {
AppOptions.set('pdfBug', true);
let enabled = hashParams['pdfbug'].split(',');
waitOn.push(loadAndEnablePDFBug(enabled));
}
// It is not possible to change locale for the (various) extension builds.
if ((typeof PDFJSDev === 'undefined' ||
PDFJSDev.test('!PRODUCTION || GENERIC')) && 'locale' in hashParams) {
AppOptions.set('locale', hashParams['locale']);
}
return Promise.all(waitOn);
},
@ -270,164 +268,160 @@ let PDFViewerApplication = {
/**
* @private
*/
_initializeL10n() {
async _initializeL10n() {
this.l10n = this.externalServices.createL10n({
locale: AppOptions.get('locale'),
});
return this.l10n.getDirection().then((dir) => {
document.getElementsByTagName('html')[0].dir = dir;
});
const dir = await this.l10n.getDirection();
document.getElementsByTagName('html')[0].dir = dir;
},
/**
* @private
*/
_initializeViewerComponents() {
let { appConfig, } = this;
async _initializeViewerComponents() {
const appConfig = this.appConfig;
return new Promise((resolve, reject) => {
this.overlayManager = new OverlayManager();
this.overlayManager = new OverlayManager();
const dispatchToDOM = AppOptions.get('eventBusDispatchToDOM');
let eventBus = appConfig.eventBus || getGlobalEventBus(dispatchToDOM);
this.eventBus = eventBus;
const dispatchToDOM = AppOptions.get('eventBusDispatchToDOM');
let eventBus = appConfig.eventBus || getGlobalEventBus(dispatchToDOM);
this.eventBus = eventBus;
let pdfRenderingQueue = new PDFRenderingQueue();
pdfRenderingQueue.onIdle = this.cleanup.bind(this);
this.pdfRenderingQueue = pdfRenderingQueue;
let pdfRenderingQueue = new PDFRenderingQueue();
pdfRenderingQueue.onIdle = this.cleanup.bind(this);
this.pdfRenderingQueue = pdfRenderingQueue;
let pdfLinkService = new PDFLinkService({
eventBus,
externalLinkTarget: AppOptions.get('externalLinkTarget'),
externalLinkRel: AppOptions.get('externalLinkRel'),
});
this.pdfLinkService = pdfLinkService;
let pdfLinkService = new PDFLinkService({
eventBus,
externalLinkTarget: AppOptions.get('externalLinkTarget'),
externalLinkRel: AppOptions.get('externalLinkRel'),
});
this.pdfLinkService = pdfLinkService;
let downloadManager = this.externalServices.createDownloadManager({
disableCreateObjectURL: AppOptions.get('disableCreateObjectURL'),
});
this.downloadManager = downloadManager;
let downloadManager = this.externalServices.createDownloadManager({
disableCreateObjectURL: AppOptions.get('disableCreateObjectURL'),
});
this.downloadManager = downloadManager;
let container = appConfig.mainContainer;
let viewer = appConfig.viewerContainer;
this.pdfViewer = new PDFViewer({
let container = appConfig.mainContainer;
let viewer = appConfig.viewerContainer;
this.pdfViewer = new PDFViewer({
container,
viewer,
eventBus,
renderingQueue: pdfRenderingQueue,
linkService: pdfLinkService,
downloadManager,
renderer: AppOptions.get('renderer'),
enableWebGL: AppOptions.get('enableWebGL'),
l10n: this.l10n,
textLayerMode: AppOptions.get('textLayerMode'),
imageResourcesPath: AppOptions.get('imageResourcesPath'),
renderInteractiveForms: AppOptions.get('renderInteractiveForms'),
enablePrintAutoRotate: AppOptions.get('enablePrintAutoRotate'),
useOnlyCssZoom: AppOptions.get('useOnlyCssZoom'),
maxCanvasPixels: AppOptions.get('maxCanvasPixels'),
});
pdfRenderingQueue.setViewer(this.pdfViewer);
pdfLinkService.setViewer(this.pdfViewer);
let thumbnailContainer = appConfig.sidebar.thumbnailView;
this.pdfThumbnailViewer = new PDFThumbnailViewer({
container: thumbnailContainer,
renderingQueue: pdfRenderingQueue,
linkService: pdfLinkService,
l10n: this.l10n,
});
pdfRenderingQueue.setThumbnailViewer(this.pdfThumbnailViewer);
this.pdfHistory = new PDFHistory({
linkService: pdfLinkService,
eventBus,
});
pdfLinkService.setHistory(this.pdfHistory);
this.findController = new PDFFindController({
pdfViewer: this.pdfViewer,
eventBus,
});
this.findController.onUpdateResultsCount = (matchCount) => {
if (this.supportsIntegratedFind) {
return;
}
this.findBar.updateResultsCount(matchCount);
};
this.findController.onUpdateState = (state, previous, matchCount) => {
if (this.supportsIntegratedFind) {
this.externalServices.updateFindControlState({
result: state,
findPrevious: previous,
});
} else {
this.findBar.updateUIState(state, previous, matchCount);
}
};
this.pdfViewer.setFindController(this.findController);
// TODO: improve `PDFFindBar` constructor parameter passing
let findBarConfig = Object.create(appConfig.findBar);
findBarConfig.findController = this.findController;
findBarConfig.eventBus = eventBus;
this.findBar = new PDFFindBar(findBarConfig, this.l10n);
this.pdfDocumentProperties =
new PDFDocumentProperties(appConfig.documentProperties,
this.overlayManager, eventBus, this.l10n);
this.pdfCursorTools = new PDFCursorTools({
container,
eventBus,
cursorToolOnLoad: AppOptions.get('cursorToolOnLoad'),
});
this.toolbar = new Toolbar(appConfig.toolbar, container, eventBus,
this.l10n);
this.secondaryToolbar =
new SecondaryToolbar(appConfig.secondaryToolbar, container, eventBus);
if (this.supportsFullscreen) {
this.pdfPresentationMode = new PDFPresentationMode({
container,
viewer,
eventBus,
renderingQueue: pdfRenderingQueue,
linkService: pdfLinkService,
downloadManager,
renderer: AppOptions.get('renderer'),
enableWebGL: AppOptions.get('enableWebGL'),
l10n: this.l10n,
textLayerMode: AppOptions.get('textLayerMode'),
imageResourcesPath: AppOptions.get('imageResourcesPath'),
renderInteractiveForms: AppOptions.get('renderInteractiveForms'),
enablePrintAutoRotate: AppOptions.get('enablePrintAutoRotate'),
useOnlyCssZoom: AppOptions.get('useOnlyCssZoom'),
maxCanvasPixels: AppOptions.get('maxCanvasPixels'),
});
pdfRenderingQueue.setViewer(this.pdfViewer);
pdfLinkService.setViewer(this.pdfViewer);
let thumbnailContainer = appConfig.sidebar.thumbnailView;
this.pdfThumbnailViewer = new PDFThumbnailViewer({
container: thumbnailContainer,
renderingQueue: pdfRenderingQueue,
linkService: pdfLinkService,
l10n: this.l10n,
});
pdfRenderingQueue.setThumbnailViewer(this.pdfThumbnailViewer);
this.pdfHistory = new PDFHistory({
linkService: pdfLinkService,
eventBus,
});
pdfLinkService.setHistory(this.pdfHistory);
this.findController = new PDFFindController({
pdfViewer: this.pdfViewer,
eventBus,
contextMenuItems: appConfig.fullscreen,
});
this.findController.onUpdateResultsCount = (matchCount) => {
if (this.supportsIntegratedFind) {
return;
}
this.findBar.updateResultsCount(matchCount);
};
this.findController.onUpdateState = (state, previous, matchCount) => {
if (this.supportsIntegratedFind) {
this.externalServices.updateFindControlState({
result: state,
findPrevious: previous,
});
} else {
this.findBar.updateUIState(state, previous, matchCount);
}
};
}
this.pdfViewer.setFindController(this.findController);
this.passwordPrompt = new PasswordPrompt(appConfig.passwordOverlay,
this.overlayManager, this.l10n);
// TODO: improve `PDFFindBar` constructor parameter passing
let findBarConfig = Object.create(appConfig.findBar);
findBarConfig.findController = this.findController;
findBarConfig.eventBus = eventBus;
this.findBar = new PDFFindBar(findBarConfig, this.l10n);
this.pdfDocumentProperties =
new PDFDocumentProperties(appConfig.documentProperties,
this.overlayManager, eventBus, this.l10n);
this.pdfCursorTools = new PDFCursorTools({
container,
eventBus,
cursorToolOnLoad: AppOptions.get('cursorToolOnLoad'),
});
this.toolbar = new Toolbar(appConfig.toolbar, container, eventBus,
this.l10n);
this.secondaryToolbar =
new SecondaryToolbar(appConfig.secondaryToolbar, container, eventBus);
if (this.supportsFullscreen) {
this.pdfPresentationMode = new PDFPresentationMode({
container,
viewer,
pdfViewer: this.pdfViewer,
eventBus,
contextMenuItems: appConfig.fullscreen,
});
}
this.passwordPrompt = new PasswordPrompt(appConfig.passwordOverlay,
this.overlayManager, this.l10n);
this.pdfOutlineViewer = new PDFOutlineViewer({
container: appConfig.sidebar.outlineView,
eventBus,
linkService: pdfLinkService,
});
this.pdfAttachmentViewer = new PDFAttachmentViewer({
container: appConfig.sidebar.attachmentsView,
eventBus,
downloadManager,
});
// TODO: improve `PDFSidebar` constructor parameter passing
let sidebarConfig = Object.create(appConfig.sidebar);
sidebarConfig.pdfViewer = this.pdfViewer;
sidebarConfig.pdfThumbnailViewer = this.pdfThumbnailViewer;
sidebarConfig.pdfOutlineViewer = this.pdfOutlineViewer;
sidebarConfig.eventBus = eventBus;
this.pdfSidebar = new PDFSidebar(sidebarConfig, this.l10n);
this.pdfSidebar.onToggled = this.forceRendering.bind(this);
this.pdfSidebarResizer = new PDFSidebarResizer(appConfig.sidebarResizer,
eventBus, this.l10n);
resolve(undefined);
this.pdfOutlineViewer = new PDFOutlineViewer({
container: appConfig.sidebar.outlineView,
eventBus,
linkService: pdfLinkService,
});
this.pdfAttachmentViewer = new PDFAttachmentViewer({
container: appConfig.sidebar.attachmentsView,
eventBus,
downloadManager,
});
// TODO: improve `PDFSidebar` constructor parameter passing
let sidebarConfig = Object.create(appConfig.sidebar);
sidebarConfig.pdfViewer = this.pdfViewer;
sidebarConfig.pdfThumbnailViewer = this.pdfThumbnailViewer;
sidebarConfig.pdfOutlineViewer = this.pdfOutlineViewer;
sidebarConfig.eventBus = eventBus;
this.pdfSidebar = new PDFSidebar(sidebarConfig, this.l10n);
this.pdfSidebar.onToggled = this.forceRendering.bind(this);
this.pdfSidebarResizer = new PDFSidebarResizer(appConfig.sidebarResizer,
eventBus, this.l10n);
},
run(config) {
@ -582,12 +576,12 @@ let PDFViewerApplication = {
* @returns {Promise} - Returns the promise, which is resolved when all
* destruction is completed.
*/
close() {
async close() {
let errorWrapper = this.appConfig.errorWrapper.container;
errorWrapper.setAttribute('hidden', 'true');
if (!this.pdfLoadingTask) {
return Promise.resolve();
return;
}
let promise = this.pdfLoadingTask.destroy();
@ -632,13 +626,10 @@ let PDFViewerApplication = {
* @returns {Promise} - Returns the promise, which is resolved when document
* is opened.
*/
open(file, args) {
async open(file, args) {
if (this.pdfLoadingTask) {
// We need to destroy already opened document.
return this.close().then(() => {
// ... and repeat the open() call.
return this.open(file, args);
});
await this.close();
}
// Set the necessary global worker parameters, using the available options.
const workerParameters = AppOptions.getAll('worker');
@ -951,10 +942,6 @@ let PDFViewerApplication = {
}
}
let initialParams = {
bookmark: null,
hash: null,
};
let storePromise = store.getMultiple({
page: null,
zoom: DEFAULT_SCALE_VALUE,
@ -966,8 +953,10 @@ let PDFViewerApplication = {
spreadMode: null,
}).catch(() => { /* Unable to read from storage; ignoring errors. */ });
Promise.all([storePromise, pageModePromise]).then(
([values = {}, pageMode]) => {
Promise.all([
storePromise, pageModePromise,
]).then(async ([values = {}, pageMode]) => {
const initialBookmark = this.initialBookmark;
// Initialize the default values, from user preferences.
const zoom = AppOptions.get('defaultZoomValue');
let hash = zoom ? `zoom=${zoom}` : null;
@ -990,52 +979,40 @@ let PDFViewerApplication = {
// Always let the user preference/history take precedence.
sidebarView = sidebarView || apiPageModeToSidebarView(pageMode);
}
return {
hash,
rotation,
sidebarView,
scrollMode,
spreadMode,
};
}).then(({ hash, rotation, sidebarView, scrollMode, spreadMode, }) => {
initialParams.bookmark = this.initialBookmark;
initialParams.hash = hash;
this.setInitialView(hash, {
rotation, sidebarView, scrollMode, spreadMode,
});
this.eventBus.dispatch('documentinit', { source: this, });
// Make all navigation keys work on document load,
// unless the viewer is embedded in a web page.
if (!this.isViewerEmbedded) {
pdfViewer.focus();
}
return Promise.race([
// For documents with different page sizes, once all pages are resolved,
// ensure that the correct location becomes visible on load.
// (To reduce the risk, in very large and/or slow loading documents,
// that the location changes *after* the user has started interacting
// with the viewer, wait for either `pagesPromise` or a timeout.)
await Promise.race([
pagesPromise,
new Promise((resolve) => {
setTimeout(resolve, FORCE_PAGES_LOADED_TIMEOUT);
}),
]);
}).then(() => {
// For documents with different page sizes, once all pages are resolved,
// ensure that the correct location becomes visible on load.
// To reduce the risk, in very large and/or slow loading documents,
// that the location changes *after* the user has started interacting
// with the viewer, wait for either `pagesPromise` or a timeout above.
if (!initialParams.bookmark && !initialParams.hash) {
if (!initialBookmark && !hash) {
return;
}
if (pdfViewer.hasEqualPageSizes) {
return;
}
this.initialBookmark = initialParams.bookmark;
this.initialBookmark = initialBookmark;
// eslint-disable-next-line no-self-assign
pdfViewer.currentScaleValue = pdfViewer.currentScaleValue;
this.setInitialView(initialParams.hash);
// Re-apply the initial document location.
this.setInitialView(hash);
}).then(function() {
// At this point, rendering of the initial page(s) should always have
// started (and may even have completed).
@ -1629,14 +1606,14 @@ function webViewerInitialized() {
PDFViewerApplication.pdfSidebar.toggle();
});
Promise.resolve().then(function() {
try {
webViewerOpenFileViaURL(file);
}).catch(function(reason) {
} catch (reason) {
PDFViewerApplication.l10n.get('loading_error', null,
'An error occurred while loading the PDF.').then((msg) => {
PDFViewerApplication.error(msg, reason);
});
});
}
}
let webViewerOpenFileViaURL;

View File

@ -300,7 +300,7 @@ function setReferer(url, callback) {
let storageArea = chrome.storage.sync || chrome.storage.local;
class ChromePreferences extends BasePreferences {
_writeToStorage(prefObj) {
async _writeToStorage(prefObj) {
return new Promise((resolve) => {
if (prefObj === this.defaults) {
let keysToRemove = Object.keys(this.defaults);
@ -317,7 +317,7 @@ class ChromePreferences extends BasePreferences {
});
}
_readFromStorage(prefObj) {
async _readFromStorage(prefObj) {
return new Promise((resolve) => {
let getPreferences = (defaultPrefs) => {
if (chrome.runtime.lastError) {

View File

@ -124,13 +124,13 @@ class DownloadManager {
}
class FirefoxPreferences extends BasePreferences {
_writeToStorage(prefObj) {
async _writeToStorage(prefObj) {
return new Promise(function(resolve) {
FirefoxCom.request('setPreferences', prefObj, resolve);
});
}
_readFromStorage(prefObj) {
async _readFromStorage(prefObj) {
return new Promise(function(resolve) {
FirefoxCom.request('getPreferences', prefObj, function(prefStr) {
let readPrefs = JSON.parse(prefStr);
@ -145,21 +145,20 @@ class MozL10n {
this.mozL10n = mozL10n;
}
getLanguage() {
return Promise.resolve(this.mozL10n.getLanguage());
async getLanguage() {
return this.mozL10n.getLanguage();
}
getDirection() {
return Promise.resolve(this.mozL10n.getDirection());
async getDirection() {
return this.mozL10n.getDirection();
}
get(property, args, fallback) {
return Promise.resolve(this.mozL10n.get(property, args, fallback));
async get(property, args, fallback) {
return this.mozL10n.get(property, args, fallback);
}
translate(element) {
async translate(element) {
this.mozL10n.translate(element);
return Promise.resolve();
}
}

View File

@ -26,18 +26,12 @@ if (typeof PDFJSDev !== 'undefined' && !PDFJSDev.test('GENERIC')) {
let GenericCom = {};
class GenericPreferences extends BasePreferences {
_writeToStorage(prefObj) {
return new Promise(function(resolve) {
localStorage.setItem('pdfjs.preferences', JSON.stringify(prefObj));
resolve();
});
async _writeToStorage(prefObj) {
localStorage.setItem('pdfjs.preferences', JSON.stringify(prefObj));
}
_readFromStorage(prefObj) {
return new Promise(function(resolve) {
let readPrefs = JSON.parse(localStorage.getItem('pdfjs.preferences'));
resolve(readPrefs);
});
async _readFromStorage(prefObj) {
return JSON.parse(localStorage.getItem('pdfjs.preferences'));
}
}

View File

@ -27,28 +27,24 @@ class GenericL10n {
});
}
getLanguage() {
return this._ready.then((l10n) => {
return l10n.getLanguage();
});
async getLanguage() {
const l10n = await this._ready;
return l10n.getLanguage();
}
getDirection() {
return this._ready.then((l10n) => {
return l10n.getDirection();
});
async getDirection() {
const l10n = await this._ready;
return l10n.getDirection();
}
get(property, args, fallback) {
return this._ready.then((l10n) => {
return l10n.get(property, args, fallback);
});
async get(property, args, fallback) {
const l10n = await this._ready;
return l10n.get(property, args, fallback);
}
translate(element) {
return this._ready.then((l10n) => {
return l10n.translate(element);
});
async translate(element) {
const l10n = await this._ready;
return l10n.translate(element);
}
}

View File

@ -163,12 +163,12 @@ class IL10n {
/**
* @returns {Promise<string>} - Resolves to the current locale.
*/
getLanguage() {}
async getLanguage() {}
/**
* @returns {Promise<string>} - Resolves to 'rtl' or 'ltr'.
*/
getDirection() {}
async getDirection() {}
/**
* Translates text identified by the key and adds/formats data using the args
@ -179,12 +179,12 @@ class IL10n {
* @param {string} fallback
* @returns {Promise<string>}
*/
get(key, args, fallback) { }
async get(key, args, fallback) { }
/**
* Translates HTML element.
* @param {HTMLElement} element
* @returns {Promise<void>}
*/
translate(element) { }
async translate(element) { }
}

View File

@ -37,22 +37,20 @@ class OverlayManager {
* @returns {Promise} A promise that is resolved when the overlay has been
* registered.
*/
register(name, element, callerCloseMethod = null, canForceClose = false) {
return new Promise((resolve) => {
let container;
if (!name || !element || !(container = element.parentNode)) {
throw new Error('Not enough parameters.');
} else if (this._overlays[name]) {
throw new Error('The overlay is already registered.');
}
this._overlays[name] = {
element,
container,
callerCloseMethod,
canForceClose,
};
resolve();
});
async register(name, element, callerCloseMethod = null,
canForceClose = false) {
let container;
if (!name || !element || !(container = element.parentNode)) {
throw new Error('Not enough parameters.');
} else if (this._overlays[name]) {
throw new Error('The overlay is already registered.');
}
this._overlays[name] = {
element,
container,
callerCloseMethod,
canForceClose,
};
}
/**
@ -60,16 +58,13 @@ class OverlayManager {
* @returns {Promise} A promise that is resolved when the overlay has been
* unregistered.
*/
unregister(name) {
return new Promise((resolve) => {
if (!this._overlays[name]) {
throw new Error('The overlay does not exist.');
} else if (this._active === name) {
throw new Error('The overlay cannot be removed while it is active.');
}
delete this._overlays[name];
resolve();
});
async unregister(name) {
if (!this._overlays[name]) {
throw new Error('The overlay does not exist.');
} else if (this._active === name) {
throw new Error('The overlay cannot be removed while it is active.');
}
delete this._overlays[name];
}
/**
@ -77,26 +72,23 @@ class OverlayManager {
* @returns {Promise} A promise that is resolved when the overlay has been
* opened.
*/
open(name) {
return new Promise((resolve) => {
if (!this._overlays[name]) {
throw new Error('The overlay does not exist.');
} else if (this._active) {
if (this._overlays[name].canForceClose) {
this._closeThroughCaller();
} else if (this._active === name) {
throw new Error('The overlay is already active.');
} else {
throw new Error('Another overlay is currently active.');
}
async open(name) {
if (!this._overlays[name]) {
throw new Error('The overlay does not exist.');
} else if (this._active) {
if (this._overlays[name].canForceClose) {
this._closeThroughCaller();
} else if (this._active === name) {
throw new Error('The overlay is already active.');
} else {
throw new Error('Another overlay is currently active.');
}
this._active = name;
this._overlays[this._active].element.classList.remove('hidden');
this._overlays[this._active].container.classList.remove('hidden');
}
this._active = name;
this._overlays[this._active].element.classList.remove('hidden');
this._overlays[this._active].container.classList.remove('hidden');
window.addEventListener('keydown', this._keyDownBound);
resolve();
});
window.addEventListener('keydown', this._keyDownBound);
}
/**
@ -104,22 +96,19 @@ class OverlayManager {
* @returns {Promise} A promise that is resolved when the overlay has been
* closed.
*/
close(name) {
return new Promise((resolve) => {
if (!this._overlays[name]) {
throw new Error('The overlay does not exist.');
} else if (!this._active) {
throw new Error('The overlay is currently not active.');
} else if (this._active !== name) {
throw new Error('Another overlay is currently active.');
}
this._overlays[this._active].container.classList.add('hidden');
this._overlays[this._active].element.classList.add('hidden');
this._active = null;
async close(name) {
if (!this._overlays[name]) {
throw new Error('The overlay does not exist.');
} else if (!this._active) {
throw new Error('The overlay is currently not active.');
} else if (this._active !== name) {
throw new Error('Another overlay is currently active.');
}
this._overlays[this._active].container.classList.add('hidden');
this._overlays[this._active].element.classList.add('hidden');
this._active = null;
window.removeEventListener('keydown', this._keyDownBound);
resolve();
});
window.removeEventListener('keydown', this._keyDownBound);
}
/**

View File

@ -83,8 +83,8 @@ class BasePreferences {
* @return {Promise} A promise that is resolved when the preference values
* have been written.
*/
_writeToStorage(prefObj) {
return Promise.reject(new Error('Not implemented: _writeToStorage'));
async _writeToStorage(prefObj) {
throw new Error('Not implemented: _writeToStorage');
}
/**
@ -93,8 +93,8 @@ class BasePreferences {
* @return {Promise} A promise that is resolved with an {Object} containing
* the preferences that have been read.
*/
_readFromStorage(prefObj) {
return Promise.reject(new Error('Not implemented: _readFromStorage'));
async _readFromStorage(prefObj) {
throw new Error('Not implemented: _readFromStorage');
}
/**
@ -102,11 +102,10 @@ class BasePreferences {
* @return {Promise} A promise that is resolved when the preference values
* have been reset.
*/
reset() {
return this._initializedPromise.then(() => {
this.prefs = Object.assign(Object.create(null), this.defaults);
return this._writeToStorage(this.defaults);
});
async reset() {
await this._initializedPromise;
this.prefs = Object.assign(Object.create(null), this.defaults);
return this._writeToStorage(this.defaults);
}
/**
@ -116,31 +115,32 @@ class BasePreferences {
* @return {Promise} A promise that is resolved when the value has been set,
* provided that the preference exists and the types match.
*/
set(name, value) {
return this._initializedPromise.then(() => {
if (this.defaults[name] === undefined) {
throw new Error(`Set preference: "${name}" is undefined.`);
} else if (value === undefined) {
throw new Error('Set preference: no value is specified.');
}
let valueType = typeof value;
let defaultType = typeof this.defaults[name];
async set(name, value) {
await this._initializedPromise;
let defaultValue = this.defaults[name];
if (valueType !== defaultType) {
if (valueType === 'number' && defaultType === 'string') {
value = value.toString();
} else {
throw new Error(`Set preference: "${value}" is a ${valueType}, ` +
`expected a ${defaultType}.`);
}
if (defaultValue === undefined) {
throw new Error(`Set preference: "${name}" is undefined.`);
} else if (value === undefined) {
throw new Error('Set preference: no value is specified.');
}
let valueType = typeof value;
let defaultType = typeof defaultValue;
if (valueType !== defaultType) {
if (valueType === 'number' && defaultType === 'string') {
value = value.toString();
} else {
if (valueType === 'number' && !Number.isInteger(value)) {
throw new Error(`Set preference: "${value}" must be an integer.`);
}
throw new Error(`Set preference: "${value}" is a ${valueType}, ` +
`expected a ${defaultType}.`);
}
this.prefs[name] = value;
return this._writeToStorage(this.prefs);
});
} else {
if (valueType === 'number' && !Number.isInteger(value)) {
throw new Error(`Set preference: "${value}" must be an integer.`);
}
}
this.prefs[name] = value;
return this._writeToStorage(this.prefs);
}
/**
@ -149,21 +149,20 @@ class BasePreferences {
* @return {Promise} A promise that is resolved with a {boolean|number|string}
* containing the value of the preference.
*/
get(name) {
return this._initializedPromise.then(() => {
let defaultValue = this.defaults[name];
async get(name) {
await this._initializedPromise;
let defaultValue = this.defaults[name];
if (defaultValue === undefined) {
throw new Error(`Get preference: "${name}" is undefined.`);
} else {
let prefValue = this.prefs[name];
if (defaultValue === undefined) {
throw new Error(`Get preference: "${name}" is undefined.`);
} else {
let prefValue = this.prefs[name];
if (prefValue !== undefined) {
return prefValue;
}
if (prefValue !== undefined) {
return prefValue;
}
return defaultValue;
});
}
return defaultValue;
}
/**
@ -171,10 +170,9 @@ class BasePreferences {
* @return {Promise} A promise that is resolved with an {Object} containing
* the values of all preferences.
*/
getAll() {
return this._initializedPromise.then(() => {
return Object.assign(Object.create(null), this.defaults, this.prefs);
});
async getAll() {
await this._initializedPromise;
return Object.assign(Object.create(null), this.defaults, this.prefs);
}
}

View File

@ -56,21 +56,19 @@ function formatL10nValue(text, args) {
* @implements {IL10n}
*/
let NullL10n = {
getLanguage() {
return Promise.resolve('en-us');
async getLanguage() {
return 'en-us';
},
getDirection() {
return Promise.resolve('ltr');
async getDirection() {
return 'ltr';
},
get(property, args, fallback) {
return Promise.resolve(formatL10nValue(fallback, args));
async get(property, args, fallback) {
return formatL10nValue(fallback, args);
},
translate(element) {
return Promise.resolve();
},
async translate(element) { },
};
/**

View File

@ -54,64 +54,54 @@ class ViewHistory {
});
}
_writeToStorage() {
return new Promise((resolve) => {
let databaseStr = JSON.stringify(this.database);
async _writeToStorage() {
let databaseStr = JSON.stringify(this.database);
if (typeof PDFJSDev !== 'undefined' &&
PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
sessionStorage.setItem('pdfjs.history', databaseStr);
} else {
localStorage.setItem('pdfjs.history', databaseStr);
}
resolve();
});
if (typeof PDFJSDev !== 'undefined' &&
PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
sessionStorage.setItem('pdfjs.history', databaseStr);
return;
}
localStorage.setItem('pdfjs.history', databaseStr);
}
_readFromStorage() {
return new Promise(function(resolve) {
if (typeof PDFJSDev !== 'undefined' &&
PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
resolve(sessionStorage.getItem('pdfjs.history'));
} else {
resolve(localStorage.getItem('pdfjs.history'));
}
});
async _readFromStorage() {
if (typeof PDFJSDev !== 'undefined' &&
PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
return sessionStorage.getItem('pdfjs.history');
}
return localStorage.getItem('pdfjs.history');
}
set(name, val) {
return this._initializedPromise.then(() => {
this.file[name] = val;
return this._writeToStorage();
});
async set(name, val) {
await this._initializedPromise;
this.file[name] = val;
return this._writeToStorage();
}
setMultiple(properties) {
return this._initializedPromise.then(() => {
for (let name in properties) {
this.file[name] = properties[name];
}
return this._writeToStorage();
});
async setMultiple(properties) {
await this._initializedPromise;
for (let name in properties) {
this.file[name] = properties[name];
}
return this._writeToStorage();
}
get(name, defaultValue) {
return this._initializedPromise.then(() => {
async get(name, defaultValue) {
await this._initializedPromise;
let val = this.file[name];
return val !== undefined ? val : defaultValue;
}
async getMultiple(properties) {
await this._initializedPromise;
let values = Object.create(null);
for (let name in properties) {
let val = this.file[name];
return val !== undefined ? val : defaultValue;
});
}
getMultiple(properties) {
return this._initializedPromise.then(() => {
let values = Object.create(null);
for (let name in properties) {
let val = this.file[name];
values[name] = val !== undefined ? val : properties[name];
}
return values;
});
values[name] = val !== undefined ? val : properties[name];
}
return values;
}
}