: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
_dispatchEventFromSandbox(actions, jsEvent) {
const commonActions = this._commonActions;
for (const name of Object.keys(jsEvent.detail)) {
const action = actions[name] || commonActions[name];
_setDefaultPropertiesFromJS(element) {
if (!this.enableScripting) {
const storedData = this.annotationStorage.getRawValue(this.data.id);
const commonActions = this._commonActions;
for (const [actionName, detail] of Object.entries(storedData)) {
const action = commonActions[actionName];
delete storedData[actionName];
_createQuadrilaterals() {
const [rectBlX, rectBlY, rectTrX, rectTrY] = this.data.rect;
if (quadPoints.length === 1) {
if (rectTrX === trX && rectTrY === trY && rectBlX === blX && rectBlY === blY) {
svgBuffer = ["url('data:image/svg+xml;utf8,", `<svg xmlns="http://www.w3.org/2000/svg"`, ` preserveAspectRatio="none" viewBox="0 0 1 1">`, `<g fill="transparent" stroke="${borderColor}" stroke-width="${borderWidth}">`];
this.container.classList.add("hasBorder");
const width = rectTrX - rectBlX;
const height = rectTrY - rectBlY;
const svg = svgFactory.createElement("svg");
svg.classList.add("quadrilateralsContainer");
svg.setAttribute("width", 0);
svg.setAttribute("height", 0);
const defs = svgFactory.createElement("defs");
const clipPath = svgFactory.createElement("clipPath");
const id = `clippath_${this.data.id}`;
clipPath.setAttribute("id", id);
clipPath.setAttribute("clipPathUnits", "objectBoundingBox");
const rect = svgFactory.createElement("rect");
const x = (blX - rectBlX) / width;
const y = (rectTrY - trY) / height;
const rectWidth = (trX - blX) / width;
const rectHeight = (trY - blY) / height;
rect.setAttribute("x", x);
rect.setAttribute("y", y);
rect.setAttribute("width", rectWidth);
rect.setAttribute("height", rectHeight);
svgBuffer?.push(`<rect vector-effect="non-scaling-stroke" x="${x}" y="${y}" width="${rectWidth}" height="${rectHeight}"/>`);
svgBuffer.push(`</g></svg>')`);
style.backgroundImage = svgBuffer.join("");
this.container.append(svg);
this.container.style.clipPath = `url(#${id})`;
container.setAttribute("aria-haspopup", "dialog");
const popup = this.#popupElement = new PopupAnnotationElement({
modificationDate: data.modificationDate,
contentsObj: data.contentsObj,
this.parent.div.append(popup.render());
unreachable("Abstract method `AnnotationElement.render` called");
_getElementsByName(name, skipId = null) {
if (this._fieldObjects) {
const fieldObj = this._fieldObjects[name];
const exportValue = typeof exportValues === "string" ? exportValues : null;
const domElement = document.querySelector(`[data-element-id="${id}"]`);
if (domElement && !GetElementsByNameSet.has(domElement)) {
warn(`_getElementsByName - element not allowed: ${id}`);
for (const domElement of document.getElementsByName(name)) {
const id = domElement.getAttribute("data-element-id");
if (!GetElementsByNameSet.has(domElement)) {
this.container.hidden = false;
this.container.hidden = true;
getElementsToTriggerPopup() {
const triggers = this.getElementsToTriggerPopup();
if (Array.isArray(triggers)) {
for (const element of triggers) {
element.classList.add("highlightArea");
triggers.classList.add("highlightArea");
annotationEditorType: mode,
this.container.addEventListener("dblclick", () => {
this.linkService.eventBus?.dispatch("switchannotationeditormode", {
class LinkAnnotationElement extends AnnotationElement {
constructor(parameters, options = null) {
ignoreBorder: !!options?.ignoreBorder,
createQuadrilaterals: true
this.isTooltipOnly = parameters.data.isTooltipOnly;
const link = document.createElement("a");
link.setAttribute("data-element-id", data.id);
linkService.addLinkAttributes(link, data.url, data.newWindow);
} else if (data.action) {
this._bindNamedAction(link, data.action);
} else if (data.attachment) {
this.#bindAttachment(link, data.attachment, data.attachmentDest);
} else if (data.setOCGState) {
this.#bindSetOCGState(link, data.setOCGState);
this._bindLink(link, data.dest);
if (data.actions && (data.actions.Action || data.actions["Mouse Up"] || data.actions["Mouse Down"]) && this.enableScripting && this.hasJSActions) {
this._bindJSAction(link, data);
this._bindResetFormAction(link, data.resetForm);
} else if (this.isTooltipOnly && !isBound) {
this._bindLink(link, "");
this.container.classList.add("linkAnnotation");
this.container.append(link);
this.container.setAttribute("data-internal-link", "");
_bindLink(link, destination) {
link.href = this.linkService.getDestinationHash(destination);
this.linkService.goToDestination(destination);
if (destination || destination === "") {
_bindNamedAction(link, action) {
link.href = this.linkService.getAnchorUrl("");
this.linkService.executeNamedAction(action);
#bindAttachment(link, attachment, dest = null) {
link.href = this.linkService.getAnchorUrl("");
if (attachment.description) {
link.title = attachment.description;
this.downloadManager?.openOrDownloadData(attachment.content, attachment.filename, dest);
#bindSetOCGState(link, action) {
link.href = this.linkService.getAnchorUrl("");
this.linkService.executeSetOCGState(action);
_bindJSAction(link, data) {
link.href = this.linkService.getAnchorUrl("");
const map = new Map([["Action", "onclick"], ["Mouse Up", "onmouseup"], ["Mouse Down", "onmousedown"]]);
for (const name of Object.keys(data.actions)) {
const jsName = map.get(name);
this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
link.onclick = () => false;
_bindResetFormAction(link, resetForm) {
const otherClickAction = link.onclick;
link.href = this.linkService.getAnchorUrl("");
if (!this._fieldObjects) {
warn(`_bindResetFormAction - "resetForm" action not supported, ` + "ensure that the `fieldObjects` parameter is provided.");
link.onclick = () => false;
if (resetFormFields.length !== 0 || resetFormRefs.length !== 0) {
const fieldIds = new Set(resetFormRefs);
for (const fieldName of resetFormFields) {
const fields = this._fieldObjects[fieldName] || [];
for (const fields of Object.values(this._fieldObjects)) {
for (const field of fields) {
if (fieldIds.has(field.id) === include) {
for (const fields of Object.values(this._fieldObjects)) {
allFields.push(...fields);
const storage = this.annotationStorage;
for (const field of allFields) {
const value = field.defaultValue || "";
const value = field.defaultValue === field.exportValues;
const value = field.defaultValue || "";
const domElement = document.querySelector(`[data-element-id="${id}"]`);
} else if (!GetElementsByNameSet.has(domElement)) {
warn(`_bindResetFormAction - element not allowed: ${id}`);
domElement.dispatchEvent(new Event("resetform"));
if (this.enableScripting) {
this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
class TextAnnotationElement extends AnnotationElement {
constructor(parameters) {
this.container.classList.add("textAnnotation");
const image = document.createElement("img");
image.src = this.imageResourcesPath + "annotation-" + this.data.name.toLowerCase() + ".svg";
image.setAttribute("data-l10n-id", "pdfjs-text-annotation-type");
image.setAttribute("data-l10n-args", JSON.stringify({
if (!this.data.popupRef && this.hasPopupData) {
this.container.append(image);
class WidgetAnnotationElement extends AnnotationElement {
showElementAndHideCanvas(element) {
if (this.data.hasOwnCanvas) {
if (element.previousSibling?.nodeName === "CANVAS") {
element.previousSibling.hidden = true;
return util_FeatureTest.platform.isMac ? event.metaKey : event.ctrlKey;
_setEventListener(element, elementData, baseName, eventName, valueGetter) {
if (baseName.includes("mouse")) {
element.addEventListener(baseName, event => {
this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
value: valueGetter(event),