From 71376f089c10bc4695bfe00b28ebf274ef80619d Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Mon, 25 Sep 2023 14:57:34 +0200 Subject: [PATCH] [Editor] Remove the class fooEditing from the layer when destroying it and simplify the way to handle the different types of editors. --- src/display/editor/annotation_editor_layer.js | 62 +++++++++---------- src/display/editor/editor.js | 10 +-- src/display/editor/freetext.js | 9 ++- src/display/editor/ink.js | 2 + src/display/editor/stamp.js | 2 + web/annotation_editor_layer_builder.css | 2 +- 6 files changed, 47 insertions(+), 40 deletions(-) diff --git a/src/display/editor/annotation_editor_layer.js b/src/display/editor/annotation_editor_layer.js index ca9bf08a6..ef2cb1ecd 100644 --- a/src/display/editor/annotation_editor_layer.js +++ b/src/display/editor/annotation_editor_layer.js @@ -73,6 +73,13 @@ class AnnotationEditorLayer { static _initialized = false; + static #editorTypes = new Map( + [FreeTextEditor, InkEditor, StampEditor].map(type => [ + type._editorType, + type, + ]) + ); + /** * @param {AnnotationEditorLayerOptions} options */ @@ -85,7 +92,7 @@ class AnnotationEditorLayer { viewport, l10n, }) { - const editorTypes = [FreeTextEditor, InkEditor, StampEditor]; + const editorTypes = [...AnnotationEditorLayer.#editorTypes.values()]; if (!AnnotationEditorLayer._initialized) { AnnotationEditorLayer._initialized = true; for (const editorType of editorTypes) { @@ -131,18 +138,13 @@ class AnnotationEditorLayer { } if (mode !== AnnotationEditorType.NONE) { - this.div.classList.toggle( - "freeTextEditing", - mode === AnnotationEditorType.FREETEXT - ); - this.div.classList.toggle( - "inkEditing", - mode === AnnotationEditorType.INK - ); - this.div.classList.toggle( - "stampEditing", - mode === AnnotationEditorType.STAMP - ); + const { classList } = this.div; + for (const editorType of AnnotationEditorLayer.#editorTypes.values()) { + classList.toggle( + `${editorType._type}Editing`, + mode === editorType._editorType + ); + } this.div.hidden = false; } } @@ -262,6 +264,11 @@ class AnnotationEditorLayer { if (this.isEmpty) { this.div.hidden = true; } + const { classList } = this.div; + for (const editorType of AnnotationEditorLayer.#editorTypes.values()) { + classList.remove(`${editorType._type}Editing`); + } + this.#isDisabling = false; } @@ -458,15 +465,10 @@ class AnnotationEditorLayer { * @returns {AnnotationEditor} */ #createNewEditor(params) { - switch (this.#uiManager.getMode()) { - case AnnotationEditorType.FREETEXT: - return new FreeTextEditor(params); - case AnnotationEditorType.INK: - return new InkEditor(params); - case AnnotationEditorType.STAMP: - return new StampEditor(params); - } - return null; + const editorType = AnnotationEditorLayer.#editorTypes.get( + this.#uiManager.getMode() + ); + return editorType ? new editorType.prototype.constructor(params) : null; } /** @@ -497,18 +499,14 @@ class AnnotationEditorLayer { /** * Create a new editor * @param {Object} data - * @returns {AnnotationEditor} + * @returns {AnnotationEditor | null} */ deserialize(data) { - switch (data.annotationType ?? data.annotationEditorType) { - case AnnotationEditorType.FREETEXT: - return FreeTextEditor.deserialize(data, this, this.#uiManager); - case AnnotationEditorType.INK: - return InkEditor.deserialize(data, this, this.#uiManager); - case AnnotationEditorType.STAMP: - return StampEditor.deserialize(data, this, this.#uiManager); - } - return null; + return ( + AnnotationEditorLayer.#editorTypes + .get(data.annotationType ?? data.annotationEditorType) + ?.deserialize(data, this, this.#uiManager) || null + ); } /** diff --git a/src/display/editor/editor.js b/src/display/editor/editor.js index 2de0aea40..1df51c131 100644 --- a/src/display/editor/editor.js +++ b/src/display/editor/editor.js @@ -941,7 +941,7 @@ class AnnotationEditor { /** * Render this editor in a div. - * @returns {HTMLDivElement} + * @returns {HTMLDivElement | null} */ render() { this.div = document.createElement("div"); @@ -1192,8 +1192,9 @@ class AnnotationEditor { * new annotation to add to the pdf document. * * To implement in subclasses. - * @param {boolean} isForCopying - * @param {Object} [context] + * @param {boolean} [isForCopying] + * @param {Object | null} [context] + * @returns {Object | null} */ serialize(isForCopying = false, context = null) { unreachable("An editor must be serializable"); @@ -1206,7 +1207,7 @@ class AnnotationEditor { * @param {Object} data * @param {AnnotationEditorLayer} parent * @param {AnnotationEditorUIManager} uiManager - * @returns {AnnotationEditor} + * @returns {AnnotationEditor | null} */ static deserialize(data, parent, uiManager) { const editor = new this.prototype.constructor({ @@ -1327,6 +1328,7 @@ class AnnotationEditor { /** * Get the div which really contains the displayed content. + * @returns {HTMLDivElement | undefined} */ get contentDiv() { return this.div; diff --git a/src/display/editor/freetext.js b/src/display/editor/freetext.js index efad76948..c4cb10ae5 100644 --- a/src/display/editor/freetext.js +++ b/src/display/editor/freetext.js @@ -132,6 +132,8 @@ class FreeTextEditor extends AnnotationEditor { static _type = "freetext"; + static _editorType = AnnotationEditorType.FREETEXT; + constructor(params) { super({ ...params, name: "freeTextEditor" }); this.#color = @@ -335,7 +337,7 @@ class FreeTextEditor extends AnnotationEditor { // In case the blur callback hasn't been called. this.isEditing = false; - this.parent.div.classList.add("freeTextEditing"); + this.parent.div.classList.add("freetextEditing"); } /** @inheritdoc */ @@ -374,7 +376,7 @@ class FreeTextEditor extends AnnotationEditor { this.isEditing = false; if (this.parent) { this.parent.setEditingState(true); - this.parent.div.classList.add("freeTextEditing"); + this.parent.div.classList.add("freetextEditing"); } super.remove(); } @@ -508,7 +510,7 @@ class FreeTextEditor extends AnnotationEditor { } editorDivInput(event) { - this.parent.div.classList.toggle("freeTextEditing", this.isEmpty()); + this.parent.div.classList.toggle("freetextEditing", this.isEmpty()); } /** @inheritdoc */ @@ -649,6 +651,7 @@ class FreeTextEditor extends AnnotationEditor { } } + /** @inheritdoc */ get contentDiv() { return this.editorDiv; } diff --git a/src/display/editor/ink.js b/src/display/editor/ink.js index c475c6659..9194a9564 100644 --- a/src/display/editor/ink.js +++ b/src/display/editor/ink.js @@ -63,6 +63,8 @@ class InkEditor extends AnnotationEditor { static _type = "ink"; + static _editorType = AnnotationEditorType.INK; + constructor(params) { super({ ...params, name: "inkEditor" }); this.color = params.color || null; diff --git a/src/display/editor/stamp.js b/src/display/editor/stamp.js index 54835317f..94f15136d 100644 --- a/src/display/editor/stamp.js +++ b/src/display/editor/stamp.js @@ -44,6 +44,8 @@ class StampEditor extends AnnotationEditor { static _type = "stamp"; + static _editorType = AnnotationEditorType.STAMP; + constructor(params) { super({ ...params, name: "stampEditor" }); this.#bitmapUrl = params.bitmapUrl; diff --git a/web/annotation_editor_layer_builder.css b/web/annotation_editor_layer_builder.css index 73d313402..a17183370 100644 --- a/web/annotation_editor_layer_builder.css +++ b/web/annotation_editor_layer_builder.css @@ -121,7 +121,7 @@ height: 100%; } -.annotationEditorLayer.freeTextEditing { +.annotationEditorLayer.freetextEditing { cursor: var(--editorFreeText-editing-cursor); }