: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
const p = document.createElement("p");
p.classList.add("popupContent");
const lines = str.split(/(?:\r\n?|\n)/);
for (let i = 0, ii = lines.length; i < ii; ++i) {
p.append(document.createTextNode(line));
p.append(document.createElement("br"));
if (event.altKey || event.shiftKey || event.ctrlKey || event.metaKey) {
if (event.key === "Enter" || event.key === "Escape" && this.#pinned) {
contentsObj: this.#contentsObj,
this.#richText = this.#makePopupContent(popupContent);
this.#contentsObj = null;
contentsObj: this.#contentsObj,
if (this.#position !== null) {
let useParentRect = !!this.#parentRect;
let rect = useParentRect ? this.#parentRect : this.#rect;
for (const element of this.#elements) {
if (!rect || Util.intersect(element.data.rect, rect) !== null) {
rect = element.data.rect;
const normalizedRect = Util.normalizeRect([rect[0], view[3] - rect[1] + view[1], rect[2], view[3] - rect[3] + view[1]]);
const HORIZONTAL_SPACE_AFTER_ANNOTATION = 5;
const parentWidth = useParentRect ? rect[2] - rect[0] + HORIZONTAL_SPACE_AFTER_ANNOTATION : 0;
const popupLeft = normalizedRect[0] + parentWidth;
const popupTop = normalizedRect[1];
this.#position = [100 * (popupLeft - pageX) / pageWidth, 100 * (popupTop - pageY) / pageHeight];
style.left = `${this.#position[0]}%`;
style.top = `${this.#position[1]}%`;
this.#pinned = !this.#pinned;
this.#container.addEventListener("click", this.#boundToggle);
this.#container.addEventListener("keydown", this.#boundKeyDown);
this.#container.removeEventListener("click", this.#boundToggle);
this.#container.removeEventListener("keydown", this.#boundKeyDown);
this.#container.hidden = false;
this.#container.style.zIndex = parseInt(this.#container.style.zIndex) + 1000;
} else if (this.#pinned) {
this.#container.classList.add("focused");
this.#container.classList.remove("focused");
if (this.#pinned || !this.isVisible) {
this.#container.hidden = true;
this.#container.style.zIndex = parseInt(this.#container.style.zIndex) - 1000;
this.#wasVisible = this.isVisible;
this.#container.hidden = true;
this.#wasVisible = false;
this.#container.hidden = false;
return this.#container.hidden === false;
class FreeTextAnnotationElement extends AnnotationElement {
constructor(parameters) {
this.textContent = parameters.data.textContent;
this.textPosition = parameters.data.textPosition;
this.annotationEditorType = AnnotationEditorType.FREETEXT;
this.container.classList.add("freeTextAnnotation");
const content = document.createElement("div");
content.classList.add("annotationTextContent");
content.setAttribute("role", "comment");
for (const line of this.textContent) {
const lineSpan = document.createElement("span");
lineSpan.textContent = line;
content.append(lineSpan);
this.container.append(content);
if (!this.data.popupRef && this.hasPopupData) {
this._editOnDoubleClick();
return this.data.hasOwnCanvas;
class LineAnnotationElement extends AnnotationElement {
constructor(parameters) {
this.container.classList.add("lineAnnotation");
} = getRectDims(data.rect);
const svg = this.svgFactory.create(width, height, true);
const line = this.#line = this.svgFactory.createElement("svg:line");
line.setAttribute("x1", data.rect[2] - data.lineCoordinates[0]);
line.setAttribute("y1", data.rect[3] - data.lineCoordinates[1]);
line.setAttribute("x2", data.rect[2] - data.lineCoordinates[2]);
line.setAttribute("y2", data.rect[3] - data.lineCoordinates[3]);
line.setAttribute("stroke-width", data.borderStyle.width || 1);
line.setAttribute("stroke", "transparent");
line.setAttribute("fill", "transparent");
this.container.append(svg);
if (!data.popupRef && this.hasPopupData) {
getElementsToTriggerPopup() {
this.container.classList.add("highlightArea");
class SquareAnnotationElement extends AnnotationElement {
constructor(parameters) {
this.container.classList.add("squareAnnotation");
} = getRectDims(data.rect);
const svg = this.svgFactory.create(width, height, true);
const borderWidth = data.borderStyle.width;
const square = this.#square = this.svgFactory.createElement("svg:rect");
square.setAttribute("x", borderWidth / 2);
square.setAttribute("y", borderWidth / 2);
square.setAttribute("width", width - borderWidth);
square.setAttribute("height", height - borderWidth);
square.setAttribute("stroke-width", borderWidth || 1);
square.setAttribute("stroke", "transparent");
square.setAttribute("fill", "transparent");
this.container.append(svg);
if (!data.popupRef && this.hasPopupData) {
getElementsToTriggerPopup() {
this.container.classList.add("highlightArea");
class CircleAnnotationElement extends AnnotationElement {
constructor(parameters) {
this.container.classList.add("circleAnnotation");
} = getRectDims(data.rect);
const svg = this.svgFactory.create(width, height, true);
const borderWidth = data.borderStyle.width;
const circle = this.#circle = this.svgFactory.createElement("svg:ellipse");
circle.setAttribute("cx", width / 2);
circle.setAttribute("cy", height / 2);
circle.setAttribute("rx", width / 2 - borderWidth / 2);
circle.setAttribute("ry", height / 2 - borderWidth / 2);
circle.setAttribute("stroke-width", borderWidth || 1);
circle.setAttribute("stroke", "transparent");
circle.setAttribute("fill", "transparent");
this.container.append(svg);
if (!data.popupRef && this.hasPopupData) {
getElementsToTriggerPopup() {
this.container.classList.add("highlightArea");
class PolylineAnnotationElement extends AnnotationElement {
constructor(parameters) {
this.containerClassName = "polylineAnnotation";
this.svgElementName = "svg:polyline";
this.container.classList.add(this.containerClassName);
} = getRectDims(data.rect);
const svg = this.svgFactory.create(width, height, true);
for (const coordinate of data.vertices) {
const x = coordinate.x - data.rect[0];
const y = data.rect[3] - coordinate.y;
points.push(x + "," + y);
points = points.join(" ");
const polyline = this.#polyline = this.svgFactory.createElement(this.svgElementName);
polyline.setAttribute("points", points);
polyline.setAttribute("stroke-width", data.borderStyle.width || 1);
polyline.setAttribute("stroke", "transparent");
polyline.setAttribute("fill", "transparent");
this.container.append(svg);
if (!data.popupRef && this.hasPopupData) {
getElementsToTriggerPopup() {
this.container.classList.add("highlightArea");
class PolygonAnnotationElement extends PolylineAnnotationElement {
constructor(parameters) {
this.containerClassName = "polygonAnnotation";
this.svgElementName = "svg:polygon";
class CaretAnnotationElement extends AnnotationElement {
constructor(parameters) {
this.container.classList.add("caretAnnotation");
if (!this.data.popupRef && this.hasPopupData) {
class InkAnnotationElement extends AnnotationElement {
constructor(parameters) {
this.containerClassName = "inkAnnotation";
this.svgElementName = "svg:polyline";
this.annotationEditorType = AnnotationEditorType.INK;
this.container.classList.add(this.containerClassName);
} = getRectDims(data.rect);
const svg = this.svgFactory.create(width, height, true);
for (const inkList of data.inkLists) {
for (const coordinate of inkList) {
const x = coordinate.x - data.rect[0];
const y = data.rect[3] - coordinate.y;
points.push(`${x},${y}`);
points = points.join(" ");
const polyline = this.svgFactory.createElement(this.svgElementName);
this.#polylines.push(polyline);
polyline.setAttribute("points", points);
polyline.setAttribute("stroke-width", data.borderStyle.width || 1);
polyline.setAttribute("stroke", "transparent");
polyline.setAttribute("fill", "transparent");
if (!data.popupRef && this.hasPopupData) {
this.container.append(svg);
getElementsToTriggerPopup() {
this.container.classList.add("highlightArea");
class HighlightAnnotationElement extends AnnotationElement {
constructor(parameters) {
createQuadrilaterals: true
if (!this.data.popupRef && this.hasPopupData) {
this.container.classList.add("highlightAnnotation");
class UnderlineAnnotationElement extends AnnotationElement {
constructor(parameters) {
createQuadrilaterals: true
if (!this.data.popupRef && this.hasPopupData) {
this.container.classList.add("underlineAnnotation");
class SquigglyAnnotationElement extends AnnotationElement {
constructor(parameters) {
createQuadrilaterals: true
if (!this.data.popupRef && this.hasPopupData) {
this.container.classList.add("squigglyAnnotation");
class StrikeOutAnnotationElement extends AnnotationElement {
constructor(parameters) {
createQuadrilaterals: true
if (!this.data.popupRef && this.hasPopupData) {
this.container.classList.add("strikeoutAnnotation");
class StampAnnotationElement extends AnnotationElement {
constructor(parameters) {
this.container.classList.add("stampAnnotation");
if (!this.data.popupRef && this.hasPopupData) {
class FileAttachmentAnnotationElement extends AnnotationElement {
constructor(parameters) {
this.filename = file.filename;
this.content = file.content;
this.linkService.eventBus?.dispatch("fileattachmentannotation", {