Merge pull request #16521 from calixteman/restore_connect_layers

[Editor] Connect then annotation layer and the editor one
This commit is contained in:
calixteman 2023-06-05 14:20:24 +02:00 committed by GitHub
commit 77fb6834d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 79 additions and 3 deletions

View File

@ -20,6 +20,7 @@
import { import {
AnnotationBorderStyleType, AnnotationBorderStyleType,
AnnotationEditorType,
AnnotationType, AnnotationType,
assert, assert,
FeatureTest, FeatureTest,
@ -504,7 +505,7 @@ class AnnotationElement {
* *
* @public * @public
* @memberof AnnotationElement * @memberof AnnotationElement
* @returns {HTMLElement|Array<HTMLElement>} A section element or * @returns {HTMLElement|Array<HTMLElement>|undefined} A section element or
* an array of section elements. * an array of section elements.
*/ */
render() { render() {
@ -558,6 +559,18 @@ class AnnotationElement {
} }
return fields; return fields;
} }
show() {
if (this.container) {
this.container.hidden = false;
}
}
hide() {
if (this.container) {
this.container.hidden = true;
}
}
} }
class LinkAnnotationElement extends AnnotationElement { class LinkAnnotationElement extends AnnotationElement {
@ -2048,6 +2061,7 @@ class FreeTextAnnotationElement extends AnnotationElement {
); );
super(parameters, { isRenderable, ignoreBorder: true }); super(parameters, { isRenderable, ignoreBorder: true });
this.textContent = parameters.data.textContent; this.textContent = parameters.data.textContent;
this.annotationEditorType = AnnotationEditorType.FREETEXT;
} }
render() { render() {
@ -2328,6 +2342,7 @@ class InkAnnotationElement extends AnnotationElement {
// Use the polyline SVG element since it allows us to use coordinates // Use the polyline SVG element since it allows us to use coordinates
// directly and to draw both straight lines and curves. // directly and to draw both straight lines and curves.
this.svgElementName = "svg:polyline"; this.svgElementName = "svg:polyline";
this.annotationEditorType = AnnotationEditorType.INK;
} }
render() { render() {
@ -2596,6 +2611,9 @@ class FileAttachmentAnnotationElement extends AnnotationElement {
* @property {TextAccessibilityManager} [accessibilityManager] * @property {TextAccessibilityManager} [accessibilityManager]
*/ */
/**
* Manage the layer containing all the annotations.
*/
class AnnotationLayer { class AnnotationLayer {
#accessibilityManager = null; #accessibilityManager = null;
@ -2603,6 +2621,8 @@ class AnnotationLayer {
#div = null; #div = null;
#editableAnnotations = new Set();
constructor({ div, accessibilityManager, annotationCanvasMap }) { constructor({ div, accessibilityManager, annotationCanvasMap }) {
this.#div = div; this.#div = div;
this.#accessibilityManager = accessibilityManager; this.#accessibilityManager = accessibilityManager;
@ -2666,6 +2686,11 @@ class AnnotationLayer {
if (!element.isRenderable) { if (!element.isRenderable) {
continue; continue;
} }
if (element.annotationEditorType > 0) {
this.#editableAnnotations.add(element);
}
const rendered = element.render(); const rendered = element.render();
if (data.hidden) { if (data.hidden) {
rendered.style.visibility = "hidden"; rendered.style.visibility = "hidden";
@ -2732,6 +2757,10 @@ class AnnotationLayer {
} }
this.#annotationCanvasMap.clear(); this.#annotationCanvasMap.clear();
} }
getEditableAnnotations() {
return this.#editableAnnotations;
}
} }
export { AnnotationLayer }; export { AnnotationLayer, FreeTextAnnotationElement, InkAnnotationElement };

View File

@ -20,6 +20,8 @@
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
/** @typedef {import("../../web/text_accessibility.js").TextAccessibilityManager} TextAccessibilityManager */ /** @typedef {import("../../web/text_accessibility.js").TextAccessibilityManager} TextAccessibilityManager */
/** @typedef {import("../../web/interfaces").IL10n} IL10n */ /** @typedef {import("../../web/interfaces").IL10n} IL10n */
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/annotation_layer.js").AnnotationLayer} AnnotationLayer */
import { AnnotationEditorType, FeatureTest } from "../../shared/util.js"; import { AnnotationEditorType, FeatureTest } from "../../shared/util.js";
import { bindEvents } from "./tools.js"; import { bindEvents } from "./tools.js";
@ -36,6 +38,7 @@ import { setLayerDimensions } from "../display_utils.js";
* @property {TextAccessibilityManager} [accessibilityManager] * @property {TextAccessibilityManager} [accessibilityManager]
* @property {number} pageIndex * @property {number} pageIndex
* @property {IL10n} l10n * @property {IL10n} l10n
* @property {AnnotationLayer} [annotationLayer]
*/ */
/** /**
@ -51,6 +54,8 @@ class AnnotationEditorLayer {
#allowClick = false; #allowClick = false;
#annotationLayer = null;
#boundPointerup = this.pointerup.bind(this); #boundPointerup = this.pointerup.bind(this);
#boundPointerdown = this.pointerdown.bind(this); #boundPointerdown = this.pointerdown.bind(this);
@ -80,6 +85,7 @@ class AnnotationEditorLayer {
this.pageIndex = options.pageIndex; this.pageIndex = options.pageIndex;
this.div = options.div; this.div = options.div;
this.#accessibilityManager = options.accessibilityManager; this.#accessibilityManager = options.accessibilityManager;
this.#annotationLayer = options.annotationLayer;
this.#uiManager.addLayer(this); this.#uiManager.addLayer(this);
} }
@ -169,6 +175,17 @@ class AnnotationEditorLayer {
*/ */
enable() { enable() {
this.div.style.pointerEvents = "auto"; this.div.style.pointerEvents = "auto";
if (this.#annotationLayer) {
const editables = this.#annotationLayer.getEditableAnnotations();
for (const editable of editables) {
const editor = this.deserialize(editable);
if (!editor) {
continue;
}
editable.hide();
this.addOrRebuild(editor);
}
}
for (const editor of this.#editors.values()) { for (const editor of this.#editors.values()) {
editor.enableEditing(); editor.enableEditing();
} }
@ -181,6 +198,10 @@ class AnnotationEditorLayer {
this.div.style.pointerEvents = "none"; this.div.style.pointerEvents = "none";
for (const editor of this.#editors.values()) { for (const editor of this.#editors.values()) {
editor.disableEditing(); editor.disableEditing();
if (!editor.hasElementChanged()) {
editor.annotationElement.show();
editor.remove();
}
} }
this.#cleanup(); this.#cleanup();
if (this.isEmpty) { if (this.isEmpty) {
@ -368,7 +389,7 @@ class AnnotationEditorLayer {
* @returns {AnnotationEditor} * @returns {AnnotationEditor}
*/ */
deserialize(data) { deserialize(data) {
switch (data.annotationType) { switch (data.annotationType ?? data.annotationEditorType) {
case AnnotationEditorType.FREETEXT: case AnnotationEditorType.FREETEXT:
return FreeTextEditor.deserialize(data, this, this.#uiManager); return FreeTextEditor.deserialize(data, this, this.#uiManager);
case AnnotationEditorType.INK: case AnnotationEditorType.INK:

View File

@ -67,6 +67,7 @@ class AnnotationEditor {
this.name = parameters.name; this.name = parameters.name;
this.div = null; this.div = null;
this._uiManager = parameters.uiManager; this._uiManager = parameters.uiManager;
this.annotationElement = null;
const { const {
rotation, rotation,
@ -599,6 +600,15 @@ class AnnotationEditor {
this.parent.setActiveEditor(null); this.parent.setActiveEditor(null);
} }
} }
/**
* Check if the editor has been changed.
* @param {Object} serialized
* @returns {boolean}
*/
hasElementChanged(serialized = null) {
return false;
}
} }
export { AnnotationEditor }; export { AnnotationEditor };

View File

@ -26,6 +26,7 @@ import {
} from "../../shared/util.js"; } from "../../shared/util.js";
import { bindEvents, KeyboardManager } from "./tools.js"; import { bindEvents, KeyboardManager } from "./tools.js";
import { AnnotationEditor } from "./editor.js"; import { AnnotationEditor } from "./editor.js";
import { FreeTextAnnotationElement } from "../annotation_layer.js";
/** /**
* Basic text editor in order to create a FreeTex annotation. * Basic text editor in order to create a FreeTex annotation.
@ -489,6 +490,9 @@ class FreeTextEditor extends AnnotationEditor {
/** @inheritdoc */ /** @inheritdoc */
static deserialize(data, parent, uiManager) { static deserialize(data, parent, uiManager) {
if (data instanceof FreeTextAnnotationElement) {
return null;
}
const editor = super.deserialize(data, parent, uiManager); const editor = super.deserialize(data, parent, uiManager);
editor.#fontSize = data.fontSize; editor.#fontSize = data.fontSize;

View File

@ -19,6 +19,7 @@ import {
Util, Util,
} from "../../shared/util.js"; } from "../../shared/util.js";
import { AnnotationEditor } from "./editor.js"; import { AnnotationEditor } from "./editor.js";
import { InkAnnotationElement } from "../annotation_layer.js";
import { opacityToHex } from "./tools.js"; import { opacityToHex } from "./tools.js";
// The dimensions of the resizer is 15x15: // The dimensions of the resizer is 15x15:
@ -1130,6 +1131,9 @@ class InkEditor extends AnnotationEditor {
/** @inheritdoc */ /** @inheritdoc */
static deserialize(data, parent, uiManager) { static deserialize(data, parent, uiManager) {
if (data instanceof InkAnnotationElement) {
return null;
}
const editor = super.deserialize(data, parent, uiManager); const editor = super.deserialize(data, parent, uiManager);
editor.thickness = data.thickness; editor.thickness = data.thickness;

View File

@ -21,6 +21,8 @@
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
/** @typedef {import("./text_accessibility.js").TextAccessibilityManager} TextAccessibilityManager */ /** @typedef {import("./text_accessibility.js").TextAccessibilityManager} TextAccessibilityManager */
/** @typedef {import("./interfaces").IL10n} IL10n */ /** @typedef {import("./interfaces").IL10n} IL10n */
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/annotation_layer.js").AnnotationLayer} AnnotationLayer */
import { AnnotationEditorLayer } from "pdfjs-lib"; import { AnnotationEditorLayer } from "pdfjs-lib";
import { NullL10n } from "./l10n_utils.js"; import { NullL10n } from "./l10n_utils.js";
@ -32,9 +34,12 @@ import { NullL10n } from "./l10n_utils.js";
* @property {PDFPageProxy} pdfPage * @property {PDFPageProxy} pdfPage
* @property {IL10n} [l10n] * @property {IL10n} [l10n]
* @property {TextAccessibilityManager} [accessibilityManager] * @property {TextAccessibilityManager} [accessibilityManager]
* @property {AnnotationLayer} [annotationLayer]
*/ */
class AnnotationEditorLayerBuilder { class AnnotationEditorLayerBuilder {
#annotationLayer = null;
#uiManager; #uiManager;
/** /**
@ -49,6 +54,7 @@ class AnnotationEditorLayerBuilder {
this.div = null; this.div = null;
this._cancelled = false; this._cancelled = false;
this.#uiManager = options.uiManager; this.#uiManager = options.uiManager;
this.#annotationLayer = options.annotationLayer || null;
} }
/** /**
@ -85,6 +91,7 @@ class AnnotationEditorLayerBuilder {
pageIndex: this.pdfPage.pageNumber - 1, pageIndex: this.pdfPage.pageNumber - 1,
l10n: this.l10n, l10n: this.l10n,
viewport: clonedViewport, viewport: clonedViewport,
annotationLayer: this.#annotationLayer,
}); });
const parameters = { const parameters = {

View File

@ -979,6 +979,7 @@ class PDFPageView {
pdfPage, pdfPage,
l10n, l10n,
accessibilityManager: this._accessibilityManager, accessibilityManager: this._accessibilityManager,
annotationLayer: this.annotationLayer?.annotationLayer,
}); });
} }
this.#renderAnnotationEditorLayer(); this.#renderAnnotationEditorLayer();