[api-minor][editor] Indicate, in the title, if the document has been edited (bug 1785854)

Note that this patch prepends the document title with "* ", rather than only "*" as suggested in the bug, since there's nothing that says that a PDF document cannot specify a title[1] beginning with an asterisk. To reduce possible confusion, having a space between the "editing marker" and the actual document title thus cannot hurt as far as I'm concerned.

In order to notify the viewer when all `AnnotationEditor`s have been removed, we utilize the existing `onAnnotationEditor`-callback to allow the document title to be updated as necessary.

Finally, this patch makes the following (slightly unrelated) changes:
 - Rename the `AnnotationStorage.removeKey` method to just `AnnotationStorage.remove` instead. This is consistent with e.g. the `has`-method and should suffice to explain what it does.
 - Remove the `AnnotationStorage.hasAnnotationEditors` getter, since the viewer now tracks the necessary state internally. This avoids unnecessarily having to iterate through the `AnnotationStorage`-instance when saving/printing the document.

---
[1] Using either an /Info dictionary or a /Metadata stream.
This commit is contained in:
Jonas Jenwald 2022-08-26 00:03:19 +02:00
parent 76f665d57f
commit 151dfc9a25
3 changed files with 33 additions and 26 deletions

View File

@ -68,12 +68,21 @@ class AnnotationStorage {
* Remove a value from the storage.
* @param {string} key
*/
removeKey(key) {
remove(key) {
this._storage.delete(key);
if (this._storage.size === 0) {
this.resetModified();
}
if (typeof this.onAnnotationEditor === "function") {
for (const value of this._storage.values()) {
if (value instanceof AnnotationEditor) {
return;
}
}
this.onAnnotationEditor(null);
}
}
/**
@ -172,15 +181,6 @@ class AnnotationStorage {
return clone;
}
get hasAnnotationEditors() {
for (const value of this._storage.values()) {
if (value instanceof AnnotationEditor) {
return true;
}
}
return false;
}
/**
* PLEASE NOTE: Only intended for usage within the API itself.
* @ignore

View File

@ -207,7 +207,7 @@ class AnnotationEditorLayer {
this.#uiManager.removeEditor(editor);
this.detach(editor);
this.annotationStorage.removeKey(editor.id);
this.annotationStorage.remove(editor.id);
editor.div.style.display = "none";
setTimeout(() => {
// When the div is removed from DOM the focus can move on the

View File

@ -262,6 +262,8 @@ const PDFViewerApplication = {
_wheelUnusedTicks: 0,
_idleCallbacks: new Set(),
_PDFBug: null,
_hasAnnotationEditors: false,
_title: document.title,
_printAnnotationStoragePromise: null,
// Called once when the document is loaded.
@ -788,12 +790,14 @@ const PDFViewerApplication = {
this.setTitle(title);
},
setTitle(title) {
setTitle(title = this._title) {
this._title = title;
if (this.isViewerEmbedded) {
// Embedded PDF viewers should not be changing their parent page's title.
return;
}
document.title = title;
document.title = `${this._hasAnnotationEditors ? "* " : ""}${title}`;
},
get _docFilename() {
@ -880,10 +884,12 @@ const PDFViewerApplication = {
this._contentLength = null;
this._saveInProgress = false;
this._docStats = null;
this._hasAnnotationEditors = false;
this._cancelIdleCallbacks();
promises.push(this.pdfScriptingManager.destroyPromise);
this.setTitle();
this.pdfSidebar.reset();
this.pdfOutlineViewer.reset();
this.pdfAttachmentViewer.reset();
@ -1045,12 +1051,10 @@ const PDFViewerApplication = {
this._saveInProgress = false;
}
if (this.pdfDocument?.annotationStorage.hasAnnotationEditors) {
if (this._hasAnnotationEditors) {
this.externalServices.reportTelemetry({
type: "editing",
data: {
type: "save",
},
data: { type: "save" },
});
}
},
@ -1582,7 +1586,7 @@ const PDFViewerApplication = {
}
if (pdfTitle) {
this.setTitle(
`${pdfTitle} - ${this._contentDispositionFilename || document.title}`
`${pdfTitle} - ${this._contentDispositionFilename || this._title}`
);
} else if (this._contentDispositionFilename) {
this.setTitle(this._contentDispositionFilename);
@ -1744,10 +1748,15 @@ const PDFViewerApplication = {
}
};
annotationStorage.onAnnotationEditor = typeStr => {
this.externalServices.reportTelemetry({
type: "editing",
data: { type: typeStr },
});
this._hasAnnotationEditors = !!typeStr;
this.setTitle();
if (typeStr) {
this.externalServices.reportTelemetry({
type: "editing",
data: { type: typeStr },
});
}
};
},
@ -1888,12 +1897,10 @@ const PDFViewerApplication = {
type: "print",
});
if (this.pdfDocument?.annotationStorage.hasAnnotationEditors) {
if (this._hasAnnotationEditors) {
this.externalServices.reportTelemetry({
type: "editing",
data: {
type: "print",
},
data: { type: "print" },
});
}
},