A couple of SignaturePropertiesManager improvements (PR 21247 follow-up)

- Replace the `loadFromDocument` and `reset` methods with a single `setDocument` method, since that's consistent with many other viewer components.

 - Replace the internal `#loadToken` field with simple `pdfDocument` checks, when checking if the document is still current, which again is consistent with (all) other viewer components.

 - Remove a couple of comments, which didn't add a lot of value and sounded a whole lot like "AI speak".
This commit is contained in:
Jonas Jenwald 2026-07-02 14:00:44 +02:00
parent 43c29379de
commit fa207b4ce8
2 changed files with 23 additions and 39 deletions

View File

@ -1207,7 +1207,7 @@ const PDFViewerApplication = {
this.pdfViewer.setDocument(null); this.pdfViewer.setDocument(null);
this.pdfLinkService.setDocument(null); this.pdfLinkService.setDocument(null);
this.pdfDocumentProperties?.setDocument(null); this.pdfDocumentProperties?.setDocument(null);
this.signaturePropertiesManager?.reset(); this.signaturePropertiesManager?.setDocument(null);
} }
this.pdfLinkService.externalLinkEnabled = true; this.pdfLinkService.externalLinkEnabled = true;
this.store = null; this.store = null;
@ -1905,7 +1905,7 @@ const PDFViewerApplication = {
verifier, verifier,
eventBus: this.eventBus, eventBus: this.eventBus,
}); });
this.signaturePropertiesManager.loadFromDocument(pdfDocument); this.signaturePropertiesManager.setDocument(pdfDocument);
return true; return true;
}, },

View File

@ -87,8 +87,7 @@ function bannerStateForResults(results) {
let worst = "verified"; let worst = "verified";
for (const r of results) { for (const r of results) {
if ( if (
r && r?.status &&
r.status &&
STATUS_INFO[r.status].priority > STATUS_INFO[worst].priority STATUS_INFO[r.status].priority > STATUS_INFO[worst].priority
) { ) {
worst = r.status; worst = r.status;
@ -193,15 +192,6 @@ class SignaturePropertiesManager {
// is updated via #updateButtonState(). // is updated via #updateButtonState().
#needsRender = false; #needsRender = false;
// Identifies the current `loadFromDocument` call. Each load rotates the
// token; in-flight `#verify()` promises capture the value at start and
// bail on resolve if the manager has since switched to another document.
// Prevents a stale verification for doc A from writing into doc B's
// results map after a fast doc-switch.
#loadToken = null;
// Held only to ferry per-signature byte payloads from the worker into
// `#verify`. Cleared in `reset()` so we don't pin a closed document.
#pdfDocument = null; #pdfDocument = null;
constructor({ appConfig, verifier, eventBus }) { constructor({ appConfig, verifier, eventBus }) {
@ -258,10 +248,21 @@ class SignaturePropertiesManager {
); );
} }
async loadFromDocument(pdfDocument) { async setDocument(pdfDocument) {
const token = Symbol("sig-load"); if (this.#pdfDocument) {
this.#loadToken = token; this.#signatures = [];
this.#results.clear();
this.#pendingVerify.clear();
this.#needsRender = false;
this.#hideButton();
this.#close();
this.#updateButtonState();
}
this.#pdfDocument = pdfDocument; this.#pdfDocument = pdfDocument;
if (!pdfDocument) {
return;
}
this.#signatures = []; this.#signatures = [];
this.#results.clear(); this.#results.clear();
this.#pendingVerify.clear(); this.#pendingVerify.clear();
@ -275,8 +276,7 @@ class SignaturePropertiesManager {
console.warn("getSignatures failed:", ex); console.warn("getSignatures failed:", ex);
signatures = []; signatures = [];
} }
if (this.#loadToken !== token) { if (pdfDocument !== this.#pdfDocument) {
// A newer document load (or reset) raced ahead — drop this result.
return; return;
} }
this.#signatures = signatures || []; this.#signatures = signatures || [];
@ -305,26 +305,10 @@ class SignaturePropertiesManager {
// Kick off verification automatically — the toolbar button reflects the // Kick off verification automatically — the toolbar button reflects the
// aggregate state and updates as each signature resolves. // aggregate state and updates as each signature resolves.
for (const sig of this.#signatures) { for (const sig of this.#signatures) {
this.#verify(sig, token); this.#verify(sig, pdfDocument);
} }
} }
reset() {
// Rotate the token so any in-flight verify from the previous document
// sees a mismatch and bails before mutating state.
this.#loadToken = null;
this.#pdfDocument = null;
this.#signatures = [];
this.#results.clear();
this.#pendingVerify.clear();
this.#needsRender = false;
this.#hideButton();
this.#close();
this.#updateButtonState();
}
// --- internal ---
#showButton() { #showButton() {
const root = this.#appConfig.signaturePropertiesButton.parentElement; const root = this.#appConfig.signaturePropertiesButton.parentElement;
if (root) { if (root) {
@ -635,7 +619,7 @@ class SignaturePropertiesManager {
return total; return total;
} }
async #verify(signature, loadToken) { async #verify(signature, pdfDocument) {
if (!this.#verifier || this.#pendingVerify.has(signature.id)) { if (!this.#verifier || this.#pendingVerify.has(signature.id)) {
return; return;
} }
@ -648,8 +632,8 @@ class SignaturePropertiesManager {
// lazily, one signature at a time, so the bytes never sit in main // lazily, one signature at a time, so the bytes never sit in main
// thread memory for the document's lifetime. `bytes` goes out of // thread memory for the document's lifetime. `bytes` goes out of
// scope as soon as the verifier returns. // scope as soon as the verifier returns.
const bytes = await this.#pdfDocument?.getSignatureData(signature.id); const bytes = await pdfDocument.getSignatureData(signature.id);
if (this.#loadToken !== loadToken) { if (pdfDocument !== this.#pdfDocument) {
return; return;
} }
if (!bytes) { if (!bytes) {
@ -667,7 +651,7 @@ class SignaturePropertiesManager {
}; };
} }
this.#pendingVerify.delete(signature.id); this.#pendingVerify.delete(signature.id);
if (this.#loadToken !== loadToken) { if (pdfDocument !== this.#pdfDocument) {
// The user switched documents while this verify was in flight; the // The user switched documents while this verify was in flight; the
// result belongs to a defunct load and would corrupt the new doc. // result belongs to a defunct load and would corrupt the new doc.
return; return;