1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-22 16:18:08 +02:00

[Editor] Add the possibility to move the caret with the keyboard once an highlight has been made (bug 1881684)

This commit is contained in:
Calixte Denizet 2024-02-26 10:39:44 +01:00
parent 9600c48d4f
commit a9f47e87d5
3 changed files with 146 additions and 2 deletions

View file

@ -16,11 +16,12 @@
import {
AnnotationEditorParamsType,
AnnotationEditorType,
shadow,
Util,
} from "../../shared/util.js";
import { bindEvents, KeyboardManager } from "./tools.js";
import { FreeOutliner, Outliner } from "./outliner.js";
import { AnnotationEditor } from "./editor.js";
import { bindEvents } from "./tools.js";
import { ColorPicker } from "./color_picker.js";
import { noContextMenu } from "../display_utils.js";
@ -28,6 +29,10 @@ import { noContextMenu } from "../display_utils.js";
* Basic draw editor in order to generate an Highlight annotation.
*/
class HighlightEditor extends AnnotationEditor {
#anchorNode = null;
#anchorOffset = 0;
#boxes;
#clipPathId = null;
@ -36,6 +41,10 @@ class HighlightEditor extends AnnotationEditor {
#focusOutlines = null;
#focusNode = null;
#focusOffset = 0;
#highlightDiv = null;
#highlightOutlines = null;
@ -44,6 +53,8 @@ class HighlightEditor extends AnnotationEditor {
#isFreeHighlight = false;
#boundKeydown = this.#keydown.bind(this);
#lastPoint = null;
#opacity;
@ -72,6 +83,20 @@ class HighlightEditor extends AnnotationEditor {
static _freeHighlightClipId = "";
static get _keyboardManager() {
const proto = HighlightEditor.prototype;
return shadow(
this,
"_keyboardManager",
new KeyboardManager([
[["ArrowLeft", "mac+ArrowLeft"], proto._moveCaret, { args: [0] }],
[["ArrowRight", "mac+ArrowRight"], proto._moveCaret, { args: [1] }],
[["ArrowUp", "mac+ArrowUp"], proto._moveCaret, { args: [2] }],
[["ArrowDown", "mac+ArrowDown"], proto._moveCaret, { args: [3] }],
])
);
}
constructor(params) {
super({ ...params, name: "highlightEditor" });
this.color = params.color || HighlightEditor._defaultColor;
@ -86,6 +111,10 @@ class HighlightEditor extends AnnotationEditor {
this.#createFreeOutlines(params);
this.#addToDrawLayer();
} else {
this.#anchorNode = params.anchorNode;
this.#anchorOffset = params.anchorOffset;
this.#focusNode = params.focusNode;
this.#focusOffset = params.focusOffset;
this.#createOutlines();
this.#addToDrawLayer();
this.rotate(this.rotation);
@ -530,6 +559,8 @@ class HighlightEditor extends AnnotationEditor {
const div = super.render();
if (this.#isFreeHighlight) {
div.classList.add("free");
} else {
this.div.addEventListener("keydown", this.#boundKeydown);
}
const highlightDiv = (this.#highlightDiv = document.createElement("div"));
div.append(highlightDiv);
@ -552,6 +583,36 @@ class HighlightEditor extends AnnotationEditor {
this.parent.drawLayer.removeClass(this.#outlineId, "hovered");
}
#keydown(event) {
HighlightEditor._keyboardManager.exec(this, event);
}
_moveCaret(direction) {
this.parent.unselect(this);
switch (direction) {
case 0 /* left */:
case 2 /* up */:
this.#setCaret(/* start = */ true);
break;
case 1 /* right */:
case 3 /* down */:
this.#setCaret(/* start = */ false);
break;
}
}
#setCaret(start) {
if (!this.#anchorNode) {
return;
}
const selection = window.getSelection();
if (start) {
selection.setPosition(this.#anchorNode, this.#anchorOffset);
} else {
selection.setPosition(this.#focusNode, this.#focusOffset);
}
}
/** @inheritdoc */
select() {
super.select();
@ -563,6 +624,9 @@ class HighlightEditor extends AnnotationEditor {
unselect() {
super.unselect();
this.parent?.drawLayer.removeClass(this.#outlineId, "selected");
if (!this.#isFreeHighlight) {
this.#setCaret(/* start = */ false);
}
}
#getRotation() {

View file

@ -947,7 +947,7 @@ class AnnotationEditorUIManager {
if (!selection || selection.isCollapsed) {
return;
}
const { anchorNode } = selection;
const { anchorNode, anchorOffset, focusNode, focusOffset } = selection;
const anchorElement =
anchorNode.nodeType === Node.TEXT_NODE
? anchorNode.parentElement
@ -966,6 +966,10 @@ class AnnotationEditorUIManager {
layer.createAndAddNewEditor({ x: 0, y: 0 }, false, {
methodOfCreation,
boxes,
anchorNode,
anchorOffset,
focusNode,
focusOffset,
});
break;
}