mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-20 15:18:08 +02:00
[Editor] Make the text layer focusable before the editors (bug 1881746)
Keep the different layers in a constant order to avoid the use of a z-index and a tab-index.
This commit is contained in:
parent
0022310b9c
commit
1b00511301
14 changed files with 187 additions and 36 deletions
|
@ -109,7 +109,6 @@
|
|||
font-size: calc(100px * var(--scale-factor));
|
||||
transform-origin: 0 0;
|
||||
cursor: auto;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.annotationEditorLayer.waiting {
|
||||
|
|
|
@ -30,13 +30,13 @@ import { GenericL10n } from "web-null_l10n";
|
|||
/**
|
||||
* @typedef {Object} AnnotationEditorLayerBuilderOptions
|
||||
* @property {AnnotationEditorUIManager} [uiManager]
|
||||
* @property {HTMLDivElement} pageDiv
|
||||
* @property {PDFPageProxy} pdfPage
|
||||
* @property {IL10n} [l10n]
|
||||
* @property {TextAccessibilityManager} [accessibilityManager]
|
||||
* @property {AnnotationLayer} [annotationLayer]
|
||||
* @property {TextLayer} [textLayer]
|
||||
* @property {DrawLayer} [drawLayer]
|
||||
* @property {function} [onAppend]
|
||||
*/
|
||||
|
||||
class AnnotationEditorLayerBuilder {
|
||||
|
@ -44,6 +44,8 @@ class AnnotationEditorLayerBuilder {
|
|||
|
||||
#drawLayer = null;
|
||||
|
||||
#onAppend = null;
|
||||
|
||||
#textLayer = null;
|
||||
|
||||
#uiManager;
|
||||
|
@ -52,7 +54,6 @@ class AnnotationEditorLayerBuilder {
|
|||
* @param {AnnotationEditorLayerBuilderOptions} options
|
||||
*/
|
||||
constructor(options) {
|
||||
this.pageDiv = options.pageDiv;
|
||||
this.pdfPage = options.pdfPage;
|
||||
this.accessibilityManager = options.accessibilityManager;
|
||||
this.l10n = options.l10n;
|
||||
|
@ -66,6 +67,7 @@ class AnnotationEditorLayerBuilder {
|
|||
this.#annotationLayer = options.annotationLayer || null;
|
||||
this.#textLayer = options.textLayer || null;
|
||||
this.#drawLayer = options.drawLayer || null;
|
||||
this.#onAppend = options.onAppend || null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,10 +93,9 @@ class AnnotationEditorLayerBuilder {
|
|||
// Create an AnnotationEditor layer div
|
||||
const div = (this.div = document.createElement("div"));
|
||||
div.className = "annotationEditorLayer";
|
||||
div.tabIndex = 0;
|
||||
div.hidden = true;
|
||||
div.dir = this.#uiManager.direction;
|
||||
this.pageDiv.append(div);
|
||||
this.#onAppend?.(div);
|
||||
|
||||
this.annotationEditorLayer = new AnnotationEditorLayer({
|
||||
uiManager: this.#uiManager,
|
||||
|
@ -125,7 +126,6 @@ class AnnotationEditorLayerBuilder {
|
|||
if (!this.div) {
|
||||
return;
|
||||
}
|
||||
this.pageDiv = null;
|
||||
this.annotationEditorLayer.destroy();
|
||||
this.div.remove();
|
||||
}
|
||||
|
|
|
@ -76,7 +76,6 @@
|
|||
left: 0;
|
||||
pointer-events: none;
|
||||
transform-origin: 0 0;
|
||||
z-index: 3;
|
||||
|
||||
&[data-main-rotation="90"] .norotate {
|
||||
transform: rotate(270deg) translateX(-100%);
|
||||
|
|
|
@ -28,7 +28,6 @@ import { PresentationModeState } from "./ui_utils.js";
|
|||
|
||||
/**
|
||||
* @typedef {Object} AnnotationLayerBuilderOptions
|
||||
* @property {HTMLDivElement} pageDiv
|
||||
* @property {PDFPageProxy} pdfPage
|
||||
* @property {AnnotationStorage} [annotationStorage]
|
||||
* @property {string} [imageResourcesPath] - Path for image resources, mainly
|
||||
|
@ -42,16 +41,18 @@ import { PresentationModeState } from "./ui_utils.js";
|
|||
* [fieldObjectsPromise]
|
||||
* @property {Map<string, HTMLCanvasElement>} [annotationCanvasMap]
|
||||
* @property {TextAccessibilityManager} [accessibilityManager]
|
||||
* @property {function} [onAppend]
|
||||
*/
|
||||
|
||||
class AnnotationLayerBuilder {
|
||||
#onAppend = null;
|
||||
|
||||
#onPresentationModeChanged = null;
|
||||
|
||||
/**
|
||||
* @param {AnnotationLayerBuilderOptions} options
|
||||
*/
|
||||
constructor({
|
||||
pageDiv,
|
||||
pdfPage,
|
||||
linkService,
|
||||
downloadManager,
|
||||
|
@ -63,8 +64,8 @@ class AnnotationLayerBuilder {
|
|||
fieldObjectsPromise = null,
|
||||
annotationCanvasMap = null,
|
||||
accessibilityManager = null,
|
||||
onAppend = null,
|
||||
}) {
|
||||
this.pageDiv = pageDiv;
|
||||
this.pdfPage = pdfPage;
|
||||
this.linkService = linkService;
|
||||
this.downloadManager = downloadManager;
|
||||
|
@ -76,6 +77,7 @@ class AnnotationLayerBuilder {
|
|||
this._fieldObjectsPromise = fieldObjectsPromise || Promise.resolve(null);
|
||||
this._annotationCanvasMap = annotationCanvasMap;
|
||||
this._accessibilityManager = accessibilityManager;
|
||||
this.#onAppend = onAppend;
|
||||
|
||||
this.annotationLayer = null;
|
||||
this.div = null;
|
||||
|
@ -115,7 +117,7 @@ class AnnotationLayerBuilder {
|
|||
// if there is at least one annotation.
|
||||
const div = (this.div = document.createElement("div"));
|
||||
div.className = "annotationLayer";
|
||||
this.pageDiv.append(div);
|
||||
this.#onAppend?.(div);
|
||||
|
||||
if (annotations.length === 0) {
|
||||
this.hide();
|
||||
|
|
|
@ -99,6 +99,14 @@ const DEFAULT_LAYER_PROPERTIES =
|
|||
},
|
||||
};
|
||||
|
||||
const LAYERS_ORDER = new Map([
|
||||
["canvasWrapper", 0],
|
||||
["textLayer", 1],
|
||||
["annotationLayer", 2],
|
||||
["annotationEditorLayer", 3],
|
||||
["xfaLayer", 2],
|
||||
]);
|
||||
|
||||
/**
|
||||
* @implements {IRenderableView}
|
||||
*/
|
||||
|
@ -127,6 +135,8 @@ class PDFPageView {
|
|||
|
||||
#viewportMap = new WeakMap();
|
||||
|
||||
#layers = [null, null, null, null];
|
||||
|
||||
/**
|
||||
* @param {PDFPageViewOptions} options
|
||||
*/
|
||||
|
@ -223,6 +233,19 @@ class PDFPageView {
|
|||
}
|
||||
}
|
||||
|
||||
#addLayer(div, name) {
|
||||
const pos = LAYERS_ORDER.get(name);
|
||||
this.#layers[pos] = div;
|
||||
for (let i = pos - 1; i >= 0; i--) {
|
||||
const layer = this.#layers[i];
|
||||
if (layer) {
|
||||
layer.after(div);
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.div.prepend(div);
|
||||
}
|
||||
|
||||
get renderingState() {
|
||||
return this.#renderingState;
|
||||
}
|
||||
|
@ -392,7 +415,7 @@ class PDFPageView {
|
|||
if (this.xfaLayer?.div) {
|
||||
// Pause translation when inserting the xfaLayer in the DOM.
|
||||
this.l10n.pause();
|
||||
this.div.append(this.xfaLayer.div);
|
||||
this.#addLayer(this.xfaLayer.div, "xfaLayer");
|
||||
this.l10n.resume();
|
||||
}
|
||||
|
||||
|
@ -531,6 +554,10 @@ class PDFPageView {
|
|||
continue;
|
||||
}
|
||||
node.remove();
|
||||
const layerIndex = this.#layers.indexOf(node);
|
||||
if (layerIndex >= 0) {
|
||||
this.#layers[layerIndex] = null;
|
||||
}
|
||||
}
|
||||
div.removeAttribute("data-loaded");
|
||||
|
||||
|
@ -877,7 +904,8 @@ class PDFPageView {
|
|||
// overflow will be hidden in Firefox.
|
||||
const canvasWrapper = document.createElement("div");
|
||||
canvasWrapper.classList.add("canvasWrapper");
|
||||
div.append(canvasWrapper);
|
||||
canvasWrapper.setAttribute("aria-hidden", true);
|
||||
this.#addLayer(canvasWrapper, "canvasWrapper");
|
||||
|
||||
if (
|
||||
!this.textLayer &&
|
||||
|
@ -891,13 +919,13 @@ class PDFPageView {
|
|||
accessibilityManager: this._accessibilityManager,
|
||||
enablePermissions:
|
||||
this.#textLayerMode === TextLayerMode.ENABLE_PERMISSIONS,
|
||||
onAppend: textLayerDiv => {
|
||||
// Pause translation when inserting the textLayer in the DOM.
|
||||
this.l10n.pause();
|
||||
this.#addLayer(textLayerDiv, "textLayer");
|
||||
this.l10n.resume();
|
||||
},
|
||||
});
|
||||
this.textLayer.onAppend = textLayerDiv => {
|
||||
// Pause translation when inserting the textLayer in the DOM.
|
||||
this.l10n.pause();
|
||||
this.div.append(textLayerDiv);
|
||||
this.l10n.resume();
|
||||
};
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -915,7 +943,6 @@ class PDFPageView {
|
|||
|
||||
this._annotationCanvasMap ||= new Map();
|
||||
this.annotationLayer = new AnnotationLayerBuilder({
|
||||
pageDiv: div,
|
||||
pdfPage,
|
||||
annotationStorage,
|
||||
imageResourcesPath: this.imageResourcesPath,
|
||||
|
@ -927,6 +954,9 @@ class PDFPageView {
|
|||
fieldObjectsPromise,
|
||||
annotationCanvasMap: this._annotationCanvasMap,
|
||||
accessibilityManager: this._accessibilityManager,
|
||||
onAppend: annotationLayerDiv => {
|
||||
this.#addLayer(annotationLayerDiv, "annotationLayer");
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1042,13 +1072,15 @@ class PDFPageView {
|
|||
if (!this.annotationEditorLayer) {
|
||||
this.annotationEditorLayer = new AnnotationEditorLayerBuilder({
|
||||
uiManager: annotationEditorUIManager,
|
||||
pageDiv: div,
|
||||
pdfPage,
|
||||
l10n,
|
||||
accessibilityManager: this._accessibilityManager,
|
||||
annotationLayer: this.annotationLayer?.annotationLayer,
|
||||
textLayer: this.textLayer,
|
||||
drawLayer: this.drawLayer.getDrawLayer(),
|
||||
onAppend: annotationEditorLayerDiv => {
|
||||
this.#addLayer(annotationEditorLayerDiv, "annotationEditorLayer");
|
||||
},
|
||||
});
|
||||
}
|
||||
this.#renderAnnotationEditorLayer();
|
||||
|
|
|
@ -75,7 +75,6 @@
|
|||
overflow: hidden;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.pdfViewer .page {
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
text-size-adjust: none;
|
||||
forced-color-adjust: none;
|
||||
transform-origin: 0 0;
|
||||
z-index: 2;
|
||||
caret-color: CanvasText;
|
||||
|
||||
&.highlighting {
|
||||
|
|
|
@ -28,6 +28,7 @@ import { removeNullCharacters } from "./ui_utils.js";
|
|||
* @property {TextHighlighter} highlighter - Optional object that will handle
|
||||
* highlighting text from the find controller.
|
||||
* @property {TextAccessibilityManager} [accessibilityManager]
|
||||
* @property {function} [onAppend]
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -38,6 +39,8 @@ import { removeNullCharacters } from "./ui_utils.js";
|
|||
class TextLayerBuilder {
|
||||
#enablePermissions = false;
|
||||
|
||||
#onAppend = null;
|
||||
|
||||
#rotation = 0;
|
||||
|
||||
#scale = 0;
|
||||
|
@ -48,6 +51,7 @@ class TextLayerBuilder {
|
|||
highlighter = null,
|
||||
accessibilityManager = null,
|
||||
enablePermissions = false,
|
||||
onAppend = null,
|
||||
}) {
|
||||
this.textContentItemsStr = [];
|
||||
this.renderingDone = false;
|
||||
|
@ -57,14 +61,10 @@ class TextLayerBuilder {
|
|||
this.highlighter = highlighter;
|
||||
this.accessibilityManager = accessibilityManager;
|
||||
this.#enablePermissions = enablePermissions === true;
|
||||
|
||||
/**
|
||||
* Callback used to attach the textLayer to the DOM.
|
||||
* @type {function}
|
||||
*/
|
||||
this.onAppend = null;
|
||||
this.#onAppend = onAppend;
|
||||
|
||||
this.div = document.createElement("div");
|
||||
this.div.tabIndex = 0;
|
||||
this.div.className = "textLayer";
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ class TextLayerBuilder {
|
|||
this.#rotation = rotation;
|
||||
// Ensure that the textLayer is appended to the DOM *before* handling
|
||||
// e.g. a pending search operation.
|
||||
this.onAppend(this.div);
|
||||
this.#onAppend?.(this.div);
|
||||
this.highlighter?.enable();
|
||||
this.accessibilityManager?.enable();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue