Actually remove a scripting-instance, and its global events, upon document closing

I was actually quite surprised to find that, despite the various `scripting`-getters implementing `destroySandbox` methods, there were no attempts at actually cleaning-up either the "sandbox" or removing the globally registered event listeners.
This commit is contained in:
Jonas Jenwald 2020-12-06 13:57:24 +01:00
parent f4d8a427f0
commit 1e007f9285

View File

@ -257,6 +257,7 @@ const PDFViewerApplication = {
_saveInProgress: false, _saveInProgress: false,
_wheelUnusedTicks: 0, _wheelUnusedTicks: 0,
_idleCallbacks: new Set(), _idleCallbacks: new Set(),
_scriptingInstance: null,
// Called once when the document is loaded. // Called once when the document is loaded.
async initialize(appConfig) { async initialize(appConfig) {
@ -803,6 +804,18 @@ const PDFViewerApplication = {
} }
this._idleCallbacks.clear(); this._idleCallbacks.clear();
if (this._scriptingInstance) {
const { scripting, events } = this._scriptingInstance;
try {
scripting.destroySandbox();
} catch (ex) {}
for (const [name, listener] of events) {
window.removeEventListener(name, listener);
}
this._scriptingInstance = null;
}
this.pdfSidebar.reset(); this.pdfSidebar.reset();
this.pdfOutlineViewer.reset(); this.pdfOutlineViewer.reset();
this.pdfAttachmentViewer.reset(); this.pdfAttachmentViewer.reset();
@ -1423,6 +1436,9 @@ const PDFViewerApplication = {
return; return;
} }
const { scripting } = this.externalServices; const { scripting } = this.externalServices;
// Store a reference to the current scripting-instance, to allow destruction
// of the sandbox and removal of the event listeners at document closing.
this._scriptingInstance = { scripting, events: new Map() };
if (!this.documentInfo) { if (!this.documentInfo) {
// It should be *extremely* rare for metadata to not have been resolved // It should be *extremely* rare for metadata to not have been resolved
@ -1439,7 +1455,7 @@ const PDFViewerApplication = {
} }
} }
window.addEventListener("updateFromSandbox", event => { const updateFromSandbox = event => {
const { detail } = event; const { detail } = event;
const { id, command, value } = detail; const { id, command, value } = detail;
if (!id) { if (!id) {
@ -1486,11 +1502,20 @@ const PDFViewerApplication = {
pdfDocument.annotationStorage.setValue(id, value); pdfDocument.annotationStorage.setValue(id, value);
} }
} }
}); };
window.addEventListener("updateFromSandbox", updateFromSandbox);
// Ensure that the event listener can be removed at document closing.
this._scriptingInstance.events.set("updateFromSandbox", updateFromSandbox);
window.addEventListener("dispatchEventInSandbox", function (event) { const dispatchEventInSandbox = event => {
scripting.dispatchEventInSandbox(event.detail); scripting.dispatchEventInSandbox(event.detail);
}); };
window.addEventListener("dispatchEventInSandbox", dispatchEventInSandbox);
// Ensure that the event listener can be removed at document closing.
this._scriptingInstance.events.set(
"dispatchEventInSandbox",
dispatchEventInSandbox
);
const dispatchEventName = generateRandomStringForSandbox(objects); const dispatchEventName = generateRandomStringForSandbox(objects);