UNPKG

@anoki/fse-ui

Version:

FSE UI components library

718 lines (715 loc) 21.5 kB
import { __require as ue } from "./index.es628.js"; import { __require as ge } from "./index.es629.js"; import { __require as pe } from "./index.es630.js"; import { __require as he } from "./index.es631.js"; import { __require as me } from "./index.es632.js"; import { __require as we } from "./index.es633.js"; var $, Y; function Se() { if (Y) return $; Y = 1; const J = /* @__PURE__ */ ue(), B = ge(), { isPlainObject: K } = pe(), L = he(), Q = me(), { parse: j } = we(), ee = [ "img", "audio", "video", "picture", "svg", "object", "map", "iframe", "embed" ], te = ["script", "style"]; function E(d, t) { d && Object.keys(d).forEach(function(w) { t(d[w], w); }); } function x(d, t) { return {}.hasOwnProperty.call(d, t); } function U(d, t) { const w = []; return E(d, function(i) { t(i) && w.push(i); }), w; } function re(d) { for (const t in d) if (x(d, t)) return !1; return !0; } function ne(d) { return d.map(function(t) { if (!t.url) throw new Error("URL missing"); return t.url + (t.w ? ` ${t.w}w` : "") + (t.h ? ` ${t.h}h` : "") + (t.d ? ` ${t.d}x` : ""); }).join(", "); } $ = v; const se = /^[^\0\t\n\f\r /<=>]+$/; function v(d, t, w) { if (d == null) return ""; typeof d == "number" && (d = d.toString()); let i = "", h = ""; function R(e, n) { const r = this; this.tag = e, this.attribs = n || {}, this.tagPosition = i.length, this.text = "", this.openingTagLength = 0, this.mediaChildren = [], this.updateParentNodeText = function() { if (g.length) { const s = g[g.length - 1]; s.text += r.text; } }, this.updateParentNodeMediaChildren = function() { g.length && ee.includes(this.tag) && g[g.length - 1].mediaChildren.push(this.tag); }; } t = Object.assign({}, v.defaults, t), t.parser = Object.assign({}, ie, t.parser); const q = function(e) { return t.allowedTags === !1 || (t.allowedTags || []).indexOf(e) > -1; }; te.forEach(function(e) { q(e) && !t.allowVulnerableTags && console.warn(` ⚠️ Your \`allowedTags\` option includes, \`${e}\`, which is inherently vulnerable to XSS attacks. Please remove it from \`allowedTags\`. Or, to disable this warning, add the \`allowVulnerableTags\` option and ensure you are accounting for this risk. `); }); const le = t.nonTextTags || [ "script", "style", "textarea", "option" ]; let f, M; t.allowedAttributes && (f = {}, M = {}, E(t.allowedAttributes, function(e, n) { f[n] = []; const r = []; e.forEach(function(s) { typeof s == "string" && s.indexOf("*") >= 0 ? r.push(B(s).replace(/\\\*/g, ".*")) : f[n].push(s); }), r.length && (M[n] = new RegExp("^(" + r.join("|") + ")$")); })); const C = {}, D = {}, _ = {}; E(t.allowedClasses, function(e, n) { if (f && (x(f, n) || (f[n] = []), f[n].push("class")), C[n] = e, Array.isArray(e)) { const r = []; C[n] = [], _[n] = [], e.forEach(function(s) { typeof s == "string" && s.indexOf("*") >= 0 ? r.push(B(s).replace(/\\\*/g, ".*")) : s instanceof RegExp ? _[n].push(s) : C[n].push(s); }), r.length && (D[n] = new RegExp("^(" + r.join("|") + ")$")); } }); const I = {}; let z; E(t.transformTags, function(e, n) { let r; typeof e == "function" ? r = e : typeof e == "string" && (r = v.simpleTransform(e)), n === "*" ? z = r : I[n] = r; }); let m, g, P, S, A, O, H = !1; W(); const F = new J.Parser({ onopentag: function(e, n) { if (t.onOpenTag && t.onOpenTag(e, n), t.enforceHtmlBoundary && e === "html" && W(), A) { O++; return; } const r = new R(e, n); g.push(r); let s = !1; const u = !!r.text; let p; if (x(I, e) && (p = I[e](e, n), r.attribs = n = p.attribs, p.text !== void 0 && (r.innerText = p.text), e !== p.tagName && (r.name = e = p.tagName, S[m] = p.tagName)), z && (p = z(e, n), r.attribs = n = p.attribs, e !== p.tagName && (r.name = e = p.tagName, S[m] = p.tagName)), (!q(e) || t.disallowedTagsMode === "recursiveEscape" && !re(P) || t.nestingLimit != null && m >= t.nestingLimit) && (s = !0, P[m] = !0, (t.disallowedTagsMode === "discard" || t.disallowedTagsMode === "completelyDiscard") && le.indexOf(e) !== -1 && (A = !0, O = 1)), m++, s) { if (t.disallowedTagsMode === "discard" || t.disallowedTagsMode === "completelyDiscard") { if (r.innerText && !u) { const c = y(r.innerText); t.textFilter ? i += t.textFilter(c, e) : i += c, H = !0; } return; } h = i, i = ""; } i += "<" + e, e === "script" && (t.allowedScriptHostnames || t.allowedScriptDomains) && (r.innerText = ""), s && (t.disallowedTagsMode === "escape" || t.disallowedTagsMode === "recursiveEscape") && t.preserveEscapedAttributes ? E(n, function(c, l) { i += " " + l + '="' + y(c || "", !0) + '"'; }) : (!f || x(f, e) || f["*"]) && E(n, function(c, l) { if (!se.test(l)) { delete r.attribs[l]; return; } if (c === "" && !t.allowedEmptyAttributes.includes(l) && (t.nonBooleanAttributes.includes(l) || t.nonBooleanAttributes.includes("*"))) { delete r.attribs[l]; return; } let N = !1; if (!f || x(f, e) && f[e].indexOf(l) !== -1 || f["*"] && f["*"].indexOf(l) !== -1 || x(M, e) && M[e].test(l) || M["*"] && M["*"].test(l)) N = !0; else if (f && f[e]) { for (const o of f[e]) if (K(o) && o.name && o.name === l) { N = !0; let a = ""; if (o.multiple === !0) { const k = c.split(" "); for (const T of k) o.values.indexOf(T) !== -1 && (a === "" ? a = T : a += " " + T); } else o.values.indexOf(c) >= 0 && (a = c); c = a; } } if (N) { if (t.allowedSchemesAppliedToAttributes.indexOf(l) !== -1 && G(e, c)) { delete r.attribs[l]; return; } if (e === "script" && l === "src") { let o = !0; try { const a = V(c); if (t.allowedScriptHostnames || t.allowedScriptDomains) { const k = (t.allowedScriptHostnames || []).find(function(b) { return b === a.url.hostname; }), T = (t.allowedScriptDomains || []).find(function(b) { return a.url.hostname === b || a.url.hostname.endsWith(`.${b}`); }); o = k || T; } } catch { o = !1; } if (!o) { delete r.attribs[l]; return; } } if (e === "iframe" && l === "src") { let o = !0; try { const a = V(c); if (a.isRelativeUrl) o = x(t, "allowIframeRelativeUrls") ? t.allowIframeRelativeUrls : !t.allowedIframeHostnames && !t.allowedIframeDomains; else if (t.allowedIframeHostnames || t.allowedIframeDomains) { const k = (t.allowedIframeHostnames || []).find(function(b) { return b === a.url.hostname; }), T = (t.allowedIframeDomains || []).find(function(b) { return a.url.hostname === b || a.url.hostname.endsWith(`.${b}`); }); o = k || T; } } catch { o = !1; } if (!o) { delete r.attribs[l]; return; } } if (l === "srcset") try { let o = Q(c); if (o.forEach(function(a) { G("srcset", a.url) && (a.evil = !0); }), o = U(o, function(a) { return !a.evil; }), o.length) c = ne(U(o, function(a) { return !a.evil; })), r.attribs[l] = c; else { delete r.attribs[l]; return; } } catch { delete r.attribs[l]; return; } if (l === "class") { const o = C[e], a = C["*"], k = D[e], T = _[e], b = _["*"], de = D["*"], X = [ k, de ].concat(T, b).filter(function(fe) { return fe; }); if (o && a ? c = Z( c, L(o, a), X ) : c = Z( c, o || a, X ), !c.length) { delete r.attribs[l]; return; } } if (l === "style") { if (t.parseStyleAttributes) try { const o = j(e + " {" + c + "}", { map: !1 }), a = oe( o, t.allowedStyles ); if (c = ae(a), c.length === 0) { delete r.attribs[l]; return; } } catch { typeof window < "u" && console.warn('Failed to parse "' + e + " {" + c + `}", If you're running this in a browser, we recommend to disable style parsing: options.parseStyleAttributes: false, since this only works in a node environment due to a postcss dependency, More info: https://github.com/apostrophecms/sanitize-html/issues/547`), delete r.attribs[l]; return; } else if (t.allowedStyles) throw new Error("allowedStyles option cannot be used together with parseStyleAttributes: false."); } i += " " + l, c && c.length ? i += '="' + y(c, !0) + '"' : t.allowedEmptyAttributes.includes(l) && (i += '=""'); } else delete r.attribs[l]; }), t.selfClosing.indexOf(e) !== -1 ? i += " />" : (i += ">", r.innerText && !u && !t.textFilter && (i += y(r.innerText), H = !0)), s && (i = h + y(i), h = ""), r.openingTagLength = i.length - r.tagPosition; }, ontext: function(e) { if (A) return; const n = g[g.length - 1]; let r; if (n && (r = n.tag, e = n.innerText !== void 0 ? n.innerText : e), t.disallowedTagsMode === "completelyDiscard" && !q(r)) e = ""; else if ((t.disallowedTagsMode === "discard" || t.disallowedTagsMode === "completelyDiscard") && (r === "script" || r === "style")) i += e; else if (!H) { const s = y(e, !1); t.textFilter ? i += t.textFilter(s, r) : i += s; } if (g.length) { const s = g[g.length - 1]; s.text += e; } }, onclosetag: function(e, n) { if (t.onCloseTag && t.onCloseTag(e, n), A) if (O--, !O) A = !1; else return; const r = g.pop(); if (!r) return; if (r.tag !== e) { g.push(r); return; } A = t.enforceHtmlBoundary ? e === "html" : !1, m--; const s = P[m]; if (s) { if (delete P[m], t.disallowedTagsMode === "discard" || t.disallowedTagsMode === "completelyDiscard") { r.updateParentNodeText(); return; } h = i, i = ""; } if (S[m] && (e = S[m], delete S[m]), t.exclusiveFilter) { const u = t.exclusiveFilter(r); if (u === "excludeTag") { s && (i = h, h = ""), i = i.substring(0, r.tagPosition) + i.substring(r.tagPosition + r.openingTagLength); return; } else if (u) { i = i.substring(0, r.tagPosition); return; } } if (r.updateParentNodeMediaChildren(), r.updateParentNodeText(), // Already output /> t.selfClosing.indexOf(e) !== -1 || // Escaped tag, closing tag is implied n && !q(e) && ["escape", "recursiveEscape"].indexOf(t.disallowedTagsMode) >= 0) { s && (i = h, h = ""); return; } i += "</" + e + ">", s && (i = h + y(i), h = ""), H = !1; } }, t.parser); if (F.write(d), F.end(), t.disallowedTagsMode === "escape" || t.disallowedTagsMode === "recursiveEscape") { const e = F.endIndex; if (e != null && e >= 0 && e < d.length) { const n = d.substring(e); i += y(n); } else (e == null || e < 0) && d.length > 0 && i === "" && (i = y(d)); } return i; function W() { i = "", m = 0, g = [], P = {}, S = {}, A = !1, O = 0; } function y(e, n) { return typeof e != "string" && (e = e + ""), t.parser.decodeEntities && (e = e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"), n && (e = e.replace(/"/g, "&quot;"))), e = e.replace(/&(?![a-zA-Z0-9#]{1,20};)/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"), n && (e = e.replace(/"/g, "&quot;")), e; } function G(e, n) { for (n = n.replace(/[\x00-\x20]+/g, ""); ; ) { const u = n.indexOf("<!--"); if (u === -1) break; const p = n.indexOf("-->", u + 4); if (p === -1) break; n = n.substring(0, u) + n.substring(p + 3); } const r = n.match(/^([a-zA-Z][a-zA-Z0-9.\-+]*):/); if (!r) return n.match(/^[/\\]{2}/) ? !t.allowProtocolRelative : !1; const s = r[1].toLowerCase(); return x(t.allowedSchemesByTag, e) ? t.allowedSchemesByTag[e].indexOf(s) === -1 : !t.allowedSchemes || t.allowedSchemes.indexOf(s) === -1; } function V(e) { if (e = e.replace(/^(\w+:)?\s*[\\/]\s*[\\/]/, "$1//"), e.startsWith("relative:")) throw new Error("relative: exploit attempt"); let n = "relative://relative-site"; for (let u = 0; u < 100; u++) n += `/${u}`; const r = new URL(e, n); return { isRelativeUrl: r && r.hostname === "relative-site" && r.protocol === "relative:", url: r }; } function oe(e, n) { if (!n) return e; const r = e.nodes[0]; let s; return n[r.selector] && n["*"] ? s = L( n[r.selector], n["*"] ) : s = n[r.selector] || n["*"], s && (e.nodes[0].nodes = r.nodes.reduce(ce(s), [])), e; } function ae(e) { return e.nodes[0].nodes.reduce(function(n, r) { return n.push( `${r.prop}:${r.value}${r.important ? " !important" : ""}` ), n; }, []).join(";"); } function ce(e) { return function(n, r) { return x(e, r.prop) && e[r.prop].some(function(u) { return u.test(r.value); }) && n.push(r), n; }; } function Z(e, n, r) { return n ? (e = e.split(/\s+/), e.filter(function(s) { return n.indexOf(s) !== -1 || r.some(function(u) { return u.test(s); }); }).join(" ")) : e; } } const ie = { decodeEntities: !0 }; return v.defaults = { allowedTags: [ // Sections derived from MDN element categories and limited to the more // benign categories. // https://developer.mozilla.org/en-US/docs/Web/HTML/Element // Content sectioning "address", "article", "aside", "footer", "header", "h1", "h2", "h3", "h4", "h5", "h6", "hgroup", "main", "nav", "section", // Text content "blockquote", "dd", "div", "dl", "dt", "figcaption", "figure", "hr", "li", "menu", "ol", "p", "pre", "ul", // Inline text semantics "a", "abbr", "b", "bdi", "bdo", "br", "cite", "code", "data", "dfn", "em", "i", "kbd", "mark", "q", "rb", "rp", "rt", "rtc", "ruby", "s", "samp", "small", "span", "strong", "sub", "sup", "time", "u", "var", "wbr", // Table content "caption", "col", "colgroup", "table", "tbody", "td", "tfoot", "th", "thead", "tr" ], // Tags that cannot be boolean nonBooleanAttributes: [ "abbr", "accept", "accept-charset", "accesskey", "action", "allow", "alt", "as", "autocapitalize", "autocomplete", "blocking", "charset", "cite", "class", "color", "cols", "colspan", "content", "contenteditable", "coords", "crossorigin", "data", "datetime", "decoding", "dir", "dirname", "download", "draggable", "enctype", "enterkeyhint", "fetchpriority", "for", "form", "formaction", "formenctype", "formmethod", "formtarget", "headers", "height", "hidden", "high", "href", "hreflang", "http-equiv", "id", "imagesizes", "imagesrcset", "inputmode", "integrity", "is", "itemid", "itemprop", "itemref", "itemtype", "kind", "label", "lang", "list", "loading", "low", "max", "maxlength", "media", "method", "min", "minlength", "name", "nonce", "optimum", "pattern", "ping", "placeholder", "popover", "popovertarget", "popovertargetaction", "poster", "preload", "referrerpolicy", "rel", "rows", "rowspan", "sandbox", "scope", "shape", "size", "sizes", "slot", "span", "spellcheck", "src", "srcdoc", "srclang", "srcset", "start", "step", "style", "tabindex", "target", "title", "translate", "type", "usemap", "value", "width", "wrap", // Event handlers "onauxclick", "onafterprint", "onbeforematch", "onbeforeprint", "onbeforeunload", "onbeforetoggle", "onblur", "oncancel", "oncanplay", "oncanplaythrough", "onchange", "onclick", "onclose", "oncontextlost", "oncontextmenu", "oncontextrestored", "oncopy", "oncuechange", "oncut", "ondblclick", "ondrag", "ondragend", "ondragenter", "ondragleave", "ondragover", "ondragstart", "ondrop", "ondurationchange", "onemptied", "onended", "onerror", "onfocus", "onformdata", "onhashchange", "oninput", "oninvalid", "onkeydown", "onkeypress", "onkeyup", "onlanguagechange", "onload", "onloadeddata", "onloadedmetadata", "onloadstart", "onmessage", "onmessageerror", "onmousedown", "onmouseenter", "onmouseleave", "onmousemove", "onmouseout", "onmouseover", "onmouseup", "onoffline", "ononline", "onpagehide", "onpageshow", "onpaste", "onpause", "onplay", "onplaying", "onpopstate", "onprogress", "onratechange", "onreset", "onresize", "onrejectionhandled", "onscroll", "onscrollend", "onsecuritypolicyviolation", "onseeked", "onseeking", "onselect", "onslotchange", "onstalled", "onstorage", "onsubmit", "onsuspend", "ontimeupdate", "ontoggle", "onunhandledrejection", "onunload", "onvolumechange", "onwaiting", "onwheel" ], disallowedTagsMode: "discard", allowedAttributes: { a: ["href", "name", "target"], // We don't currently allow img itself by default, but // these attributes would make sense if we did. img: ["src", "srcset", "alt", "title", "width", "height", "loading"] }, allowedEmptyAttributes: [ "alt" ], // Lots of these won't come up by default because we don't allow them selfClosing: ["img", "br", "hr", "area", "base", "basefont", "input", "link", "meta"], // URL schemes we permit allowedSchemes: ["http", "https", "ftp", "mailto", "tel"], allowedSchemesByTag: {}, allowedSchemesAppliedToAttributes: ["href", "src", "cite"], allowProtocolRelative: !0, enforceHtmlBoundary: !1, parseStyleAttributes: !0, preserveEscapedAttributes: !1 }, v.simpleTransform = function(d, t, w) { return w = w === void 0 ? !0 : w, t = t || {}, function(i, h) { let R; if (w) for (R in t) h[R] = t[R]; else h = t; return { tagName: d, attribs: h }; }; }, $; } export { Se as __require }; //# sourceMappingURL=index.es627.js.map