[Editor] When editing mode is disabled, allow to double click on a added annotation to edit it

It's already possible but only when double clicking outside the the text layer.
This patach adds the possibility to click on the text layer.
This commit is contained in:
Calixte Denizet 2025-06-19 21:15:06 +02:00
parent 5653458b51
commit d0b0064643
3 changed files with 116 additions and 1 deletions

View File

@ -25,7 +25,11 @@
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/struct_tree_layer_builder.js").StructTreeLayerBuilder} StructTreeLayerBuilder */
import { AnnotationEditorType, FeatureTest } from "../../shared/util.js";
import {
AnnotationEditorPrefix,
AnnotationEditorType,
FeatureTest,
} from "../../shared/util.js";
import { AnnotationEditor } from "./editor.js";
import { FreeTextEditor } from "./freetext.js";
import { HighlightEditor } from "./highlight.js";
@ -85,6 +89,10 @@ class AnnotationEditorLayer {
#textSelectionAC = null;
#textLayerDblClickAC = null;
#lastPointerDownTimestamp = -1;
#uiManager;
static _initialized = false;
@ -238,6 +246,8 @@ class AnnotationEditorLayer {
this.#isEnabling = true;
this.div.tabIndex = 0;
this.togglePointerEvents(true);
this.#textLayerDblClickAC?.abort();
this.#textLayerDblClickAC = null;
const annotationElementIds = new Set();
for (const editor of this.#editors.values()) {
editor.enableEditing();
@ -280,6 +290,52 @@ class AnnotationEditorLayer {
this.#isDisabling = true;
this.div.tabIndex = -1;
this.togglePointerEvents(false);
if (this.#textLayer && !this.#textLayerDblClickAC) {
this.#textLayerDblClickAC = new AbortController();
const signal = this.#uiManager.combinedSignal(this.#textLayerDblClickAC);
this.#textLayer.div.addEventListener(
"pointerdown",
e => {
// It's the default value in Fenix:
// https://searchfox.org/mozilla-central/rev/beba5cde846f944c4d709e75cbe499d17af880a4/modules/libpref/init/StaticPrefList.yaml#19064
// and in Chrome and Windows:
// https://source.chromium.org/chromium/chromium/src/+/main:ui/events/event_constants.h;drc=f0f5f3ceebb00da9363ccc7a1e2c0f17b6b383ba;l=115
const DBL_CLICK_THRESHOLD = 500;
const { clientX, clientY, timeStamp } = e;
const lastPointerDownTimestamp = this.#lastPointerDownTimestamp;
if (timeStamp - lastPointerDownTimestamp > DBL_CLICK_THRESHOLD) {
this.#lastPointerDownTimestamp = timeStamp;
return;
}
this.#lastPointerDownTimestamp = -1;
const { classList } = this.div;
classList.toggle("getElements", true);
const elements = document.elementsFromPoint(clientX, clientY);
classList.toggle("getElements", false);
if (!this.div.contains(elements[0])) {
return;
}
let id;
const regex = new RegExp(`^${AnnotationEditorPrefix}[0-9]+$`);
for (const element of elements) {
if (regex.test(element.id)) {
id = element.id;
break;
}
}
if (!id) {
return;
}
const editor = this.#editors.get(id);
if (editor?.annotationElementId === null) {
e.stopPropagation();
e.preventDefault();
editor.dblclick();
}
},
{ signal, capture: true }
);
}
const changedAnnotations = new Map();
const resetAnnotations = new Map();
for (const editor of this.#editors.values()) {

View File

@ -3357,4 +3357,56 @@ describe("FreeText Editor", () => {
);
});
});
describe("Edit added Freetext annotation", () => {
let pages;
beforeEach(async () => {
pages = await loadAndWait("tracemonkey.pdf", ".annotationEditorLayer");
});
afterEach(async () => {
await closePages(pages);
});
it("must check that an added Freetext can be edited in double clicking on it", async () => {
await Promise.all(
pages.map(async ([browserName, page]) => {
await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0);
const data = "Hello PDF.js World !!";
await page.mouse.click(
rect.x + rect.width / 2,
rect.y + rect.height / 2
);
await page.waitForSelector(editorSelector, { visible: true });
await page.type(`${editorSelector} .internal`, data);
await commit(page);
await waitForSerialized(page, 1);
await switchToFreeText(page, /* disable */ true);
const modeChangedHandle = await createPromise(page, resolve => {
window.PDFViewerApplication.eventBus.on(
"annotationeditormodechanged",
resolve,
{ once: true }
);
});
const editorRect = await getRect(page, editorSelector);
await page.mouse.click(
editorRect.x + editorRect.width / 2,
editorRect.y + editorRect.height / 2,
{ count: 2 }
);
await page.waitForSelector(".annotationEditorLayer.freetextEditing");
await awaitPromise(modeChangedHandle);
})
);
});
});
});

View File

@ -134,6 +134,13 @@
&.drawing * {
pointer-events: none !important;
}
&.getElements {
pointer-events: auto !important;
> div {
pointer-events: auto !important;
}
}
}
.annotationEditorLayer.waiting {