@pdf-viewer/react
Version:
A react-pdf-viewer component for React and Next.js. Suitable for react-pdf document.
307 lines (306 loc) • 8.97 kB
JavaScript
import { sanitizeExternalUrl as L } from "./sanitizeExternalUrl.js";
import { AnnotationSubType as _, AnnotationType as l } from "./types.js";
import { dateFormatter as I } from "./dateFormatter.js";
const v = ["click", "dblclick", "input", "change"], g = /* @__PURE__ */ new Map(), E = (e, t) => `${e.loadingTask.docId}___${t.num}R${t.gen === 0 ? "" : t.gen}`;
function x(e, t) {
const n = E(e, t);
return g.has(n) ? g.get(n) ?? null : null;
}
const B = (e, t, n) => {
g.set(E(e, t), n);
}, O = (e, t) => {
switch (t[1].name) {
case "XYZ":
return {
bottomOffset: (n, a) => t[3] === null ? a : t[3],
leftOffset: (n, a) => t[2] === null ? 0 : t[2],
pageIndex: e,
scaleTo: t[4]
};
case "Fit":
case "FitB":
return {
bottomOffset: 0,
leftOffset: 0,
pageIndex: e,
scaleTo: 1
};
case "FitH":
case "FitBH":
return {
bottomOffset: t[2],
leftOffset: 0,
pageIndex: e,
scaleTo: 1
};
default:
return {
bottomOffset: 0,
leftOffset: 0,
pageIndex: e,
scaleTo: 1
};
}
};
async function b(e, t) {
let n;
if (typeof t == "string" ? n = await e.getDestination(t) : n = t, n && typeof n[0] == "object" && n[0] !== null) {
const a = n[0], s = x(e, a);
if (s === null) {
const r = await e.getPageIndex(a);
return B(e, a, r), await b(e, n);
} else
return O(s, n);
} else
return O(n[0], n);
}
const H = (e) => {
const n = e.target.parentNode;
if (!n)
return;
const a = new MutationObserver((s) => {
s.forEach(() => {
n.querySelectorAll(
'[data-l10n-id="pdfjs-annotation-date-time-string"]'
).forEach((o) => {
const c = o.getAttribute("data-l10n-args");
if (c) {
try {
const { dateObj: i } = JSON.parse(c);
i && (o.textContent = I(i));
} catch {
}
a.disconnect();
}
});
});
});
return a.observe(n, {
childList: !0,
// Watch for changes to child elements
subtree: !0,
// Watch all descendants, not just direct children
attributes: !0
// Watch for changes to attributes
}), () => a.disconnect();
}, M = (e, t, n, a) => {
if (e.type !== "click")
return;
const s = e.target, r = s.getAttribute("data-element-id"), o = s.getAttribute("href");
if (o && o !== "#")
return;
const c = t.find((i) => i.id === r);
!c || c.annotationType !== _.Link || c.dest && b(n, c.dest).then((i) => {
a(i);
});
};
function P(e, t) {
for (const n of v)
e.addEventListener(n, t);
}
function U(e, t) {
for (const n of v)
e.removeEventListener(n, t);
}
function V(e) {
const { id: t, url: n, unsafeUrl: a } = e;
new MutationObserver((r, o) => {
const c = document.querySelector(`[data-annotation-id="${t}"]`);
if (c) {
const i = c.querySelector("a"), p = L((n || a) ?? "", "");
i && (i == null || i.setAttribute("target", "_blank"), i == null || i.setAttribute("href", p), i == null || i.setAttribute("rel", "noopener noreferrer")), o.disconnect();
}
}).observe(document.body, { childList: !0, subtree: !0 });
}
function $(e, t, n) {
const { rotation: a, scale: s } = t, r = a % 180 === 0;
if (e.fieldType === "Btn" && e.pushButton) {
const o = e.rect[2] - e.rect[0], c = e.rect[3] - e.rect[1], i = document.createElement("canvas");
i.setAttribute("width", ((r ? o : c) * s).toString()), i.setAttribute("height", ((r ? c : o) * s).toString()), n.set(e.id, i);
}
}
function k(e) {
var r;
let t = e;
for (; t.tagName !== "SECTION"; )
t = t.parentElement;
const n = t.getAttribute("aria-haspopup") === "dialog", a = t.classList.contains("popupAnnotation");
if (!n && !a)
return;
let s = t.id || t.getAttribute("aria-controls");
if (s || (s = (r = t.firstChild) == null ? void 0 : r.id), s && t.parentElement) {
const o = t.parentElement.querySelector(`[aria-controls="${s}"]`);
o && new MutationObserver((i, p) => {
const h = document.querySelectorAll(".popupDate");
h.length > 0 && (h.forEach((m) => {
if (m.innerHTML)
return !1;
const N = m.getAttribute("data-l10n-args");
if (N) {
const { date: y, time: A } = JSON.parse(N);
y && A && (m.textContent = `${y}, ${A}`);
}
}), p.disconnect());
}).observe(o, { childList: !0, subtree: !0 });
}
}
function d(e, t, n) {
const a = [];
if (n)
for (const s of n)
s[e] === t && a.push(s);
return a;
}
function u(e, t) {
return { type: e, data: t };
}
async function S(e, t) {
if (e.dest)
if (typeof e.dest == "string") {
const n = await b(t, e.dest);
return u(l.INTERNAL_LINK, {
referencedPage: n.pageIndex,
offset: null
});
} else {
const n = await t.getPageIndex(e.dest[0]);
return u(l.INTERNAL_LINK, {
referencedPage: n,
offset: {
left: e.dest[2],
bottom: e.dest[3]
}
});
}
else if (e.url)
return u(l.LINK, {
url: e.url,
unsafeUrl: e.unsafeUrl
});
}
function T(e) {
for (const t of e.getElementsByTagName("span")) {
let n = t.textContent;
const a = JSON.parse(t.dataset.l10nArgs ?? "{}");
if (n)
for (const s in a)
n = n.replace(`{{${s}}}`, a[s]);
t.textContent = n;
}
}
function w(e) {
return u(l.FILE_ATTACHMENT, e.file);
}
function f(e, t) {
switch (e.type) {
case "textarea":
case "text":
return u(l.FORM_TEXT, {
fieldName: e.name,
value: e.value
});
case "select-one":
case "select-multiple":
const n = [];
for (const s of e.options)
n.push({
value: s.value,
label: s.label
});
const a = [];
for (const s of e.selectedOptions)
a.push({
value: s.value,
label: s.label
});
return u(l.FORM_SELECT, {
fieldName: e.name,
value: a,
options: n
});
case "checkbox":
return u(l.FORM_CHECKBOX, {
fieldName: e.name,
checked: e.checked
});
case "radio":
return u(l.FORM_RADIO, {
fieldName: e.name,
...t
});
case "button":
return u(l.FORM_BUTTON, {
fieldName: e.name,
...t
});
}
}
async function D(e, t, n) {
var s;
let a = e.target.parentNode;
if (a.tagName === "DIV" && (a = a.firstChild), k(a), typeof a.className != "object")
if (a.className === "linkAnnotation" && e.type === "click") {
const r = (s = a.dataset) == null ? void 0 : s.annotationId;
if (r) {
const o = d("id", r, n);
if (o.length)
return await S(o[0], t);
}
} else if (
/* annotation.className.includes('popupAnnotation') || */
a.className.includes("textAnnotation")
)
T(a);
else if (a.className.includes("fileAttachmentAnnotation")) {
T(a);
const r = a.dataset.annotationId;
if (r && e.type === "dblclick")
return w(d("id", r, n)[0]);
} else if (a.className.includes("textWidgetAnnotation") && e.type === "input") {
let r = a.getElementsByTagName("input")[0];
return r || (r = a.getElementsByTagName("textarea")[0]), f(r);
} else {
if (a.className.includes("choiceWidgetAnnotation") && e.type === "input")
return f(a.getElementsByTagName("select")[0]);
if (a.className.includes("buttonWidgetAnnotation checkBox") && e.type === "change")
return f(a.getElementsByTagName("input")[0]);
if (a.className.includes("buttonWidgetAnnotation radioButton") && e.type === "change") {
const r = a.dataset.annotationId;
if (r) {
const o = d("id", r, n)[0], c = [];
for (const i of d(
"fieldName",
o.fieldName,
n
))
i.buttonValue && c.push(i.buttonValue);
return f(a.getElementsByTagName("input")[0], {
value: o.buttonValue,
defaultValue: o.fieldValue,
options: c
});
}
} else if (a.className.includes("buttonWidgetAnnotation pushButton") && e.type === "click") {
const r = a.dataset.annotationId;
if (r) {
const o = d("id", r, n)[0], { action: c } = o;
return c && ["Print", "SaveAs"].includes(c) ? { type: l.BUTTON, data: o } : o.resetForm ? f(
{ name: o.fieldName, type: "button" },
{ actions: o.actions, reset: !0 }
) : f(
{ name: o.fieldName, type: "button" },
{ actions: o.actions, reset: !1 }
);
}
}
}
}
export {
D as annotationEventsHandler,
H as annotationsEvents,
P as bindLayerEvents,
V as handleAnnotationLink,
$ as handleAnnotationWidget,
M as handleClick,
U as unbindLayerEvents
};