diff --git a/src/display/editor/annotation_editor_layer.js b/src/display/editor/annotation_editor_layer.js index 5205c82a2..9c459628f 100644 --- a/src/display/editor/annotation_editor_layer.js +++ b/src/display/editor/annotation_editor_layer.js @@ -43,9 +43,9 @@ import { InkEditor } from "./ink.js"; class AnnotationEditorLayer { #allowClick = false; - #boundClick; + #boundPointerup = this.pointerup.bind(this); - #boundMousedown; + #boundPointerdown = this.pointerdown.bind(this); #editors = new Map(); @@ -76,8 +76,6 @@ class AnnotationEditorLayer { this.annotationStorage = options.annotationStorage; this.pageIndex = options.pageIndex; this.div = options.div; - this.#boundClick = this.click.bind(this); - this.#boundMousedown = this.mousedown.bind(this); this.#uiManager.addLayer(this); } @@ -213,13 +211,13 @@ class AnnotationEditorLayer { } enableClick() { - this.div.addEventListener("mousedown", this.#boundMousedown); - this.div.addEventListener("click", this.#boundClick); + this.div.addEventListener("pointerdown", this.#boundPointerdown); + this.div.addEventListener("pointerup", this.#boundPointerup); } disableClick() { - this.div.removeEventListener("mousedown", this.#boundMousedown); - this.div.removeEventListener("click", this.#boundClick); + this.div.removeEventListener("pointerdown", this.#boundPointerdown); + this.div.removeEventListener("pointerup", this.#boundPointerup); } attach(editor) { @@ -524,7 +522,7 @@ class AnnotationEditorLayer { /** * Create and add a new editor. - * @param {MouseEvent} event + * @param {PointerEvent} event * @returns {AnnotationEditor} */ #createAndAddNewEditor(event) { @@ -579,10 +577,10 @@ class AnnotationEditorLayer { } /** - * Mouseclick callback. - * @param {MouseEvent} event + * Pointerup callback. + * @param {PointerEvent} event */ - click(event) { + pointerup(event) { if (event.target !== this.div) { return; } @@ -596,10 +594,10 @@ class AnnotationEditorLayer { } /** - * Mousedown callback. - * @param {MouseEvent} event + * Pointerdown callback. + * @param {PointerEvent} event */ - mousedown(event) { + pointerdown(event) { if (event.target !== this.div) { return; } diff --git a/src/display/editor/editor.js b/src/display/editor/editor.js index aaa33f9e4..b60ef5826 100644 --- a/src/display/editor/editor.js +++ b/src/display/editor/editor.js @@ -251,7 +251,7 @@ class AnnotationEditor { this.div.setAttribute("data-editor-rotation", (360 - this.rotation) % 360); this.div.className = this.name; this.div.setAttribute("id", this.id); - this.div.tabIndex = 0; + this.div.setAttribute("tabIndex", 0); this.setInForeground(); @@ -261,16 +261,16 @@ class AnnotationEditor { const [tx, ty] = this.getInitialTranslation(); this.translate(tx, ty); - bindEvents(this, this.div, ["dragstart", "mousedown", "mouseup"]); + bindEvents(this, this.div, ["dragstart", "pointerdown", "pointerup"]); return this.div; } /** - * Onmousedown callback. - * @param {MouseEvent} event + * Onpointerdown callback. + * @param {PointerEvent} event */ - mousedown(event) { + pointerdown(event) { if (event.button !== 0) { // Avoid to focus this editor because of a non-left click. event.preventDefault(); @@ -284,9 +284,9 @@ class AnnotationEditor { /** * Onmouseup callback. - * @param {MouseEvent} event + * @param {PointerEvent} event */ - mouseup(event) { + pointerup(event) { if (this.#wasFocused) { this.#select(); } diff --git a/src/display/editor/freetext.js b/src/display/editor/freetext.js index ddd1f944f..307f61e2a 100644 --- a/src/display/editor/freetext.js +++ b/src/display/editor/freetext.js @@ -223,7 +223,6 @@ class FreeTextEditor extends AnnotationEditor { this.overlayDiv.classList.remove("enabled"); this.editorDiv.contentEditable = true; this.div.draggable = false; - this.div.removeAttribute("tabIndex"); this.editorDiv.addEventListener("keydown", this.#boundEditorDivKeydown); this.editorDiv.addEventListener("focus", this.#boundEditorDivFocus); this.editorDiv.addEventListener("blur", this.#boundEditorDivBlur); @@ -236,17 +235,27 @@ class FreeTextEditor extends AnnotationEditor { this.overlayDiv.classList.add("enabled"); this.editorDiv.contentEditable = false; this.div.draggable = true; - this.div.tabIndex = 0; this.editorDiv.removeEventListener("keydown", this.#boundEditorDivKeydown); this.editorDiv.removeEventListener("focus", this.#boundEditorDivFocus); this.editorDiv.removeEventListener("blur", this.#boundEditorDivBlur); + + // In case the blur callback hasn't been called. + this.isEditing = false; + } + + /** @inheritdoc */ + focusin(event) { + super.focusin(event); + if (event.target !== this.editorDiv) { + this.editorDiv.focus(); + } } /** @inheritdoc */ onceAdded() { if (this.width) { // The editor was created in using ctrl+c. - this.div.focus(); + this.parent.setActiveEditor(this); return; } this.enableEditMode(); @@ -330,7 +339,7 @@ class FreeTextEditor extends AnnotationEditor { /** * onkeydown callback. - * @param {MouseEvent} event + * @param {KeyboardEvent} event */ keydown(event) { if (event.target === this.div && event.key === "Enter") { @@ -423,6 +432,10 @@ class FreeTextEditor extends AnnotationEditor { // eslint-disable-next-line no-unsanitized/property this.editorDiv.innerHTML = this.#contentHTML; this.div.draggable = true; + this.editorDiv.contentEditable = false; + } else { + this.div.draggable = false; + this.editorDiv.contentEditable = true; } return this.div; diff --git a/src/display/editor/ink.js b/src/display/editor/ink.js index c906b81d2..d68604305 100644 --- a/src/display/editor/ink.js +++ b/src/display/editor/ink.js @@ -36,13 +36,13 @@ class InkEditor extends AnnotationEditor { #baseWidth = 0; - #boundCanvasMousemove; + #boundCanvasPointermove = this.canvasPointermove.bind(this); - #boundCanvasMouseleave; + #boundCanvasPointerleave = this.canvasPointerleave.bind(this); - #boundCanvasMouseup; + #boundCanvasPointerup = this.canvasPointerup.bind(this); - #boundCanvasMousedown; + #boundCanvasPointerdown = this.canvasPointerdown.bind(this); #disableEditing = false; @@ -71,11 +71,6 @@ class InkEditor extends AnnotationEditor { this.translationX = this.translationY = 0; this.x = 0; this.y = 0; - - this.#boundCanvasMousemove = this.canvasMousemove.bind(this); - this.#boundCanvasMouseleave = this.canvasMouseleave.bind(this); - this.#boundCanvasMouseup = this.canvasMouseup.bind(this); - this.#boundCanvasMousedown = this.canvasMousedown.bind(this); } static initialize(l10n) { @@ -230,8 +225,8 @@ class InkEditor extends AnnotationEditor { super.enableEditMode(); this.div.draggable = false; - this.canvas.addEventListener("mousedown", this.#boundCanvasMousedown); - this.canvas.addEventListener("mouseup", this.#boundCanvasMouseup); + this.canvas.addEventListener("pointerdown", this.#boundCanvasPointerdown); + this.canvas.addEventListener("pointerup", this.#boundCanvasPointerup); } /** @inheritdoc */ @@ -244,8 +239,11 @@ class InkEditor extends AnnotationEditor { this.div.draggable = !this.isEmpty(); this.div.classList.remove("editing"); - this.canvas.removeEventListener("mousedown", this.#boundCanvasMousedown); - this.canvas.removeEventListener("mouseup", this.#boundCanvasMouseup); + this.canvas.removeEventListener( + "pointerdown", + this.#boundCanvasPointerdown + ); + this.canvas.removeEventListener("pointerup", this.#boundCanvasPointerup); } /** @inheritdoc */ @@ -393,7 +391,6 @@ class InkEditor extends AnnotationEditor { /** * Commit the curves we have in this editor. - * @returns {undefined} */ commit() { if (this.#disableEditing) { @@ -428,11 +425,10 @@ class InkEditor extends AnnotationEditor { } /** - * onmousedown callback for the canvas we're drawing on. - * @param {MouseEvent} event - * @returns {undefined} + * onpointerdown callback for the canvas we're drawing on. + * @param {PointerEvent} event */ - canvasMousedown(event) { + canvasPointerdown(event) { if (event.button !== 0 || !this.isInEditMode() || this.#disableEditing) { return; } @@ -441,30 +437,32 @@ class InkEditor extends AnnotationEditor { // Since it's the last child, there's no need to give it a higher z-index. this.setInForeground(); + if (event.type !== "mouse") { + this.div.focus(); + } + event.stopPropagation(); - this.canvas.addEventListener("mouseleave", this.#boundCanvasMouseleave); - this.canvas.addEventListener("mousemove", this.#boundCanvasMousemove); + this.canvas.addEventListener("pointerleave", this.#boundCanvasPointerleave); + this.canvas.addEventListener("pointermove", this.#boundCanvasPointermove); this.#startDrawing(event.offsetX, event.offsetY); } /** - * onmousemove callback for the canvas we're drawing on. - * @param {MouseEvent} event - * @returns {undefined} + * onpointermove callback for the canvas we're drawing on. + * @param {PointerEvent} event */ - canvasMousemove(event) { + canvasPointermove(event) { event.stopPropagation(); this.#draw(event.offsetX, event.offsetY); } /** - * onmouseup callback for the canvas we're drawing on. - * @param {MouseEvent} event - * @returns {undefined} + * onpointerup callback for the canvas we're drawing on. + * @param {PointerEvent} event */ - canvasMouseup(event) { + canvasPointerup(event) { if (event.button !== 0) { return; } @@ -479,24 +477,29 @@ class InkEditor extends AnnotationEditor { } /** - * onmouseleave callback for the canvas we're drawing on. - * @param {MouseEvent} event - * @returns {undefined} + * onpointerleave callback for the canvas we're drawing on. + * @param {PointerEvent} event */ - canvasMouseleave(event) { + canvasPointerleave(event) { this.#endDrawing(event); this.setInBackground(); } /** * End the drawing. - * @param {MouseEvent} event + * @param {PointerEvent} event */ #endDrawing(event) { this.#stopDrawing(event.offsetX, event.offsetY); - this.canvas.removeEventListener("mouseleave", this.#boundCanvasMouseleave); - this.canvas.removeEventListener("mousemove", this.#boundCanvasMousemove); + this.canvas.removeEventListener( + "pointerleave", + this.#boundCanvasPointerleave + ); + this.canvas.removeEventListener( + "pointermove", + this.#boundCanvasPointermove + ); } /** diff --git a/web/annotation_editor_layer_builder.css b/web/annotation_editor_layer_builder.css index 44ebc00c0..7e38fcd81 100644 --- a/web/annotation_editor_layer_builder.css +++ b/web/annotation_editor_layer_builder.css @@ -62,6 +62,7 @@ height: auto; z-index: 1; transform-origin: 0 0; + touch-action: none; } .annotationEditorLayer .freeTextEditor .internal { @@ -135,4 +136,5 @@ left: 0; width: 100%; height: 100%; + touch-action: none; }