From 6545551e761330d9cc98036c392182ef3a6bfb9d Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Thu, 21 Sep 2023 18:40:35 +0200 Subject: [PATCH] [Editor] Avoid to darken the current editor when opening the alt-text dialog --- src/pdf.js | 2 ++ test/unit/pdf_spec.js | 2 ++ web/alt_text_manager.js | 48 ++++++++++++++++++++++++- web/annotation_editor_layer_builder.css | 2 +- 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/pdf.js b/src/pdf.js index 6e097586b..7c7b0e88e 100644 --- a/src/pdf.js +++ b/src/pdf.js @@ -54,6 +54,7 @@ import { version, } from "./display/api.js"; import { + DOMSVGFactory, getFilenameFromUrl, getPdfFilenameFromUrl, getXfaPageViewport, @@ -90,6 +91,7 @@ export { build, CMapCompressionType, createValidAbsoluteUrl, + DOMSVGFactory, FeatureTest, getDocument, getFilenameFromUrl, diff --git a/test/unit/pdf_spec.js b/test/unit/pdf_spec.js index 3f2fd210a..6631c883f 100644 --- a/test/unit/pdf_spec.js +++ b/test/unit/pdf_spec.js @@ -43,6 +43,7 @@ import { version, } from "../../src/display/api.js"; import { + DOMSVGFactory, getFilenameFromUrl, getPdfFilenameFromUrl, getXfaPageViewport, @@ -86,6 +87,7 @@ describe("pdfjs_api", function () { build, CMapCompressionType, createValidAbsoluteUrl, + DOMSVGFactory, FeatureTest, getDocument, getFilenameFromUrl, diff --git a/web/alt_text_manager.js b/web/alt_text_manager.js index 350728350..2006e82f6 100644 --- a/web/alt_text_manager.js +++ b/web/alt_text_manager.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { shadow } from "pdfjs-lib"; +import { DOMSVGFactory, shadow } from "pdfjs-lib"; class AltTextManager { #boundUpdateUIState = this.#updateUIState.bind(this); @@ -46,6 +46,10 @@ class AltTextManager { #previousAltText = null; + #svgElement = null; + + #rectElement = null; + constructor( { dialog, @@ -87,11 +91,46 @@ class AltTextManager { ]); } + #createSVGElement() { + if (this.#svgElement) { + return; + } + + // We create a mask to add to the dialog backdrop: the idea is to have a + // darken background everywhere except on the editor to clearly see the + // picture to describe. + + const svgFactory = new DOMSVGFactory(); + const svg = (this.#svgElement = svgFactory.createElement("svg")); + svg.setAttribute("width", "0"); + svg.setAttribute("height", "0"); + const defs = svgFactory.createElement("defs"); + svg.append(defs); + const mask = svgFactory.createElement("mask"); + defs.append(mask); + mask.setAttribute("id", "alttext-manager-mask"); + mask.setAttribute("maskContentUnits", "objectBoundingBox"); + let rect = svgFactory.createElement("rect"); + mask.append(rect); + rect.setAttribute("fill", "white"); + rect.setAttribute("width", "1"); + rect.setAttribute("height", "1"); + rect.setAttribute("x", "0"); + rect.setAttribute("y", "0"); + + rect = this.#rectElement = svgFactory.createElement("rect"); + mask.append(rect); + rect.setAttribute("fill", "black"); + this.#dialog.append(svg); + } + async editAltText(uiManager, editor) { if (this.#currentEditor || !editor) { return; } + this.#createSVGElement(); + this.#hasUsedPointer = false; for (const element of this._elements) { element.addEventListener("pointerdown", this.#boundPointerDown); @@ -134,6 +173,11 @@ class AltTextManager { const MARGIN = 10; const isLTR = this.#uiManager.direction === "ltr"; + this.#rectElement.setAttribute("width", `${width / windowW}`); + this.#rectElement.setAttribute("height", `${height / windowH}`); + this.#rectElement.setAttribute("x", `${x / windowW}`); + this.#rectElement.setAttribute("y", `${y / windowH}`); + let left = null; let top = y; top += Math.min(windowH - (top + dialogH), 0); @@ -254,6 +298,8 @@ class AltTextManager { this.#currentEditor = null; this.#uiManager = null; this.#finish(); + this.#svgElement?.remove(); + this.#svgElement = this.#rectElement = null; } } diff --git a/web/annotation_editor_layer_builder.css b/web/annotation_editor_layer_builder.css index 43fd34be9..66be0a0c3 100644 --- a/web/annotation_editor_layer_builder.css +++ b/web/annotation_editor_layer_builder.css @@ -688,7 +688,7 @@ &::backdrop { /* This is needed to avoid to darken the image the user want to describe. */ - display: none; + mask: url(#alttext-manager-mask); } &.positioned {