Merge pull request #18284 from calixteman/editor_signal
[Editor] Remove the various listeners when destroying the editor manager
This commit is contained in:
commit
c53f71a7d2
@ -49,20 +49,27 @@ class AltText {
|
|||||||
altText.textContent = msg;
|
altText.textContent = msg;
|
||||||
altText.setAttribute("aria-label", msg);
|
altText.setAttribute("aria-label", msg);
|
||||||
altText.tabIndex = "0";
|
altText.tabIndex = "0";
|
||||||
altText.addEventListener("contextmenu", noContextMenu);
|
const signal = this.#editor._uiManager._signal;
|
||||||
altText.addEventListener("pointerdown", event => event.stopPropagation());
|
altText.addEventListener("contextmenu", noContextMenu, { signal });
|
||||||
|
altText.addEventListener("pointerdown", event => event.stopPropagation(), {
|
||||||
|
signal,
|
||||||
|
});
|
||||||
|
|
||||||
const onClick = event => {
|
const onClick = event => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.#editor._uiManager.editAltText(this.#editor);
|
this.#editor._uiManager.editAltText(this.#editor);
|
||||||
};
|
};
|
||||||
altText.addEventListener("click", onClick, { capture: true });
|
altText.addEventListener("click", onClick, { capture: true, signal });
|
||||||
altText.addEventListener("keydown", event => {
|
altText.addEventListener(
|
||||||
if (event.target === altText && event.key === "Enter") {
|
"keydown",
|
||||||
this.#altTextWasFromKeyBoard = true;
|
event => {
|
||||||
onClick(event);
|
if (event.target === altText && event.key === "Enter") {
|
||||||
}
|
this.#altTextWasFromKeyBoard = true;
|
||||||
});
|
onClick(event);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ signal }
|
||||||
|
);
|
||||||
await this.#setState();
|
await this.#setState();
|
||||||
|
|
||||||
return altText;
|
return altText;
|
||||||
@ -142,22 +149,39 @@ class AltText {
|
|||||||
button.setAttribute("aria-describedby", id);
|
button.setAttribute("aria-describedby", id);
|
||||||
|
|
||||||
const DELAY_TO_SHOW_TOOLTIP = 100;
|
const DELAY_TO_SHOW_TOOLTIP = 100;
|
||||||
button.addEventListener("mouseenter", () => {
|
const signal = this.#editor._uiManager._signal;
|
||||||
this.#altTextTooltipTimeout = setTimeout(() => {
|
signal.addEventListener(
|
||||||
this.#altTextTooltipTimeout = null;
|
"abort",
|
||||||
this.#altTextTooltip.classList.add("show");
|
() => {
|
||||||
this.#editor._reportTelemetry({
|
|
||||||
action: "alt_text_tooltip",
|
|
||||||
});
|
|
||||||
}, DELAY_TO_SHOW_TOOLTIP);
|
|
||||||
});
|
|
||||||
button.addEventListener("mouseleave", () => {
|
|
||||||
if (this.#altTextTooltipTimeout) {
|
|
||||||
clearTimeout(this.#altTextTooltipTimeout);
|
clearTimeout(this.#altTextTooltipTimeout);
|
||||||
this.#altTextTooltipTimeout = null;
|
this.#altTextTooltipTimeout = null;
|
||||||
}
|
},
|
||||||
this.#altTextTooltip?.classList.remove("show");
|
{ once: true }
|
||||||
});
|
);
|
||||||
|
button.addEventListener(
|
||||||
|
"mouseenter",
|
||||||
|
() => {
|
||||||
|
this.#altTextTooltipTimeout = setTimeout(() => {
|
||||||
|
this.#altTextTooltipTimeout = null;
|
||||||
|
this.#altTextTooltip.classList.add("show");
|
||||||
|
this.#editor._reportTelemetry({
|
||||||
|
action: "alt_text_tooltip",
|
||||||
|
});
|
||||||
|
}, DELAY_TO_SHOW_TOOLTIP);
|
||||||
|
},
|
||||||
|
{ signal }
|
||||||
|
);
|
||||||
|
button.addEventListener(
|
||||||
|
"mouseleave",
|
||||||
|
() => {
|
||||||
|
if (this.#altTextTooltipTimeout) {
|
||||||
|
clearTimeout(this.#altTextTooltipTimeout);
|
||||||
|
this.#altTextTooltipTimeout = null;
|
||||||
|
}
|
||||||
|
this.#altTextTooltip?.classList.remove("show");
|
||||||
|
},
|
||||||
|
{ signal }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
tooltip.innerText = this.#altTextDecorative
|
tooltip.innerText = this.#altTextDecorative
|
||||||
? await AltText._l10nPromise.get(
|
? await AltText._l10nPromise.get(
|
||||||
|
|||||||
@ -365,7 +365,8 @@ class AnnotationEditorLayer {
|
|||||||
this.#boundTextLayerPointerDown = this.#textLayerPointerDown.bind(this);
|
this.#boundTextLayerPointerDown = this.#textLayerPointerDown.bind(this);
|
||||||
this.#textLayer.div.addEventListener(
|
this.#textLayer.div.addEventListener(
|
||||||
"pointerdown",
|
"pointerdown",
|
||||||
this.#boundTextLayerPointerDown
|
this.#boundTextLayerPointerDown,
|
||||||
|
{ signal: this.#uiManager._signal }
|
||||||
);
|
);
|
||||||
this.#textLayer.div.classList.add("highlighting");
|
this.#textLayer.div.classList.add("highlighting");
|
||||||
}
|
}
|
||||||
@ -409,7 +410,7 @@ class AnnotationEditorLayer {
|
|||||||
() => {
|
() => {
|
||||||
this.#textLayer.div.classList.remove("free");
|
this.#textLayer.div.classList.remove("free");
|
||||||
},
|
},
|
||||||
{ once: true }
|
{ once: true, signal: this.#uiManager._signal }
|
||||||
);
|
);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
@ -419,10 +420,13 @@ class AnnotationEditorLayer {
|
|||||||
if (this.#boundPointerdown) {
|
if (this.#boundPointerdown) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const signal = this.#uiManager._signal;
|
||||||
this.#boundPointerdown = this.pointerdown.bind(this);
|
this.#boundPointerdown = this.pointerdown.bind(this);
|
||||||
this.#boundPointerup = this.pointerup.bind(this);
|
this.#boundPointerup = this.pointerup.bind(this);
|
||||||
this.div.addEventListener("pointerdown", this.#boundPointerdown);
|
this.div.addEventListener("pointerdown", this.#boundPointerdown, {
|
||||||
this.div.addEventListener("pointerup", this.#boundPointerup);
|
signal,
|
||||||
|
});
|
||||||
|
this.div.addEventListener("pointerup", this.#boundPointerup, { signal });
|
||||||
}
|
}
|
||||||
|
|
||||||
disableClick() {
|
disableClick() {
|
||||||
@ -540,7 +544,7 @@ class AnnotationEditorLayer {
|
|||||||
() => {
|
() => {
|
||||||
editor._focusEventsAllowed = true;
|
editor._focusEventsAllowed = true;
|
||||||
},
|
},
|
||||||
{ once: true }
|
{ once: true, signal: this.#uiManager._signal }
|
||||||
);
|
);
|
||||||
activeElement.focus();
|
activeElement.focus();
|
||||||
} else {
|
} else {
|
||||||
@ -596,6 +600,10 @@ class AnnotationEditorLayer {
|
|||||||
return AnnotationEditorLayer.#editorTypes.get(this.#uiManager.getMode());
|
return AnnotationEditorLayer.#editorTypes.get(this.#uiManager.getMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get _signal() {
|
||||||
|
return this.#uiManager._signal;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new editor
|
* Create a new editor
|
||||||
* @param {Object} params
|
* @param {Object} params
|
||||||
|
|||||||
@ -89,8 +89,9 @@ class ColorPicker {
|
|||||||
button.tabIndex = "0";
|
button.tabIndex = "0";
|
||||||
button.setAttribute("data-l10n-id", "pdfjs-editor-colorpicker-button");
|
button.setAttribute("data-l10n-id", "pdfjs-editor-colorpicker-button");
|
||||||
button.setAttribute("aria-haspopup", true);
|
button.setAttribute("aria-haspopup", true);
|
||||||
button.addEventListener("click", this.#openDropdown.bind(this));
|
const signal = this.#uiManager._signal;
|
||||||
button.addEventListener("keydown", this.#boundKeyDown);
|
button.addEventListener("click", this.#openDropdown.bind(this), { signal });
|
||||||
|
button.addEventListener("keydown", this.#boundKeyDown, { signal });
|
||||||
const swatch = (this.#buttonSwatch = document.createElement("span"));
|
const swatch = (this.#buttonSwatch = document.createElement("span"));
|
||||||
swatch.className = "swatch";
|
swatch.className = "swatch";
|
||||||
swatch.setAttribute("aria-hidden", true);
|
swatch.setAttribute("aria-hidden", true);
|
||||||
@ -109,7 +110,8 @@ class ColorPicker {
|
|||||||
|
|
||||||
#getDropdownRoot() {
|
#getDropdownRoot() {
|
||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
div.addEventListener("contextmenu", noContextMenu);
|
const signal = this.#uiManager._signal;
|
||||||
|
div.addEventListener("contextmenu", noContextMenu, { signal });
|
||||||
div.className = "dropdown";
|
div.className = "dropdown";
|
||||||
div.role = "listbox";
|
div.role = "listbox";
|
||||||
div.setAttribute("aria-multiselectable", false);
|
div.setAttribute("aria-multiselectable", false);
|
||||||
@ -127,11 +129,13 @@ class ColorPicker {
|
|||||||
swatch.className = "swatch";
|
swatch.className = "swatch";
|
||||||
swatch.style.backgroundColor = color;
|
swatch.style.backgroundColor = color;
|
||||||
button.setAttribute("aria-selected", color === this.#defaultColor);
|
button.setAttribute("aria-selected", color === this.#defaultColor);
|
||||||
button.addEventListener("click", this.#colorSelect.bind(this, color));
|
button.addEventListener("click", this.#colorSelect.bind(this, color), {
|
||||||
|
signal,
|
||||||
|
});
|
||||||
div.append(button);
|
div.append(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
div.addEventListener("keydown", this.#boundKeyDown);
|
div.addEventListener("keydown", this.#boundKeyDown, { signal });
|
||||||
|
|
||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
@ -211,7 +215,9 @@ class ColorPicker {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.#dropdownWasFromKeyboard = event.detail === 0;
|
this.#dropdownWasFromKeyboard = event.detail === 0;
|
||||||
window.addEventListener("pointerdown", this.#boundPointerDown);
|
window.addEventListener("pointerdown", this.#boundPointerDown, {
|
||||||
|
signal: this.#uiManager._signal,
|
||||||
|
});
|
||||||
if (this.#dropdown) {
|
if (this.#dropdown) {
|
||||||
this.#dropdown.classList.remove("hidden");
|
this.#dropdown.classList.remove("hidden");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -715,6 +715,7 @@ class AnnotationEditor {
|
|||||||
"bottomLeft",
|
"bottomLeft",
|
||||||
"middleLeft",
|
"middleLeft",
|
||||||
];
|
];
|
||||||
|
const signal = this._uiManager._signal;
|
||||||
for (const name of classes) {
|
for (const name of classes) {
|
||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
this.#resizersDiv.append(div);
|
this.#resizersDiv.append(div);
|
||||||
@ -722,9 +723,10 @@ class AnnotationEditor {
|
|||||||
div.setAttribute("data-resizer-name", name);
|
div.setAttribute("data-resizer-name", name);
|
||||||
div.addEventListener(
|
div.addEventListener(
|
||||||
"pointerdown",
|
"pointerdown",
|
||||||
this.#resizerPointerdown.bind(this, name)
|
this.#resizerPointerdown.bind(this, name),
|
||||||
|
{ signal }
|
||||||
);
|
);
|
||||||
div.addEventListener("contextmenu", noContextMenu);
|
div.addEventListener("contextmenu", noContextMenu, { signal });
|
||||||
div.tabIndex = -1;
|
div.tabIndex = -1;
|
||||||
}
|
}
|
||||||
this.div.prepend(this.#resizersDiv);
|
this.div.prepend(this.#resizersDiv);
|
||||||
@ -742,14 +744,15 @@ class AnnotationEditor {
|
|||||||
const boundResizerPointermove = this.#resizerPointermove.bind(this, name);
|
const boundResizerPointermove = this.#resizerPointermove.bind(this, name);
|
||||||
const savedDraggable = this._isDraggable;
|
const savedDraggable = this._isDraggable;
|
||||||
this._isDraggable = false;
|
this._isDraggable = false;
|
||||||
const pointerMoveOptions = { passive: true, capture: true };
|
const signal = this._uiManager._signal;
|
||||||
|
const pointerMoveOptions = { passive: true, capture: true, signal };
|
||||||
this.parent.togglePointerEvents(false);
|
this.parent.togglePointerEvents(false);
|
||||||
window.addEventListener(
|
window.addEventListener(
|
||||||
"pointermove",
|
"pointermove",
|
||||||
boundResizerPointermove,
|
boundResizerPointermove,
|
||||||
pointerMoveOptions
|
pointerMoveOptions
|
||||||
);
|
);
|
||||||
window.addEventListener("contextmenu", noContextMenu);
|
window.addEventListener("contextmenu", noContextMenu, { signal });
|
||||||
const savedX = this.x;
|
const savedX = this.x;
|
||||||
const savedY = this.y;
|
const savedY = this.y;
|
||||||
const savedWidth = this.width;
|
const savedWidth = this.width;
|
||||||
@ -776,10 +779,10 @@ class AnnotationEditor {
|
|||||||
|
|
||||||
this.#addResizeToUndoStack(savedX, savedY, savedWidth, savedHeight);
|
this.#addResizeToUndoStack(savedX, savedY, savedWidth, savedHeight);
|
||||||
};
|
};
|
||||||
window.addEventListener("pointerup", pointerUpCallback);
|
window.addEventListener("pointerup", pointerUpCallback, { signal });
|
||||||
// If the user switches to another window (with alt+tab), then we end the
|
// If the user switches to another window (with alt+tab), then we end the
|
||||||
// resize session.
|
// resize session.
|
||||||
window.addEventListener("blur", pointerUpCallback);
|
window.addEventListener("blur", pointerUpCallback, { signal });
|
||||||
}
|
}
|
||||||
|
|
||||||
#addResizeToUndoStack(savedX, savedY, savedWidth, savedHeight) {
|
#addResizeToUndoStack(savedX, savedY, savedWidth, savedHeight) {
|
||||||
@ -1027,8 +1030,9 @@ class AnnotationEditor {
|
|||||||
|
|
||||||
this.setInForeground();
|
this.setInForeground();
|
||||||
|
|
||||||
this.div.addEventListener("focusin", this.#boundFocusin);
|
const signal = this._uiManager._signal;
|
||||||
this.div.addEventListener("focusout", this.#boundFocusout);
|
this.div.addEventListener("focusin", this.#boundFocusin, { signal });
|
||||||
|
this.div.addEventListener("focusout", this.#boundFocusout, { signal });
|
||||||
|
|
||||||
const [parentWidth, parentHeight] = this.parentDimensions;
|
const [parentWidth, parentHeight] = this.parentDimensions;
|
||||||
if (this.parentRotation % 180 !== 0) {
|
if (this.parentRotation % 180 !== 0) {
|
||||||
@ -1089,9 +1093,10 @@ class AnnotationEditor {
|
|||||||
this._uiManager.setUpDragSession();
|
this._uiManager.setUpDragSession();
|
||||||
|
|
||||||
let pointerMoveOptions, pointerMoveCallback;
|
let pointerMoveOptions, pointerMoveCallback;
|
||||||
|
const signal = this._uiManager._signal;
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
this.div.classList.add("moving");
|
this.div.classList.add("moving");
|
||||||
pointerMoveOptions = { passive: true, capture: true };
|
pointerMoveOptions = { passive: true, capture: true, signal };
|
||||||
this.#prevDragX = event.clientX;
|
this.#prevDragX = event.clientX;
|
||||||
this.#prevDragY = event.clientY;
|
this.#prevDragY = event.clientY;
|
||||||
pointerMoveCallback = e => {
|
pointerMoveCallback = e => {
|
||||||
@ -1128,11 +1133,11 @@ class AnnotationEditor {
|
|||||||
this.#selectOnPointerEvent(event);
|
this.#selectOnPointerEvent(event);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
window.addEventListener("pointerup", pointerUpCallback);
|
window.addEventListener("pointerup", pointerUpCallback, { signal });
|
||||||
// If the user is using alt+tab during the dragging session, the pointerup
|
// If the user is using alt+tab during the dragging session, the pointerup
|
||||||
// event could be not fired, but a blur event is fired so we can use it in
|
// event could be not fired, but a blur event is fired so we can use it in
|
||||||
// order to interrupt the dragging session.
|
// order to interrupt the dragging session.
|
||||||
window.addEventListener("blur", pointerUpCallback);
|
window.addEventListener("blur", pointerUpCallback, { signal });
|
||||||
}
|
}
|
||||||
|
|
||||||
moveInDOM() {
|
moveInDOM() {
|
||||||
@ -1284,8 +1289,9 @@ class AnnotationEditor {
|
|||||||
* To implement in subclasses.
|
* To implement in subclasses.
|
||||||
*/
|
*/
|
||||||
rebuild() {
|
rebuild() {
|
||||||
this.div?.addEventListener("focusin", this.#boundFocusin);
|
const signal = this._uiManager._signal;
|
||||||
this.div?.addEventListener("focusout", this.#boundFocusout);
|
this.div?.addEventListener("focusin", this.#boundFocusin, { signal });
|
||||||
|
this.div?.addEventListener("focusout", this.#boundFocusout, { signal });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1429,12 +1435,15 @@ class AnnotationEditor {
|
|||||||
this.#allResizerDivs = Array.from(children);
|
this.#allResizerDivs = Array.from(children);
|
||||||
const boundResizerKeydown = this.#resizerKeydown.bind(this);
|
const boundResizerKeydown = this.#resizerKeydown.bind(this);
|
||||||
const boundResizerBlur = this.#resizerBlur.bind(this);
|
const boundResizerBlur = this.#resizerBlur.bind(this);
|
||||||
|
const signal = this._uiManager._signal;
|
||||||
for (const div of this.#allResizerDivs) {
|
for (const div of this.#allResizerDivs) {
|
||||||
const name = div.getAttribute("data-resizer-name");
|
const name = div.getAttribute("data-resizer-name");
|
||||||
div.setAttribute("role", "spinbutton");
|
div.setAttribute("role", "spinbutton");
|
||||||
div.addEventListener("keydown", boundResizerKeydown);
|
div.addEventListener("keydown", boundResizerKeydown, { signal });
|
||||||
div.addEventListener("blur", boundResizerBlur);
|
div.addEventListener("blur", boundResizerBlur, { signal });
|
||||||
div.addEventListener("focus", this.#resizerFocus.bind(this, name));
|
div.addEventListener("focus", this.#resizerFocus.bind(this, name), {
|
||||||
|
signal,
|
||||||
|
});
|
||||||
AnnotationEditor._l10nPromise
|
AnnotationEditor._l10nPromise
|
||||||
.get(`pdfjs-editor-resizer-label-${name}`)
|
.get(`pdfjs-editor-resizer-label-${name}`)
|
||||||
.then(msg => div.setAttribute("aria-label", msg));
|
.then(msg => div.setAttribute("aria-label", msg));
|
||||||
|
|||||||
@ -307,11 +307,22 @@ class FreeTextEditor extends AnnotationEditor {
|
|||||||
this.editorDiv.contentEditable = true;
|
this.editorDiv.contentEditable = true;
|
||||||
this._isDraggable = false;
|
this._isDraggable = false;
|
||||||
this.div.removeAttribute("aria-activedescendant");
|
this.div.removeAttribute("aria-activedescendant");
|
||||||
this.editorDiv.addEventListener("keydown", this.#boundEditorDivKeydown);
|
const signal = this._uiManager._signal;
|
||||||
this.editorDiv.addEventListener("focus", this.#boundEditorDivFocus);
|
this.editorDiv.addEventListener("keydown", this.#boundEditorDivKeydown, {
|
||||||
this.editorDiv.addEventListener("blur", this.#boundEditorDivBlur);
|
signal,
|
||||||
this.editorDiv.addEventListener("input", this.#boundEditorDivInput);
|
});
|
||||||
this.editorDiv.addEventListener("paste", this.#boundEditorDivPaste);
|
this.editorDiv.addEventListener("focus", this.#boundEditorDivFocus, {
|
||||||
|
signal,
|
||||||
|
});
|
||||||
|
this.editorDiv.addEventListener("blur", this.#boundEditorDivBlur, {
|
||||||
|
signal,
|
||||||
|
});
|
||||||
|
this.editorDiv.addEventListener("input", this.#boundEditorDivInput, {
|
||||||
|
signal,
|
||||||
|
});
|
||||||
|
this.editorDiv.addEventListener("paste", this.#boundEditorDivPaste, {
|
||||||
|
signal,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @inheritdoc */
|
/** @inheritdoc */
|
||||||
|
|||||||
@ -568,7 +568,9 @@ class HighlightEditor extends AnnotationEditor {
|
|||||||
if (this.#isFreeHighlight) {
|
if (this.#isFreeHighlight) {
|
||||||
div.classList.add("free");
|
div.classList.add("free");
|
||||||
} else {
|
} else {
|
||||||
this.div.addEventListener("keydown", this.#boundKeydown);
|
this.div.addEventListener("keydown", this.#boundKeydown, {
|
||||||
|
signal: this._uiManager._signal,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const highlightDiv = (this.#highlightDiv = document.createElement("div"));
|
const highlightDiv = (this.#highlightDiv = document.createElement("div"));
|
||||||
div.append(highlightDiv);
|
div.append(highlightDiv);
|
||||||
@ -702,7 +704,8 @@ class HighlightEditor extends AnnotationEditor {
|
|||||||
const pointerMove = e => {
|
const pointerMove = e => {
|
||||||
this.#highlightMove(parent, e);
|
this.#highlightMove(parent, e);
|
||||||
};
|
};
|
||||||
const pointerDownOptions = { capture: true, passive: false };
|
const signal = parent._signal;
|
||||||
|
const pointerDownOptions = { capture: true, passive: false, signal };
|
||||||
const pointerDown = e => {
|
const pointerDown = e => {
|
||||||
// Avoid to have undesired clicks during the drawing.
|
// Avoid to have undesired clicks during the drawing.
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -720,12 +723,12 @@ class HighlightEditor extends AnnotationEditor {
|
|||||||
window.removeEventListener("contextmenu", noContextMenu);
|
window.removeEventListener("contextmenu", noContextMenu);
|
||||||
this.#endHighlight(parent, e);
|
this.#endHighlight(parent, e);
|
||||||
};
|
};
|
||||||
window.addEventListener("blur", pointerUpCallback);
|
window.addEventListener("blur", pointerUpCallback, { signal });
|
||||||
window.addEventListener("pointerup", pointerUpCallback);
|
window.addEventListener("pointerup", pointerUpCallback, { signal });
|
||||||
window.addEventListener("pointerdown", pointerDown, pointerDownOptions);
|
window.addEventListener("pointerdown", pointerDown, pointerDownOptions);
|
||||||
window.addEventListener("contextmenu", noContextMenu);
|
window.addEventListener("contextmenu", noContextMenu, { signal });
|
||||||
|
|
||||||
textLayer.addEventListener("pointermove", pointerMove);
|
textLayer.addEventListener("pointermove", pointerMove, { signal });
|
||||||
this._freeHighlight = new FreeOutliner(
|
this._freeHighlight = new FreeOutliner(
|
||||||
{ x, y },
|
{ x, y },
|
||||||
[layerX, layerY, parentWidth, parentHeight],
|
[layerX, layerY, parentWidth, parentHeight],
|
||||||
|
|||||||
@ -261,7 +261,7 @@ class InkEditor extends AnnotationEditor {
|
|||||||
this.#canvasContextMenuTimeoutId = null;
|
this.#canvasContextMenuTimeoutId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#observer.disconnect();
|
this.#observer?.disconnect();
|
||||||
this.#observer = null;
|
this.#observer = null;
|
||||||
|
|
||||||
super.remove();
|
super.remove();
|
||||||
@ -296,7 +296,9 @@ class InkEditor extends AnnotationEditor {
|
|||||||
|
|
||||||
super.enableEditMode();
|
super.enableEditMode();
|
||||||
this._isDraggable = false;
|
this._isDraggable = false;
|
||||||
this.canvas.addEventListener("pointerdown", this.#boundCanvasPointerdown);
|
this.canvas.addEventListener("pointerdown", this.#boundCanvasPointerdown, {
|
||||||
|
signal: this._uiManager._signal,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @inheritdoc */
|
/** @inheritdoc */
|
||||||
@ -363,10 +365,19 @@ class InkEditor extends AnnotationEditor {
|
|||||||
* @param {number} y
|
* @param {number} y
|
||||||
*/
|
*/
|
||||||
#startDrawing(x, y) {
|
#startDrawing(x, y) {
|
||||||
this.canvas.addEventListener("contextmenu", noContextMenu);
|
const signal = this._uiManager._signal;
|
||||||
this.canvas.addEventListener("pointerleave", this.#boundCanvasPointerleave);
|
this.canvas.addEventListener("contextmenu", noContextMenu, { signal });
|
||||||
this.canvas.addEventListener("pointermove", this.#boundCanvasPointermove);
|
this.canvas.addEventListener(
|
||||||
this.canvas.addEventListener("pointerup", this.#boundCanvasPointerup);
|
"pointerleave",
|
||||||
|
this.#boundCanvasPointerleave,
|
||||||
|
{ signal }
|
||||||
|
);
|
||||||
|
this.canvas.addEventListener("pointermove", this.#boundCanvasPointermove, {
|
||||||
|
signal,
|
||||||
|
});
|
||||||
|
this.canvas.addEventListener("pointerup", this.#boundCanvasPointerup, {
|
||||||
|
signal,
|
||||||
|
});
|
||||||
this.canvas.removeEventListener(
|
this.canvas.removeEventListener(
|
||||||
"pointerdown",
|
"pointerdown",
|
||||||
this.#boundCanvasPointerdown
|
this.#boundCanvasPointerdown
|
||||||
@ -706,7 +717,9 @@ class InkEditor extends AnnotationEditor {
|
|||||||
this.#boundCanvasPointermove
|
this.#boundCanvasPointermove
|
||||||
);
|
);
|
||||||
this.canvas.removeEventListener("pointerup", this.#boundCanvasPointerup);
|
this.canvas.removeEventListener("pointerup", this.#boundCanvasPointerup);
|
||||||
this.canvas.addEventListener("pointerdown", this.#boundCanvasPointerdown);
|
this.canvas.addEventListener("pointerdown", this.#boundCanvasPointerdown, {
|
||||||
|
signal: this._uiManager._signal,
|
||||||
|
});
|
||||||
|
|
||||||
// Slight delay to avoid the context menu to appear (it can happen on a long
|
// Slight delay to avoid the context menu to appear (it can happen on a long
|
||||||
// tap with a pen).
|
// tap with a pen).
|
||||||
@ -751,6 +764,14 @@ class InkEditor extends AnnotationEditor {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.#observer.observe(this.div);
|
this.#observer.observe(this.div);
|
||||||
|
this._uiManager._signal.addEventListener(
|
||||||
|
"abort",
|
||||||
|
() => {
|
||||||
|
this.#observer?.disconnect();
|
||||||
|
this.#observer = null;
|
||||||
|
},
|
||||||
|
{ once: true }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @inheritdoc */
|
/** @inheritdoc */
|
||||||
|
|||||||
@ -160,26 +160,35 @@ class StampEditor extends AnnotationEditor {
|
|||||||
}
|
}
|
||||||
input.type = "file";
|
input.type = "file";
|
||||||
input.accept = StampEditor.supportedTypesStr;
|
input.accept = StampEditor.supportedTypesStr;
|
||||||
|
const signal = this._uiManager._signal;
|
||||||
this.#bitmapPromise = new Promise(resolve => {
|
this.#bitmapPromise = new Promise(resolve => {
|
||||||
input.addEventListener("change", async () => {
|
input.addEventListener(
|
||||||
if (!input.files || input.files.length === 0) {
|
"change",
|
||||||
|
async () => {
|
||||||
|
if (!input.files || input.files.length === 0) {
|
||||||
|
this.remove();
|
||||||
|
} else {
|
||||||
|
this._uiManager.enableWaiting(true);
|
||||||
|
const data = await this._uiManager.imageManager.getFromFile(
|
||||||
|
input.files[0]
|
||||||
|
);
|
||||||
|
this.#getBitmapFetched(data);
|
||||||
|
}
|
||||||
|
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("TESTING")) {
|
||||||
|
input.remove();
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
},
|
||||||
|
{ signal }
|
||||||
|
);
|
||||||
|
input.addEventListener(
|
||||||
|
"cancel",
|
||||||
|
() => {
|
||||||
this.remove();
|
this.remove();
|
||||||
} else {
|
resolve();
|
||||||
this._uiManager.enableWaiting(true);
|
},
|
||||||
const data = await this._uiManager.imageManager.getFromFile(
|
{ signal }
|
||||||
input.files[0]
|
);
|
||||||
);
|
|
||||||
this.#getBitmapFetched(data);
|
|
||||||
}
|
|
||||||
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("TESTING")) {
|
|
||||||
input.remove();
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
input.addEventListener("cancel", () => {
|
|
||||||
this.remove();
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
}).finally(() => this.#getBitmapDone());
|
}).finally(() => this.#getBitmapDone());
|
||||||
if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("TESTING")) {
|
if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("TESTING")) {
|
||||||
input.click();
|
input.click();
|
||||||
@ -536,6 +545,14 @@ class StampEditor extends AnnotationEditor {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.#observer.observe(this.div);
|
this.#observer.observe(this.div);
|
||||||
|
this._uiManager._signal.addEventListener(
|
||||||
|
"abort",
|
||||||
|
() => {
|
||||||
|
this.#observer?.disconnect();
|
||||||
|
this.#observer = null;
|
||||||
|
},
|
||||||
|
{ once: true }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @inheritdoc */
|
/** @inheritdoc */
|
||||||
|
|||||||
@ -32,8 +32,11 @@ class EditorToolbar {
|
|||||||
const editToolbar = (this.#toolbar = document.createElement("div"));
|
const editToolbar = (this.#toolbar = document.createElement("div"));
|
||||||
editToolbar.className = "editToolbar";
|
editToolbar.className = "editToolbar";
|
||||||
editToolbar.setAttribute("role", "toolbar");
|
editToolbar.setAttribute("role", "toolbar");
|
||||||
editToolbar.addEventListener("contextmenu", noContextMenu);
|
const signal = this.#editor._uiManager._signal;
|
||||||
editToolbar.addEventListener("pointerdown", EditorToolbar.#pointerDown);
|
editToolbar.addEventListener("contextmenu", noContextMenu, { signal });
|
||||||
|
editToolbar.addEventListener("pointerdown", EditorToolbar.#pointerDown, {
|
||||||
|
signal,
|
||||||
|
});
|
||||||
|
|
||||||
const buttons = (this.#buttons = document.createElement("div"));
|
const buttons = (this.#buttons = document.createElement("div"));
|
||||||
buttons.className = "buttons";
|
buttons.className = "buttons";
|
||||||
@ -77,13 +80,16 @@ class EditorToolbar {
|
|||||||
// If we're clicking on a button with the keyboard or with
|
// If we're clicking on a button with the keyboard or with
|
||||||
// the mouse, we don't want to trigger any focus events on
|
// the mouse, we don't want to trigger any focus events on
|
||||||
// the editor.
|
// the editor.
|
||||||
|
const signal = this.#editor._uiManager._signal;
|
||||||
element.addEventListener("focusin", this.#focusIn.bind(this), {
|
element.addEventListener("focusin", this.#focusIn.bind(this), {
|
||||||
capture: true,
|
capture: true,
|
||||||
|
signal,
|
||||||
});
|
});
|
||||||
element.addEventListener("focusout", this.#focusOut.bind(this), {
|
element.addEventListener("focusout", this.#focusOut.bind(this), {
|
||||||
capture: true,
|
capture: true,
|
||||||
|
signal,
|
||||||
});
|
});
|
||||||
element.addEventListener("contextmenu", noContextMenu);
|
element.addEventListener("contextmenu", noContextMenu, { signal });
|
||||||
}
|
}
|
||||||
|
|
||||||
hide() {
|
hide() {
|
||||||
@ -104,9 +110,13 @@ class EditorToolbar {
|
|||||||
`pdfjs-editor-remove-${this.#editor.editorType}-button`
|
`pdfjs-editor-remove-${this.#editor.editorType}-button`
|
||||||
);
|
);
|
||||||
this.#addListenersToElement(button);
|
this.#addListenersToElement(button);
|
||||||
button.addEventListener("click", e => {
|
button.addEventListener(
|
||||||
this.#editor._uiManager.delete();
|
"click",
|
||||||
});
|
e => {
|
||||||
|
this.#editor._uiManager.delete();
|
||||||
|
},
|
||||||
|
{ signal: this.#editor._uiManager._signal }
|
||||||
|
);
|
||||||
this.#buttons.append(button);
|
this.#buttons.append(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +160,9 @@ class HighlightToolbar {
|
|||||||
const editToolbar = (this.#toolbar = document.createElement("div"));
|
const editToolbar = (this.#toolbar = document.createElement("div"));
|
||||||
editToolbar.className = "editToolbar";
|
editToolbar.className = "editToolbar";
|
||||||
editToolbar.setAttribute("role", "toolbar");
|
editToolbar.setAttribute("role", "toolbar");
|
||||||
editToolbar.addEventListener("contextmenu", noContextMenu);
|
editToolbar.addEventListener("contextmenu", noContextMenu, {
|
||||||
|
signal: this.#uiManager._signal,
|
||||||
|
});
|
||||||
|
|
||||||
const buttons = (this.#buttons = document.createElement("div"));
|
const buttons = (this.#buttons = document.createElement("div"));
|
||||||
buttons.className = "buttons";
|
buttons.className = "buttons";
|
||||||
@ -207,10 +219,15 @@ class HighlightToolbar {
|
|||||||
button.append(span);
|
button.append(span);
|
||||||
span.className = "visuallyHidden";
|
span.className = "visuallyHidden";
|
||||||
span.setAttribute("data-l10n-id", "pdfjs-highlight-floating-button-label");
|
span.setAttribute("data-l10n-id", "pdfjs-highlight-floating-button-label");
|
||||||
button.addEventListener("contextmenu", noContextMenu);
|
const signal = this.#uiManager._signal;
|
||||||
button.addEventListener("click", () => {
|
button.addEventListener("contextmenu", noContextMenu, { signal });
|
||||||
this.#uiManager.highlightSelection("floating_button");
|
button.addEventListener(
|
||||||
});
|
"click",
|
||||||
|
() => {
|
||||||
|
this.#uiManager.highlightSelection("floating_button");
|
||||||
|
},
|
||||||
|
{ signal }
|
||||||
|
);
|
||||||
this.#buttons.append(button);
|
this.#buttons.append(button);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -534,6 +534,8 @@ class ColorManager {
|
|||||||
* some action like copy/paste, undo/redo, ...
|
* some action like copy/paste, undo/redo, ...
|
||||||
*/
|
*/
|
||||||
class AnnotationEditorUIManager {
|
class AnnotationEditorUIManager {
|
||||||
|
#abortController = new AbortController();
|
||||||
|
|
||||||
#activeEditor = null;
|
#activeEditor = null;
|
||||||
|
|
||||||
#allEditors = new Map();
|
#allEditors = new Map();
|
||||||
@ -600,10 +602,6 @@ class AnnotationEditorUIManager {
|
|||||||
|
|
||||||
#boundCut = this.cut.bind(this);
|
#boundCut = this.cut.bind(this);
|
||||||
|
|
||||||
#boundDragOver = this.dragOver.bind(this);
|
|
||||||
|
|
||||||
#boundDrop = this.drop.bind(this);
|
|
||||||
|
|
||||||
#boundPaste = this.paste.bind(this);
|
#boundPaste = this.paste.bind(this);
|
||||||
|
|
||||||
#boundKeydown = this.keydown.bind(this);
|
#boundKeydown = this.keydown.bind(this);
|
||||||
@ -616,8 +614,6 @@ class AnnotationEditorUIManager {
|
|||||||
|
|
||||||
#boundOnScaleChanging = this.onScaleChanging.bind(this);
|
#boundOnScaleChanging = this.onScaleChanging.bind(this);
|
||||||
|
|
||||||
#boundSelectionChange = this.#selectionChange.bind(this);
|
|
||||||
|
|
||||||
#boundOnRotationChanging = this.onRotationChanging.bind(this);
|
#boundOnRotationChanging = this.onRotationChanging.bind(this);
|
||||||
|
|
||||||
#previousStates = {
|
#previousStates = {
|
||||||
@ -785,6 +781,7 @@ class AnnotationEditorUIManager {
|
|||||||
enableHighlightFloatingButton,
|
enableHighlightFloatingButton,
|
||||||
mlManager
|
mlManager
|
||||||
) {
|
) {
|
||||||
|
this._signal = this.#abortController.signal;
|
||||||
this.#container = container;
|
this.#container = container;
|
||||||
this.#viewer = viewer;
|
this.#viewer = viewer;
|
||||||
this.#altTextManager = altTextManager;
|
this.#altTextManager = altTextManager;
|
||||||
@ -820,9 +817,10 @@ class AnnotationEditorUIManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
this.#removeDragAndDropListeners();
|
this.#abortController?.abort();
|
||||||
this.#removeKeyboardManager();
|
this.#abortController = null;
|
||||||
this.#removeFocusManager();
|
this._signal = null;
|
||||||
|
|
||||||
this._eventBus._off("editingaction", this.#boundOnEditingAction);
|
this._eventBus._off("editingaction", this.#boundOnEditingAction);
|
||||||
this._eventBus._off("pagechanging", this.#boundOnPageChanging);
|
this._eventBus._off("pagechanging", this.#boundOnPageChanging);
|
||||||
this._eventBus._off("scalechanging", this.#boundOnScaleChanging);
|
this._eventBus._off("scalechanging", this.#boundOnScaleChanging);
|
||||||
@ -847,7 +845,6 @@ class AnnotationEditorUIManager {
|
|||||||
clearTimeout(this.#translationTimeoutId);
|
clearTimeout(this.#translationTimeoutId);
|
||||||
this.#translationTimeoutId = null;
|
this.#translationTimeoutId = null;
|
||||||
}
|
}
|
||||||
this.#removeSelectionListener();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async mlGuess(data) {
|
async mlGuess(data) {
|
||||||
@ -1084,6 +1081,7 @@ class AnnotationEditorUIManager {
|
|||||||
|
|
||||||
this.#highlightWhenShiftUp = this.isShiftKeyDown;
|
this.#highlightWhenShiftUp = this.isShiftKeyDown;
|
||||||
if (!this.isShiftKeyDown) {
|
if (!this.isShiftKeyDown) {
|
||||||
|
const signal = this._signal;
|
||||||
const pointerup = e => {
|
const pointerup = e => {
|
||||||
if (e.type === "pointerup" && e.button !== 0) {
|
if (e.type === "pointerup" && e.button !== 0) {
|
||||||
// Do nothing on right click.
|
// Do nothing on right click.
|
||||||
@ -1095,8 +1093,8 @@ class AnnotationEditorUIManager {
|
|||||||
this.#onSelectEnd("main_toolbar");
|
this.#onSelectEnd("main_toolbar");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
window.addEventListener("pointerup", pointerup);
|
window.addEventListener("pointerup", pointerup, { signal });
|
||||||
window.addEventListener("blur", pointerup);
|
window.addEventListener("blur", pointerup, { signal });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1109,16 +1107,19 @@ class AnnotationEditorUIManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#addSelectionListener() {
|
#addSelectionListener() {
|
||||||
document.addEventListener("selectionchange", this.#boundSelectionChange);
|
document.addEventListener(
|
||||||
}
|
"selectionchange",
|
||||||
|
this.#selectionChange.bind(this),
|
||||||
#removeSelectionListener() {
|
{
|
||||||
document.removeEventListener("selectionchange", this.#boundSelectionChange);
|
signal: this._signal,
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#addFocusManager() {
|
#addFocusManager() {
|
||||||
window.addEventListener("focus", this.#boundFocus);
|
const signal = this._signal;
|
||||||
window.addEventListener("blur", this.#boundBlur);
|
window.addEventListener("focus", this.#boundFocus, { signal });
|
||||||
|
window.addEventListener("blur", this.#boundBlur, { signal });
|
||||||
}
|
}
|
||||||
|
|
||||||
#removeFocusManager() {
|
#removeFocusManager() {
|
||||||
@ -1160,16 +1161,17 @@ class AnnotationEditorUIManager {
|
|||||||
() => {
|
() => {
|
||||||
lastEditor._focusEventsAllowed = true;
|
lastEditor._focusEventsAllowed = true;
|
||||||
},
|
},
|
||||||
{ once: true }
|
{ once: true, signal: this._signal }
|
||||||
);
|
);
|
||||||
lastActiveElement.focus();
|
lastActiveElement.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
#addKeyboardManager() {
|
#addKeyboardManager() {
|
||||||
|
const signal = this._signal;
|
||||||
// The keyboard events are caught at the container level in order to be able
|
// The keyboard events are caught at the container level in order to be able
|
||||||
// to execute some callbacks even if the current page doesn't have focus.
|
// to execute some callbacks even if the current page doesn't have focus.
|
||||||
window.addEventListener("keydown", this.#boundKeydown);
|
window.addEventListener("keydown", this.#boundKeydown, { signal });
|
||||||
window.addEventListener("keyup", this.#boundKeyup);
|
window.addEventListener("keyup", this.#boundKeyup, { signal });
|
||||||
}
|
}
|
||||||
|
|
||||||
#removeKeyboardManager() {
|
#removeKeyboardManager() {
|
||||||
@ -1178,9 +1180,10 @@ class AnnotationEditorUIManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#addCopyPasteListeners() {
|
#addCopyPasteListeners() {
|
||||||
document.addEventListener("copy", this.#boundCopy);
|
const signal = this._signal;
|
||||||
document.addEventListener("cut", this.#boundCut);
|
document.addEventListener("copy", this.#boundCopy, { signal });
|
||||||
document.addEventListener("paste", this.#boundPaste);
|
document.addEventListener("cut", this.#boundCut, { signal });
|
||||||
|
document.addEventListener("paste", this.#boundPaste, { signal });
|
||||||
}
|
}
|
||||||
|
|
||||||
#removeCopyPasteListeners() {
|
#removeCopyPasteListeners() {
|
||||||
@ -1190,13 +1193,9 @@ class AnnotationEditorUIManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#addDragAndDropListeners() {
|
#addDragAndDropListeners() {
|
||||||
document.addEventListener("dragover", this.#boundDragOver);
|
const signal = this._signal;
|
||||||
document.addEventListener("drop", this.#boundDrop);
|
document.addEventListener("dragover", this.dragOver.bind(this), { signal });
|
||||||
}
|
document.addEventListener("drop", this.drop.bind(this), { signal });
|
||||||
|
|
||||||
#removeDragAndDropListeners() {
|
|
||||||
document.removeEventListener("dragover", this.#boundDragOver);
|
|
||||||
document.removeEventListener("drop", this.#boundDrop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addEditListeners() {
|
addEditListeners() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user