From 086c044dc34dfc0f74fbe41f4ecb402b2cd34884 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:13:33 +0200 Subject: Merging upstream version 125.0.1. Signed-off-by: Daniel Baumann --- toolkit/components/pdfjs/content/build/pdf.mjs | 726 +++++++++++++++++++------ 1 file changed, 557 insertions(+), 169 deletions(-) (limited to 'toolkit/components/pdfjs/content/build/pdf.mjs') diff --git a/toolkit/components/pdfjs/content/build/pdf.mjs b/toolkit/components/pdfjs/content/build/pdf.mjs index 72dcbae165..4e51efdb78 100644 --- a/toolkit/components/pdfjs/content/build/pdf.mjs +++ b/toolkit/components/pdfjs/content/build/pdf.mjs @@ -139,7 +139,8 @@ const AnnotationEditorParamsType = { HIGHLIGHT_COLOR: 31, HIGHLIGHT_DEFAULT_COLOR: 32, HIGHLIGHT_THICKNESS: 33, - HIGHLIGHT_FREE: 34 + HIGHLIGHT_FREE: 34, + HIGHLIGHT_SHOW_ALL: 35 }; const PermissionFlag = { PRINT: 0x04, @@ -1591,9 +1592,173 @@ function setLayerDimensions(div, viewport, mustFlip = false, mustRotate = true) } } +;// CONCATENATED MODULE: ./src/display/editor/toolbar.js + +class EditorToolbar { + #toolbar = null; + #colorPicker = null; + #editor; + #buttons = null; + constructor(editor) { + this.#editor = editor; + } + render() { + const editToolbar = this.#toolbar = document.createElement("div"); + editToolbar.className = "editToolbar"; + editToolbar.setAttribute("role", "toolbar"); + editToolbar.addEventListener("contextmenu", noContextMenu); + editToolbar.addEventListener("pointerdown", EditorToolbar.#pointerDown); + const buttons = this.#buttons = document.createElement("div"); + buttons.className = "buttons"; + editToolbar.append(buttons); + const position = this.#editor.toolbarPosition; + if (position) { + const { + style + } = editToolbar; + const x = this.#editor._uiManager.direction === "ltr" ? 1 - position[0] : position[0]; + style.insetInlineEnd = `${100 * x}%`; + style.top = `calc(${100 * position[1]}% + var(--editor-toolbar-vert-offset))`; + } + this.#addDeleteButton(); + return editToolbar; + } + static #pointerDown(e) { + e.stopPropagation(); + } + #focusIn(e) { + this.#editor._focusEventsAllowed = false; + e.preventDefault(); + e.stopPropagation(); + } + #focusOut(e) { + this.#editor._focusEventsAllowed = true; + e.preventDefault(); + e.stopPropagation(); + } + #addListenersToElement(element) { + element.addEventListener("focusin", this.#focusIn.bind(this), { + capture: true + }); + element.addEventListener("focusout", this.#focusOut.bind(this), { + capture: true + }); + element.addEventListener("contextmenu", noContextMenu); + } + hide() { + this.#toolbar.classList.add("hidden"); + this.#colorPicker?.hideDropdown(); + } + show() { + this.#toolbar.classList.remove("hidden"); + } + #addDeleteButton() { + const button = document.createElement("button"); + button.className = "delete"; + button.tabIndex = 0; + button.setAttribute("data-l10n-id", `pdfjs-editor-remove-${this.#editor.editorType}-button`); + this.#addListenersToElement(button); + button.addEventListener("click", e => { + this.#editor._uiManager.delete(); + }); + this.#buttons.append(button); + } + get #divider() { + const divider = document.createElement("div"); + divider.className = "divider"; + return divider; + } + addAltTextButton(button) { + this.#addListenersToElement(button); + this.#buttons.prepend(button, this.#divider); + } + addColorPicker(colorPicker) { + this.#colorPicker = colorPicker; + const button = colorPicker.renderButton(); + this.#addListenersToElement(button); + this.#buttons.prepend(button, this.#divider); + } + remove() { + this.#toolbar.remove(); + this.#colorPicker?.destroy(); + this.#colorPicker = null; + } +} +class HighlightToolbar { + #buttons = null; + #toolbar = null; + #uiManager; + constructor(uiManager) { + this.#uiManager = uiManager; + } + #render() { + const editToolbar = this.#toolbar = document.createElement("div"); + editToolbar.className = "editToolbar"; + editToolbar.setAttribute("role", "toolbar"); + editToolbar.addEventListener("contextmenu", noContextMenu); + const buttons = this.#buttons = document.createElement("div"); + buttons.className = "buttons"; + editToolbar.append(buttons); + this.#addHighlightButton(); + return editToolbar; + } + #getLastPoint(boxes, isLTR) { + let lastY = 0; + let lastX = 0; + for (const box of boxes) { + const y = box.y + box.height; + if (y < lastY) { + continue; + } + const x = box.x + (isLTR ? box.width : 0); + if (y > lastY) { + lastX = x; + lastY = y; + continue; + } + if (isLTR) { + if (x > lastX) { + lastX = x; + } + } else if (x < lastX) { + lastX = x; + } + } + return [isLTR ? 1 - lastX : lastX, lastY]; + } + show(parent, boxes, isLTR) { + const [x, y] = this.#getLastPoint(boxes, isLTR); + const { + style + } = this.#toolbar ||= this.#render(); + parent.append(this.#toolbar); + style.insetInlineEnd = `${100 * x}%`; + style.top = `calc(${100 * y}% + var(--editor-toolbar-vert-offset))`; + } + hide() { + this.#toolbar.remove(); + } + #addHighlightButton() { + const button = document.createElement("button"); + button.className = "highlightButton"; + button.tabIndex = 0; + button.setAttribute("data-l10n-id", `pdfjs-highlight-floating-button`); + const span = document.createElement("span"); + button.append(span); + span.className = "visuallyHidden"; + span.setAttribute("data-l10n-id", "pdfjs-editor-highlight-button-label"); + button.addEventListener("contextmenu", noContextMenu); + button.addEventListener("click", () => { + this.#uiManager.highlightSelection("floating_button"); + }); + this.#buttons.append(button); + } +} + ;// CONCATENATED MODULE: ./src/display/editor/tools.js + function bindEvents(obj, element, names) { for (const name of names) { element.addEventListener(name, obj[name].bind(obj)); @@ -1933,10 +2098,12 @@ class AnnotationEditorUIManager { #draggingEditors = null; #editorTypes = null; #editorsToRescale = new Set(); + #enableHighlightFloatingButton = false; #filterFactory = null; #focusMainContainerTimeoutId = null; #highlightColors = null; #highlightWhenShiftUp = false; + #highlightToolbar = null; #idManager = new IdManager(); #isEnabled = false; #isWaiting = false; @@ -1947,6 +2114,7 @@ class AnnotationEditorUIManager { #selectedEditors = new Set(); #selectedTextNode = null; #pageColors = null; + #showAllStates = null; #boundBlur = this.blur.bind(this); #boundFocus = this.focus.bind(this); #boundCopy = this.copy.bind(this); @@ -2031,7 +2199,7 @@ class AnnotationEditorUIManager { checker: arrowChecker }]])); } - constructor(container, viewer, altTextManager, eventBus, pdfDocument, pageColors, highlightColors, mlManager) { + constructor(container, viewer, altTextManager, eventBus, pdfDocument, pageColors, highlightColors, enableHighlightFloatingButton, mlManager) { this.#container = container; this.#viewer = viewer; this.#altTextManager = altTextManager; @@ -2041,10 +2209,12 @@ class AnnotationEditorUIManager { this._eventBus._on("scalechanging", this.#boundOnScaleChanging); this._eventBus._on("rotationchanging", this.#boundOnRotationChanging); this.#addSelectionListener(); + this.#addKeyboardManager(); this.#annotationStorage = pdfDocument.annotationStorage; this.#filterFactory = pdfDocument.filterFactory; this.#pageColors = pageColors; this.#highlightColors = highlightColors || null; + this.#enableHighlightFloatingButton = enableHighlightFloatingButton; this.#mlManager = mlManager || null; this.viewParameters = { realScale: PixelsPerInch.PDF_TO_CSS_UNITS, @@ -2069,6 +2239,8 @@ class AnnotationEditorUIManager { this.#selectedEditors.clear(); this.#commandManager.destroy(); this.#altTextManager?.destroy(); + this.#highlightToolbar?.hide(); + this.#highlightToolbar = null; if (this.#focusMainContainerTimeoutId) { clearTimeout(this.#focusMainContainerTimeoutId); this.#focusMainContainerTimeoutId = null; @@ -2149,6 +2321,11 @@ class AnnotationEditorUIManager { this.commitOrRemove(); this.viewParameters.rotation = pagesRotation; } + #getAnchorElementForSelection({ + anchorNode + }) { + return anchorNode.nodeType === Node.TEXT_NODE ? anchorNode.parentElement : anchorNode; + } highlightSelection(methodOfCreation = "") { const selection = document.getSelection(); if (!selection || selection.isCollapsed) { @@ -2160,15 +2337,20 @@ class AnnotationEditorUIManager { focusNode, focusOffset } = selection; - const anchorElement = anchorNode.nodeType === Node.TEXT_NODE ? anchorNode.parentElement : anchorNode; + const text = selection.toString(); + const anchorElement = this.#getAnchorElementForSelection(selection); const textLayer = anchorElement.closest(".textLayer"); const boxes = this.getSelectionBoxes(textLayer); + if (!boxes) { + return; + } selection.empty(); if (this.#mode === AnnotationEditorType.NONE) { this._eventBus.dispatch("showannotationeditorui", { source: this, mode: AnnotationEditorType.HIGHLIGHT }); + this.showAllEditors("highlight", true, true); } for (const layer of this.#allLayers.values()) { if (layer.hasTextLayer(textLayer)) { @@ -2181,12 +2363,27 @@ class AnnotationEditorUIManager { anchorNode, anchorOffset, focusNode, - focusOffset + focusOffset, + text }); break; } } } + #displayHighlightToolbar() { + const selection = document.getSelection(); + if (!selection || selection.isCollapsed) { + return; + } + const anchorElement = this.#getAnchorElementForSelection(selection); + const textLayer = anchorElement.closest(".textLayer"); + const boxes = this.getSelectionBoxes(textLayer); + if (!boxes) { + return; + } + this.#highlightToolbar ||= new HighlightToolbar(this); + this.#highlightToolbar.show(textLayer, boxes, this.direction === "ltr"); + } addToAnnotationStorage(editor) { if (!editor.isEmpty() && this.#annotationStorage && !this.#annotationStorage.has(editor.id)) { this.#annotationStorage.setValue(editor.id, editor); @@ -2196,6 +2393,7 @@ class AnnotationEditorUIManager { const selection = document.getSelection(); if (!selection || selection.isCollapsed) { if (this.#selectedTextNode) { + this.#highlightToolbar?.hide(); this.#selectedTextNode = null; this.#dispatchUpdateStates({ hasSelectedText: false @@ -2209,9 +2407,11 @@ class AnnotationEditorUIManager { if (anchorNode === this.#selectedTextNode) { return; } - const anchorElement = anchorNode.nodeType === Node.TEXT_NODE ? anchorNode.parentElement : anchorNode; - if (!anchorElement.closest(".textLayer")) { + const anchorElement = this.#getAnchorElementForSelection(selection); + const textLayer = anchorElement.closest(".textLayer"); + if (!textLayer) { if (this.#selectedTextNode) { + this.#highlightToolbar?.hide(); this.#selectedTextNode = null; this.#dispatchUpdateStates({ hasSelectedText: false @@ -2219,13 +2419,17 @@ class AnnotationEditorUIManager { } return; } + this.#highlightToolbar?.hide(); this.#selectedTextNode = anchorNode; this.#dispatchUpdateStates({ hasSelectedText: true }); - if (this.#mode !== AnnotationEditorType.HIGHLIGHT) { + if (this.#mode !== AnnotationEditorType.HIGHLIGHT && this.#mode !== AnnotationEditorType.NONE) { return; } + if (this.#mode === AnnotationEditorType.HIGHLIGHT) { + this.showAllEditors("highlight", true, true); + } this.#highlightWhenShiftUp = this.isShiftKeyDown; if (!this.isShiftKeyDown) { const pointerup = e => { @@ -2235,13 +2439,20 @@ class AnnotationEditorUIManager { window.removeEventListener("pointerup", pointerup); window.removeEventListener("blur", pointerup); if (e.type === "pointerup") { - this.highlightSelection("main_toolbar"); + this.#onSelectEnd("main_toolbar"); } }; window.addEventListener("pointerup", pointerup); window.addEventListener("blur", pointerup); } } + #onSelectEnd(methodOfCreation = "") { + if (this.#mode === AnnotationEditorType.HIGHLIGHT) { + this.highlightSelection(methodOfCreation); + } else if (this.#enableHighlightFloatingButton) { + this.#displayHighlightToolbar(); + } + } #addSelectionListener() { document.addEventListener("selectionchange", this.#boundSelectionChange); } @@ -2260,7 +2471,7 @@ class AnnotationEditorUIManager { this.isShiftKeyDown = false; if (this.#highlightWhenShiftUp) { this.#highlightWhenShiftUp = false; - this.highlightSelection("main_toolbar"); + this.#onSelectEnd("main_toolbar"); } if (!this.hasSelection) { return; @@ -2398,7 +2609,7 @@ class AnnotationEditorUIManager { if (!this.isShiftKeyDown && event.key === "Shift") { this.isShiftKeyDown = true; } - if (!this.isEditorHandlingKeyboard) { + if (this.#mode !== AnnotationEditorType.NONE && !this.isEditorHandlingKeyboard) { AnnotationEditorUIManager._keyboardManager.exec(this, event); } } @@ -2407,7 +2618,7 @@ class AnnotationEditorUIManager { this.isShiftKeyDown = false; if (this.#highlightWhenShiftUp) { this.#highlightWhenShiftUp = false; - this.highlightSelection("main_toolbar"); + this.#onSelectEnd("main_toolbar"); } } } @@ -2447,7 +2658,6 @@ class AnnotationEditorUIManager { setEditingState(isEditing) { if (isEditing) { this.#addFocusManager(); - this.#addKeyboardManager(); this.#addCopyPasteListeners(); this.#dispatchUpdateStates({ isEditing: this.#mode !== AnnotationEditorType.NONE, @@ -2458,7 +2668,6 @@ class AnnotationEditorUIManager { }); } else { this.#removeFocusManager(); - this.#removeKeyboardManager(); this.#removeCopyPasteListeners(); this.#dispatchUpdateStates({ isEditing: false @@ -2554,6 +2763,20 @@ class AnnotationEditorUIManager { case AnnotationEditorParamsType.HIGHLIGHT_DEFAULT_COLOR: this.#mainHighlightColorPicker?.updateColor(value); break; + case AnnotationEditorParamsType.HIGHLIGHT_SHOW_ALL: + this._eventBus.dispatch("reporttelemetry", { + source: this, + details: { + type: "editing", + data: { + type: "highlight", + action: "toggle_visibility" + } + } + }); + (this.#showAllStates ||= new Map()).set(type, value); + this.showAllEditors("highlight", value); + break; } for (const editor of this.#selectedEditors) { editor.updateParams(type, value); @@ -2562,6 +2785,17 @@ class AnnotationEditorUIManager { editorType.updateDefaultParams(type, value); } } + showAllEditors(type, visible, updateButton = false) { + for (const editor of this.#allEditors.values()) { + if (editor.editorType === type) { + editor.show(visible); + } + } + const state = this.#showAllStates?.get(AnnotationEditorParamsType.HIGHLIGHT_SHOW_ALL) ?? true; + if (state !== visible) { + this.#dispatchUpdateUI([[AnnotationEditorParamsType.HIGHLIGHT_SHOW_ALL, visible]]); + } + } enableWaiting(mustWait = false) { if (this.#isWaiting === mustWait) { return; @@ -2582,6 +2816,9 @@ class AnnotationEditorUIManager { for (const layer of this.#allLayers.values()) { layer.enable(); } + for (const editor of this.#allEditors.values()) { + editor.enable(); + } } } #disableAll() { @@ -2591,6 +2828,9 @@ class AnnotationEditorUIManager { for (const layer of this.#allLayers.values()) { layer.disable(); } + for (const editor of this.#allEditors.values()) { + editor.disable(); + } } } getEditors(pageIndex) { @@ -2641,6 +2881,7 @@ class AnnotationEditorUIManager { layer.addOrRebuild(editor); } else { this.addEditor(editor); + this.addToAnnotationStorage(editor); } } setActiveEditor(editor) { @@ -3172,98 +3413,6 @@ class AltText { } } -;// CONCATENATED MODULE: ./src/display/editor/toolbar.js - -class EditorToolbar { - #toolbar = null; - #colorPicker = null; - #editor; - #buttons = null; - constructor(editor) { - this.#editor = editor; - } - render() { - const editToolbar = this.#toolbar = document.createElement("div"); - editToolbar.className = "editToolbar"; - editToolbar.addEventListener("contextmenu", noContextMenu); - editToolbar.addEventListener("pointerdown", EditorToolbar.#pointerDown); - const buttons = this.#buttons = document.createElement("div"); - buttons.className = "buttons"; - editToolbar.append(buttons); - const position = this.#editor.toolbarPosition; - if (position) { - const { - style - } = editToolbar; - const x = this.#editor._uiManager.direction === "ltr" ? 1 - position[0] : position[0]; - style.insetInlineEnd = `${100 * x}%`; - style.top = `calc(${100 * position[1]}% + var(--editor-toolbar-vert-offset))`; - } - this.#addDeleteButton(); - return editToolbar; - } - static #pointerDown(e) { - e.stopPropagation(); - } - #focusIn(e) { - this.#editor._focusEventsAllowed = false; - e.preventDefault(); - e.stopPropagation(); - } - #focusOut(e) { - this.#editor._focusEventsAllowed = true; - e.preventDefault(); - e.stopPropagation(); - } - #addListenersToElement(element) { - element.addEventListener("focusin", this.#focusIn.bind(this), { - capture: true - }); - element.addEventListener("focusout", this.#focusOut.bind(this), { - capture: true - }); - element.addEventListener("contextmenu", noContextMenu); - } - hide() { - this.#toolbar.classList.add("hidden"); - this.#colorPicker?.hideDropdown(); - } - show() { - this.#toolbar.classList.remove("hidden"); - } - #addDeleteButton() { - const button = document.createElement("button"); - button.className = "delete"; - button.tabIndex = 0; - button.setAttribute("data-l10n-id", `pdfjs-editor-remove-${this.#editor.editorType}-button`); - this.#addListenersToElement(button); - button.addEventListener("click", e => { - this.#editor._uiManager.delete(); - }); - this.#buttons.append(button); - } - get #divider() { - const divider = document.createElement("div"); - divider.className = "divider"; - return divider; - } - addAltTextButton(button) { - this.#addListenersToElement(button); - this.#buttons.prepend(button, this.#divider); - } - addColorPicker(colorPicker) { - this.#colorPicker = colorPicker; - const button = colorPicker.renderButton(); - this.#addListenersToElement(button); - this.#buttons.prepend(button, this.#divider); - } - remove() { - this.#toolbar.remove(); - this.#colorPicker?.destroy(); - this.#colorPicker = null; - } -} - ;// CONCATENATED MODULE: ./src/display/editor/editor.js @@ -3273,6 +3422,7 @@ class EditorToolbar { class AnnotationEditor { #allResizerDivs = null; #altText = null; + #disabled = false; #keepAspectRatio = false; #resizersDiv = null; #savedDimensions = null; @@ -3289,6 +3439,7 @@ class AnnotationEditor { #prevDragY = 0; #telemetryTimeouts = null; _initialOptions = Object.create(null); + _isVisible = true; _uiManager = null; _focusEventsAllowed = true; _l10nPromise = null; @@ -3555,6 +3706,9 @@ class AnnotationEditor { return [-x, -y]; } } + get _mustFixPosition() { + return true; + } fixAndSetPosition(rotation = this.rotation) { const [pageWidth, pageHeight] = this.pageDimensions; let { @@ -3567,23 +3721,25 @@ class AnnotationEditor { height *= pageHeight; x *= pageWidth; y *= pageHeight; - switch (rotation) { - case 0: - x = Math.max(0, Math.min(pageWidth - width, x)); - y = Math.max(0, Math.min(pageHeight - height, y)); - break; - case 90: - x = Math.max(0, Math.min(pageWidth - height, x)); - y = Math.min(pageHeight, Math.max(width, y)); - break; - case 180: - x = Math.min(pageWidth, Math.max(width, x)); - y = Math.min(pageHeight, Math.max(height, y)); - break; - case 270: - x = Math.min(pageWidth, Math.max(height, x)); - y = Math.max(0, Math.min(pageHeight - width, y)); - break; + if (this._mustFixPosition) { + switch (rotation) { + case 0: + x = Math.max(0, Math.min(pageWidth - width, x)); + y = Math.max(0, Math.min(pageHeight - height, y)); + break; + case 90: + x = Math.max(0, Math.min(pageWidth - height, x)); + y = Math.min(pageHeight, Math.max(width, y)); + break; + case 180: + x = Math.min(pageWidth, Math.max(width, x)); + y = Math.min(pageHeight, Math.max(height, y)); + break; + case 270: + x = Math.min(pageWidth, Math.max(height, x)); + y = Math.max(0, Math.min(pageHeight - width, y)); + break; + } } this.x = x /= pageWidth; this.y = y /= pageHeight; @@ -3902,7 +4058,10 @@ 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.setAttribute("tabIndex", 0); + this.div.tabIndex = this.#disabled ? -1 : 0; + if (!this._isVisible) { + this.div.classList.add("hidden"); + } this.setInForeground(); this.div.addEventListener("focusin", this.#boundFocusin); this.div.addEventListener("focusout", this.#boundFocusout); @@ -4100,6 +4259,7 @@ class AnnotationEditor { } this.#telemetryTimeouts = null; } + this.parent = null; } get isResizable() { return false; @@ -4319,6 +4479,22 @@ class AnnotationEditor { } }); } + show(visible = this._isVisible) { + this.div.classList.toggle("hidden", !visible); + this._isVisible = visible; + } + enable() { + if (this.div) { + this.div.tabIndex = 0; + } + this.#disabled = false; + } + disable() { + if (this.div) { + this.div.tabIndex = -1; + } + this.#disabled = true; + } } class FakeEditor extends AnnotationEditor { constructor(params) { @@ -8373,18 +8549,44 @@ class Metadata { const INTERNAL = Symbol("INTERNAL"); class OptionalContentGroup { + #isDisplay = false; + #isPrint = false; + #userSet = false; #visible = true; - constructor(name, intent) { + constructor(renderingIntent, { + name, + intent, + usage + }) { + this.#isDisplay = !!(renderingIntent & RenderingIntentFlag.DISPLAY); + this.#isPrint = !!(renderingIntent & RenderingIntentFlag.PRINT); this.name = name; this.intent = intent; + this.usage = usage; } get visible() { - return this.#visible; + if (this.#userSet) { + return this.#visible; + } + if (!this.#visible) { + return false; + } + const { + print, + view + } = this.usage; + if (this.#isDisplay) { + return view?.viewState !== "OFF"; + } else if (this.#isPrint) { + return print?.printState !== "OFF"; + } + return true; } - _setVisible(internal, visible) { + _setVisible(internal, visible, userSet = false) { if (internal !== INTERNAL) { unreachable("Internal method `_setVisible` called."); } + this.#userSet = userSet; this.#visible = visible; } } @@ -8393,7 +8595,8 @@ class OptionalContentConfig { #groups = new Map(); #initialHash = null; #order = null; - constructor(data) { + constructor(data, renderingIntent = RenderingIntentFlag.DISPLAY) { + this.renderingIntent = renderingIntent; this.name = null; this.creator = null; if (data === null) { @@ -8403,7 +8606,7 @@ class OptionalContentConfig { this.creator = data.creator; this.#order = data.order; for (const group of data.groups) { - this.#groups.set(group.id, new OptionalContentGroup(group.name, group.intent)); + this.#groups.set(group.id, new OptionalContentGroup(renderingIntent, group)); } if (data.baseState === "OFF") { for (const group of this.#groups.values()) { @@ -8524,11 +8727,43 @@ class OptionalContentConfig { return true; } setVisibility(id, visible = true) { - if (!this.#groups.has(id)) { + const group = this.#groups.get(id); + if (!group) { warn(`Optional content group not found: ${id}`); return; } - this.#groups.get(id)._setVisible(INTERNAL, !!visible); + group._setVisible(INTERNAL, !!visible, true); + this.#cachedGetHash = null; + } + setOCGState({ + state, + preserveRB + }) { + let operator; + for (const elem of state) { + switch (elem) { + case "ON": + case "OFF": + case "Toggle": + operator = elem; + continue; + } + const group = this.#groups.get(elem); + if (!group) { + continue; + } + switch (operator) { + case "ON": + group._setVisible(INTERNAL, true); + break; + case "OFF": + group._setVisible(INTERNAL, false); + break; + case "Toggle": + group._setVisible(INTERNAL, !group.visible); + break; + } + } this.#cachedGetHash = null; } get hasInitialVisibility() { @@ -8970,7 +9205,7 @@ function getDocument(src) { } const fetchDocParams = { docId, - apiVersion: "4.1.249", + apiVersion: "4.1.342", data, password, disableAutoFetch, @@ -9207,8 +9442,13 @@ class PDFDocumentProxy { getOutline() { return this._transport.getOutline(); } - getOptionalContentConfig() { - return this._transport.getOptionalContentConfig(); + getOptionalContentConfig({ + intent = "display" + } = {}) { + const { + renderingIntent + } = this._transport.getRenderingIntent(intent); + return this._transport.getOptionalContentConfig(renderingIntent); } getPermissions() { return this._transport.getPermissions(); @@ -9299,8 +9539,10 @@ class PDFPageProxy { getAnnotations({ intent = "display" } = {}) { - const intentArgs = this._transport.getRenderingIntent(intent); - return this._transport.getAnnotations(this._pageIndex, intentArgs.renderingIntent); + const { + renderingIntent + } = this._transport.getRenderingIntent(intent); + return this._transport.getAnnotations(this._pageIndex, renderingIntent); } getJSActions() { return this._transport.getPageJSActions(this._pageIndex); @@ -9328,21 +9570,23 @@ class PDFPageProxy { }) { this._stats?.time("Overall"); const intentArgs = this._transport.getRenderingIntent(intent, annotationMode, printAnnotationStorage); + const { + renderingIntent, + cacheKey + } = intentArgs; this.#pendingCleanup = false; this.#abortDelayedCleanup(); - if (!optionalContentConfigPromise) { - optionalContentConfigPromise = this._transport.getOptionalContentConfig(); - } - let intentState = this._intentStates.get(intentArgs.cacheKey); + optionalContentConfigPromise ||= this._transport.getOptionalContentConfig(renderingIntent); + let intentState = this._intentStates.get(cacheKey); if (!intentState) { intentState = Object.create(null); - this._intentStates.set(intentArgs.cacheKey, intentState); + this._intentStates.set(cacheKey, intentState); } if (intentState.streamReaderCancelTimeout) { clearTimeout(intentState.streamReaderCancelTimeout); intentState.streamReaderCancelTimeout = null; } - const intentPrint = !!(intentArgs.renderingIntent & RenderingIntentFlag.PRINT); + const intentPrint = !!(renderingIntent & RenderingIntentFlag.PRINT); if (!intentState.displayReadyCapability) { intentState.displayReadyCapability = new PromiseCapability(); intentState.operatorList = { @@ -9399,6 +9643,9 @@ class PDFPageProxy { return; } this._stats?.time("Rendering"); + if (!(optionalContentConfig.renderingIntent & renderingIntent)) { + throw new Error("Must use the same `intent`-argument when calling the `PDFPageProxy.render` " + "and `PDFDocumentProxy.getOptionalContentConfig` methods."); + } internalRenderTask.initializeGraphics({ transparency, optionalContentConfig @@ -10338,8 +10585,8 @@ class WorkerTransport { getOutline() { return this.messageHandler.sendWithPromise("GetOutline", null); } - getOptionalContentConfig() { - return this.messageHandler.sendWithPromise("GetOptionalContentConfig", null).then(results => new OptionalContentConfig(results)); + getOptionalContentConfig(renderingIntent) { + return this.#cacheSimpleMethod("GetOptionalContentConfig").then(data => new OptionalContentConfig(data, renderingIntent)); } getPermissions() { return this.messageHandler.sendWithPromise("GetPermissions", null); @@ -10602,8 +10849,8 @@ class InternalRenderTask { } } } -const version = "4.1.249"; -const build = "d07f37f44"; +const version = "4.1.342"; +const build = "e384df6f1"; ;// CONCATENATED MODULE: ./src/shared/scripting_utils.js function makeColorComp(n) { @@ -11002,9 +11249,12 @@ class AnnotationElement { container.tabIndex = DEFAULT_TAB_INDEX; } container.style.zIndex = this.parent.zIndex++; - if (this.data.popupRef) { + if (data.popupRef) { container.setAttribute("aria-haspopup", "dialog"); } + if (data.alternativeText) { + container.title = data.alternativeText; + } if (data.noRotate) { container.classList.add("norotate"); } @@ -11652,9 +11902,6 @@ class TextAnnotationElement extends AnnotationElement { } class WidgetAnnotationElement extends AnnotationElement { render() { - if (this.data.alternativeText) { - this.container.title = this.data.alternativeText; - } return this.container; } showElementAndHideCanvas(element) { @@ -12255,9 +12502,6 @@ class PushButtonWidgetAnnotationElement extends LinkAnnotationElement { render() { const container = super.render(); container.classList.add("buttonWidgetAnnotation", "pushButton"); - if (this.data.alternativeText) { - container.title = this.data.alternativeText; - } const linkElement = container.lastChild; if (this.enableScripting && this.hasJSActions && linkElement) { this._setDefaultPropertiesFromJS(linkElement); @@ -13271,11 +13515,13 @@ class AnnotationLayer { +const EOL_PATTERN = /\r\n?|\n/g; class FreeTextEditor extends AnnotationEditor { #boundEditorDivBlur = this.editorDivBlur.bind(this); #boundEditorDivFocus = this.editorDivFocus.bind(this); #boundEditorDivInput = this.editorDivInput.bind(this); #boundEditorDivKeydown = this.editorDivKeydown.bind(this); + #boundEditorDivPaste = this.editorDivPaste.bind(this); #color; #content = ""; #editorDivId = `${this.id}-editor`; @@ -13428,6 +13674,7 @@ class FreeTextEditor extends AnnotationEditor { this.editorDiv.addEventListener("focus", this.#boundEditorDivFocus); this.editorDiv.addEventListener("blur", this.#boundEditorDivBlur); this.editorDiv.addEventListener("input", this.#boundEditorDivInput); + this.editorDiv.addEventListener("paste", this.#boundEditorDivPaste); } disableEditMode() { if (!this.isInEditMode()) { @@ -13443,6 +13690,7 @@ class FreeTextEditor extends AnnotationEditor { this.editorDiv.removeEventListener("focus", this.#boundEditorDivFocus); this.editorDiv.removeEventListener("blur", this.#boundEditorDivBlur); this.editorDiv.removeEventListener("input", this.#boundEditorDivInput); + this.editorDiv.removeEventListener("paste", this.#boundEditorDivPaste); this.div.focus({ preventScroll: true }); @@ -13484,10 +13732,8 @@ class FreeTextEditor extends AnnotationEditor { #extractText() { const buffer = []; this.editorDiv.normalize(); - const EOL_PATTERN = /\r\n?|\n/g; for (const child of this.editorDiv.childNodes) { - const content = child.nodeType === Node.TEXT_NODE ? child.nodeValue : child.innerText; - buffer.push(content.replaceAll(EOL_PATTERN, "")); + buffer.push(FreeTextEditor.#getNodeContent(child)); } return buffer.join("\n"); } @@ -13657,6 +13903,85 @@ class FreeTextEditor extends AnnotationEditor { } return this.div; } + static #getNodeContent(node) { + return (node.nodeType === Node.TEXT_NODE ? node.nodeValue : node.innerText).replaceAll(EOL_PATTERN, ""); + } + editorDivPaste(event) { + const clipboardData = event.clipboardData || window.clipboardData; + const { + types + } = clipboardData; + if (types.length === 1 && types[0] === "text/plain") { + return; + } + event.preventDefault(); + const paste = FreeTextEditor.#deserializeContent(clipboardData.getData("text") || "").replaceAll(EOL_PATTERN, "\n"); + if (!paste) { + return; + } + const selection = window.getSelection(); + if (!selection.rangeCount) { + return; + } + this.editorDiv.normalize(); + selection.deleteFromDocument(); + const range = selection.getRangeAt(0); + if (!paste.includes("\n")) { + range.insertNode(document.createTextNode(paste)); + this.editorDiv.normalize(); + selection.collapseToStart(); + return; + } + const { + startContainer, + startOffset + } = range; + const bufferBefore = []; + const bufferAfter = []; + if (startContainer.nodeType === Node.TEXT_NODE) { + const parent = startContainer.parentElement; + bufferAfter.push(startContainer.nodeValue.slice(startOffset).replaceAll(EOL_PATTERN, "")); + if (parent !== this.editorDiv) { + let buffer = bufferBefore; + for (const child of this.editorDiv.childNodes) { + if (child === parent) { + buffer = bufferAfter; + continue; + } + buffer.push(FreeTextEditor.#getNodeContent(child)); + } + } + bufferBefore.push(startContainer.nodeValue.slice(0, startOffset).replaceAll(EOL_PATTERN, "")); + } else if (startContainer === this.editorDiv) { + let buffer = bufferBefore; + let i = 0; + for (const child of this.editorDiv.childNodes) { + if (i++ === startOffset) { + buffer = bufferAfter; + } + buffer.push(FreeTextEditor.#getNodeContent(child)); + } + } + this.#content = `${bufferBefore.join("\n")}${paste}${bufferAfter.join("\n")}`; + this.#setContent(); + const newRange = new Range(); + let beforeLength = bufferBefore.reduce((acc, line) => acc + line.length, 0); + for (const { + firstChild + } of this.editorDiv.childNodes) { + if (firstChild.nodeType === Node.TEXT_NODE) { + const length = firstChild.nodeValue.length; + if (beforeLength <= length) { + newRange.setStart(firstChild, beforeLength); + newRange.setEnd(firstChild, beforeLength); + break; + } + beforeLength -= length; + } + } + selection.removeAllRanges(); + selection.addRange(newRange); + } #setContent() { this.editorDiv.replaceChildren(); if (!this.#content) { @@ -14392,6 +14717,7 @@ class ColorPicker { #dropdown = null; #dropdownWasFromKeyboard = false; #isMainColorPicker = false; + #editor = null; #eventBus; #uiManager = null; #type; @@ -14405,6 +14731,7 @@ class ColorPicker { if (editor) { this.#isMainColorPicker = false; this.#type = AnnotationEditorParamsType.HIGHLIGHT_COLOR; + this.#editor = editor; } else { this.#isMainColorPicker = true; this.#type = AnnotationEditorParamsType.HIGHLIGHT_DEFAULT_COLOR; @@ -14423,6 +14750,7 @@ class ColorPicker { button.addEventListener("keydown", this.#boundKeyDown); const swatch = this.#buttonSwatch = document.createElement("span"); swatch.className = "swatch"; + swatch.setAttribute("aria-hidden", true); swatch.style.backgroundColor = this.#defaultColor; button.append(swatch); return button; @@ -14546,7 +14874,11 @@ class ColorPicker { return this.#dropdown && !this.#dropdown.classList.contains("hidden"); } _hideDropdownFromKeyboard() { - if (this.#isMainColorPicker || !this.#isDropdownVisible) { + if (this.#isMainColorPicker) { + return; + } + if (!this.#isDropdownVisible) { + this.#editor?.unselect(); return; } this.hideDropdown(); @@ -14600,6 +14932,7 @@ class HighlightEditor extends AnnotationEditor { #lastPoint = null; #opacity; #outlineId = null; + #text = ""; #thickness; #methodOfCreation = ""; static _defaultColor = null; @@ -14633,6 +14966,7 @@ class HighlightEditor extends AnnotationEditor { this.#opacity = params.opacity || HighlightEditor._defaultOpacity; this.#boxes = params.boxes || null; this.#methodOfCreation = params.methodOfCreation || ""; + this.#text = params.text || ""; this._isDraggable = false; if (params.highlightId > -1) { this.#isFreeHighlight = true; @@ -14857,11 +15191,11 @@ class HighlightEditor extends AnnotationEditor { this.div.focus(); } remove() { - super.remove(); this.#cleanDrawLayer(); this._reportTelemetry({ action: "deleted" }); + super.remove(); } rebuild() { if (!this.parent) { @@ -14885,6 +15219,7 @@ class HighlightEditor extends AnnotationEditor { mustBeSelected = !this.parent && this.div?.classList.contains("selectedEditor"); } super.setParent(parent); + this.show(this._isVisible); if (mustBeSelected) { this.select(); } @@ -14979,6 +15314,12 @@ class HighlightEditor extends AnnotationEditor { return this.div; } const div = super.render(); + if (this.#text) { + const mark = document.createElement("mark"); + div.append(mark); + mark.append(document.createTextNode(this.#text)); + mark.className = "visuallyHidden"; + } if (this.#isFreeHighlight) { div.classList.add("free"); } else { @@ -14986,6 +15327,7 @@ class HighlightEditor extends AnnotationEditor { } const highlightDiv = this.#highlightDiv = document.createElement("div"); div.append(highlightDiv); + highlightDiv.setAttribute("aria-hidden", "true"); highlightDiv.className = "internal"; highlightDiv.style.clipPath = this.#clipPathId; const [parentWidth, parentHeight] = this.parentDimensions; @@ -15029,16 +15371,32 @@ class HighlightEditor extends AnnotationEditor { } select() { super.select(); + if (!this.#outlineId) { + return; + } this.parent?.drawLayer.removeClass(this.#outlineId, "hovered"); this.parent?.drawLayer.addClass(this.#outlineId, "selected"); } unselect() { super.unselect(); + if (!this.#outlineId) { + return; + } this.parent?.drawLayer.removeClass(this.#outlineId, "selected"); if (!this.#isFreeHighlight) { this.#setCaret(false); } } + get _mustFixPosition() { + return !this.#isFreeHighlight; + } + show(visible = this._isVisible) { + super.show(visible); + if (this.parent) { + this.parent.drawLayer.show(this.#id, visible); + this.parent.drawLayer.show(this.#outlineId, visible); + } + } #getRotation() { return this.#isFreeHighlight ? this.rotation : 0; } @@ -15487,7 +15845,7 @@ class InkEditor extends AnnotationEditor { this.allRawPaths.push(currentPath); this.paths.push(bezier); this.bezierPath2D.push(path2D); - this.rebuild(); + this._uiManager.rebuild(this); }; const undo = () => { this.allRawPaths.pop(); @@ -16114,7 +16472,7 @@ class StampEditor extends AnnotationEditor { if (this.div === null) { return; } - if (this.#bitmapId) { + if (this.#bitmapId && this.#canvas === null) { this.#getBitmap(); } if (!this.isAttachedToDOM) { @@ -16126,7 +16484,7 @@ class StampEditor extends AnnotationEditor { this.div.focus(); } isEmpty() { - return !(this.#bitmapPromise || this.#bitmap || this.#bitmapUrl || this.#bitmapFile); + return !(this.#bitmapPromise || this.#bitmap || this.#bitmapUrl || this.#bitmapFile || this.#bitmapId); } get isResizable() { return true; @@ -16142,6 +16500,7 @@ class StampEditor extends AnnotationEditor { } super.render(); this.div.hidden = true; + this.addAltTextButton(); if (this.#bitmap) { this.#createCanvas(); } else { @@ -16186,7 +16545,6 @@ class StampEditor extends AnnotationEditor { this._reportTelemetry({ action: "inserted_image" }); - this.addAltTextButton(); if (this.#bitmapFileName) { canvas.setAttribute("aria-label", this.#bitmapFileName); } @@ -16404,9 +16762,9 @@ class AnnotationEditorLayer { #accessibilityManager; #allowClick = false; #annotationLayer = null; - #boundPointerup = this.pointerup.bind(this); - #boundPointerdown = this.pointerdown.bind(this); - #boundTextLayerPointerDown = this.#textLayerPointerDown.bind(this); + #boundPointerup = null; + #boundPointerdown = null; + #boundTextLayerPointerDown = null; #editorFocusTimeoutId = null; #editors = new Map(); #hadPointerDown = false; @@ -16448,6 +16806,9 @@ class AnnotationEditorLayer { get isEmpty() { return this.#editors.size === 0; } + get isInvisible() { + return this.isEmpty && this.#uiManager.getMode() === AnnotationEditorType.NONE; + } updateToolbar(mode) { this.#uiManager.updateToolbar(mode); } @@ -16519,6 +16880,7 @@ class AnnotationEditorLayer { this.#annotationLayer?.div.classList.toggle("disabled", !enabled); } enable() { + this.div.tabIndex = 0; this.togglePointerEvents(true); const annotationElementIds = new Set(); for (const editor of this.#editors.values()) { @@ -16549,6 +16911,7 @@ class AnnotationEditorLayer { } disable() { this.#isDisabling = true; + this.div.tabIndex = -1; this.togglePointerEvents(false); const hiddenAnnotationIds = new Set(); for (const editor of this.#editors.values()) { @@ -16597,14 +16960,18 @@ class AnnotationEditorLayer { this.#uiManager.setActiveEditor(editor); } enableTextSelection() { - if (this.#textLayer?.div) { + this.div.tabIndex = -1; + if (this.#textLayer?.div && !this.#boundTextLayerPointerDown) { + this.#boundTextLayerPointerDown = this.#textLayerPointerDown.bind(this); this.#textLayer.div.addEventListener("pointerdown", this.#boundTextLayerPointerDown); this.#textLayer.div.classList.add("highlighting"); } } disableTextSelection() { - if (this.#textLayer?.div) { + this.div.tabIndex = 0; + if (this.#textLayer?.div && this.#boundTextLayerPointerDown) { this.#textLayer.div.removeEventListener("pointerdown", this.#boundTextLayerPointerDown); + this.#boundTextLayerPointerDown = null; this.#textLayer.div.classList.remove("highlighting"); } } @@ -16617,6 +16984,7 @@ class AnnotationEditorLayer { if (event.button !== 0 || event.ctrlKey && isMac) { return; } + this.#uiManager.showAllEditors("highlight", true, true); this.#textLayer.div.classList.add("free"); HighlightEditor.startHighlighting(this, this.#uiManager.direction === "ltr", event); this.#textLayer.div.addEventListener("pointerup", () => { @@ -16628,12 +16996,22 @@ class AnnotationEditorLayer { } } enableClick() { + if (this.#boundPointerdown) { + return; + } + this.#boundPointerdown = this.pointerdown.bind(this); + this.#boundPointerup = this.pointerup.bind(this); this.div.addEventListener("pointerdown", this.#boundPointerdown); this.div.addEventListener("pointerup", this.#boundPointerup); } disableClick() { + if (!this.#boundPointerdown) { + return; + } this.div.removeEventListener("pointerdown", this.#boundPointerdown); this.div.removeEventListener("pointerup", this.#boundPointerup); + this.#boundPointerdown = null; + this.#boundPointerup = null; } attach(editor) { this.#editors.set(editor.id, editor); @@ -16678,6 +17056,9 @@ class AnnotationEditorLayer { } } add(editor) { + if (editor.parent === this && editor.isAttachedToDOM) { + return; + } this.changeParent(editor); this.#uiManager.addEditor(editor); this.attach(editor); @@ -16720,6 +17101,7 @@ class AnnotationEditorLayer { if (editor.needsToBeRebuilt()) { editor.parent ||= this; editor.rebuild(); + editor.show(); } else { this.add(editor); } @@ -16910,6 +17292,7 @@ class AnnotationEditorLayer { setLayerDimensions(this.div, viewport); for (const editor of this.#uiManager.getEditors(this.pageIndex)) { this.add(editor); + editor.rebuild(); } this.updateMode(); } @@ -16917,6 +17300,7 @@ class AnnotationEditorLayer { viewport }) { this.#uiManager.commitOrRemove(); + this.#cleanup(); const oldRotation = this.viewport.rotation; const rotation = viewport.rotation; this.viewport = viewport; @@ -16928,7 +17312,7 @@ class AnnotationEditorLayer { editor.rotate(rotation); } } - this.updateMode(); + this.addInkEditorIfNeeded(false); } get pageDimensions() { const { @@ -16990,6 +17374,7 @@ class DrawLayer { #createSVG(box) { const svg = DrawLayer._svgFactory.create(1, 1, true); this.#parent.append(svg); + svg.setAttribute("aria-hidden", true); DrawLayer.#setBox(svg, box); return svg; } @@ -17102,6 +17487,9 @@ class DrawLayer { updateBox(id, box) { DrawLayer.#setBox(this.#mapping.get(id), box); } + show(id, visible) { + this.#mapping.get(id).classList.toggle("hidden", !visible); + } rotate(id, angle) { this.#mapping.get(id).setAttribute("data-main-rotation", angle); } @@ -17146,8 +17534,8 @@ class DrawLayer { -const pdfjsVersion = "4.1.249"; -const pdfjsBuild = "d07f37f44"; +const pdfjsVersion = "4.1.342"; +const pdfjsBuild = "e384df6f1"; var __webpack_exports__AbortException = __webpack_exports__.AbortException; var __webpack_exports__AnnotationEditorLayer = __webpack_exports__.AnnotationEditorLayer; -- cgit v1.2.3