: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
}) => !(el instanceof HTMLButtonElement) && self.#container.contains(document.activeElement)
}], [["Escape", "mac+Escape"], proto.unselectAll], [["ArrowLeft", "mac+ArrowLeft"], proto.translateSelectedEditors, {
}], [["ctrl+ArrowLeft", "mac+shift+ArrowLeft"], proto.translateSelectedEditors, {
}], [["ArrowRight", "mac+ArrowRight"], proto.translateSelectedEditors, {
}], [["ctrl+ArrowRight", "mac+shift+ArrowRight"], proto.translateSelectedEditors, {
}], [["ArrowUp", "mac+ArrowUp"], proto.translateSelectedEditors, {
}], [["ctrl+ArrowUp", "mac+shift+ArrowUp"], proto.translateSelectedEditors, {
}], [["ArrowDown", "mac+ArrowDown"], proto.translateSelectedEditors, {
}], [["ctrl+ArrowDown", "mac+shift+ArrowDown"], proto.translateSelectedEditors, {
constructor(container, viewer, altTextManager, eventBus, pdfDocument, pageColors, highlightColors, enableHighlightFloatingButton, mlManager) {
this.#container = container;
this.#altTextManager = altTextManager;
this._eventBus = eventBus;
this._eventBus._on("editingaction", this.#boundOnEditingAction);
this._eventBus._on("pagechanging", this.#boundOnPageChanging);
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;
realScale: PixelsPerInch.PDF_TO_CSS_UNITS,
this.isShiftKeyDown = false;
this.#removeKeyboardManager();
this.#removeFocusManager();
this._eventBus._off("editingaction", this.#boundOnEditingAction);
this._eventBus._off("pagechanging", this.#boundOnPageChanging);
this._eventBus._off("scalechanging", this.#boundOnScaleChanging);
this._eventBus._off("rotationchanging", this.#boundOnRotationChanging);
for (const layer of this.#allLayers.values()) {
this.#allEditors.clear();
this.#editorsToRescale.clear();
this.#activeEditor = null;
this.#selectedEditors.clear();
this.#commandManager.destroy();
this.#altTextManager?.destroy();
this.#highlightToolbar?.hide();
this.#highlightToolbar = null;
if (this.#focusMainContainerTimeoutId) {
clearTimeout(this.#focusMainContainerTimeoutId);
this.#focusMainContainerTimeoutId = null;
if (this.#translationTimeoutId) {
clearTimeout(this.#translationTimeoutId);
this.#translationTimeoutId = null;
this.#removeSelectionListener();
return this.#mlManager?.guess(data) || null;
return !!this.#mlManager;
return shadow(this, "hcmFilter", this.#pageColors ? this.#filterFactory.addHCMFilter(this.#pageColors.foreground, this.#pageColors.background) : "none");
return shadow(this, "direction", getComputedStyle(this.#container).direction);
return shadow(this, "highlightColors", this.#highlightColors ? new Map(this.#highlightColors.split(",").map(pair => pair.split("=").map(x => x.trim()))) : null);
get highlightColorNames() {
return shadow(this, "highlightColorNames", this.highlightColors ? new Map(Array.from(this.highlightColors, e => e.reverse())) : null);
setMainHighlightColorPicker(colorPicker) {
this.#mainHighlightColorPicker = colorPicker;
this.#altTextManager?.editAltText(this, editor);
this.#currentPageIndex = pageNumber - 1;
for (const layer of this.#allLayers.values()) {
} = layer.div.getBoundingClientRect();
if (x >= layerX && x <= layerX + width && y >= layerY && y <= layerY + height) {
disableUserSelect(value = false) {
this.#viewer.classList.toggle("noUserSelect", value);
addShouldRescale(editor) {
this.#editorsToRescale.add(editor);
removeShouldRescale(editor) {
this.#editorsToRescale.delete(editor);
this.viewParameters.realScale = scale * PixelsPerInch.PDF_TO_CSS_UNITS;
for (const editor of this.#editorsToRescale) {
editor.onScaleChanging();
this.viewParameters.rotation = pagesRotation;
#getAnchorElementForSelection({
return anchorNode.nodeType === Node.TEXT_NODE ? anchorNode.parentElement : anchorNode;
highlightSelection(methodOfCreation = "") {
const selection = document.getSelection();
if (!selection || selection.isCollapsed) {
const text = selection.toString();
const anchorElement = this.#getAnchorElementForSelection(selection);
const textLayer = anchorElement.closest(".textLayer");
const boxes = this.getSelectionBoxes(textLayer);
if (this.#mode === AnnotationEditorType.NONE) {
this._eventBus.dispatch("showannotationeditorui", {
mode: AnnotationEditorType.HIGHLIGHT
this.showAllEditors("highlight", true, true);
for (const layer of this.#allLayers.values()) {
if (layer.hasTextLayer(textLayer)) {
layer.createAndAddNewEditor({
#displayHighlightToolbar() {
const selection = document.getSelection();
if (!selection || selection.isCollapsed) {
const anchorElement = this.#getAnchorElementForSelection(selection);
const textLayer = anchorElement.closest(".textLayer");
const boxes = this.getSelectionBoxes(textLayer);
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);
const selection = document.getSelection();
if (!selection || selection.isCollapsed) {
if (this.#selectedTextNode) {
this.#highlightToolbar?.hide();
this.#selectedTextNode = null;
this.#dispatchUpdateStates({
if (anchorNode === this.#selectedTextNode) {
const anchorElement = this.#getAnchorElementForSelection(selection);
const textLayer = anchorElement.closest(".textLayer");
if (this.#selectedTextNode) {
this.#highlightToolbar?.hide();
this.#selectedTextNode = null;
this.#dispatchUpdateStates({
this.#highlightToolbar?.hide();
this.#selectedTextNode = anchorNode;
this.#dispatchUpdateStates({
if (this.#mode !== AnnotationEditorType.HIGHLIGHT && this.#mode !== AnnotationEditorType.NONE) {
if (this.#mode === AnnotationEditorType.HIGHLIGHT) {
this.showAllEditors("highlight", true, true);
this.#highlightWhenShiftUp = this.isShiftKeyDown;
if (!this.isShiftKeyDown) {
if (e.type === "pointerup" && e.button !== 0) {
window.removeEventListener("pointerup", pointerup);
window.removeEventListener("blur", pointerup);
if (e.type === "pointerup") {
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);
#removeSelectionListener() {
document.removeEventListener("selectionchange", this.#boundSelectionChange);
window.addEventListener("focus", this.#boundFocus);
window.addEventListener("blur", this.#boundBlur);
window.removeEventListener("focus", this.#boundFocus);
window.removeEventListener("blur", this.#boundBlur);
this.isShiftKeyDown = false;
if (this.#highlightWhenShiftUp) {
this.#highlightWhenShiftUp = false;
this.#onSelectEnd("main_toolbar");
if (!this.hasSelection) {
for (const editor of this.#selectedEditors) {
if (editor.div.contains(activeElement)) {
this.#lastActiveElement = [editor, activeElement];
editor._focusEventsAllowed = false;
if (!this.#lastActiveElement) {
const [lastEditor, lastActiveElement] = this.#lastActiveElement;
this.#lastActiveElement = null;
lastActiveElement.addEventListener("focusin", () => {
lastEditor._focusEventsAllowed = true;
lastActiveElement.focus();
window.addEventListener("keydown", this.#boundKeydown);
window.addEventListener("keyup", this.#boundKeyup);
#removeKeyboardManager() {
window.removeEventListener("keydown", this.#boundKeydown);
window.removeEventListener("keyup", this.#boundKeyup);
#addCopyPasteListeners() {
document.addEventListener("copy", this.#boundCopy);
document.addEventListener("cut", this.#boundCut);
document.addEventListener("paste", this.#boundPaste);
#removeCopyPasteListeners() {
document.removeEventListener("copy", this.#boundCopy);
document.removeEventListener("cut", this.#boundCut);
document.removeEventListener("paste", this.#boundPaste);
this.#addKeyboardManager();
this.#addCopyPasteListeners();
this.#removeKeyboardManager();
this.#removeCopyPasteListeners();
this.#activeEditor?.commitOrRemove();
if (!this.hasSelection) {
for (const editor of this.#selectedEditors) {
const serialized = editor.serialize(true);
editors.push(serialized);
if (editors.length === 0) {
event.clipboardData.setData("application/pdfjs", JSON.stringify(editors));
for (const item of clipboardData.items) {
for (const editorType of this.#editorTypes) {
if (editorType.isHandlingMimeForPasting(item.type)) {
editorType.paste(item, this.currentLayer);
let data = clipboardData.getData("application/pdfjs");
warn(`paste: "${ex.message}".`);
if (!Array.isArray(data)) {
const layer = this.currentLayer;
for (const editor of data) {
const deserializedEditor = layer.deserialize(editor);
if (!deserializedEditor) {
newEditors.push(deserializedEditor);
for (const editor of newEditors) {
this.#addEditorToLayer(editor);
this.#selectEditors(newEditors);
for (const editor of newEditors) {
warn(`paste: "${ex.message}".`);
if (!this.isShiftKeyDown && event.key === "Shift") {
this.isShiftKeyDown = true;
if (this.#mode !== AnnotationEditorType.NONE && !this.isEditorHandlingKeyboard) {
AnnotationEditorUIManager._keyboardManager.exec(this, event);
if (this.isShiftKeyDown && event.key === "Shift") {
this.isShiftKeyDown = false;
if (this.#highlightWhenShiftUp) {
this.#highlightWhenShiftUp = false;
this.#onSelectEnd("main_toolbar");
case "highlightSelection":
this.highlightSelection("context_menu");
#dispatchUpdateStates(details) {
const hasChanged = Object.entries(details).some(([key, value]) => this.#previousStates[key] !== value);
this._eventBus.dispatch("annotationeditorstateschanged", {
details: Object.assign(this.#previousStates, details)
if (this.#mode === AnnotationEditorType.HIGHLIGHT && details.hasSelectedEditor === false) {
this.#dispatchUpdateUI([[AnnotationEditorParamsType.HIGHLIGHT_FREE, true]]);
#dispatchUpdateUI(details) {
this._eventBus.dispatch("annotationeditorparamschanged", {
setEditingState(isEditing) {
this.#addCopyPasteListeners();
this.#dispatchUpdateStates({
isEditing: this.#mode !== AnnotationEditorType.NONE,
isEmpty: this.#isEmpty(),
hasSomethingToUndo: this.#commandManager.hasSomethingToUndo(),
hasSomethingToRedo: this.#commandManager.hasSomethingToRedo(),
this.#removeFocusManager();
this.#removeCopyPasteListeners();
this.#dispatchUpdateStates({