Merge pull request #20023 from calixteman/edit_added_annotation

[Editor] When editing mode is disabled, allow to double click on a added annotation to edit it
This commit is contained in:
Tim van der Meij 2025-06-21 16:23:56 +02:00 committed by GitHub
commit ac399e77e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
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

@ -3338,4 +3338,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 {