|
25 | 25 | // eslint-disable-next-line max-len |
26 | 26 | /** @typedef {import("../src/display/struct_tree_layer_builder.js").StructTreeLayerBuilder} StructTreeLayerBuilder */ |
27 | 27 |
|
28 | | -import { AnnotationEditorType, FeatureTest } from "../../shared/util.js"; |
| 28 | +import { |
| 29 | + AnnotationEditorPrefix, |
| 30 | + AnnotationEditorType, |
| 31 | + FeatureTest, |
| 32 | +} from "../../shared/util.js"; |
29 | 33 | import { AnnotationEditor } from "./editor.js"; |
30 | 34 | import { FreeTextEditor } from "./freetext.js"; |
31 | 35 | import { HighlightEditor } from "./highlight.js"; |
@@ -85,6 +89,10 @@ class AnnotationEditorLayer { |
85 | 89 |
|
86 | 90 | #textSelectionAC = null; |
87 | 91 |
|
| 92 | + #textLayerDblClickAC = null; |
| 93 | + |
| 94 | + #lastPointerDownTimestamp = -1; |
| 95 | + |
88 | 96 | #uiManager; |
89 | 97 |
|
90 | 98 | static _initialized = false; |
@@ -238,6 +246,8 @@ class AnnotationEditorLayer { |
238 | 246 | this.#isEnabling = true; |
239 | 247 | this.div.tabIndex = 0; |
240 | 248 | this.togglePointerEvents(true); |
| 249 | + this.#textLayerDblClickAC?.abort(); |
| 250 | + this.#textLayerDblClickAC = null; |
241 | 251 | const annotationElementIds = new Set(); |
242 | 252 | for (const editor of this.#editors.values()) { |
243 | 253 | editor.enableEditing(); |
@@ -280,6 +290,52 @@ class AnnotationEditorLayer { |
280 | 290 | this.#isDisabling = true; |
281 | 291 | this.div.tabIndex = -1; |
282 | 292 | this.togglePointerEvents(false); |
| 293 | + if (this.#textLayer && !this.#textLayerDblClickAC) { |
| 294 | + this.#textLayerDblClickAC = new AbortController(); |
| 295 | + const signal = this.#uiManager.combinedSignal(this.#textLayerDblClickAC); |
| 296 | + this.#textLayer.div.addEventListener( |
| 297 | + "pointerdown", |
| 298 | + e => { |
| 299 | + // It's the default value in Fenix: |
| 300 | + // https://searchfox.org/mozilla-central/rev/beba5cde846f944c4d709e75cbe499d17af880a4/modules/libpref/init/StaticPrefList.yaml#19064 |
| 301 | + // and in Chrome and Windows: |
| 302 | + // https://source.chromium.org/chromium/chromium/src/+/main:ui/events/event_constants.h;drc=f0f5f3ceebb00da9363ccc7a1e2c0f17b6b383ba;l=115 |
| 303 | + const DBL_CLICK_THRESHOLD = 500; |
| 304 | + const { clientX, clientY, timeStamp } = e; |
| 305 | + const lastPointerDownTimestamp = this.#lastPointerDownTimestamp; |
| 306 | + if (timeStamp - lastPointerDownTimestamp > DBL_CLICK_THRESHOLD) { |
| 307 | + this.#lastPointerDownTimestamp = timeStamp; |
| 308 | + return; |
| 309 | + } |
| 310 | + this.#lastPointerDownTimestamp = -1; |
| 311 | + const { classList } = this.div; |
| 312 | + classList.toggle("getElements", true); |
| 313 | + const elements = document.elementsFromPoint(clientX, clientY); |
| 314 | + classList.toggle("getElements", false); |
| 315 | + if (!this.div.contains(elements[0])) { |
| 316 | + return; |
| 317 | + } |
| 318 | + let id; |
| 319 | + const regex = new RegExp(`^${AnnotationEditorPrefix}[0-9]+$`); |
| 320 | + for (const element of elements) { |
| 321 | + if (regex.test(element.id)) { |
| 322 | + id = element.id; |
| 323 | + break; |
| 324 | + } |
| 325 | + } |
| 326 | + if (!id) { |
| 327 | + return; |
| 328 | + } |
| 329 | + const editor = this.#editors.get(id); |
| 330 | + if (editor?.annotationElementId === null) { |
| 331 | + e.stopPropagation(); |
| 332 | + e.preventDefault(); |
| 333 | + editor.dblclick(); |
| 334 | + } |
| 335 | + }, |
| 336 | + { signal, capture: true } |
| 337 | + ); |
| 338 | + } |
283 | 339 | const changedAnnotations = new Map(); |
284 | 340 | const resetAnnotations = new Map(); |
285 | 341 | for (const editor of this.#editors.values()) { |
|
0 commit comments