mirror of
https://github.com/zen-browser/pdf.js.git
synced 2025-07-10 02:05:37 +02:00
[api-minor] Move the viewer scripting initialization/handling into a new PDFScriptingManager
class
The *main* purpose of this patch is to allow scripting to be used together with the viewer components, note the updated "simpleviewer"/"singlepageviewer" examples, in addition to the full default viewer. Given how the scripting functionality is currently implemented in the default viewer, trying to re-use this with the standalone viewer components would be *very* hard and ideally you'd want it to work out-of-the-box. For an initial implementation, in the default viewer, of the scripting functionality it probably made sense to simply dump all of the code in the `app.js` file, however that cannot be used with the viewer components. To address this, the functionality is moved into a new `PDFScriptingManager` class which can thus be handled in the same way as all other viewer components (and e.g. be passed to the `BaseViewer`-implementations). Obviously the scripting functionality needs quite a lot of data, during its initialization, and for the default viewer we want to maintain the current way of doing the lookups since that helps avoid a number of redundant API-calls. To that end, the `PDFScriptingManager` implementation accepts (optional) factories/functions such that we can maintain the current behaviour for the default viewer. For the viewer components specifically, fallback code-paths are provided to ensure that scripting will "just work"[1]. Besides moving the viewer handling of the scripting code to its own file/class, this patch also takes the opportunity to re-factor the functionality into a number of helper methods to improve overall readability[2]. Note that it's definitely possible that the `PDFScriptingManager` class could be improved even further (e.g. for general re-use), since it's still heavily tailored to the default viewer use-case, however I believe that this patch is still a good step forward overall. --- [1] Obviously *all* the relevant document properties might not be available in the viewer components use-case (e.g. the various URLs), but most things should work just fine. [2] The old `PDFViewerApplication._initializeJavaScript` method, where everything was simply inlined, have over time (in my opinion) become quite large and somewhat difficult to *easily* reason about.
This commit is contained in:
parent
5b9638329c
commit
a6d1cba38c
8 changed files with 525 additions and 261 deletions
|
@ -55,6 +55,8 @@ const DEFAULT_CACHE_SIZE = 10;
|
|||
* component.
|
||||
* @property {PDFFindController} [findController] - The find controller
|
||||
* component.
|
||||
* @property {PDFScriptingManager} [scriptingManager] - The scripting manager
|
||||
* component.
|
||||
* @property {PDFRenderingQueue} [renderingQueue] - The rendering queue object.
|
||||
* @property {boolean} [removePageBorders] - Removes the border shadow around
|
||||
* the pages. The default value is `false`.
|
||||
|
@ -77,10 +79,8 @@ const DEFAULT_CACHE_SIZE = 10;
|
|||
* total pixels, i.e. width * height. Use -1 for no limit. The default value
|
||||
* is 4096 * 4096 (16 mega-pixels).
|
||||
* @property {IL10n} l10n - Localization service.
|
||||
* @property {boolean} [enableScripting] - Enable embedded script execution.
|
||||
* The default value is `false`.
|
||||
* @property {Object} [mouseState] - The mouse button state. The default value
|
||||
* is `null`.
|
||||
* @property {boolean} [enableScripting] - Enable embedded script execution
|
||||
* (also requires {scriptingManager} being set). The default value is `false`.
|
||||
*/
|
||||
|
||||
function PDFPageViewBuffer(size) {
|
||||
|
@ -183,6 +183,7 @@ class BaseViewer {
|
|||
this.linkService = options.linkService || new SimpleLinkService();
|
||||
this.downloadManager = options.downloadManager || null;
|
||||
this.findController = options.findController || null;
|
||||
this._scriptingManager = options.scriptingManager || null;
|
||||
this.removePageBorders = options.removePageBorders || false;
|
||||
this.textLayerMode = Number.isInteger(options.textLayerMode)
|
||||
? options.textLayerMode
|
||||
|
@ -195,8 +196,8 @@ class BaseViewer {
|
|||
this.useOnlyCssZoom = options.useOnlyCssZoom || false;
|
||||
this.maxCanvasPixels = options.maxCanvasPixels;
|
||||
this.l10n = options.l10n || NullL10n;
|
||||
this.enableScripting = options.enableScripting || false;
|
||||
this._mouseState = options.mouseState || null;
|
||||
this.enableScripting =
|
||||
options.enableScripting === true && !!this._scriptingManager;
|
||||
|
||||
this.defaultRenderingQueue = !options.renderingQueue;
|
||||
if (this.defaultRenderingQueue) {
|
||||
|
@ -468,6 +469,12 @@ class BaseViewer {
|
|||
if (this.findController) {
|
||||
this.findController.setDocument(null);
|
||||
}
|
||||
if (this._scriptingManager) {
|
||||
// Defer this slightly, to allow the "pageclose" event to be handled.
|
||||
Promise.resolve().then(() => {
|
||||
this._scriptingManager.setDocument(null);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.pdfDocument = pdfDocument;
|
||||
|
@ -562,6 +569,9 @@ class BaseViewer {
|
|||
if (this.findController) {
|
||||
this.findController.setDocument(pdfDocument); // Enable searching.
|
||||
}
|
||||
if (this.enableScripting) {
|
||||
this._scriptingManager.setDocument(pdfDocument);
|
||||
}
|
||||
|
||||
// In addition to 'disableAutoFetch' being set, also attempt to reduce
|
||||
// resource usage when loading *very* long/large documents.
|
||||
|
@ -1299,7 +1309,7 @@ class BaseViewer {
|
|||
enableScripting,
|
||||
hasJSActionsPromise:
|
||||
hasJSActionsPromise || this.pdfDocument?.hasJSActions(),
|
||||
mouseState: mouseState || this._mouseState,
|
||||
mouseState: mouseState || this._scriptingManager?.mouseState,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1645,7 +1655,7 @@ class BaseViewer {
|
|||
}
|
||||
const eventBus = this.eventBus,
|
||||
pageOpenPendingSet = (this._pageOpenPendingSet = new Set()),
|
||||
scriptingEvents = (this._scriptingEvents ||= Object.create(null));
|
||||
scriptingEvents = (this._scriptingEvents = Object.create(null));
|
||||
|
||||
const dispatchPageClose = pageNumber => {
|
||||
if (pageOpenPendingSet.has(pageNumber)) {
|
||||
|
@ -1709,15 +1719,11 @@ class BaseViewer {
|
|||
|
||||
// Remove the event listeners.
|
||||
eventBus._off("pagechanging", scriptingEvents.onPageChanging);
|
||||
scriptingEvents.onPageChanging = null;
|
||||
|
||||
eventBus._off("pagerendered", scriptingEvents.onPageRendered);
|
||||
scriptingEvents.onPageRendered = null;
|
||||
|
||||
eventBus._off("pagesdestroy", scriptingEvents.onPagesDestroy);
|
||||
scriptingEvents.onPagesDestroy = null;
|
||||
|
||||
this._pageOpenPendingSet = null;
|
||||
this._scriptingEvents = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue