UNPKG

bug-reporterjs-lib

Version:

A lightweight and framework-agnostic JavaScript bug reporter with screenshot capture, error logging, and Axios error tracking. Designed to work seamlessly in Vue, React, and plain JavaScript projects.

483 lines (482 loc) 16.6 kB
function W(t, e) { if (t.match(/^[a-z]+:\/\//i)) return t; if (t.match(/^\/\//)) return window.location.protocol + t; if (t.match(/^[a-z]+:/i)) return t; const r = document.implementation.createHTMLDocument(), n = r.createElement("base"), s = r.createElement("a"); return r.head.appendChild(n), r.body.appendChild(s), e && (n.href = e), s.href = t, s.href; } const j = /* @__PURE__ */ (() => { let t = 0; const e = () => ( // eslint-disable-next-line no-bitwise `0000${(Math.random() * 36 ** 4 << 0).toString(36)}`.slice(-4) ); return () => (t += 1, `u${e()}${t}`); })(); function m(t) { const e = []; for (let r = 0, n = t.length; r < n; r++) e.push(t[r]); return e; } let g = null; function A(t = {}) { return g || (t.includeStyleProperties ? (g = t.includeStyleProperties, g) : (g = m(window.getComputedStyle(document.documentElement)), g)); } function y(t, e) { const n = (t.ownerDocument.defaultView || window).getComputedStyle(t).getPropertyValue(e); return n ? parseFloat(n.replace("px", "")) : 0; } function q(t) { const e = y(t, "border-left-width"), r = y(t, "border-right-width"); return t.clientWidth + e + r; } function z(t) { const e = y(t, "border-top-width"), r = y(t, "border-bottom-width"); return t.clientHeight + e + r; } function k(t, e = {}) { const r = e.width || q(t), n = e.height || z(t); return { width: r, height: n }; } function B() { let t, e; try { e = process; } catch { } const r = e && e.env ? e.env.devicePixelRatio : null; return r && (t = parseInt(r, 10), Number.isNaN(t) && (t = 1)), t || window.devicePixelRatio || 1; } const u = 16384; function G(t) { (t.width > u || t.height > u) && (t.width > u && t.height > u ? t.width > t.height ? (t.height *= u / t.width, t.width = u) : (t.width *= u / t.height, t.height = u) : t.width > u ? (t.height *= u / t.width, t.width = u) : (t.width *= u / t.height, t.height = u)); } function w(t) { return new Promise((e, r) => { const n = new Image(); n.onload = () => { n.decode().then(() => { requestAnimationFrame(() => e(n)); }); }, n.onerror = r, n.crossOrigin = "anonymous", n.decoding = "async", n.src = t; }); } async function X(t) { return Promise.resolve().then(() => new XMLSerializer().serializeToString(t)).then(encodeURIComponent).then((e) => `data:image/svg+xml;charset=utf-8,${e}`); } async function J(t, e, r) { const n = "http://www.w3.org/2000/svg", s = document.createElementNS(n, "svg"), i = document.createElementNS(n, "foreignObject"); return s.setAttribute("width", `${e}`), s.setAttribute("height", `${r}`), s.setAttribute("viewBox", `0 0 ${e} ${r}`), i.setAttribute("width", "100%"), i.setAttribute("height", "100%"), i.setAttribute("x", "0"), i.setAttribute("y", "0"), i.setAttribute("externalResourcesRequired", "true"), s.appendChild(i), i.appendChild(t), X(s); } const l = (t, e) => { if (t instanceof e) return !0; const r = Object.getPrototypeOf(t); return r === null ? !1 : r.constructor.name === e.name || l(r, e); }; function K(t) { const e = t.getPropertyValue("content"); return `${t.cssText} content: '${e.replace(/'|"/g, "")}';`; } function Q(t, e) { return A(e).map((r) => { const n = t.getPropertyValue(r), s = t.getPropertyPriority(r); return `${r}: ${n}${s ? " !important" : ""};`; }).join(" "); } function Y(t, e, r, n) { const s = `.${t}:${e}`, i = r.cssText ? K(r) : Q(r, n); return document.createTextNode(`${s}{${i}}`); } function C(t, e, r, n) { const s = window.getComputedStyle(t, r), i = s.getPropertyValue("content"); if (i === "" || i === "none") return; const c = j(); try { e.className = `${e.className} ${c}`; } catch { return; } const a = document.createElement("style"); a.appendChild(Y(c, r, s, n)), e.appendChild(a); } function Z(t, e, r) { C(t, e, ":before", r), C(t, e, ":after", r); } const P = "application/font-woff", $ = "image/jpeg", N = { woff: P, woff2: P, ttf: "application/font-truetype", eot: "application/vnd.ms-fontobject", png: "image/png", jpg: $, jpeg: $, gif: "image/gif", tiff: "image/tiff", svg: "image/svg+xml", webp: "image/webp" }; function tt(t) { const e = /\.([^./]*?)$/g.exec(t); return e ? e[1] : ""; } function x(t) { const e = tt(t).toLowerCase(); return N[e] || ""; } function et(t) { return t.split(/,/)[1]; } function E(t) { return t.search(/^(data:)/) !== -1; } function rt(t, e) { return `data:${e};base64,${t}`; } async function D(t, e, r) { const n = await fetch(t, e); if (n.status === 404) throw new Error(`Resource "${n.url}" not found`); const s = await n.blob(); return new Promise((i, c) => { const a = new FileReader(); a.onerror = c, a.onloadend = () => { try { i(r({ res: n, result: a.result })); } catch (o) { c(o); } }, a.readAsDataURL(s); }); } const b = {}; function nt(t, e, r) { let n = t.replace(/\?.*/, ""); return r && (n = t), /ttf|otf|eot|woff2?/i.test(n) && (n = n.replace(/.*\//, "")), e ? `[${e}]${n}` : n; } async function R(t, e, r) { const n = nt(t, e, r.includeQueryParams); if (b[n] != null) return b[n]; r.cacheBust && (t += (/\?/.test(t) ? "&" : "?") + (/* @__PURE__ */ new Date()).getTime()); let s; try { const i = await D(t, r.fetchRequestInit, ({ res: c, result: a }) => (e || (e = c.headers.get("Content-Type") || ""), et(a))); s = rt(i, e); } catch (i) { s = r.imagePlaceholder || ""; let c = `Failed to fetch resource: ${t}`; i && (c = typeof i == "string" ? i : i.message), c && console.warn(c); } return b[n] = s, s; } async function it(t) { const e = t.toDataURL(); return e === "data:," ? t.cloneNode(!1) : w(e); } async function st(t, e) { if (t.currentSrc) { const i = document.createElement("canvas"), c = i.getContext("2d"); i.width = t.clientWidth, i.height = t.clientHeight, c?.drawImage(t, 0, 0, i.width, i.height); const a = i.toDataURL(); return w(a); } const r = t.poster, n = x(r), s = await R(r, n, e); return w(s); } async function ct(t, e) { var r; try { if (!((r = t?.contentDocument) === null || r === void 0) && r.body) return await p(t.contentDocument.body, e, !0); } catch { } return t.cloneNode(!1); } async function at(t, e) { return l(t, HTMLCanvasElement) ? it(t) : l(t, HTMLVideoElement) ? st(t, e) : l(t, HTMLIFrameElement) ? ct(t, e) : t.cloneNode(v(t)); } const ot = (t) => t.tagName != null && t.tagName.toUpperCase() === "SLOT", v = (t) => t.tagName != null && t.tagName.toUpperCase() === "SVG"; async function lt(t, e, r) { var n, s; if (v(e)) return e; let i = []; return ot(t) && t.assignedNodes ? i = m(t.assignedNodes()) : l(t, HTMLIFrameElement) && (!((n = t.contentDocument) === null || n === void 0) && n.body) ? i = m(t.contentDocument.body.childNodes) : i = m(((s = t.shadowRoot) !== null && s !== void 0 ? s : t).childNodes), i.length === 0 || l(t, HTMLVideoElement) || await i.reduce((c, a) => c.then(() => p(a, r)).then((o) => { o && e.appendChild(o); }), Promise.resolve()), e; } function ut(t, e, r) { const n = e.style; if (!n) return; const s = window.getComputedStyle(t); s.cssText ? (n.cssText = s.cssText, n.transformOrigin = s.transformOrigin) : A(r).forEach((i) => { let c = s.getPropertyValue(i); i === "font-size" && c.endsWith("px") && (c = `${Math.floor(parseFloat(c.substring(0, c.length - 2))) - 0.1}px`), l(t, HTMLIFrameElement) && i === "display" && c === "inline" && (c = "block"), i === "d" && e.getAttribute("d") && (c = `path(${e.getAttribute("d")})`), n.setProperty(i, c, s.getPropertyPriority(i)); }); } function ft(t, e) { l(t, HTMLTextAreaElement) && (e.innerHTML = t.value), l(t, HTMLInputElement) && e.setAttribute("value", t.value); } function ht(t, e) { if (l(t, HTMLSelectElement)) { const r = e, n = Array.from(r.children).find((s) => t.value === s.getAttribute("value")); n && n.setAttribute("selected", ""); } } function mt(t, e, r) { return l(e, Element) && (ut(t, e, r), Z(t, e, r), ft(t, e), ht(t, e)), e; } async function gt(t, e) { const r = t.querySelectorAll ? t.querySelectorAll("use") : []; if (r.length === 0) return t; const n = {}; for (let i = 0; i < r.length; i++) { const a = r[i].getAttribute("xlink:href"); if (a) { const o = t.querySelector(a), f = document.querySelector(a); !o && f && !n[a] && (n[a] = await p(f, e, !0)); } } const s = Object.values(n); if (s.length) { const i = "http://www.w3.org/1999/xhtml", c = document.createElementNS(i, "svg"); c.setAttribute("xmlns", i), c.style.position = "absolute", c.style.width = "0", c.style.height = "0", c.style.overflow = "hidden", c.style.display = "none"; const a = document.createElementNS(i, "defs"); c.appendChild(a); for (let o = 0; o < s.length; o++) a.appendChild(s[o]); t.appendChild(c); } return t; } async function p(t, e, r) { return !r && e.filter && !e.filter(t) ? null : Promise.resolve(t).then((n) => at(n, e)).then((n) => lt(t, n, e)).then((n) => mt(t, n, e)).then((n) => gt(n, e)); } const U = /url\((['"]?)([^'"]+?)\1\)/g, dt = /url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g, yt = /src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g; function wt(t) { const e = t.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1"); return new RegExp(`(url\\(['"]?)(${e})(['"]?\\))`, "g"); } function pt(t) { const e = []; return t.replace(U, (r, n, s) => (e.push(s), r)), e.filter((r) => !E(r)); } async function St(t, e, r, n, s) { try { const i = r ? W(e, r) : e, c = x(e); let a; return s || (a = await R(i, c, n)), t.replace(wt(e), `$1${a}$3`); } catch { } return t; } function bt(t, { preferredFontFormat: e }) { return e ? t.replace(yt, (r) => { for (; ; ) { const [n, , s] = dt.exec(r) || []; if (!s) return ""; if (s === e) return `src: ${n};`; } }) : t; } function H(t) { return t.search(U) !== -1; } async function V(t, e, r) { if (!H(t)) return t; const n = bt(t, r); return pt(n).reduce((i, c) => i.then((a) => St(a, c, e, r)), Promise.resolve(n)); } async function d(t, e, r) { var n; const s = (n = e.style) === null || n === void 0 ? void 0 : n.getPropertyValue(t); if (s) { const i = await V(s, null, r); return e.style.setProperty(t, i, e.style.getPropertyPriority(t)), !0; } return !1; } async function Et(t, e) { await d("background", t, e) || await d("background-image", t, e), await d("mask", t, e) || await d("-webkit-mask", t, e) || await d("mask-image", t, e) || await d("-webkit-mask-image", t, e); } async function xt(t, e) { const r = l(t, HTMLImageElement); if (!(r && !E(t.src)) && !(l(t, SVGImageElement) && !E(t.href.baseVal))) return; const n = r ? t.src : t.href.baseVal, s = await R(n, x(n), e); await new Promise((i, c) => { t.onload = i, t.onerror = e.onImageErrorHandler ? (...o) => { try { i(e.onImageErrorHandler(...o)); } catch (f) { c(f); } } : c; const a = t; a.decode && (a.decode = i), a.loading === "lazy" && (a.loading = "eager"), r ? (t.srcset = "", t.src = s) : t.href.baseVal = s; }); } async function Rt(t, e) { const n = m(t.childNodes).map((s) => M(s, e)); await Promise.all(n).then(() => t); } async function M(t, e) { l(t, Element) && (await Et(t, e), await xt(t, e), await Rt(t, e)); } function Ct(t, e) { const { style: r } = t; e.backgroundColor && (r.backgroundColor = e.backgroundColor), e.width && (r.width = `${e.width}px`), e.height && (r.height = `${e.height}px`); const n = e.style; return n != null && Object.keys(n).forEach((s) => { r[s] = n[s]; }), t; } const T = {}; async function F(t) { let e = T[t]; if (e != null) return e; const n = await (await fetch(t)).text(); return e = { url: t, cssText: n }, T[t] = e, e; } async function L(t, e) { let r = t.cssText; const n = /url\(["']?([^"')]+)["']?\)/g, i = (r.match(/url\([^)]+\)/g) || []).map(async (c) => { let a = c.replace(n, "$1"); return a.startsWith("https://") || (a = new URL(a, t.url).href), D(a, e.fetchRequestInit, ({ result: o }) => (r = r.replace(c, `url(${o})`), [c, o])); }); return Promise.all(i).then(() => r); } function I(t) { if (t == null) return []; const e = [], r = /(\/\*[\s\S]*?\*\/)/gi; let n = t.replace(r, ""); const s = new RegExp("((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})", "gi"); for (; ; ) { const o = s.exec(n); if (o === null) break; e.push(o[0]); } n = n.replace(s, ""); const i = /@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi, c = "((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})", a = new RegExp(c, "gi"); for (; ; ) { let o = i.exec(n); if (o === null) { if (o = a.exec(n), o === null) break; i.lastIndex = a.lastIndex; } else a.lastIndex = i.lastIndex; e.push(o[0]); } return e; } async function Pt(t, e) { const r = [], n = []; return t.forEach((s) => { if ("cssRules" in s) try { m(s.cssRules || []).forEach((i, c) => { if (i.type === CSSRule.IMPORT_RULE) { let a = c + 1; const o = i.href, f = F(o).then((h) => L(h, e)).then((h) => I(h).forEach((S) => { try { s.insertRule(S, S.startsWith("@import") ? a += 1 : s.cssRules.length); } catch (_) { console.error("Error inserting rule from remote css", { rule: S, error: _ }); } })).catch((h) => { console.error("Error loading remote css", h.toString()); }); n.push(f); } }); } catch (i) { const c = t.find((a) => a.href == null) || document.styleSheets[0]; s.href != null && n.push(F(s.href).then((a) => L(a, e)).then((a) => I(a).forEach((o) => { c.insertRule(o, c.cssRules.length); })).catch((a) => { console.error("Error loading remote stylesheet", a); })), console.error("Error inlining remote css file", i); } }), Promise.all(n).then(() => (t.forEach((s) => { if ("cssRules" in s) try { m(s.cssRules || []).forEach((i) => { r.push(i); }); } catch (i) { console.error(`Error while reading CSS rules from ${s.href}`, i); } }), r)); } function $t(t) { return t.filter((e) => e.type === CSSRule.FONT_FACE_RULE).filter((e) => H(e.style.getPropertyValue("src"))); } async function Tt(t, e) { if (t.ownerDocument == null) throw new Error("Provided element is not within a Document"); const r = m(t.ownerDocument.styleSheets), n = await Pt(r, e); return $t(n); } function O(t) { return t.trim().replace(/["']/g, ""); } function Ft(t) { const e = /* @__PURE__ */ new Set(); function r(n) { (n.style.fontFamily || getComputedStyle(n).fontFamily).split(",").forEach((i) => { e.add(O(i)); }), Array.from(n.children).forEach((i) => { i instanceof HTMLElement && r(i); }); } return r(t), e; } async function Lt(t, e) { const r = await Tt(t, e), n = Ft(t); return (await Promise.all(r.filter((i) => n.has(O(i.style.fontFamily))).map((i) => { const c = i.parentStyleSheet ? i.parentStyleSheet.href : null; return V(i.cssText, c, e); }))).join(` `); } async function It(t, e) { const r = e.fontEmbedCSS != null ? e.fontEmbedCSS : e.skipFonts ? null : await Lt(t, e); if (r) { const n = document.createElement("style"), s = document.createTextNode(r); n.appendChild(s), t.firstChild ? t.insertBefore(n, t.firstChild) : t.appendChild(n); } } async function At(t, e = {}) { const { width: r, height: n } = k(t, e), s = await p(t, e, !0); return await It(s, e), await M(s, e), Ct(s, e), await J(s, r, n); } async function kt(t, e = {}) { const { width: r, height: n } = k(t, e), s = await At(t, e), i = await w(s), c = document.createElement("canvas"), a = c.getContext("2d"), o = e.pixelRatio || B(), f = e.canvasWidth || r, h = e.canvasHeight || n; return c.width = f * o, c.height = h * o, e.skipAutoScale || G(c), c.style.width = `${f}`, c.style.height = `${h}`, e.backgroundColor && (a.fillStyle = e.backgroundColor, a.fillRect(0, 0, c.width, c.height)), a.drawImage(i, 0, 0, c.width, c.height), c; } async function Dt(t, e = {}) { return (await kt(t, e)).toDataURL("image/jpeg", e.quality || 1); } export { kt as toCanvas, Dt as toJpeg, At as toSvg };