vite-plugin-dom
Version:
Enables DOM manipulation and comment injection during the build process
538 lines (533 loc) • 13.4 kB
JavaScript
import { DomUtils as c, DefaultHandler as S, Parser as M } from "htmlparser2";
var s;
(function(e) {
e.Root = "root", e.Text = "text", e.Directive = "directive", e.Comment = "comment", e.Script = "script", e.Style = "style", e.Tag = "tag", e.CDATA = "cdata", e.Doctype = "doctype";
})(s || (s = {}));
function $(e) {
return e.type === s.Tag || e.type === s.Script || e.type === s.Style;
}
const I = s.Root, P = s.Text, L = s.Directive, E = s.Comment, R = s.Script, U = s.Style, k = s.Tag, F = s.CDATA, j = s.Doctype, y = /["&'<>$\x80-\uFFFF]/g, G = /* @__PURE__ */ new Map([
[34, """],
[38, "&"],
[39, "'"],
[60, "<"],
[62, ">"]
]), _ = (
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
String.prototype.codePointAt != null ? (e, t) => e.codePointAt(t) : (
// http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
(e, t) => (e.charCodeAt(t) & 64512) === 55296 ? (e.charCodeAt(t) - 55296) * 1024 + e.charCodeAt(t + 1) - 56320 + 65536 : e.charCodeAt(t)
)
);
function w(e) {
let t = "", n = 0, r;
for (; (r = y.exec(e)) !== null; ) {
const i = r.index, a = e.charCodeAt(i), o = G.get(a);
o !== void 0 ? (t += e.substring(n, i) + o, n = i + 1) : (t += `${e.substring(n, i)}&#x${_(e, i).toString(16)};`, n = y.lastIndex += +((a & 64512) === 55296));
}
return t + e.substr(n);
}
function T(e, t) {
return function(r) {
let i, a = 0, o = "";
for (; i = e.exec(r); )
a !== i.index && (o += r.substring(a, i.index)), o += t.get(i[0].charCodeAt(0)), a = i.index + 1;
return o + r.substring(a);
};
}
const H = T(/["&\u00A0]/g, /* @__PURE__ */ new Map([
[34, """],
[38, "&"],
[160, " "]
])), q = T(/[&<>\u00A0]/g, /* @__PURE__ */ new Map([
[38, "&"],
[60, "<"],
[62, ">"],
[160, " "]
])), B = new Map([
"altGlyph",
"altGlyphDef",
"altGlyphItem",
"animateColor",
"animateMotion",
"animateTransform",
"clipPath",
"feBlend",
"feColorMatrix",
"feComponentTransfer",
"feComposite",
"feConvolveMatrix",
"feDiffuseLighting",
"feDisplacementMap",
"feDistantLight",
"feDropShadow",
"feFlood",
"feFuncA",
"feFuncB",
"feFuncG",
"feFuncR",
"feGaussianBlur",
"feImage",
"feMerge",
"feMergeNode",
"feMorphology",
"feOffset",
"fePointLight",
"feSpecularLighting",
"feSpotLight",
"feTile",
"feTurbulence",
"foreignObject",
"glyphRef",
"linearGradient",
"radialGradient",
"textPath"
].map((e) => [e.toLowerCase(), e])), O = new Map([
"definitionURL",
"attributeName",
"attributeType",
"baseFrequency",
"baseProfile",
"calcMode",
"clipPathUnits",
"diffuseConstant",
"edgeMode",
"filterUnits",
"glyphRef",
"gradientTransform",
"gradientUnits",
"kernelMatrix",
"kernelUnitLength",
"keyPoints",
"keySplines",
"keyTimes",
"lengthAdjust",
"limitingConeAngle",
"markerHeight",
"markerUnits",
"markerWidth",
"maskContentUnits",
"maskUnits",
"numOctaves",
"pathLength",
"patternContentUnits",
"patternTransform",
"patternUnits",
"pointsAtX",
"pointsAtY",
"pointsAtZ",
"preserveAlpha",
"preserveAspectRatio",
"primitiveUnits",
"refX",
"refY",
"repeatCount",
"repeatDur",
"requiredExtensions",
"requiredFeatures",
"specularConstant",
"specularExponent",
"spreadMethod",
"startOffset",
"stdDeviation",
"stitchTiles",
"surfaceScale",
"systemLanguage",
"tableValues",
"targetX",
"targetY",
"textLength",
"viewBox",
"viewTarget",
"xChannelSelector",
"yChannelSelector",
"zoomAndPan"
].map((e) => [e.toLowerCase(), e])), X = /* @__PURE__ */ new Set([
"style",
"script",
"xmp",
"iframe",
"noembed",
"noframes",
"plaintext",
"noscript"
]);
function V(e) {
return e.replace(/"/g, """);
}
function Y(e, t) {
var n;
if (!e)
return;
const r = ((n = t.encodeEntities) !== null && n !== void 0 ? n : t.decodeEntities) === !1 ? V : t.xmlMode || t.encodeEntities !== "utf8" ? w : H;
return Object.keys(e).map((i) => {
var a, o;
const l = (a = e[i]) !== null && a !== void 0 ? a : "";
return t.xmlMode === "foreign" && (i = (o = O.get(i)) !== null && o !== void 0 ? o : i), !t.emptyAttrs && !t.xmlMode && l === "" ? i : `${i}="${r(l)}"`;
}).join(" ");
}
const v = /* @__PURE__ */ new Set([
"area",
"base",
"basefont",
"br",
"col",
"command",
"embed",
"frame",
"hr",
"img",
"input",
"isindex",
"keygen",
"link",
"meta",
"param",
"source",
"track",
"wbr"
]);
function x(e, t = {}) {
const n = "length" in e ? e : [e];
let r = "";
for (let i = 0; i < n.length; i++)
r += W(n[i], t);
return r;
}
function W(e, t) {
switch (e.type) {
case I:
return x(e.children, t);
case j:
case L:
return J(e);
case E:
return te(e);
case F:
return ee(e);
case R:
case U:
case k:
return Z(e, t);
case P:
return K(e, t);
}
}
const z = /* @__PURE__ */ new Set([
"mi",
"mo",
"mn",
"ms",
"mtext",
"annotation-xml",
"foreignObject",
"desc",
"title"
]), Q = /* @__PURE__ */ new Set(["svg", "math"]);
function Z(e, t) {
var n;
t.xmlMode === "foreign" && (e.name = (n = B.get(e.name)) !== null && n !== void 0 ? n : e.name, e.parent && z.has(e.parent.name) && (t = { ...t, xmlMode: !1 })), !t.xmlMode && Q.has(e.name) && (t = { ...t, xmlMode: "foreign" });
let r = `<${e.name}`;
const i = Y(e.attribs, t);
return i && (r += ` ${i}`), e.children.length === 0 && (t.xmlMode ? (
// In XML mode or foreign mode, and user hasn't explicitly turned off self-closing tags
t.selfClosingTags !== !1
) : (
// User explicitly asked for self-closing tags, even in HTML mode
t.selfClosingTags && v.has(e.name)
)) ? (t.xmlMode || (r += " "), r += "/>") : (r += ">", e.children.length > 0 && (r += x(e.children, t)), (t.xmlMode || !v.has(e.name)) && (r += `</${e.name}>`)), r;
}
function J(e) {
return `<${e.data}>`;
}
function K(e, t) {
var n;
let r = e.data || "";
return ((n = t.encodeEntities) !== null && n !== void 0 ? n : t.decodeEntities) !== !1 && !(!t.xmlMode && e.parent && X.has(e.parent.name)) && (r = t.xmlMode || t.encodeEntities !== "utf8" ? w(r) : q(r)), r;
}
function ee(e) {
return `<![CDATA[${e.children[0].data}]]>`;
}
function te(e) {
return `<!--${e.data}-->`;
}
class D {
constructor() {
this.parent = null, this.prev = null, this.next = null, this.startIndex = null, this.endIndex = null;
}
// Read-write aliases for properties
/**
* Same as {@link parent}.
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
*/
get parentNode() {
return this.parent;
}
set parentNode(t) {
this.parent = t;
}
/**
* Same as {@link prev}.
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
*/
get previousSibling() {
return this.prev;
}
set previousSibling(t) {
this.prev = t;
}
/**
* Same as {@link next}.
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
*/
get nextSibling() {
return this.next;
}
set nextSibling(t) {
this.next = t;
}
/**
* Clone this node, and optionally its children.
*
* @param recursive Clone child nodes as well.
* @returns A clone of the node.
*/
cloneNode(t = !1) {
return N(this, t);
}
}
class b extends D {
/**
* @param data The content of the data node
*/
constructor(t) {
super(), this.data = t;
}
/**
* Same as {@link data}.
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
*/
get nodeValue() {
return this.data;
}
set nodeValue(t) {
this.data = t;
}
}
class f extends b {
constructor() {
super(...arguments), this.type = s.Text;
}
get nodeType() {
return 3;
}
}
class d extends b {
constructor() {
super(...arguments), this.type = s.Comment;
}
get nodeType() {
return 8;
}
}
class ne extends b {
constructor(t, n) {
super(n), this.name = t, this.type = s.Directive;
}
get nodeType() {
return 1;
}
}
class C extends D {
/**
* @param children Children of the node. Only certain node types can have children.
*/
constructor(t) {
super(), this.children = t;
}
// Aliases
/** First child of the node. */
get firstChild() {
var t;
return (t = this.children[0]) !== null && t !== void 0 ? t : null;
}
/** Last child of the node. */
get lastChild() {
return this.children.length > 0 ? this.children[this.children.length - 1] : null;
}
/**
* Same as {@link children}.
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
*/
get childNodes() {
return this.children;
}
set childNodes(t) {
this.children = t;
}
}
class re extends C {
constructor() {
super(...arguments), this.type = s.CDATA;
}
get nodeType() {
return 4;
}
}
class ie extends C {
constructor() {
super(...arguments), this.type = s.Root;
}
get nodeType() {
return 9;
}
}
class se extends C {
/**
* @param name Name of the tag, eg. `div`, `span`.
* @param attribs Object mapping attribute names to attribute values.
* @param children Children of the node.
*/
constructor(t, n, r = [], i = t === "script" ? s.Script : t === "style" ? s.Style : s.Tag) {
super(r), this.name = t, this.attribs = n, this.type = i;
}
get nodeType() {
return 1;
}
// DOM Level 1 aliases
/**
* Same as {@link name}.
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
*/
get tagName() {
return this.name;
}
set tagName(t) {
this.name = t;
}
get attributes() {
return Object.keys(this.attribs).map((t) => {
var n, r;
return {
name: t,
value: this.attribs[t],
namespace: (n = this["x-attribsNamespace"]) === null || n === void 0 ? void 0 : n[t],
prefix: (r = this["x-attribsPrefix"]) === null || r === void 0 ? void 0 : r[t]
};
});
}
}
function ae(e) {
return $(e);
}
function oe(e) {
return e.type === s.CDATA;
}
function ce(e) {
return e.type === s.Text;
}
function le(e) {
return e.type === s.Comment;
}
function ue(e) {
return e.type === s.Directive;
}
function fe(e) {
return e.type === s.Root;
}
function N(e, t = !1) {
let n;
if (ce(e))
n = new f(e.data);
else if (le(e))
n = new d(e.data);
else if (ae(e)) {
const r = t ? g(e.children) : [], i = new se(e.name, { ...e.attribs }, r);
r.forEach((a) => a.parent = i), e.namespace != null && (i.namespace = e.namespace), e["x-attribsNamespace"] && (i["x-attribsNamespace"] = { ...e["x-attribsNamespace"] }), e["x-attribsPrefix"] && (i["x-attribsPrefix"] = { ...e["x-attribsPrefix"] }), n = i;
} else if (oe(e)) {
const r = t ? g(e.children) : [], i = new re(r);
r.forEach((a) => a.parent = i), n = i;
} else if (fe(e)) {
const r = t ? g(e.children) : [], i = new ie(r);
r.forEach((a) => a.parent = i), e["x-mode"] && (i["x-mode"] = e["x-mode"]), n = i;
} else if (ue(e)) {
const r = new ne(e.name, e.data);
e["x-name"] != null && (r["x-name"] = e["x-name"], r["x-publicId"] = e["x-publicId"], r["x-systemId"] = e["x-systemId"]), n = r;
} else
throw new Error(`Not implemented yet: ${e.type}`);
return n.startIndex = e.startIndex, n.endIndex = e.endIndex, e.sourceCodeLocation != null && (n.sourceCodeLocation = e.sourceCodeLocation), n;
}
function g(e) {
const t = e.map((n) => N(n, !0));
for (let n = 1; n < t.length; n++)
t[n].prev = t[n - 1], t[n - 1].next = t[n];
return t;
}
function A(e, t, n) {
return m(e.attribs[t] || "", n);
}
function de(e, t) {
const { tags: n = [], ids: r = [], classes: i = [] } = t, a = m(e.tagName, n) ? e.tagName : "";
if (A(e, "id", r) || A(e, "class", i)) {
const o = e.attribs.id ? `${a}#` : `${a}.`, l = e.attribs.id || e.attribs.class.split(" ").filter((p) => m(p, i)).join(".");
c.prepend(e, new f(`
`)), c.append(e, new f(`
`)), c.prepend(e, new d(`BEGIN ${o + l}`)), c.append(e, new d(`/END ${o + l}`));
} else
a && (c.prepend(e, new f(`
`)), c.append(e, new f(`
`)), c.prepend(e, new d(`BEGIN ${a}`)), c.append(e, new d(`/END ${a}`)));
}
function m(e, t) {
const n = e.split(" ");
switch (typeof t) {
case "string":
return n.indexOf(t) !== -1;
case "object":
return t instanceof RegExp ? n.some((r) => t.test(r)) : Array.isArray(t) ? t.some((r) => typeof r == "string" ? n.indexOf(r) !== -1 : r instanceof RegExp ? n.some((i) => r.test(i)) : !1) : !1;
default:
return !1;
}
}
function he({
applyOnMode: e = ["static"],
comments: t,
handler: n,
onComplete: r,
...i
} = {}) {
const a = typeof n == "function", o = typeof r == "function";
let l, p;
return {
name: "plugin-dom",
apply(u, { mode: h }) {
return typeof e == "boolean" ? e : (e == null ? void 0 : e.indexOf(h)) !== -1;
},
buildStart() {
l = new S(
(u, h) => {
o && Promise.resolve(r.call(c, h, u));
},
i,
(u) => {
typeof t == "object" && de(u, t), a && Promise.resolve(n.call(c, u));
}
), p = new M(l);
},
transformIndexHtml(u) {
return p.parseComplete(u), x(l.dom);
}
};
}
export {
re as CDATA,
d as Comment,
b as DataNode,
ie as Document,
se as Element,
D as Node,
C as NodeWithChildren,
f as Text,
he as default,
A as domHas
};