Files
FrenoCorp/node_modules/babel-plugin-jsx-dom-expressions/index.js
Michael Freno 7c684a42cc FRE-600: Fix code review blockers
- Consolidated duplicate UndoManagers to single instance
- Fixed connection promise to only resolve on 'connected' status
- Fixed WebSocketProvider import (WebsocketProvider)
- Added proper doc.destroy() cleanup
- Renamed isPresenceInitialized property to avoid conflict

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-25 00:08:01 -04:00

4360 lines
133 KiB
JavaScript

'use strict';
var SyntaxJSX = require('@babel/plugin-syntax-jsx');
var t = require('@babel/types');
var helperModuleImports = require('@babel/helper-module-imports');
var htmlEntities = require('html-entities');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var t__namespace = /*#__PURE__*/_interopNamespaceDefault(t);
// list of lowercase booleans
const booleans = [
"allowfullscreen",
"async",
"alpha", // HTMLInputElement
"autofocus", // HTMLElement prop
"autoplay",
"checked",
"controls",
"default",
"disabled",
"formnovalidate",
"hidden", // HTMLElement prop - not a boolean
"indeterminate",
"inert", // HTMLElement prop
"ismap",
"loop",
"multiple",
"muted",
"nomodule",
"novalidate",
"open",
"playsinline",
"readonly",
"required",
"reversed",
"seamless", // HTMLIframeElement - non-standard
"selected",
"adauctionheaders", // experimental
"browsingtopics", // experimental
"credentialless", // experimental
"defaultchecked",
"defaultmuted",
"defaultselected",
"defer",
"disablepictureinpicture",
"disableremoteplayback",
"preservespitch", // appears as camelCase property only (not as attribute)
"shadowrootclonable",
"shadowrootcustomelementregistry", // experimental - doesnt seem to have a prop yet
"shadowrootdelegatesfocus",
"shadowrootserializable", // experimental
"sharedstoragewritable" // experimental
];
const BooleanAttributes = /*#__PURE__*/new Set(booleans);
const Properties = /*#__PURE__*/new Set([
// locked to properties
"className",
"value",
// booleans with camelCase
"readOnly",
"noValidate",
"formNoValidate",
"isMap",
"noModule",
"playsInline",
"adAuctionHeaders", // experimental
"allowFullscreen",
"browsingTopics", // experimental
"defaultChecked",
"defaultMuted",
"defaultSelected",
"disablePictureInPicture",
"disableRemotePlayback",
"preservesPitch",
"shadowRootClonable",
"shadowRootCustomElementRegistry", // experimental
"shadowRootDelegatesFocus",
"shadowRootSerializable", // experimental
"sharedStorageWritable", // experimental
...booleans]);
const ChildProperties = /*#__PURE__*/new Set([
"innerHTML",
"textContent",
"innerText",
"children"]);
// React Compat
const Aliases = /*#__PURE__*/Object.assign(Object.create(null), {
className: "class",
htmlFor: "for"
});
const PropAliases = /*#__PURE__*/Object.assign(Object.create(null), {
// locked to properties
class: "className",
// booleans map
novalidate: {
$: "noValidate",
FORM: 1
},
formnovalidate: {
$: "formNoValidate",
BUTTON: 1,
INPUT: 1
},
ismap: {
$: "isMap",
IMG: 1
},
nomodule: {
$: "noModule",
SCRIPT: 1
},
playsinline: {
$: "playsInline",
VIDEO: 1
},
readonly: {
$: "readOnly",
INPUT: 1,
TEXTAREA: 1
},
adauctionheaders: {
$: "adAuctionHeaders",
IFRAME: 1
},
allowfullscreen: {
$: "allowFullscreen",
IFRAME: 1
},
browsingtopics: {
$: "browsingTopics",
IMG: 1
},
defaultchecked: {
$: "defaultChecked",
INPUT: 1
},
defaultmuted: {
$: "defaultMuted",
AUDIO: 1,
VIDEO: 1
},
defaultselected: {
$: "defaultSelected",
OPTION: 1
},
disablepictureinpicture: {
$: "disablePictureInPicture",
VIDEO: 1
},
disableremoteplayback: {
$: "disableRemotePlayback",
AUDIO: 1,
VIDEO: 1
},
preservespitch: {
$: "preservesPitch",
AUDIO: 1,
VIDEO: 1
},
shadowrootclonable: {
$: "shadowRootClonable",
TEMPLATE: 1
},
shadowrootdelegatesfocus: {
$: "shadowRootDelegatesFocus",
TEMPLATE: 1
},
shadowrootserializable: {
$: "shadowRootSerializable",
TEMPLATE: 1
},
sharedstoragewritable: {
$: "sharedStorageWritable",
IFRAME: 1,
IMG: 1
}
});
function getPropAlias(prop, tagName) {
const a = PropAliases[prop];
return typeof a === "object" ? a[tagName] ? a["$"] : undefined : a;
}
// list of Element events that will be delegated
const DelegatedEvents = /*#__PURE__*/new Set([
"beforeinput",
"click",
"dblclick",
"contextmenu",
"focusin",
"focusout",
"input",
"keydown",
"keyup",
"mousedown",
"mousemove",
"mouseout",
"mouseover",
"mouseup",
"pointerdown",
"pointermove",
"pointerout",
"pointerover",
"pointerup",
"touchend",
"touchmove",
"touchstart"]);
const SVGElements = /*#__PURE__*/new Set([
// "a",
"altGlyph",
"altGlyphDef",
"altGlyphItem",
"animate",
"animateColor",
"animateMotion",
"animateTransform",
"circle",
"clipPath",
"color-profile",
"cursor",
"defs",
"desc",
"ellipse",
"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",
"filter",
"font",
"font-face",
"font-face-format",
"font-face-name",
"font-face-src",
"font-face-uri",
"foreignObject",
"g",
"glyph",
"glyphRef",
"hkern",
"image",
"line",
"linearGradient",
"marker",
"mask",
"metadata",
"missing-glyph",
"mpath",
"path",
"pattern",
"polygon",
"polyline",
"radialGradient",
"rect",
// "script",
"set",
"stop",
// "style",
"svg",
"switch",
"symbol",
"text",
"textPath",
// "title",
"tref",
"tspan",
"use",
"view",
"vkern"]);
const SVGNamespace = {
xlink: "http://www.w3.org/1999/xlink",
xml: "http://www.w3.org/XML/1998/namespace"
};
var VoidElements = [
'area',
'base',
'br',
'col',
'embed',
'hr',
'img',
'input',
'keygen',
'link',
'menuitem',
'meta',
'param',
'source',
'track',
'wbr'];
const reservedNameSpaces = new Set([
"class",
"on",
"oncapture",
"style",
"use",
"prop",
"attr",
"bool"]);
const nonSpreadNameSpaces = new Set(["class", "style", "use", "prop", "attr", "bool"]);
function getConfig(path) {
return path.hub.file.metadata.config;
}
const getRendererConfig = (path, renderer) => {
const config = getConfig(path);
return config?.renderers?.find((r) => r.name === renderer) ?? config;
};
function registerImportMethod(path, name, moduleName) {
const imports =
path.scope.getProgramParent().data.imports || (
path.scope.getProgramParent().data.imports = new Map());
moduleName = moduleName || getConfig(path).moduleName;
if (!imports.has(`${moduleName}:${name}`)) {
let id = helperModuleImports.addNamed(path, name, moduleName, {
nameHint: `_$${name}`
});
imports.set(`${moduleName}:${name}`, id);
return id;
} else {
let iden = imports.get(`${moduleName}:${name}`);
// the cloning is required to play well with babel-preset-env which is
// transpiling import as we add them and using the same identifier causes
// problems with the multiple identifiers of the same thing
return t__namespace.cloneNode(iden);
}
}
function jsxElementNameToString(node) {
if (t__namespace.isJSXMemberExpression(node)) {
return `${jsxElementNameToString(node.object)}.${node.property.name}`;
}
if (t__namespace.isJSXIdentifier(node) || t__namespace.isIdentifier(node)) {
return node.name;
}
return `${node.namespace.name}:${node.name.name}`;
}
function getTagName(tag) {
const jsxName = tag.openingElement.name;
return jsxElementNameToString(jsxName);
}
function isComponent(tagName) {
return (
tagName[0] && tagName[0].toLowerCase() !== tagName[0] ||
tagName.includes(".") ||
/[^a-zA-Z]/.test(tagName[0]));
}
function hasStaticMarker(object, path) {
if (!object) return false;
if (
object.leadingComments &&
object.leadingComments[0] &&
object.leadingComments[0].value.trim() === getConfig(path).staticMarker)
return true;
if (object.expression) return hasStaticMarker(object.expression, path);
}
function isDynamic(path, { checkMember, checkTags, checkCallExpressions = true, native }) {
const config = getConfig(path);
if (config.generate === "ssr" && native) {
checkMember = false;
checkCallExpressions = false;
}
const expr = path.node;
if (t__namespace.isFunction(expr)) return false;
if (
expr.leadingComments &&
expr.leadingComments[0] &&
expr.leadingComments[0].value.trim() === config.staticMarker)
{
return false;
}
if (
checkCallExpressions && (
t__namespace.isCallExpression(expr) ||
t__namespace.isOptionalCallExpression(expr) ||
t__namespace.isTaggedTemplateExpression(expr)))
{
return true;
}
if (checkMember && t__namespace.isMemberExpression(expr)) {
// Do not assume property access on namespaced imports as dynamic.
const object = path.get("object").node;
if (
t__namespace.isIdentifier(object) && (
!expr.computed ||
!isDynamic(path.get("property"), {
checkMember,
checkTags,
checkCallExpressions,
native
})))
{
const binding = path.scope.getBinding(object.name);
if (binding && binding.path.isImportNamespaceSpecifier()) {
return false;
}
}
return true;
}
if (
checkMember && (
t__namespace.isOptionalMemberExpression(expr) ||
t__namespace.isSpreadElement(expr) ||
t__namespace.isBinaryExpression(expr) && expr.operator === "in"))
{
return true;
}
if (checkTags && (t__namespace.isJSXElement(expr) || t__namespace.isJSXFragment(expr) && expr.children.length)) {
return true;
}
let dynamic;
path.traverse({
Function(p) {
if (t__namespace.isObjectMethod(p.node) && p.node.computed) {
dynamic = isDynamic(p.get("key"), { checkMember, checkTags, checkCallExpressions, native });
}
p.skip();
},
CallExpression(p) {
checkCallExpressions && (dynamic = true) && p.stop();
},
OptionalCallExpression(p) {
checkCallExpressions && (dynamic = true) && p.stop();
},
MemberExpression(p) {
checkMember && (dynamic = true) && p.stop();
},
OptionalMemberExpression(p) {
checkMember && (dynamic = true) && p.stop();
},
SpreadElement(p) {
checkMember && (dynamic = true) && p.stop();
},
BinaryExpression(p) {
checkMember && p.node.operator === "in" && (dynamic = true) && p.stop();
},
JSXElement(p) {
checkTags ? (dynamic = true) && p.stop() : p.skip();
},
JSXFragment(p) {
checkTags && p.node.children.length ? (dynamic = true) && p.stop() : p.skip();
}
});
return dynamic;
}
function getStaticExpression(path) {
const node = path.node;
let value, type;
return (
t__namespace.isJSXExpressionContainer(node) &&
t__namespace.isJSXElement(path.parent) &&
!isComponent(getTagName(path.parent)) &&
!t__namespace.isSequenceExpression(node.expression) &&
(value = path.get("expression").evaluate().value) !== undefined && (
(type = typeof value) === "string" || type === "number") &&
value);
}
// remove unnecessary JSX Text nodes
function filterChildren(children) {
return children.filter(
({ node: child }) =>
!(t__namespace.isJSXExpressionContainer(child) && t__namespace.isJSXEmptyExpression(child.expression)) && (
!t__namespace.isJSXText(child) || !/^[\r\n]\s*$/.test(child.extra.raw)));
}
function checkLength(children) {
let i = 0;
children.forEach((path) => {
const child = path.node;
!(t__namespace.isJSXExpressionContainer(child) && t__namespace.isJSXEmptyExpression(child.expression)) && (
!t__namespace.isJSXText(child) || !/^\s*$/.test(child.extra.raw) || /^ *$/.test(child.extra.raw)) &&
i++;
});
return i > 1;
}
function trimWhitespace(text) {
text = text.replace(/\r/g, "");
if (/\n/g.test(text)) {
text = text.
split("\n").
map((t, i) => i ? t.replace(/^\s*/g, "") : t).
filter((s) => !/^\s*$/.test(s)).
join(" ");
}
return text.replace(/\s+/g, " ");
}
function toEventName(name) {
return name.slice(2).toLowerCase();
}
function toPropertyName(name) {
return name.toLowerCase().replace(/-([a-z])/g, (_, w) => w.toUpperCase());
}
function wrappedByText(list, startIndex) {
let index = startIndex,
wrapped;
while (--index >= 0) {
const node = list[index];
if (!node) continue;
if (node.text) {
wrapped = true;
break;
}
if (node.id) return false;
}
if (!wrapped) return false;
index = startIndex;
while (++index < list.length) {
const node = list[index];
if (!node) continue;
if (node.text) return true;
if (node.id) return false;
}
return false;
}
function transformCondition(path, inline, deep) {
const config = getConfig(path);
const expr = path.node;
const memo = registerImportMethod(path, config.memoWrapper);
let dTest, cond, id;
if (
t__namespace.isConditionalExpression(expr) && (
isDynamic(path.get("consequent"), {
checkTags: true,
checkMember: true
}) ||
isDynamic(path.get("alternate"), { checkTags: true, checkMember: true })))
{
dTest = isDynamic(path.get("test"), { checkMember: true });
if (dTest) {
cond = expr.test;
if (!t__namespace.isBinaryExpression(cond))
cond = t__namespace.unaryExpression("!", t__namespace.unaryExpression("!", cond, true), true);
id = inline ?
t__namespace.callExpression(memo, [t__namespace.arrowFunctionExpression([], cond)]) :
path.scope.generateUidIdentifier("_c$");
expr.test = t__namespace.callExpression(id, []);
if (t__namespace.isConditionalExpression(expr.consequent) || t__namespace.isLogicalExpression(expr.consequent)) {
expr.consequent = transformCondition(path.get("consequent"), true, true);
}
if (t__namespace.isConditionalExpression(expr.alternate) || t__namespace.isLogicalExpression(expr.alternate)) {
expr.alternate = transformCondition(path.get("alternate"), true, true);
}
}
} else if (t__namespace.isLogicalExpression(expr)) {
let nextPath = path;
// handle top-level or, ie cond && <A/> || <B/>
while (nextPath.node.operator !== "&&" && t__namespace.isLogicalExpression(nextPath.node.left)) {
nextPath = nextPath.get("left");
}
nextPath.node.operator === "&&" &&
isDynamic(nextPath.get("right"), { checkTags: true, checkMember: true }) && (
dTest = isDynamic(nextPath.get("left"), {
checkMember: true
}));
if (dTest) {
cond = nextPath.node.left;
if (!t__namespace.isBinaryExpression(cond))
cond = t__namespace.unaryExpression("!", t__namespace.unaryExpression("!", cond, true), true);
id = inline ?
t__namespace.callExpression(memo, [t__namespace.arrowFunctionExpression([], cond)]) :
path.scope.generateUidIdentifier("_c$");
nextPath.node.left = t__namespace.callExpression(id, []);
}
}
if (dTest && !inline) {
const statements = [
t__namespace.variableDeclaration("var", [
t__namespace.variableDeclarator(
id,
config.memoWrapper ?
t__namespace.callExpression(memo, [t__namespace.arrowFunctionExpression([], cond)]) :
t__namespace.arrowFunctionExpression([], cond))]),
t__namespace.arrowFunctionExpression([], expr)];
return deep ?
t__namespace.callExpression(
t__namespace.arrowFunctionExpression(
[],
t__namespace.blockStatement([statements[0], t__namespace.returnStatement(statements[1])])),
[]) :
statements;
}
return deep ? expr : t__namespace.arrowFunctionExpression([], expr);
}
function escapeHTML(s, attr) {
if (typeof s !== "string") return s;
const delim = attr ? '"' : "<";
const escDelim = attr ? "&quot;" : "&lt;";
let iDelim = s.indexOf(delim);
let iAmp = s.indexOf("&");
if (iDelim < 0 && iAmp < 0) return s;
let left = 0,
out = "";
while (iDelim >= 0 && iAmp >= 0) {
if (iDelim < iAmp) {
if (left < iDelim) out += s.substring(left, iDelim);
out += escDelim;
left = iDelim + 1;
iDelim = s.indexOf(delim, left);
} else {
if (left < iAmp) out += s.substring(left, iAmp);
out += "&amp;";
left = iAmp + 1;
iAmp = s.indexOf("&", left);
}
}
if (iDelim >= 0) {
do {
if (left < iDelim) out += s.substring(left, iDelim);
out += escDelim;
left = iDelim + 1;
iDelim = s.indexOf(delim, left);
} while (iDelim >= 0);
} else {
while (iAmp >= 0) {
if (left < iAmp) out += s.substring(left, iAmp);
out += "&amp;";
left = iAmp + 1;
iAmp = s.indexOf("&", left);
}
}
return left < s.length ? out + s.substring(left) : out;
}
function convertJSXIdentifier(node) {
if (t__namespace.isJSXIdentifier(node)) {
if (t__namespace.isValidIdentifier(node.name)) {
node.type = "Identifier";
} else {
return t__namespace.stringLiteral(node.name);
}
} else if (t__namespace.isJSXMemberExpression(node)) {
return t__namespace.memberExpression(
convertJSXIdentifier(node.object),
convertJSXIdentifier(node.property));
} else if (t__namespace.isJSXNamespacedName(node)) {
return t__namespace.stringLiteral(`${node.namespace.name}:${node.name.name}`);
}
return node;
}
function canNativeSpread(key, { checkNameSpaces } = {}) {
if (checkNameSpaces && key.includes(":") && nonSpreadNameSpaces.has(key.split(":")[0]))
return false;
// TODO: figure out how to detect definitely function ref
if (key === "ref") return false;
return true;
}
const chars = "etaoinshrdlucwmfygpbTAOISWCBvkxjqzPHFMDRELNGUKVYJQZX_$";
const base = chars.length;
function getNumberedId(num) {
let out = "";
do {
const digit = num % base;
num = Math.floor(num / base);
out = chars[digit] + out;
} while (num !== 0);
return out;
}
function escapeStringForTemplate(str) {
return str.replace(/[{\\`\n\t\b\f\v\r\u2028\u2029]/g, (ch) => templateEscapes.get(ch));
}
const templateEscapes = new Map([
["{", "\\{"],
["`", "\\`"],
["\\", "\\\\"],
["\n", "\\n"],
["\t", "\\t"],
["\b", "\\b"],
["\f", "\\f"],
["\v", "\\v"],
["\r", "\\r"],
["\u2028", "\\u2028"],
["\u2029", "\\u2029"]]);
function evaluateAndInline(value, valueNode) {
if (t__namespace.isJSXExpressionContainer(value)) {
evaluateAndInline(value.expression, valueNode.get("expression"));
} else if (t__namespace.isObjectProperty(value)) {
evaluateAndInline(value.value, valueNode.get("value"));
} else if (
t__namespace.isStringLiteral(value) ||
t__namespace.isNumericLiteral(value) ||
t__namespace.isBooleanLiteral(value) ||
t__namespace.isNullLiteral(value))
; else if (t__namespace.isObjectExpression(value)) {const properties = value.properties;
const propertiesNode = valueNode.get("properties");
for (let i = 0; i < properties.length; i++) {
evaluateAndInline(properties[i], propertiesNode[i]);
}
} else {
const r = valueNode.evaluate();
if (r.confident) {
if (typeof r.value === "string") {
valueNode.replaceWith(t__namespace.stringLiteral(r.value));
} else if (typeof r.value === "number") {
valueNode.replaceWith(t__namespace.numericLiteral(r.value));
} else if (typeof r.value === "boolean") {
valueNode.replaceWith(t__namespace.booleanLiteral(r.value));
}
}
}
}
const InlineElements = [
"a",
"abbr",
"acronym",
"b",
"bdi",
"bdo",
"big",
"br",
"button",
"canvas",
"cite",
"code",
"data",
"datalist",
"del",
"dfn",
"em",
"embed",
"i",
"iframe",
"img",
"input",
"ins",
"kbd",
"label",
"map",
"mark",
"meter",
"noscript",
"object",
"output",
"picture",
"progress",
"q",
"ruby",
"s",
"samp",
"script",
"select",
"slot",
"small",
"span",
"strong",
"sub",
"sup",
"svg",
"template",
"textarea",
"time",
"u",
"tt",
"var",
"video"];
const BlockElements = [
"address",
"article",
"aside",
"blockquote",
"dd",
"details",
"dialog",
"div",
"dl",
"dt",
"fieldset",
"figcaption",
"figure",
"footer",
"form",
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"header",
"hgroup",
"hr",
"li",
"main",
"menu",
"nav",
"ol",
"p",
"pre",
"section",
"table",
"ul"];
const alwaysClose = [
"title",
"style",
"a",
"strong",
"small",
"b",
"u",
"i",
"em",
"s",
"code",
"object",
"table",
"button",
"textarea",
"select",
"iframe",
"script",
"noscript",
"template",
"fieldset"];
function transformElement$3(path, info) {
path.
get("openingElement").
get("attributes").
forEach((attr) => {
evaluateAndInline(attr.node.value, attr.get("value"));
});
let tagName = getTagName(path.node),
config = getConfig(path),
wrapSVG = info.topLevel && tagName != "svg" && SVGElements.has(tagName),
voidTag = VoidElements.indexOf(tagName) > -1,
isCustomElement =
tagName.indexOf("-") > -1 ||
path.
get("openingElement").
get("attributes").
some((a) => a.node?.name?.name === "is" || a.name?.name === "is"),
isImportNode =
(tagName === "img" || tagName === "iframe") &&
path.
get("openingElement").
get("attributes").
some((a) => a.node.name?.name === "loading"),
results = {
template: `<${tagName}`,
templateWithClosingTags: `<${tagName}`,
declarations: [],
exprs: [],
dynamics: [],
postExprs: [],
isSVG: wrapSVG,
hasCustomElement: isCustomElement,
isImportNode,
tagName,
renderer: "dom",
skipTemplate: false
};
if (!config.inlineStyles) {
path.
get("openingElement").
get("attributes").
forEach((a) => {
if (a.node.name?.name === "style") {
let value = a.node.value.expression ? a.node.value.expression : a.node.value;
if (t__namespace.isStringLiteral(value)) {
// jsx attribute value is a sting that may takes more than one line
value = t__namespace.templateLiteral(
[t__namespace.templateElement({ raw: value.value, cooked: value.value })],
[]);
}
a.get("value").replaceWith(
t__namespace.jSXExpressionContainer(t__namespace.callExpression(t__namespace.arrowFunctionExpression([], value), [])));
}
});
}
path.
get("openingElement").
get("attributes").
some((a) => {
if (a.node.name?.name === "data-hk") {
a.remove();
let filename = "";
try {
filename = path.scope.getProgramParent().path.hub.file.opts.filename;
} catch (e) {}
console.log(
"\n" +
path.
buildCodeFrameError(
`"data-hk" attribute found in template, which could potentially cause hydration miss-matches. Usually happens when copying and pasting Solid SSRed code into JSX. Please remove the attribute from the JSX. \n\n${filename}\n`).
toString());
}
});
if (config.hydratable && (tagName === "html" || tagName === "head" || tagName === "body")) {
results.skipTemplate = true;
if (tagName === "head" && info.topLevel) {
const createComponent = registerImportMethod(
path,
"createComponent",
getRendererConfig(path, "dom").moduleName);
const NoHydration = registerImportMethod(
path,
"NoHydration",
getRendererConfig(path, "dom").moduleName);
results.exprs.push(
t__namespace.expressionStatement(
t__namespace.callExpression(createComponent, [NoHydration, t__namespace.objectExpression([])])));
return results;
}
}
if (wrapSVG) {
results.template = "<svg>" + results.template;
results.templateWithClosingTags = "<svg>" + results.templateWithClosingTags;
}
if (!info.skipId) {
results.id = path.scope.generateUidIdentifier("el$");
}
transformAttributes$2(path, results);
if (config.contextToCustomElements && (tagName === "slot" || isCustomElement)) {
contextToCustomElement(path, results);
}
results.template += ">";
results.templateWithClosingTags += ">";
if (!voidTag) {
// always close tags can still be skipped if they have no closing parents and are the last element
const toBeClosed =
!info.lastElement ||
!config.omitLastClosingTag ||
info.toBeClosed && (!config.omitNestedClosingTags || info.toBeClosed.has(tagName));
if (toBeClosed) {
results.toBeClosed = new Set(info.toBeClosed || alwaysClose);
results.toBeClosed.add(tagName);
if (InlineElements.includes(tagName)) BlockElements.forEach((i) => results.toBeClosed.add(i));
} else results.toBeClosed = info.toBeClosed;
if (tagName !== "noscript") transformChildren$2(path, results, config);
if (toBeClosed) results.template += `</${tagName}>`;
results.templateWithClosingTags += `</${tagName}>`;
}
if (info.topLevel && config.hydratable && results.hasHydratableEvent) {
let runHydrationEvents = registerImportMethod(
path,
"runHydrationEvents",
getRendererConfig(path, "dom").moduleName);
results.postExprs.push(t__namespace.expressionStatement(t__namespace.callExpression(runHydrationEvents, [])));
}
if (wrapSVG) {
results.template += "</svg>";
results.templateWithClosingTags += "</svg>";
}
return results;
}
function setAttr$2(path, elem, name, value, { isSVG, dynamic, prevId, isCE, tagName }) {
// pull out namespace
const config = getConfig(path);
let parts, namespace;
if ((parts = name.split(":")) && parts[1] && reservedNameSpaces.has(parts[0])) {
name = parts[1];
namespace = parts[0];
}
if (namespace === "style") {
const setStyleProperty = registerImportMethod(
path,
"setStyleProperty",
getRendererConfig(path, "dom").moduleName);
return t__namespace.callExpression(setStyleProperty, [
elem,
t__namespace.stringLiteral(name),
t__namespace.isAssignmentExpression(value) && t__namespace.isIdentifier(value.left) ? value.right : value]);
}
if (namespace === "class") {
return t__namespace.callExpression(
t__namespace.memberExpression(
t__namespace.memberExpression(elem, t__namespace.identifier("classList")),
t__namespace.identifier("toggle")),
[
t__namespace.stringLiteral(name),
dynamic ? value : t__namespace.unaryExpression("!", t__namespace.unaryExpression("!", value))]);
}
if (name === "style") {
return t__namespace.callExpression(
registerImportMethod(path, "style", getRendererConfig(path, "dom").moduleName),
prevId ? [elem, value, prevId] : [elem, value]);
}
if (!isSVG && name === "class") {
return t__namespace.callExpression(
registerImportMethod(path, "className", getRendererConfig(path, "dom").moduleName),
[elem, value]);
}
if (name === "classList") {
return t__namespace.callExpression(
registerImportMethod(path, "classList", getRendererConfig(path, "dom").moduleName),
prevId ? [elem, value, prevId] : [elem, value]);
}
if (dynamic && name === "textContent") {
if (config.hydratable) {
return t__namespace.callExpression(registerImportMethod(path, "setProperty"), [
elem,
t__namespace.stringLiteral("data"),
value]);
}
return t__namespace.assignmentExpression("=", t__namespace.memberExpression(elem, t__namespace.identifier("data")), value);
}
if (namespace === "bool") {
return t__namespace.callExpression(
registerImportMethod(path, "setBoolAttribute", getRendererConfig(path, "dom").moduleName),
[elem, t__namespace.stringLiteral(name), value]);
}
const isChildProp = ChildProperties.has(name);
const isProp = Properties.has(name);
const alias = getPropAlias(name, tagName.toUpperCase());
if (namespace !== "attr" && (isChildProp || !isSVG && isProp || isCE || namespace === "prop")) {
if (isCE && !isChildProp && !isProp && namespace !== "prop") name = toPropertyName(name);
if (config.hydratable && namespace !== "prop") {
return t__namespace.callExpression(registerImportMethod(path, "setProperty"), [
elem,
t__namespace.stringLiteral(alias || name),
value]);
}
return t__namespace.assignmentExpression(
"=",
t__namespace.memberExpression(elem, t__namespace.identifier(alias || name)),
value);
}
let isNameSpaced = name.indexOf(":") > -1;
name = Aliases[name] || name;
!isSVG && (name = name.toLowerCase());
const ns = isNameSpaced && SVGNamespace[name.split(":")[0]];
if (ns) {
return t__namespace.callExpression(
registerImportMethod(path, "setAttributeNS", getRendererConfig(path, "dom").moduleName),
[elem, t__namespace.stringLiteral(ns), t__namespace.stringLiteral(name), value]);
} else {
return t__namespace.callExpression(
registerImportMethod(path, "setAttribute", getRendererConfig(path, "dom").moduleName),
[elem, t__namespace.stringLiteral(name), value]);
}
}
function detectResolvableEventHandler(attribute, handler) {
while (t__namespace.isIdentifier(handler)) {
const lookup = attribute.scope.getBinding(handler.name);
if (lookup) {
if (t__namespace.isVariableDeclarator(lookup.path.node)) {
handler = lookup.path.node.init;
} else if (t__namespace.isFunctionDeclaration(lookup.path.node)) {
return true;
} else return false;
} else return false;
}
return t__namespace.isFunction(handler);
}
function transformAttributes$2(path, results) {
let elem = results.id,
hasHydratableEvent = false,
children,
spreadExpr,
attributes = path.get("openingElement").get("attributes");
const tagName = getTagName(path.node),
isSVG = SVGElements.has(tagName),
isCE = tagName.includes("-") || attributes.some((a) => a.node.name?.name === "is"),
hasChildren = path.node.children.length > 0,
config = getConfig(path);
// preprocess spreads
if (attributes.some((attribute) => t__namespace.isJSXSpreadAttribute(attribute.node))) {
[attributes, spreadExpr] = processSpreads$1(path, attributes, {
elem,
isSVG,
hasChildren,
wrapConditionals: config.wrapConditionals
});
path.get("openingElement").set(
"attributes",
attributes.map((a) => a.node));
//NOTE: can't be checked at compile time so add to compiled output
hasHydratableEvent = true;
}
/**
* Inline styles
*
* 1. When string
* 2. When is an object, the key is a string, and value is string/numeric
* 3. Remove properties from object when value is undefined/null
* 4. When `value.evaluate().confident`
*
* Also, when `key` is computed value is also `value.evaluate().confident`
*/
attributes = path.get("openingElement").get("attributes");
const styleAttributes = attributes.filter((a) => a.node.name && a.node.name.name === "style");
if (styleAttributes.length > 0) {
let inlinedStyle = "";
for (let i = 0; i < styleAttributes.length; i++) {
const attr = styleAttributes[i];
let value = attr.node.value;
const node = attr.get("value");
if (t__namespace.isJSXExpressionContainer(value)) {
value = value.expression;
}
if (t__namespace.isStringLiteral(value)) {
inlinedStyle += `${value.value.replace(/;$/, "")};`;
attr.remove();
} else if (t__namespace.isObjectExpression(value)) {
const properties = value.properties;
const propertiesNode = node.get("expression").get("properties");
const toRemoveProperty = [];
for (let i = 0; i < properties.length; i++) {
const property = properties[i];
if (property.computed) {
/* { [computed]: `${1+1}px` } => { [computed]: `2px` } */
const r = propertiesNode[i].get("value").evaluate();
if (r.confident && (typeof r.value === "string" || typeof r.value === "number")) {
property.value = t__namespace.inherits(t__namespace.stringLiteral(`${r.value}`), property.value);
}
// computed cannot be inlined - maybe can be evaluated but this is pretty rare
continue;
}
if (t__namespace.isObjectProperty(property)) {
const key = t__namespace.isIdentifier(property.key) ? property.key.name : property.key.value;
if (t__namespace.isStringLiteral(property.value) || t__namespace.isNumericLiteral(property.value)) {
inlinedStyle += `${key}:${property.value.value};`;
toRemoveProperty.push(property);
} else if (
t__namespace.isIdentifier(property.value) && property.value.name === "undefined" ||
t__namespace.isNullLiteral(property.value))
{
toRemoveProperty.push(property);
} else {
const r = propertiesNode[i].get("value").evaluate();
if (r.confident && (typeof r.value === "string" || typeof r.value === "number")) {
inlinedStyle += `${key}:${r.value};`;
toRemoveProperty.push(property);
}
}
}
}
for (const remove of toRemoveProperty) {
value.properties.splice(value.properties.indexOf(remove), 1);
}
if (value.properties.length === 0) {
attr.remove();
}
}
}
if (inlinedStyle !== "") {
const styleAttribute = t__namespace.jsxAttribute(
t__namespace.jsxIdentifier("style"),
t__namespace.stringLiteral(inlinedStyle.replace(/;$/, "")));
path.get("openingElement").node.attributes.push(styleAttribute);
}
}
// preprocess styles
const styleAttribute = path.
get("openingElement").
get("attributes").
find(
(a) =>
a.node.name &&
a.node.name.name === "style" &&
t__namespace.isJSXExpressionContainer(a.node.value) &&
t__namespace.isObjectExpression(a.node.value.expression) &&
!a.node.value.expression.properties.some((p) => t__namespace.isSpreadElement(p)));
if (styleAttribute) {
let i = 0,
leading = styleAttribute.node.value.expression.leadingComments;
styleAttribute.node.value.expression.properties.slice().forEach((p, index) => {
if (!p.computed) {
if (leading) p.value.leadingComments = leading;
path.
get("openingElement").
node.attributes.splice(
styleAttribute.key + ++i,
0,
t__namespace.jsxAttribute(
t__namespace.jsxNamespacedName(
t__namespace.jsxIdentifier("style"),
t__namespace.jsxIdentifier(t__namespace.isIdentifier(p.key) ? p.key.name : p.key.value)),
t__namespace.jsxExpressionContainer(p.value)));
styleAttribute.node.value.expression.properties.splice(index - i - 1, 1);
}
});
if (!styleAttribute.node.value.expression.properties.length)
path.get("openingElement").node.attributes.splice(styleAttribute.key, 1);
}
// preprocess classList
attributes = path.get("openingElement").get("attributes");
const classListAttribute = attributes.find(
(a) =>
a.node.name &&
a.node.name.name === "classList" &&
t__namespace.isJSXExpressionContainer(a.node.value) &&
t__namespace.isObjectExpression(a.node.value.expression) &&
!a.node.value.expression.properties.some(
(p) =>
t__namespace.isSpreadElement(p) ||
p.computed ||
t__namespace.isStringLiteral(p.key) && (p.key.value.includes(" ") || p.key.value.includes(":"))));
if (classListAttribute) {
let i = 0,
leading = classListAttribute.node.value.expression.leadingComments,
classListProperties = classListAttribute.get("value").get("expression").get("properties");
classListProperties.slice().forEach((propPath, index) => {
const p = propPath.node;
const { confident, value: computed } = propPath.get("value").evaluate();
if (leading) p.value.leadingComments = leading;
if (!confident) {
path.
get("openingElement").
node.attributes.splice(
classListAttribute.key + ++i,
0,
t__namespace.jsxAttribute(
t__namespace.jsxNamespacedName(
t__namespace.jsxIdentifier("class"),
t__namespace.jsxIdentifier(t__namespace.isIdentifier(p.key) ? p.key.name : p.key.value)),
t__namespace.jsxExpressionContainer(p.value)));
} else if (computed) {
path.
get("openingElement").
node.attributes.splice(
classListAttribute.key + ++i,
0,
t__namespace.jsxAttribute(
t__namespace.jsxIdentifier("class"),
t__namespace.stringLiteral(t__namespace.isIdentifier(p.key) ? p.key.name : p.key.value)));
}
classListProperties.splice(index - i - 1, 1);
});
if (!classListProperties.length)
path.get("openingElement").node.attributes.splice(classListAttribute.key, 1);
}
// combine class properties
attributes = path.get("openingElement").get("attributes");
const classAttributes = attributes.filter(
(a) => a.node.name && (a.node.name.name === "class" || a.node.name.name === "className"));
if (classAttributes.length > 1) {
const first = classAttributes[0].node,
values = [],
quasis = [t__namespace.templateElement({ raw: "" })];
for (let i = 0; i < classAttributes.length; i++) {
const attr = classAttributes[i].node,
isLast = i === classAttributes.length - 1;
if (!t__namespace.isJSXExpressionContainer(attr.value)) {
const prev = quasis.pop();
quasis.push(
t__namespace.templateElement({
raw: (prev ? prev.value.raw : "") + `${attr.value.value}` + (isLast ? "" : " ")
}));
} else {
values.push(t__namespace.logicalExpression("||", attr.value.expression, t__namespace.stringLiteral("")));
quasis.push(t__namespace.templateElement({ raw: isLast ? "" : " " }));
}
i && attributes.splice(attributes.indexOf(classAttributes[i]), 1);
}
if (values.length) first.value = t__namespace.jsxExpressionContainer(t__namespace.templateLiteral(quasis, values));else
first.value = t__namespace.stringLiteral(quasis[0].value.raw);
}
path.get("openingElement").set(
"attributes",
attributes.map((a) => a.node));
let needsSpacing = true;
// scoped because of `needsSpacing`
function inlineAttributeOnTemplate(isSVG, key, results, value) {
!isSVG && (key = key.toLowerCase());
results.template += `${needsSpacing ? " " : ""}${key}`;
if (!value) {
needsSpacing = true;
return;
}
let text = value.value;
if (typeof text === "number") text = String(text);
let needsQuoting = !config.omitQuotes;
if (key === "style" || key === "class") {
text = trimWhitespace(text);
if (key === "style") {
text = text.replace(/; /g, ";").replace(/: /g, ":");
}
}
if (!text.length) {
needsSpacing = true;
results.template += ``;
return;
}
for (let i = 0, len = text.length; i < len; i++) {
let char = text[i];
if (
char === "'" ||
char === '"' ||
char === " " ||
char === "\t" ||
char === "\n" ||
char === "\r" ||
char === "`" ||
char === "=" ||
char === "<" ||
char === ">")
{
needsQuoting = true;
}
}
if (needsQuoting) {
needsSpacing = false;
results.template += `="${escapeHTML(text, true)}"`;
} else {
needsSpacing = true;
results.template += `=${escapeHTML(text, true)}`;
}
}
path.
get("openingElement").
get("attributes").
forEach((attribute) => {
const node = attribute.node;
let value = node.value,
key = t__namespace.isJSXNamespacedName(node.name) ?
`${node.name.namespace.name}:${node.name.name.name}` :
node.name.name,
reservedNameSpace =
t__namespace.isJSXNamespacedName(node.name) && reservedNameSpaces.has(node.name.namespace.name);
if (t__namespace.isJSXExpressionContainer(value) && !key.startsWith("use:")) {
const evaluated = attribute.get("value").get("expression").evaluate().value;
let type;
if (
evaluated !== undefined && (
(type = typeof evaluated) === "string" || type === "number"))
{
if (type === "number" && (Properties.has(key) || key.startsWith("prop:"))) {
value = t__namespace.jsxExpressionContainer(t__namespace.numericLiteral(evaluated));
} else value = t__namespace.stringLiteral(String(evaluated));
}
}
if (
t__namespace.isJSXNamespacedName(node.name) &&
reservedNameSpace &&
!t__namespace.isJSXExpressionContainer(value))
{
node.value = value = t__namespace.jsxExpressionContainer(value || t__namespace.jsxEmptyExpression());
}
if (
t__namespace.isJSXExpressionContainer(value) && (
reservedNameSpace ||
!(t__namespace.isStringLiteral(value.expression) || t__namespace.isNumericLiteral(value.expression))))
{
if (key === "ref") {
// Normalize expressions for non-null and type-as
while (
t__namespace.isTSNonNullExpression(value.expression) ||
t__namespace.isTSAsExpression(value.expression))
{
value.expression = value.expression.expression;
}
let binding,
isConstant =
t__namespace.isIdentifier(value.expression) && (
binding = path.scope.getBinding(value.expression.name)) && (
binding.kind === "const" || binding.kind === "module");
if (!isConstant && t__namespace.isLVal(value.expression)) {
const refIdentifier = path.scope.generateUidIdentifier("_ref$");
results.exprs.unshift(
t__namespace.variableDeclaration("var", [t__namespace.variableDeclarator(refIdentifier, value.expression)]),
t__namespace.expressionStatement(
t__namespace.conditionalExpression(
t__namespace.binaryExpression(
"===",
t__namespace.unaryExpression("typeof", refIdentifier),
t__namespace.stringLiteral("function")),
t__namespace.callExpression(
registerImportMethod(path, "use", getRendererConfig(path, "dom").moduleName),
[refIdentifier, elem]),
t__namespace.assignmentExpression("=", value.expression, elem))));
} else if (isConstant || t__namespace.isFunction(value.expression)) {
results.exprs.unshift(
t__namespace.expressionStatement(
t__namespace.callExpression(
registerImportMethod(path, "use", getRendererConfig(path, "dom").moduleName),
[value.expression, elem])));
} else {
const refIdentifier = path.scope.generateUidIdentifier("_ref$");
results.exprs.unshift(
t__namespace.variableDeclaration("var", [t__namespace.variableDeclarator(refIdentifier, value.expression)]),
t__namespace.expressionStatement(
t__namespace.logicalExpression(
"&&",
t__namespace.binaryExpression(
"===",
t__namespace.unaryExpression("typeof", refIdentifier),
t__namespace.stringLiteral("function")),
t__namespace.callExpression(
registerImportMethod(path, "use", getRendererConfig(path, "dom").moduleName),
[refIdentifier, elem]))));
}
} else if (key.startsWith("use:")) {
// Some trick to treat JSXIdentifier as Identifier
node.name.name.type = "Identifier";
results.exprs.unshift(
t__namespace.expressionStatement(
t__namespace.callExpression(
registerImportMethod(path, "use", getRendererConfig(path, "dom").moduleName),
[
node.name.name,
elem,
t__namespace.arrowFunctionExpression(
[],
t__namespace.isJSXEmptyExpression(value.expression) ?
t__namespace.booleanLiteral(true) :
value.expression)])));
} else if (key === "children") {
children = value;
} else if (key.startsWith("on")) {
const ev = toEventName(key);
if (key.startsWith("on:")) {
const args = [elem, t__namespace.stringLiteral(key.split(":")[1]), value.expression];
results.exprs.unshift(
t__namespace.expressionStatement(
t__namespace.callExpression(
registerImportMethod(
path,
"addEventListener",
getRendererConfig(path, "dom").moduleName),
args)));
} else if (key.startsWith("oncapture:")) {
// deprecated see above condition
const args = [
t__namespace.stringLiteral(key.split(":")[1]),
value.expression,
t__namespace.booleanLiteral(true)];
results.exprs.push(
t__namespace.expressionStatement(
t__namespace.callExpression(t__namespace.memberExpression(elem, t__namespace.identifier("addEventListener")), args)));
} else if (
config.delegateEvents && (
DelegatedEvents.has(ev) || config.delegatedEvents.indexOf(ev) !== -1))
{
// can only hydrate delegated events
hasHydratableEvent = true;
const events =
attribute.scope.getProgramParent().data.events || (
attribute.scope.getProgramParent().data.events = new Set());
events.add(ev);
let handler = value.expression;
const resolveable = detectResolvableEventHandler(attribute, handler);
if (t__namespace.isArrayExpression(handler)) {
if (handler.elements.length > 1) {
results.exprs.unshift(
t__namespace.expressionStatement(
t__namespace.assignmentExpression(
"=",
t__namespace.memberExpression(elem, t__namespace.identifier(`$$${ev}Data`)),
handler.elements[1])));
}
handler = handler.elements[0];
results.exprs.unshift(
t__namespace.expressionStatement(
t__namespace.assignmentExpression(
"=",
t__namespace.memberExpression(elem, t__namespace.identifier(`$$${ev}`)),
handler)));
} else if (t__namespace.isFunction(handler) || resolveable) {
results.exprs.unshift(
t__namespace.expressionStatement(
t__namespace.assignmentExpression(
"=",
t__namespace.memberExpression(elem, t__namespace.identifier(`$$${ev}`)),
handler)));
} else {
results.exprs.unshift(
t__namespace.expressionStatement(
t__namespace.callExpression(
registerImportMethod(
path,
"addEventListener",
getRendererConfig(path, "dom").moduleName),
[elem, t__namespace.stringLiteral(ev), handler, t__namespace.booleanLiteral(true)])));
}
} else {
let handler = value.expression;
const resolveable = detectResolvableEventHandler(attribute, handler);
if (t__namespace.isArrayExpression(handler)) {
if (handler.elements.length > 1) {
handler = t__namespace.arrowFunctionExpression(
[t__namespace.identifier("e")],
t__namespace.callExpression(handler.elements[0], [handler.elements[1], t__namespace.identifier("e")]));
} else handler = handler.elements[0];
results.exprs.unshift(
t__namespace.expressionStatement(
t__namespace.callExpression(t__namespace.memberExpression(elem, t__namespace.identifier("addEventListener")), [
t__namespace.stringLiteral(ev),
handler])));
} else if (t__namespace.isFunction(handler) || resolveable) {
results.exprs.unshift(
t__namespace.expressionStatement(
t__namespace.callExpression(t__namespace.memberExpression(elem, t__namespace.identifier("addEventListener")), [
t__namespace.stringLiteral(ev),
handler])));
} else {
results.exprs.unshift(
t__namespace.expressionStatement(
t__namespace.callExpression(
registerImportMethod(
path,
"addEventListener",
getRendererConfig(path, "dom").moduleName),
[elem, t__namespace.stringLiteral(ev), handler])));
}
}
} else if (
config.effectWrapper && (
isDynamic(attribute.get("value").get("expression"), {
checkMember: true
}) ||
(key === "classList" || key === "style") &&
!attribute.get("value").get("expression").evaluate().confident &&
!hasStaticMarker(value, path)))
{
/*
Following code doesn't repect static marker `@once`.
https://github.com/ryansolid/dom-expressions/pull/438
||
(
(
key === "classList" || key === "style") &&
!attribute.get("value").get("expression").evaluate().confident
)
)
*/
let nextElem = elem;
if (key === "value" || key === "checked") {
const effectWrapperId = registerImportMethod(path, config.effectWrapper);
results.postExprs.push(
t__namespace.expressionStatement(
t__namespace.callExpression(effectWrapperId, [
t__namespace.arrowFunctionExpression(
[],
setAttr$2(path, elem, key, value.expression, {
tagName,
isSVG,
isCE
}))])));
return;
}
if (key === "textContent") {
nextElem = attribute.scope.generateUidIdentifier("el$");
children = t__namespace.jsxText(" ");
children.extra = { raw: " ", rawValue: " " };
results.declarations.push(
t__namespace.variableDeclarator(nextElem, t__namespace.memberExpression(elem, t__namespace.identifier("firstChild"))));
}
results.dynamics.push({
elem: nextElem,
key,
value: value.expression,
isSVG,
isCE,
tagName
});
} else if (key.slice(0, 5) === "attr:") {
if (t__namespace.isJSXExpressionContainer(value)) value = value.expression;
if (t__namespace.isStringLiteral(value) || t__namespace.isNumericLiteral(value)) {
// inlined "attr:"
inlineAttributeOnTemplate(isSVG, key.slice(5), results, value);
} else {
// dynamic "attr:"
results.exprs.push(
t__namespace.expressionStatement(setAttr$2(attribute, elem, key, value, { isSVG, isCE, tagName })));
}
} else if (key.slice(0, 5) === "bool:") {
// inline it on the template when possible
let content = value;
if (t__namespace.isJSXExpressionContainer(content)) content = content.expression;
function addBoolAttribute() {
results.template += `${needsSpacing ? " " : ""}${key.slice(5)}`;
needsSpacing = true;
}
switch (content.type) {
case "StringLiteral":{
if (content.value.length && content.value !== "0") {
addBoolAttribute();
}
return;
}
case "NullLiteral":{
return;
}
case "BooleanLiteral":{
if (content.value) {
addBoolAttribute();
}
return;
}
case "Identifier":{
if (content.name === "undefined") {
return;
}
break;
}}
// when not possible to inline it in the template
results.exprs.push(
t__namespace.expressionStatement(
setAttr$2(
attribute,
elem,
key,
t__namespace.isJSXExpressionContainer(value) ? value.expression : value,
{ isSVG, isCE, tagName })));
} else {
results.exprs.push(
t__namespace.expressionStatement(
setAttr$2(attribute, elem, key, value.expression, { isSVG, isCE, tagName })));
}
} else {
if (config.hydratable && key === "$ServerOnly") {
results.skipTemplate = true;
return;
}
if (t__namespace.isJSXExpressionContainer(value)) value = value.expression;
// properties
key = Aliases[key] || key;
if (value && ChildProperties.has(key)) {
results.exprs.push(
t__namespace.expressionStatement(setAttr$2(attribute, elem, key, value, { isSVG, isCE, tagName })));
} else {
inlineAttributeOnTemplate(isSVG, key, results, value);
}
}
});
if (!hasChildren && children) {
path.node.children.push(children);
}
if (spreadExpr) results.exprs.push(spreadExpr);
results.hasHydratableEvent = results.hasHydratableEvent || hasHydratableEvent;
}
function findLastElement(children, hydratable) {
let lastElement = -1,
tagName;
for (let i = children.length - 1; i >= 0; i--) {
const node = children[i].node;
if (
hydratable ||
t__namespace.isJSXText(node) ||
getStaticExpression(children[i]) !== false ||
t__namespace.isJSXElement(node) && (tagName = getTagName(node)) && !isComponent(tagName))
{
lastElement = i;
break;
}
}
return lastElement;
}
function transformChildren$2(path, results, config) {
let tempPath = results.id && results.id.name,
tagName = getTagName(path.node),
nextPlaceholder,
childPostExprs = [],
i = 0;
const filteredChildren = filterChildren(path.get("children")),
lastElement = findLastElement(filteredChildren, config.hydratable),
childNodes = filteredChildren.reduce((memo, child, index) => {
if (child.isJSXFragment()) {
throw new Error(
`Fragments can only be used top level in JSX. Not used under a <${tagName}>.`);
}
const transformed = transformNode(child, {
toBeClosed: results.toBeClosed,
lastElement: index === lastElement,
skipId: !results.id || !detectExpressions(filteredChildren, index, config)
});
if (!transformed) return memo;
const i = memo.length;
if (transformed.text && i && memo[i - 1].text) {
memo[i - 1].template += transformed.template;
memo[i - 1].templateWithClosingTags +=
transformed.templateWithClosingTags || transformed.template;
} else memo.push(transformed);
return memo;
}, []);
childNodes.forEach((child, index) => {
if (!child) return;
if (child.tagName && child.renderer !== "dom") {
throw new Error(`<${child.tagName}> is not supported in <${tagName}>.
Wrap the usage with a component that would render this element, eg. Canvas`);
}
results.template += child.template;
results.templateWithClosingTags += child.templateWithClosingTags || child.template;
results.isImportNode = results.isImportNode || child.isImportNode;
if (child.id) {
if (child.tagName === "head") {
if (config.hydratable) {
const createComponent = registerImportMethod(
path,
"createComponent",
getRendererConfig(path, "dom").moduleName);
const NoHydration = registerImportMethod(
path,
"NoHydration",
getRendererConfig(path, "dom").moduleName);
results.exprs.push(
t__namespace.expressionStatement(
t__namespace.callExpression(createComponent, [NoHydration, t__namespace.objectExpression([])])));
}
return;
}
let getNextMatch;
if (config.hydratable && tagName === "html") {
getNextMatch = registerImportMethod(
path,
"getNextMatch",
getRendererConfig(path, "dom").moduleName);
}
const walk = t__namespace.memberExpression(
t__namespace.identifier(tempPath),
t__namespace.identifier(i === 0 ? "firstChild" : "nextSibling"));
results.declarations.push(
t__namespace.variableDeclarator(
child.id,
config.hydratable && tagName === "html" ?
t__namespace.callExpression(getNextMatch, [walk, t__namespace.stringLiteral(child.tagName)]) :
walk));
results.declarations.push(...child.declarations);
results.exprs.push(...child.exprs);
results.dynamics.push(...child.dynamics);
childPostExprs.push(...child.postExprs);
results.hasHydratableEvent = results.hasHydratableEvent || child.hasHydratableEvent;
results.hasCustomElement = results.hasCustomElement || child.hasCustomElement;
results.isImportNode = results.isImportNode || child.isImportNode;
tempPath = child.id.name;
nextPlaceholder = null;
i++;
} else if (child.exprs.length) {
let insert = registerImportMethod(path, "insert", getRendererConfig(path, "dom").moduleName);
const multi = checkLength(filteredChildren),
markers = config.hydratable && multi;
// boxed by textNodes
if (markers || wrappedByText(childNodes, index)) {
let exprId, contentId;
if (markers) tempPath = createPlaceholder(path, results, tempPath, i++, "$")[0].name;
if (nextPlaceholder) {
exprId = nextPlaceholder;
} else {
[exprId, contentId] = createPlaceholder(path, results, tempPath, i++, markers ? "/" : "");
}
if (!markers) nextPlaceholder = exprId;
results.exprs.push(
t__namespace.expressionStatement(
t__namespace.callExpression(
insert,
contentId ?
[results.id, child.exprs[0], exprId, contentId] :
[results.id, child.exprs[0], exprId])));
tempPath = exprId.name;
} else if (multi) {
results.exprs.push(
t__namespace.expressionStatement(
t__namespace.callExpression(insert, [
results.id,
child.exprs[0],
nextChild$1(childNodes, index) || t__namespace.nullLiteral()])));
} else {
results.exprs.push(
t__namespace.expressionStatement(t__namespace.callExpression(insert, [results.id, child.exprs[0]])));
}
} else nextPlaceholder = null;
});
results.postExprs.unshift(...childPostExprs);
}
function createPlaceholder(path, results, tempPath, i, char) {
const exprId = path.scope.generateUidIdentifier("el$"),
config = getConfig(path);
let contentId;
results.template += `<!${char}>`;
results.templateWithClosingTags += `<!${char}>`;
if (config.hydratable && char === "/") {
contentId = path.scope.generateUidIdentifier("co$");
results.declarations.push(
t__namespace.variableDeclarator(
t__namespace.arrayPattern([exprId, contentId]),
t__namespace.callExpression(
registerImportMethod(path, "getNextMarker", getRendererConfig(path, "dom").moduleName),
[t__namespace.memberExpression(t__namespace.identifier(tempPath), t__namespace.identifier("nextSibling"))])));
} else
results.declarations.push(
t__namespace.variableDeclarator(
exprId,
t__namespace.memberExpression(
t__namespace.identifier(tempPath),
t__namespace.identifier(i === 0 ? "firstChild" : "nextSibling"))));
return [exprId, contentId];
}
function nextChild$1(children, index) {
return children[index + 1] && (children[index + 1].id || nextChild$1(children, index + 1));
}
// reduce unnecessary refs
function detectExpressions(children, index, config) {
if (children[index - 1]) {
const node = children[index - 1].node;
if (
t__namespace.isJSXExpressionContainer(node) &&
!t__namespace.isJSXEmptyExpression(node.expression) &&
getStaticExpression(children[index - 1]) === false)
return true;
let tagName;
if (t__namespace.isJSXElement(node) && (tagName = getTagName(node)) && isComponent(tagName)) return true;
}
for (let i = index; i < children.length; i++) {
const child = children[i].node;
if (t__namespace.isJSXExpressionContainer(child)) {
if (!t__namespace.isJSXEmptyExpression(child.expression) && getStaticExpression(children[i]) === false)
return true;
} else if (t__namespace.isJSXElement(child)) {
const tagName = getTagName(child);
if (isComponent(tagName)) return true;
if (
config.contextToCustomElements && (
tagName === "slot" ||
tagName.indexOf("-") > -1 ||
child.openingElement.attributes.some((a) => a.name?.name === "is")))
return true;
if (
child.openingElement.attributes.some(
(attr) =>
t__namespace.isJSXSpreadAttribute(attr) ||
["textContent", "innerHTML", "innerText"].includes(attr.name.name) ||
attr.name.namespace && (
attr.name.namespace.name === "use" || attr.name.namespace.name === "prop") ||
t__namespace.isJSXExpressionContainer(attr.value) &&
!(
t__namespace.isStringLiteral(attr.value.expression) ||
t__namespace.isNumericLiteral(attr.value.expression))))
return true;
const nextChildren = filterChildren(children[i].get("children"));
if (nextChildren.length) if (detectExpressions(nextChildren, 0, config)) return true;
}
}
}
function contextToCustomElement(path, results) {
results.exprs.push(
t__namespace.expressionStatement(
t__namespace.assignmentExpression(
"=",
t__namespace.memberExpression(results.id, t__namespace.identifier("_$owner")),
t__namespace.callExpression(
registerImportMethod(path, "getOwner", getRendererConfig(path, "dom").moduleName),
[]))));
}
function processSpreads$1(path, attributes, { elem, isSVG, hasChildren, wrapConditionals }) {
const config = getConfig(path);
// TODO: skip but collect the names of any properties after the last spread to not overwrite them
const filteredAttributes = [];
const spreadArgs = [];
let runningObject = [];
let dynamicSpread = false;
let firstSpread = false;
attributes.forEach((attribute) => {
const node = attribute.node;
const key =
!t__namespace.isJSXSpreadAttribute(node) && (
t__namespace.isJSXNamespacedName(node.name) ?
`${node.name.namespace.name}:${node.name.name.name}` :
node.name.name);
if (t__namespace.isJSXSpreadAttribute(node)) {
const isStatic =
node.innerComments &&
node.innerComments[0] &&
node.innerComments[0].value.trim() === config.staticMarker;
firstSpread = true;
if (runningObject.length) {
spreadArgs.push(t__namespace.objectExpression(runningObject));
runningObject = [];
}
const s =
isDynamic(attribute.get("argument"), {
checkMember: true
}) && (dynamicSpread = true) ?
t__namespace.isCallExpression(node.argument) &&
!node.argument.arguments.length &&
!t__namespace.isCallExpression(node.argument.callee) &&
!t__namespace.isMemberExpression(node.argument.callee) ?
node.argument.callee :
t__namespace.arrowFunctionExpression([], node.argument) :
node.argument;
spreadArgs.push(isStatic ? t__namespace.objectExpression([t__namespace.spreadElement(s)]) : s);
} else if (
(firstSpread ||
t__namespace.isJSXExpressionContainer(node.value) &&
isDynamic(attribute.get("value").get("expression"), { checkMember: true })) &&
canNativeSpread(key, { checkNameSpaces: true }))
{
const isContainer = t__namespace.isJSXExpressionContainer(node.value);
const dynamic =
isContainer && isDynamic(attribute.get("value").get("expression"), { checkMember: true });
if (dynamic) {
const id = convertJSXIdentifier(node.name);
let expr =
wrapConditionals && (
t__namespace.isLogicalExpression(node.value.expression) ||
t__namespace.isConditionalExpression(node.value.expression)) ?
transformCondition(attribute.get("value").get("expression"), true) :
t__namespace.arrowFunctionExpression([], node.value.expression);
runningObject.push(
t__namespace.objectMethod(
"get",
id,
[],
t__namespace.blockStatement([t__namespace.returnStatement(expr.body)]),
!t__namespace.isValidIdentifier(key)));
} else {
runningObject.push(
t__namespace.objectProperty(
t__namespace.stringLiteral(key),
isContainer ?
node.value.expression :
node.value || (Properties.has(key) ? t__namespace.booleanLiteral(true) : t__namespace.stringLiteral(""))));
}
} else filteredAttributes.push(attribute);
});
if (runningObject.length) {
spreadArgs.push(t__namespace.objectExpression(runningObject));
}
const props =
spreadArgs.length === 1 && !dynamicSpread ?
spreadArgs[0] :
t__namespace.callExpression(registerImportMethod(path, "mergeProps"), spreadArgs);
return [
filteredAttributes,
t__namespace.expressionStatement(
t__namespace.callExpression(
registerImportMethod(path, "spread", getRendererConfig(path, "dom").moduleName),
[elem, props, t__namespace.booleanLiteral(isSVG), t__namespace.booleanLiteral(hasChildren)]))];
}
function createTemplate$2(path, result, wrap) {
const config = getConfig(path);
if (result.id) {
registerTemplate(path, result);
if (
!(result.exprs.length || result.dynamics.length || result.postExprs.length) &&
result.decl.declarations.length === 1)
{
return result.decl.declarations[0].init;
} else {
return t__namespace.callExpression(
t__namespace.arrowFunctionExpression(
[],
t__namespace.blockStatement([
result.decl,
...result.exprs.concat(
wrapDynamics$1(path, result.dynamics) || [],
result.postExprs || []),
t__namespace.returnStatement(result.id)])),
[]);
}
}
if (wrap && result.dynamic && config.memoWrapper) {
return t__namespace.callExpression(registerImportMethod(path, config.memoWrapper), [result.exprs[0]]);
}
return result.exprs[0];
}
function appendTemplates$1(path, templates) {
const declarators = templates.map((template) => {
const tmpl = {
cooked: template.template,
raw: escapeStringForTemplate(template.template)
};
const shouldUseImportNode = template.isCE || template.isImportNode;
const isMathML =
/^<(math|annotation|annotation-xml|maction|math|merror|mfrac|mi|mmultiscripts|mn|mo|mover|mpadded|mphantom|mprescripts|mroot|mrow|ms|mspace|msqrt|mstyle|msub|msubsup|msup|mtable|mtd|mtext|mtr|munder|munderover|semantics|menclose|mfenced)(\s|>)/.test(
template.template);
return t__namespace.variableDeclarator(
template.id,
t__namespace.addComment(
t__namespace.callExpression(
registerImportMethod(path, "template", getRendererConfig(path, "dom").moduleName),
[t__namespace.templateLiteral([t__namespace.templateElement(tmpl, true)], [])].concat(
template.isSVG || shouldUseImportNode || isMathML ?
[
t__namespace.booleanLiteral(!!shouldUseImportNode),
t__namespace.booleanLiteral(template.isSVG),
t__namespace.booleanLiteral(isMathML)] :
[])),
"leading",
"#__PURE__"));
});
path.node.body.unshift(t__namespace.variableDeclaration("var", declarators));
}
function registerTemplate(path, results) {
const { hydratable } = getConfig(path);
let decl;
if (results.template.length) {
let templateDef, templateId;
if (!results.skipTemplate) {
const templates =
path.scope.getProgramParent().data.templates || (
path.scope.getProgramParent().data.templates = []);
if (templateDef = templates.find((t) => t.template === results.template)) {
templateId = templateDef.id;
} else {
templateId = path.scope.generateUidIdentifier("tmpl$");
templates.push({
id: templateId,
template: results.template,
templateWithClosingTags: results.templateWithClosingTags,
isSVG: results.isSVG,
isCE: results.hasCustomElement,
isImportNode: results.isImportNode,
renderer: "dom"
});
}
}
decl = t__namespace.variableDeclarator(
results.id,
hydratable ?
t__namespace.callExpression(
registerImportMethod(path, "getNextElement", getRendererConfig(path, "dom").moduleName),
templateId ? [templateId] : []) :
t__namespace.callExpression(templateId, []));
}
results.declarations.unshift(decl);
results.decl = t__namespace.variableDeclaration("var", results.declarations);
}
function wrapDynamics$1(path, dynamics) {
if (!dynamics.length) return;
const config = getConfig(path);
const effectWrapperId = registerImportMethod(path, config.effectWrapper);
if (dynamics.length === 1) {
let dynamicStyle;
const prevValue =
dynamics[0].key === "classList" ||
dynamics[0].key === "style" || (
dynamicStyle = dynamics[0].key.startsWith("style:")) ?
t__namespace.identifier("_$p") :
undefined;
if (dynamicStyle) {
dynamics[0].value = t__namespace.assignmentExpression("=", prevValue, dynamics[0].value);
} else if (
dynamics[0].key.startsWith("class:") &&
!t__namespace.isBooleanLiteral(dynamics[0].value) &&
!t__namespace.isUnaryExpression(dynamics[0].value))
{
dynamics[0].value = t__namespace.unaryExpression("!", t__namespace.unaryExpression("!", dynamics[0].value));
}
return t__namespace.expressionStatement(
t__namespace.callExpression(effectWrapperId, [
t__namespace.arrowFunctionExpression(
prevValue ? [prevValue] : [],
setAttr$2(path, dynamics[0].elem, dynamics[0].key, dynamics[0].value, {
isSVG: dynamics[0].isSVG,
isCE: dynamics[0].isCE,
tagName: dynamics[0].tagName,
dynamic: true,
prevId: prevValue
}))]));
}
const prevId = t__namespace.identifier("_p$");
/** @type {t.VariableDeclarator[]} */
const declarations = [];
/** @type {t.ExpressionStatement[]} */
const statements = [];
/** @type {t.Identifier[]} */
const properties = [];
dynamics.forEach(({ elem, key, value, isSVG, isCE, tagName }, index) => {
const varIdent = path.scope.generateUidIdentifier("v$");
const propIdent = t__namespace.identifier(getNumberedId(index));
const propMember = t__namespace.memberExpression(prevId, propIdent);
if (key.startsWith("class:") && !t__namespace.isBooleanLiteral(value) && !t__namespace.isUnaryExpression(value)) {
value = t__namespace.unaryExpression("!", t__namespace.unaryExpression("!", value));
}
properties.push(propIdent);
declarations.push(t__namespace.variableDeclarator(varIdent, value));
if (key === "classList" || key === "style") {
statements.push(
t__namespace.expressionStatement(
t__namespace.assignmentExpression(
"=",
propMember,
setAttr$2(path, elem, key, varIdent, {
isSVG,
isCE,
tagName,
dynamic: true,
prevId: propMember
}))));
} else {
const prev = key.startsWith("style:") ? varIdent : undefined;
statements.push(
t__namespace.expressionStatement(
t__namespace.logicalExpression(
"&&",
t__namespace.binaryExpression("!==", varIdent, propMember),
setAttr$2(path, elem, key, t__namespace.assignmentExpression("=", propMember, varIdent), {
isSVG,
isCE,
tagName,
dynamic: true,
prevId: prev
}))));
}
});
return t__namespace.expressionStatement(
t__namespace.callExpression(effectWrapperId, [
t__namespace.arrowFunctionExpression(
[prevId],
t__namespace.blockStatement([
t__namespace.variableDeclaration("var", declarations),
...statements,
t__namespace.returnStatement(prevId)])),
t__namespace.objectExpression(properties.map((id) => t__namespace.objectProperty(id, t__namespace.identifier("undefined"))))]));
}
function createTemplate$1(path, result) {
if (!result.template) {
return result.exprs[0];
}
let template, id;
if (!Array.isArray(result.template)) {
template = t__namespace.stringLiteral(result.template);
} else if (result.template.length === 1) {
template = t__namespace.stringLiteral(result.template[0]);
} else {
const strings = result.template.map((tmpl) => t__namespace.stringLiteral(tmpl));
template = t__namespace.arrayExpression(strings);
}
const templates =
path.scope.getProgramParent().data.templates || (
path.scope.getProgramParent().data.templates = []);
const found = templates.find((tmp) => {
if (t__namespace.isArrayExpression(tmp.template) && t__namespace.isArrayExpression(template)) {
return tmp.template.elements.every(
(el, i) => template.elements[i] && el.value === template.elements[i].value);
}
return tmp.template.value === template.value;
});
if (!found) {
id = path.scope.generateUidIdentifier("tmpl$");
templates.push({
id,
template,
templateWithClosingTags: template,
renderer: "ssr"
});
} else id = found.id;
if (result.wontEscape) {
if (!Array.isArray(result.template) || result.template.length === 1) return id;else
if (
Array.isArray(result.template) &&
result.template.length === 2 &&
result.templateValues[0].type === "CallExpression" &&
result.templateValues[0].callee.name === "_$ssrHydrationKey")
{
// remove unnecessary ssr call when only hydration key is used
return t__namespace.binaryExpression(
"+",
t__namespace.binaryExpression(
"+",
t__namespace.memberExpression(id, t__namespace.numericLiteral(0), true),
result.templateValues[0]),
t__namespace.memberExpression(id, t__namespace.numericLiteral(1), true));
}
}
return t__namespace.callExpression(
registerImportMethod(path, "ssr"),
Array.isArray(result.template) && result.template.length > 1 ?
[id, ...result.templateValues] :
[id]);
}
function appendTemplates(path, templates) {
const declarators = templates.map((template) => {
return t__namespace.variableDeclarator(template.id, template.template);
});
path.node.body.unshift(t__namespace.variableDeclaration("var", declarators));
}
function appendToTemplate(template, value) {
let array;
if (Array.isArray(value)) {
[value, ...array] = value;
}
template[template.length - 1] += value;
if (array && array.length) template.push.apply(template, array);
}
function transformElement$2(path, info) {
path.
get("openingElement").
get("attributes").
forEach((attr) => {
evaluateAndInline(attr.node.value, attr.get("value"));
});
const config = getConfig(path);
const tagName = getTagName(path.node);
if (tagName === "script" || tagName === "style") path.doNotEscape = true;
// contains spread attributes
if (path.node.openingElement.attributes.some((a) => t__namespace.isJSXSpreadAttribute(a)))
return createElement(path, { ...info, ...config });
const voidTag = VoidElements.indexOf(tagName) > -1,
results = {
template: [`<${tagName}`],
templateValues: [],
declarations: [],
exprs: [],
dynamics: [],
tagName,
wontEscape: path.node.wontEscape,
renderer: "ssr"
};
if (info.topLevel && config.hydratable) {
if (tagName === "head") {
registerImportMethod(path, "NoHydration");
registerImportMethod(path, "createComponent");
const child = transformElement$2(path, { ...info, topLevel: false });
results.template = "";
results.templateWithClosingTags = "";
results.exprs.push(
t__namespace.callExpression(t__namespace.identifier("_$createComponent"), [
t__namespace.identifier("_$NoHydration"),
t__namespace.objectExpression([
t__namespace.objectMethod(
"get",
t__namespace.identifier("children"),
[],
t__namespace.blockStatement([t__namespace.returnStatement(createTemplate$1(path, child))]))])]));
return results;
}
results.template.push("");
results.templateValues.push(
t__namespace.callExpression(registerImportMethod(path, "ssrHydrationKey"), []));
}
transformAttributes$1(path, results, { ...config, ...info });
appendToTemplate(results.template, ">");
if (!voidTag) {
transformChildren$1(path, results, { ...config, ...info });
appendToTemplate(results.template, `</${tagName}>`);
}
return results;
}
function toAttribute(key, isSVG) {
key = Aliases[key] || key;
!isSVG && (key = key.toLowerCase());
return key;
}
function setAttr$1(attribute, results, name, value, isSVG) {
// strip out namespaces for now, everything at this point is an attribute
let parts;
if ((parts = name.split(":")) && parts[1] && reservedNameSpaces.has(parts[0])) {
name = parts[1];
parts[0];
}
name = toAttribute(name, isSVG);
const attr = t__namespace.callExpression(registerImportMethod(attribute, "ssrAttribute"), [
t__namespace.stringLiteral(name),
value,
t__namespace.booleanLiteral(false)]);
if (results.template[results.template.length - 1].length) {
results.template.push("");
results.templateValues.push(attr);
} else {
const last = results.templateValues.length - 1;
results.templateValues[last] = t__namespace.binaryExpression("+", results.templateValues[last], attr);
}
}
function escapeExpression(path, expression, attr, escapeLiterals) {
if (
t__namespace.isStringLiteral(expression) ||
t__namespace.isNumericLiteral(expression) ||
t__namespace.isTemplateLiteral(expression) && expression.expressions.length === 0)
{
if (escapeLiterals) {
if (t__namespace.isStringLiteral(expression)) return t__namespace.stringLiteral(escapeHTML(expression.value, attr));else
if (t__namespace.isTemplateLiteral(expression))
return t__namespace.stringLiteral(escapeHTML(expression.quasis[0].value.raw, attr));
}
return expression;
} else if (t__namespace.isFunction(expression)) {
if (t__namespace.isBlockStatement(expression.body)) {
expression.body.body = expression.body.body.map((e) => {
if (t__namespace.isReturnStatement(e))
e.argument = escapeExpression(path, e.argument, attr, escapeLiterals);
return e;
});
} else expression.body = escapeExpression(path, expression.body, attr, escapeLiterals);
return expression;
} else if (t__namespace.isTemplateLiteral(expression)) {
expression.expressions = expression.expressions.map((e) =>
escapeExpression(path, e, attr, escapeLiterals));
return expression;
} else if (t__namespace.isUnaryExpression(expression)) {
return expression;
} else if (t__namespace.isBinaryExpression(expression)) {
expression.left = escapeExpression(path, expression.left, attr, escapeLiterals);
expression.right = escapeExpression(path, expression.right, attr, escapeLiterals);
return expression;
} else if (t__namespace.isConditionalExpression(expression)) {
expression.consequent = escapeExpression(path, expression.consequent, attr, escapeLiterals);
expression.alternate = escapeExpression(path, expression.alternate, attr, escapeLiterals);
return expression;
} else if (t__namespace.isLogicalExpression(expression)) {
// Preserve the old short-circuit shape for && while still escaping the
// selected result of || and ?? as a whole.
if (expression.operator === "&&") {
expression.right = escapeExpression(path, expression.right, attr, escapeLiterals);
return expression;
}
} else if (t__namespace.isCallExpression(expression) && t__namespace.isFunction(expression.callee)) {
if (t__namespace.isBlockStatement(expression.callee.body)) {
expression.callee.body.body = expression.callee.body.body.map((e) => {
if (t__namespace.isReturnStatement(e))
e.argument = escapeExpression(path, e.argument, attr, escapeLiterals);
return e;
});
} else
expression.callee.body = escapeExpression(path, expression.callee.body, attr, escapeLiterals);
return expression;
} else if (t__namespace.isJSXElement(expression) && !isComponent(getTagName(expression))) {
expression.wontEscape = true;
return expression;
}
return t__namespace.callExpression(
registerImportMethod(path, "escape"),
[expression].concat(attr ? [t__namespace.booleanLiteral(true)] : []));
}
function transformToObject(attrName, attributes, selectedAttributes) {
const properties = [];
const existingAttribute = attributes.find((a) => a.node.name.name === attrName);
for (let i = 0; i < selectedAttributes.length; i++) {
const attr = selectedAttributes[i].node;
const computed = !t__namespace.isValidIdentifier(attr.name.name.name);
if (!computed) {
attr.name.name.type = "Identifier";
}
properties.push(
t__namespace.objectProperty(
computed ? t__namespace.stringLiteral(attr.name.name.name) : attr.name.name,
t__namespace.isJSXExpressionContainer(attr.value) ? attr.value.expression : attr.value));
(existingAttribute || i) && attributes.splice(selectedAttributes[i].key, 1);
}
if (
existingAttribute &&
t__namespace.isJSXExpressionContainer(existingAttribute.node.value) &&
t__namespace.isObjectExpression(existingAttribute.node.value.expression))
{
existingAttribute.node.value.expression.properties.push(...properties);
} else {
selectedAttributes[0].node = t__namespace.jsxAttribute(
t__namespace.jsxIdentifier(attrName),
t__namespace.jsxExpressionContainer(t__namespace.objectExpression(properties)));
}
}
function normalizeAttributes(path) {
const attributes = path.get("openingElement").get("attributes"),
styleAttributes = attributes.filter(
(a) => t__namespace.isJSXNamespacedName(a.node.name) && a.node.name.namespace.name === "style"),
classNamespaceAttributes = attributes.filter(
(a) => t__namespace.isJSXNamespacedName(a.node.name) && a.node.name.namespace.name === "class");
if (classNamespaceAttributes.length)
transformToObject("classList", attributes, classNamespaceAttributes);
const classAttributes = attributes.filter(
(a) =>
a.node.name && (
a.node.name.name === "class" ||
a.node.name.name === "className" ||
a.node.name.name === "classList"));
// combine class propertoes
if (classAttributes.length > 1) {
const first = classAttributes[0].node,
values = [],
quasis = [t__namespace.templateElement({ raw: "" })];
for (let i = 0; i < classAttributes.length; i++) {
const attr = classAttributes[i].node,
isLast = i === classAttributes.length - 1;
if (!t__namespace.isJSXExpressionContainer(attr.value)) {
const prev = quasis.pop();
quasis.push(
t__namespace.templateElement({
raw: (prev ? prev.value.raw : "") + `${attr.value.value}` + (isLast ? "" : " ")
}));
} else {
let expr = attr.value.expression;
if (attr.name.name === "classList") {
if (t__namespace.isObjectExpression(expr) && !expr.properties.some((p) => t__namespace.isSpreadElement(p))) {
transformClasslistObject(path, expr, values, quasis);
if (!isLast) quasis[quasis.length - 1].value.raw += " ";
i && attributes.splice(attributes.indexOf(classAttributes[i]), 1);
continue;
}
expr = t__namespace.callExpression(registerImportMethod(path, "ssrClassList"), [expr]);
}
values.push(t__namespace.logicalExpression("||", expr, t__namespace.stringLiteral("")));
quasis.push(t__namespace.templateElement({ raw: isLast ? "" : " " }));
}
i && attributes.splice(attributes.indexOf(classAttributes[i]), 1);
}
first.name = t__namespace.jsxIdentifier("class");
first.value = t__namespace.jsxExpressionContainer(t__namespace.templateLiteral(quasis, values));
}
if (styleAttributes.length) transformToObject("style", attributes, styleAttributes);
return attributes;
}
function transformAttributes$1(path, results, info) {
const tagName = getTagName(path.node),
isSVG = SVGElements.has(tagName),
hasChildren = path.node.children.length > 0,
attributes = normalizeAttributes(path);
let children;
attributes.forEach((attribute) => {
const node = attribute.node;
let value = node.value,
key = t__namespace.isJSXNamespacedName(node.name) ?
`${node.name.namespace.name}:${node.name.name.name}` :
node.name.name,
reservedNameSpace =
t__namespace.isJSXNamespacedName(node.name) && reservedNameSpaces.has(node.name.namespace.name);
if (
(t__namespace.isJSXNamespacedName(node.name) && reservedNameSpace || ChildProperties.has(key)) &&
!t__namespace.isJSXExpressionContainer(value))
{
node.value = value = t__namespace.jsxExpressionContainer(value || t__namespace.jsxEmptyExpression());
}
if (
t__namespace.isJSXExpressionContainer(value) && (
reservedNameSpace ||
ChildProperties.has(key) ||
!(
t__namespace.isStringLiteral(value.expression) ||
t__namespace.isNumericLiteral(value.expression) ||
t__namespace.isBooleanLiteral(value.expression))))
{
if (
key === "ref" ||
key.startsWith("use:") ||
key.startsWith("prop:") ||
key.startsWith("on"))
return;else
if (ChildProperties.has(key)) {
if (info.hydratable && key === "textContent" && value && value.expression) {
value.expression = t__namespace.logicalExpression("||", value.expression, t__namespace.stringLiteral(" "));
}
if (key === "innerHTML") path.doNotEscape = true;
children = value;
} else {
let doEscape = true;
if (key.startsWith("attr:")) key = key.replace("attr:", "");
if (BooleanAttributes.has(key) || key.startsWith("bool:")) {
key = key.replace("bool:", "");
results.template.push("");
const fn = t__namespace.callExpression(registerImportMethod(attribute, "ssrAttribute"), [
t__namespace.stringLiteral(key),
value.expression,
t__namespace.booleanLiteral(true)]);
results.templateValues.push(fn);
return;
}
if (key === "style") {
if (
t__namespace.isJSXExpressionContainer(value) &&
t__namespace.isObjectExpression(value.expression) &&
!value.expression.properties.some((p) => t__namespace.isSpreadElement(p)))
{
if (value.expression.properties.length === 0) {
return;
}
const props = value.expression.properties.map((p, i) => {
if (p.computed) {
return t__namespace.callExpression(registerImportMethod(path, "ssrStyleProperty"), [
t__namespace.binaryExpression("+", p.key, t__namespace.stringLiteral(":")),
escapeExpression(path, p.value, true, true)]);
}
return t__namespace.callExpression(registerImportMethod(path, "ssrStyleProperty"), [
t__namespace.stringLiteral(
(i ? ";" : "") + (t__namespace.isIdentifier(p.key) ? p.key.name : p.key.value) + ":"),
escapeExpression(path, p.value, true, true)]);
});
let res = props[0];
for (let i = 1; i < props.length; i++) {
res = t__namespace.binaryExpression("+", res, props[i]);
}
value.expression = res;
} else {
value.expression = t__namespace.callExpression(registerImportMethod(path, "ssrStyle"), [
value.expression]);
}
doEscape = false;
}
if (key === "classList") {
if (
t__namespace.isObjectExpression(value.expression) &&
!value.expression.properties.some((p) => t__namespace.isSpreadElement(p)))
{
const values = [],
quasis = [t__namespace.templateElement({ raw: "" })];
transformClasslistObject(path, value.expression, values, quasis);
if (!values.length) value.expression = t__namespace.stringLiteral(quasis[0].value.raw);else
if (values.length === 1 && !quasis[0].value.raw && !quasis[1].value.raw) {
value.expression = values[0];
} else value.expression = t__namespace.templateLiteral(quasis, values);
} else {
value.expression = t__namespace.callExpression(registerImportMethod(path, "ssrClassList"), [
value.expression]);
}
key = "class";
doEscape = false;
}
if (doEscape) value.expression = escapeExpression(path, value.expression, true);
if (!doEscape || t__namespace.isLiteral(value.expression)) {
key = toAttribute(key, isSVG);
appendToTemplate(results.template, ` ${key}="`);
results.template.push(`"`);
results.templateValues.push(value.expression);
} else setAttr$1(attribute, results, key, value.expression, isSVG);
}
} else {
if (key === "$ServerOnly") return;
if (t__namespace.isJSXExpressionContainer(value)) value = value.expression;
key = toAttribute(key, isSVG);
const isBoolean = BooleanAttributes.has(key);
if (isBoolean && value && value.value !== "" && !value.value) return;
appendToTemplate(results.template, ` ${key}`);
if (!value) return;
let text = isBoolean ? "" : value.value;
if (key === "style" || key === "class") {
text = trimWhitespace(String(text));
if (key === "style") {
text = text.replace(/; /g, ";").replace(/: /g, ":");
}
}
appendToTemplate(
results.template,
// `String(text)` is needed, as text.length will mess up `attr=10>` becomes `attr>` without it
String(text) === "" ? `` : `="${escapeHTML(text, true)}"`);
}
});
if (!hasChildren && children) {
path.node.children.push(children);
}
}
function transformClasslistObject(path, expr, values, quasis) {
expr.properties.forEach((prop, i) => {
const isLast = expr.properties.length - 1 === i;
let key = prop.key;
if (t__namespace.isIdentifier(prop.key) && !prop.computed) key = t__namespace.stringLiteral(key.name);else
if (prop.computed) {
key = t__namespace.callExpression(registerImportMethod(path, "escape"), [
prop.key,
t__namespace.booleanLiteral(true)]);
} else key = t__namespace.stringLiteral(escapeHTML(prop.key.value));
if (t__namespace.isBooleanLiteral(prop.value)) {
if (prop.value.value === true) {
if (!prop.computed) {
const prev = quasis.pop();
quasis.push(
t__namespace.templateElement({
raw:
(prev ? prev.value.raw : "") + (i ? " " : "") + `${key.value}` + (isLast ? "" : " ")
}));
} else {
values.push(key);
quasis.push(t__namespace.templateElement({ raw: isLast ? "" : " " }));
}
}
} else {
values.push(t__namespace.conditionalExpression(prop.value, key, t__namespace.stringLiteral("")));
quasis.push(t__namespace.templateElement({ raw: isLast ? "" : " " }));
}
});
}
function transformChildren$1(path, results, { hydratable }) {
const doNotEscape = path.doNotEscape;
const filteredChildren = filterChildren(path.get("children"));
const multi = checkLength(filteredChildren),
markers = hydratable && multi;
filteredChildren.forEach((node) => {
if (t__namespace.isJSXElement(node.node) && getTagName(node.node) === "head") {
const child = transformNode(node, { doNotEscape, hydratable: false });
registerImportMethod(path, "NoHydration");
registerImportMethod(path, "createComponent");
results.template.push("");
results.templateValues.push(
t__namespace.callExpression(t__namespace.identifier("_$createComponent"), [
t__namespace.identifier("_$NoHydration"),
t__namespace.objectExpression([
t__namespace.objectMethod(
"get",
t__namespace.identifier("children"),
[],
t__namespace.blockStatement([t__namespace.returnStatement(createTemplate$1(path, child))]))])]));
return;
}
const child = transformNode(node, { doNotEscape });
if (!child) return;
appendToTemplate(results.template, child.template);
results.templateValues.push.apply(results.templateValues, child.templateValues || []);
if (child.exprs.length) {
if (!doNotEscape && !child.spreadElement)
child.exprs[0] = escapeExpression(path, child.exprs[0]);
// boxed by textNodes
if (markers && !child.spreadElement) {
appendToTemplate(results.template, `<!--$-->`);
results.template.push("");
results.templateValues.push(child.exprs[0]);
appendToTemplate(results.template, `<!--/-->`);
} else {
results.template.push("");
results.templateValues.push(child.exprs[0]);
}
}
});
}
function createElement(path, { topLevel, hydratable }) {
const tagName = getTagName(path.node),
config = getConfig(path),
attributes = normalizeAttributes(path),
doNotEscape = path.doNotEscape;
const filteredChildren = filterChildren(path.get("children")),
multi = checkLength(filteredChildren),
markers = hydratable && multi,
childNodes = filteredChildren.reduce((memo, path) => {
if (t__namespace.isJSXText(path.node)) {
const v = htmlEntities.decode(trimWhitespace(path.node.extra.raw));
if (v.length) memo.push(t__namespace.stringLiteral(v));
} else {
const child = transformNode(path);
if (markers && child.exprs.length && !child.spreadElement)
memo.push(t__namespace.stringLiteral("<!--$-->"));
if (child.exprs.length && !doNotEscape && !child.spreadElement)
child.exprs[0] = escapeExpression(path, child.exprs[0]);
memo.push(getCreateTemplate(config, path, child)(path, child, true));
if (markers && child.exprs.length && !child.spreadElement)
memo.push(t__namespace.stringLiteral("<!--/-->"));
}
return memo;
}, []);
let props;
if (attributes.length === 1) {
props = [attributes[0].node.argument];
} else {
props = [];
let runningObject = [],
dynamicSpread = false,
hasChildren = path.node.children.length > 0;
attributes.forEach((attribute) => {
const node = attribute.node;
if (t__namespace.isJSXSpreadAttribute(node)) {
if (runningObject.length) {
props.push(t__namespace.objectExpression(runningObject));
runningObject = [];
}
props.push(
isDynamic(attribute.get("argument"), {
checkMember: true
}) && (dynamicSpread = true) ?
t__namespace.isCallExpression(node.argument) &&
!node.argument.arguments.length &&
!t__namespace.isCallExpression(node.argument.callee) &&
!t__namespace.isMemberExpression(node.argument.callee) ?
node.argument.callee :
t__namespace.arrowFunctionExpression([], node.argument) :
node.argument);
} else {
const value = node.value || t__namespace.booleanLiteral(true),
id = convertJSXIdentifier(node.name),
key = t__namespace.isJSXNamespacedName(node.name) ?
`${node.name.namespace.name}:${node.name.name.name}` :
node.name.name;
if (hasChildren && key === "children") return;
if (
key === "ref" ||
key.startsWith("use:") ||
key.startsWith("prop:") ||
key.startsWith("on"))
return;
if (t__namespace.isJSXExpressionContainer(value)) {
if (
isDynamic(attribute.get("value").get("expression"), {
checkMember: true,
checkTags: true
}))
{
let expr = t__namespace.arrowFunctionExpression([], value.expression);
runningObject.push(
t__namespace.objectMethod(
"get",
id,
[],
t__namespace.blockStatement([t__namespace.returnStatement(expr.body)]),
!t__namespace.isValidIdentifier(key)));
} else runningObject.push(t__namespace.objectProperty(id, value.expression));} else
runningObject.push(t__namespace.objectProperty(id, value));
}
});
if (runningObject.length || !props.length) props.push(t__namespace.objectExpression(runningObject));
if (props.length > 1 || dynamicSpread) {
props = [t__namespace.callExpression(registerImportMethod(path, "mergeProps"), props)];
}
}
const exprs = [
t__namespace.callExpression(registerImportMethod(path, "ssrElement"), [
t__namespace.stringLiteral(tagName),
props[0],
childNodes.length ?
hydratable ?
t__namespace.arrowFunctionExpression(
[],
childNodes.length === 1 ? childNodes[0] : t__namespace.arrayExpression(childNodes)) :
childNodes.length === 1 ?
childNodes[0] :
t__namespace.arrayExpression(childNodes) :
t__namespace.identifier("undefined"),
t__namespace.booleanLiteral(Boolean(topLevel && config.hydratable))])];
return { exprs, template: "", spreadElement: true };
}
function transformElement$1(path, info) {
path.
get("openingElement").
get("attributes").
forEach((attr) => {
evaluateAndInline(attr.node.value, attr.get("value"));
});
let tagName = getTagName(path.node),
results = {
id: path.scope.generateUidIdentifier("el$"),
declarations: [],
exprs: [],
dynamics: [],
postExprs: [],
tagName,
renderer: "universal"
};
results.declarations.push(
t__namespace.variableDeclarator(
results.id,
t__namespace.callExpression(
registerImportMethod(
path,
"createElement",
getRendererConfig(path, "universal").moduleName),
[t__namespace.stringLiteral(tagName)])));
transformAttributes(path, results);
transformChildren(path, results);
return results;
}
function transformAttributes(path, results) {
let children, spreadExpr;
let attributes = path.get("openingElement").get("attributes");
const elem = results.id,
hasChildren = path.node.children.length > 0,
config = getConfig(path);
// preprocess spreads
if (attributes.some((attribute) => t__namespace.isJSXSpreadAttribute(attribute.node))) {
[attributes, spreadExpr] = processSpreads(path, attributes, {
elem,
hasChildren,
wrapConditionals: config.wrapConditionals
});
path.get("openingElement").set(
"attributes",
attributes.map((a) => a.node));
}
path.
get("openingElement").
get("attributes").
forEach((attribute) => {
const node = attribute.node;
let value = node.value,
key = t__namespace.isJSXNamespacedName(node.name) ?
`${node.name.namespace.name}:${node.name.name.name}` :
node.name.name,
reservedNameSpace = t__namespace.isJSXNamespacedName(node.name) && node.name.namespace.name === "use";
if (
t__namespace.isJSXNamespacedName(node.name) &&
reservedNameSpace &&
!t__namespace.isJSXExpressionContainer(value))
{
node.value = value = t__namespace.jsxExpressionContainer(value || t__namespace.jsxEmptyExpression());
}
if (t__namespace.isJSXExpressionContainer(value)) {
if (key === "ref") {
// Normalize expressions for non-null and type-as
while (
t__namespace.isTSNonNullExpression(value.expression) ||
t__namespace.isTSAsExpression(value.expression))
{
value.expression = value.expression.expression;
}
let binding,
isConstant =
t__namespace.isIdentifier(value.expression) && (
binding = path.scope.getBinding(value.expression.name)) && (
binding.kind === "const" || binding.kind === "module");
if (!isConstant && t__namespace.isLVal(value.expression)) {
const refIdentifier = path.scope.generateUidIdentifier("_ref$");
results.exprs.unshift(
t__namespace.variableDeclaration("var", [t__namespace.variableDeclarator(refIdentifier, value.expression)]),
t__namespace.expressionStatement(
t__namespace.conditionalExpression(
t__namespace.binaryExpression(
"===",
t__namespace.unaryExpression("typeof", refIdentifier),
t__namespace.stringLiteral("function")),
t__namespace.callExpression(
registerImportMethod(
path,
"use",
getRendererConfig(path, "universal").moduleName),
[refIdentifier, elem]),
t__namespace.assignmentExpression("=", value.expression, elem))));
} else if (isConstant || t__namespace.isFunction(value.expression)) {
results.exprs.unshift(
t__namespace.expressionStatement(
t__namespace.callExpression(
registerImportMethod(
path,
"use",
getRendererConfig(path, "universal").moduleName),
[value.expression, elem])));
} else {
const refIdentifier = path.scope.generateUidIdentifier("_ref$");
results.exprs.unshift(
t__namespace.variableDeclaration("var", [t__namespace.variableDeclarator(refIdentifier, value.expression)]),
t__namespace.expressionStatement(
t__namespace.logicalExpression(
"&&",
t__namespace.binaryExpression(
"===",
t__namespace.unaryExpression("typeof", refIdentifier),
t__namespace.stringLiteral("function")),
t__namespace.callExpression(
registerImportMethod(
path,
"use",
getRendererConfig(path, "universal").moduleName),
[refIdentifier, elem]))));
}
} else if (key.startsWith("use:")) {
// Some trick to treat JSXIdentifier as Identifier
node.name.name.type = "Identifier";
results.exprs.unshift(
t__namespace.expressionStatement(
t__namespace.callExpression(
registerImportMethod(path, "use", getRendererConfig(path, "universal").moduleName),
[
node.name.name,
elem,
t__namespace.arrowFunctionExpression(
[],
t__namespace.isJSXEmptyExpression(value.expression) ?
t__namespace.booleanLiteral(true) :
value.expression)])));
} else if (key === "children") {
children = value;
} else if (
config.effectWrapper &&
isDynamic(attribute.get("value").get("expression"), {
checkMember: true
}))
{
results.dynamics.push({ elem, key, value: value.expression });
} else {
results.exprs.push(
t__namespace.expressionStatement(setAttr(attribute, elem, key, value.expression)));
}
} else {
results.exprs.push(t__namespace.expressionStatement(setAttr(attribute, elem, key, value)));
}
});
if (spreadExpr) results.exprs.push(spreadExpr);
if (!hasChildren && children) {
path.node.children.push(children);
}
}
function setAttr(path, elem, name, value, { prevId } = {}) {
if (!value) value = t__namespace.booleanLiteral(true);
return t__namespace.callExpression(
registerImportMethod(path, "setProp", getRendererConfig(path, "universal").moduleName),
prevId ? [elem, t__namespace.stringLiteral(name), value, prevId] : [elem, t__namespace.stringLiteral(name), value]);
}
function transformChildren(path, results) {
const filteredChildren = filterChildren(path.get("children")),
multi = checkLength(filteredChildren),
childNodes = filteredChildren.map(transformNode).reduce((memo, child) => {
if (!child) return memo;
const i = memo.length;
if (child.text && i && memo[i - 1].text) {
memo[i - 1].template += child.template;
memo[i - 1].templateWithClosingTags += child.templateWithClosingTags || child.template;
} else memo.push(child);
return memo;
}, []);
const appends = [];
childNodes.forEach((child, index) => {
if (!child) return;
if (child.tagName && child.renderer !== "universal") {
throw new Error(`<${child.tagName}> is not supported in <${getTagName(path.node)}>.
Wrap the usage with a component that would render this element, eg. Canvas`);
}
if (child.id) {
let insertNode = registerImportMethod(
path,
"insertNode",
getRendererConfig(path, "universal").moduleName);
let insert = child.id;
if (child.text) {
let createTextNode = registerImportMethod(
path,
"createTextNode",
getRendererConfig(path, "universal").moduleName);
if (multi) {
results.declarations.push(
t__namespace.variableDeclarator(
child.id,
t__namespace.callExpression(createTextNode, [
t__namespace.templateLiteral(
[t__namespace.templateElement({ raw: escapeStringForTemplate(child.template) })],
[])])));
} else
insert = t__namespace.callExpression(createTextNode, [
t__namespace.templateLiteral(
[t__namespace.templateElement({ raw: escapeStringForTemplate(child.template) })],
[])]);
}
appends.push(t__namespace.expressionStatement(t__namespace.callExpression(insertNode, [results.id, insert])));
results.declarations.push(...child.declarations);
results.exprs.push(...child.exprs);
results.dynamics.push(...child.dynamics);
} else if (child.exprs.length) {
let insert = registerImportMethod(
path,
"insert",
getRendererConfig(path, "universal").moduleName);
if (multi) {
results.exprs.push(
t__namespace.expressionStatement(
t__namespace.callExpression(insert, [
results.id,
child.exprs[0],
nextChild(childNodes, index) || t__namespace.nullLiteral()])));
} else {
results.exprs.push(
t__namespace.expressionStatement(t__namespace.callExpression(insert, [results.id, child.exprs[0]])));
}
}
});
results.exprs.unshift(...appends);
}
function nextChild(children, index) {
return children[index + 1] && (children[index + 1].id || nextChild(children, index + 1));
}
function processSpreads(path, attributes, { elem, hasChildren, wrapConditionals }) {
// TODO: skip but collect the names of any properties after the last spread to not overwrite them
const filteredAttributes = [];
const spreadArgs = [];
let runningObject = [];
let dynamicSpread = false;
let firstSpread = false;
attributes.forEach((attribute) => {
const node = attribute.node;
const key =
!t__namespace.isJSXSpreadAttribute(node) && (
t__namespace.isJSXNamespacedName(node.name) ?
`${node.name.namespace.name}:${node.name.name.name}` :
node.name.name);
if (t__namespace.isJSXSpreadAttribute(node)) {
firstSpread = true;
if (runningObject.length) {
spreadArgs.push(t__namespace.objectExpression(runningObject));
runningObject = [];
}
spreadArgs.push(
isDynamic(attribute.get("argument"), {
checkMember: true
}) && (dynamicSpread = true) ?
t__namespace.isCallExpression(node.argument) &&
!node.argument.arguments.length &&
!t__namespace.isCallExpression(node.argument.callee) &&
!t__namespace.isMemberExpression(node.argument.callee) ?
node.argument.callee :
t__namespace.arrowFunctionExpression([], node.argument) :
node.argument);
} else if (
(firstSpread ||
t__namespace.isJSXExpressionContainer(node.value) &&
isDynamic(attribute.get("value").get("expression"), { checkMember: true })) &&
canNativeSpread(key, { checkNameSpaces: true }))
{
const isContainer = t__namespace.isJSXExpressionContainer(node.value);
const dynamic =
isContainer && isDynamic(attribute.get("value").get("expression"), { checkMember: true });
if (dynamic) {
const id = convertJSXIdentifier(node.name);
let expr =
wrapConditionals && (
t__namespace.isLogicalExpression(node.value.expression) ||
t__namespace.isConditionalExpression(node.value.expression)) ?
transformCondition(attribute.get("value").get("expression"), true) :
t__namespace.arrowFunctionExpression([], node.value.expression);
runningObject.push(
t__namespace.objectMethod(
"get",
id,
[],
t__namespace.blockStatement([t__namespace.returnStatement(expr.body)]),
!t__namespace.isValidIdentifier(key)));
} else {
runningObject.push(
t__namespace.objectProperty(
t__namespace.stringLiteral(key),
isContainer ? node.value.expression : node.value || t__namespace.booleanLiteral(true)));
}
} else filteredAttributes.push(attribute);
});
if (runningObject.length) {
spreadArgs.push(t__namespace.objectExpression(runningObject));
}
const props =
spreadArgs.length === 1 && !dynamicSpread ?
spreadArgs[0] :
t__namespace.callExpression(registerImportMethod(path, "mergeProps"), spreadArgs);
return [
filteredAttributes,
t__namespace.expressionStatement(
t__namespace.callExpression(
registerImportMethod(path, "spread", getRendererConfig(path, "universal").moduleName),
[elem, props, t__namespace.booleanLiteral(hasChildren)]))];
}
function createTemplate(path, result, wrap) {
const config = getConfig(path);
if (result.id) {
result.decl = t__namespace.variableDeclaration("var", result.declarations);
if (
!(result.exprs.length || result.dynamics.length || result.postExprs.length) &&
result.decl.declarations.length === 1)
{
return result.decl.declarations[0].init;
} else {
return t__namespace.callExpression(
t__namespace.arrowFunctionExpression(
[],
t__namespace.blockStatement([
result.decl,
...result.exprs.concat(
wrapDynamics(path, result.dynamics) || [],
result.postExprs || []),
t__namespace.returnStatement(result.id)])),
[]);
}
}
if (wrap && result.dynamic && config.memoWrapper) {
return t__namespace.callExpression(registerImportMethod(path, config.memoWrapper), [result.exprs[0]]);
}
return result.exprs[0];
}
function wrapDynamics(path, dynamics) {
if (!dynamics.length) return;
const config = getConfig(path);
const effectWrapperId = registerImportMethod(path, config.effectWrapper);
if (dynamics.length === 1) {
const prevValue = t__namespace.identifier("_$p");
return t__namespace.expressionStatement(
t__namespace.callExpression(effectWrapperId, [
t__namespace.arrowFunctionExpression(
[prevValue],
setAttr(path, dynamics[0].elem, dynamics[0].key, dynamics[0].value, {
dynamic: true,
prevId: prevValue
}))]));
}
const prevId = t__namespace.identifier("_p$");
/** @type {t.VariableDeclarator[]} */
const declarations = [];
/** @type {t.ExpressionStatement[]} */
const statements = [];
/** @type {t.Identifier[]} */
const properties = [];
dynamics.forEach(({ elem, key, value }, index) => {
const varIdent = path.scope.generateUidIdentifier("v$");
const propIdent = t__namespace.identifier(getNumberedId(index));
const propMember = t__namespace.memberExpression(prevId, propIdent);
properties.push(propIdent);
declarations.push(t__namespace.variableDeclarator(varIdent, value));
statements.push(
t__namespace.expressionStatement(
t__namespace.logicalExpression(
"&&",
t__namespace.binaryExpression("!==", varIdent, propMember),
t__namespace.assignmentExpression(
"=",
propMember,
setAttr(path, elem, key, varIdent, { dynamic: true, prevId: propMember })))));
});
return t__namespace.expressionStatement(
t__namespace.callExpression(effectWrapperId, [
t__namespace.arrowFunctionExpression(
[prevId],
t__namespace.blockStatement([
t__namespace.variableDeclaration("var", declarations),
...statements,
t__namespace.returnStatement(prevId)])),
t__namespace.objectExpression(
properties.map((id) => t__namespace.objectProperty(id, t__namespace.identifier("undefined"))))]));
}
function convertComponentIdentifier(node) {
if (t__namespace.isJSXIdentifier(node)) {
if (node.name === "this") return t__namespace.thisExpression();
if (t__namespace.isValidIdentifier(node.name)) node.type = "Identifier";else
return t__namespace.stringLiteral(node.name);
} else if (t__namespace.isJSXMemberExpression(node)) {
const prop = convertComponentIdentifier(node.property);
const computed = t__namespace.isStringLiteral(prop);
return t__namespace.memberExpression(convertComponentIdentifier(node.object), prop, computed);
}
return node;
}
function transformComponent(path) {
let exprs = [],
config = getConfig(path),
tagId = convertComponentIdentifier(path.node.openingElement.name),
props = [],
runningObject = [],
dynamicSpread = false,
hasChildren = path.node.children.length > 0;
if (config.builtIns.indexOf(tagId.name) > -1 && !path.scope.hasBinding(tagId.name)) {
const newTagId = registerImportMethod(path, tagId.name);
tagId.name = newTagId.name;
}
path.
get("openingElement").
get("attributes").
forEach((attribute) => {
const node = attribute.node;
if (t__namespace.isJSXSpreadAttribute(node)) {
if (runningObject.length) {
props.push(t__namespace.objectExpression(runningObject));
runningObject = [];
}
props.push(
isDynamic(attribute.get("argument"), {
checkMember: true
}) && (dynamicSpread = true) ?
t__namespace.isCallExpression(node.argument) &&
!node.argument.arguments.length &&
!t__namespace.isCallExpression(node.argument.callee) &&
!t__namespace.isMemberExpression(node.argument.callee) ?
node.argument.callee :
t__namespace.arrowFunctionExpression([], node.argument) :
node.argument);
} else {
// handle weird babel bug around HTML entities
const value =
(t__namespace.isStringLiteral(node.value) ? t__namespace.stringLiteral(node.value.value) : node.value) ||
t__namespace.booleanLiteral(true),
id = convertJSXIdentifier(node.name),
key = id.name;
if (hasChildren && key === "children") return;
if (t__namespace.isJSXExpressionContainer(value)) {
if (key === "ref") {
if (config.generate === "ssr") return;
// Normalize expressions for non-null and type-as
while (
t__namespace.isTSNonNullExpression(value.expression) ||
t__namespace.isTSAsExpression(value.expression) ||
t__namespace.isTSSatisfiesExpression(value.expression))
{
value.expression = value.expression.expression;
}
let binding,
isConstant =
t__namespace.isIdentifier(value.expression) && (
binding = path.scope.getBinding(value.expression.name)) && (
binding.kind === "const" || binding.kind === "module");
if (!isConstant && t__namespace.isLVal(value.expression)) {
const refIdentifier = path.scope.generateUidIdentifier("_ref$");
runningObject.push(
t__namespace.objectMethod(
"method",
t__namespace.identifier("ref"),
[t__namespace.identifier("r$")],
t__namespace.blockStatement([
t__namespace.variableDeclaration("var", [
t__namespace.variableDeclarator(refIdentifier, value.expression)]),
t__namespace.expressionStatement(
t__namespace.conditionalExpression(
t__namespace.binaryExpression(
"===",
t__namespace.unaryExpression("typeof", refIdentifier),
t__namespace.stringLiteral("function")),
t__namespace.callExpression(refIdentifier, [t__namespace.identifier("r$")]),
t__namespace.assignmentExpression("=", value.expression, t__namespace.identifier("r$"))))])));
} else if (!isConstant && t__namespace.isOptionalMemberExpression(value.expression)) {
const refIdentifier = path.scope.generateUidIdentifier("_ref$");
runningObject.push(
t__namespace.objectMethod(
"method",
t__namespace.identifier("ref"),
[t__namespace.identifier("r$")],
t__namespace.blockStatement([
t__namespace.variableDeclaration("var", [
t__namespace.variableDeclarator(refIdentifier, value.expression)]),
t__namespace.expressionStatement(
t__namespace.conditionalExpression(
t__namespace.binaryExpression(
"===",
t__namespace.unaryExpression("typeof", refIdentifier),
t__namespace.stringLiteral("function")),
t__namespace.callExpression(refIdentifier, [t__namespace.identifier("r$")]),
t__namespace.logicalExpression(
"&&",
t__namespace.unaryExpression(
"!",
t__namespace.unaryExpression("!", t__namespace.identifier(value.expression.object.name))),
t__namespace.assignmentExpression(
"=",
t__namespace.memberExpression(
t__namespace.identifier(value.expression.object.name),
t__namespace.identifier(value.expression.property.name)),
t__namespace.identifier("r$")))))])));
} else if (isConstant || t__namespace.isFunction(value.expression)) {
runningObject.push(t__namespace.objectProperty(t__namespace.identifier("ref"), value.expression));
} else if (t__namespace.isCallExpression(value.expression)) {
const refIdentifier = path.scope.generateUidIdentifier("_ref$");
runningObject.push(
t__namespace.objectMethod(
"method",
t__namespace.identifier("ref"),
[t__namespace.identifier("r$")],
t__namespace.blockStatement([
t__namespace.variableDeclaration("var", [
t__namespace.variableDeclarator(refIdentifier, value.expression)]),
t__namespace.expressionStatement(
t__namespace.logicalExpression(
"&&",
t__namespace.binaryExpression(
"===",
t__namespace.unaryExpression("typeof", refIdentifier),
t__namespace.stringLiteral("function")),
t__namespace.callExpression(refIdentifier, [t__namespace.identifier("r$")])))])));
}
} else if (
isDynamic(attribute.get("value").get("expression"), {
checkMember: true,
checkTags: true
}))
{
if (
config.wrapConditionals &&
config.generate !== "ssr" && (
t__namespace.isLogicalExpression(value.expression) ||
t__namespace.isConditionalExpression(value.expression)))
{
const expr = transformCondition(attribute.get("value").get("expression"), true);
runningObject.push(
t__namespace.objectMethod(
"get",
id,
[],
t__namespace.blockStatement([t__namespace.returnStatement(expr.body)]),
!t__namespace.isValidIdentifier(key)));
} else if (
t__namespace.isCallExpression(value.expression) &&
t__namespace.isArrowFunctionExpression(value.expression.callee) &&
value.expression.callee.params.length === 0)
{
const callee = value.expression.callee;
const body = t__namespace.isBlockStatement(callee.body) ?
callee.body :
t__namespace.blockStatement([t__namespace.returnStatement(callee.body)]);
runningObject.push(t__namespace.objectMethod("get", id, [], body, !t__namespace.isValidIdentifier(key)));
} else {
runningObject.push(
t__namespace.objectMethod(
"get",
id,
[],
t__namespace.blockStatement([t__namespace.returnStatement(value.expression)]),
!t__namespace.isValidIdentifier(key)));
}
} else runningObject.push(t__namespace.objectProperty(id, value.expression));} else
runningObject.push(t__namespace.objectProperty(id, value));
}
});
const childResult = transformComponentChildren(path.get("children"), config);
if (childResult && childResult[0]) {
if (childResult[1]) {
const body =
t__namespace.isCallExpression(childResult[0]) && t__namespace.isFunction(childResult[0].arguments[0]) ?
childResult[0].arguments[0].body :
childResult[0].body ?
childResult[0].body :
childResult[0];
runningObject.push(
t__namespace.objectMethod(
"get",
t__namespace.identifier("children"),
[],
t__namespace.isExpression(body) ? t__namespace.blockStatement([t__namespace.returnStatement(body)]) : body));
} else runningObject.push(t__namespace.objectProperty(t__namespace.identifier("children"), childResult[0]));
}
if (runningObject.length || !props.length) props.push(t__namespace.objectExpression(runningObject));
if (props.length > 1 || dynamicSpread) {
props = [t__namespace.callExpression(registerImportMethod(path, "mergeProps"), props)];
}
const componentArgs = [tagId, props[0]];
exprs.push(t__namespace.callExpression(registerImportMethod(path, "createComponent"), componentArgs));
// handle hoisting conditionals
if (exprs.length > 1) {
const ret = exprs.pop();
exprs = [
t__namespace.callExpression(
t__namespace.arrowFunctionExpression([], t__namespace.blockStatement([...exprs, t__namespace.returnStatement(ret)])),
[])];
}
return { exprs, template: "", component: true };
}
function transformComponentChildren(children, config) {
const filteredChildren = filterChildren(children);
if (!filteredChildren.length) return;
let dynamic = false;
let pathNodes = [];
let transformedChildren = filteredChildren.reduce((memo, path) => {
if (t__namespace.isJSXText(path.node)) {
const v = htmlEntities.decode(trimWhitespace(path.node.extra.raw));
if (v.length) {
pathNodes.push(path.node);
memo.push(t__namespace.stringLiteral(v));
}
} else {
const child = transformNode(path, {
topLevel: true,
componentChild: true,
lastElement: true
});
dynamic = dynamic || child.dynamic;
if (
config.generate === "ssr" &&
filteredChildren.length > 1 &&
child.dynamic &&
t__namespace.isFunction(child.exprs[0]))
{
child.exprs[0] = child.exprs[0].body;
}
pathNodes.push(path.node);
memo.push(getCreateTemplate(config, path, child)(path, child, filteredChildren.length > 1));
}
return memo;
}, []);
if (transformedChildren.length === 1) {
transformedChildren = transformedChildren[0];
if (
!t__namespace.isJSXExpressionContainer(pathNodes[0]) &&
!t__namespace.isJSXSpreadChild(pathNodes[0]) &&
!t__namespace.isJSXText(pathNodes[0]))
{
transformedChildren =
t__namespace.isCallExpression(transformedChildren) &&
!transformedChildren.arguments.length &&
!t__namespace.isIdentifier(transformedChildren.callee) ?
transformedChildren.callee :
t__namespace.arrowFunctionExpression([], transformedChildren);
dynamic = true;
}
} else {
transformedChildren = t__namespace.arrowFunctionExpression([], t__namespace.arrayExpression(transformedChildren));
dynamic = true;
}
return [transformedChildren, dynamic];
}
function transformFragmentChildren(children, results, config) {
const filteredChildren = filterChildren(children),
childNodes = filteredChildren.reduce((memo, path) => {
if (t__namespace.isJSXText(path.node)) {
const v = htmlEntities.decode(trimWhitespace(path.node.extra.raw));
if (v.length) memo.push(t__namespace.stringLiteral(v));
} else {
const child = transformNode(path, { topLevel: true, fragmentChild: true, lastElement: true });
memo.push(getCreateTemplate(config, path, child)(path, child, true));
}
return memo;
}, []);
results.exprs.push(childNodes.length === 1 ? childNodes[0] : t__namespace.arrayExpression(childNodes));
}
function transformJSX(path, state) {
if (state.skip) return;
const config = getConfig(path);
const replace = transformThis(path);
const result = transformNode(
path,
t__namespace.isJSXFragment(path.node) ?
{} :
{
topLevel: true,
lastElement: true
});
const template = getCreateTemplate(config, path, result);
path.replaceWith(replace(template(path, result, false)));
path.traverse({
enter(path) {
if (
path.node.leadingComments &&
path.node.leadingComments[0] &&
path.node.leadingComments[0].value.trim() === config.staticMarker)
{
path.node.leadingComments.shift();
}
}
});
}
function getTargetFunctionParent(path, parent) {
let current = path.scope.getFunctionParent();
while (current !== parent && current.path.isArrowFunctionExpression()) {
current = current.path.parentPath.scope.getFunctionParent();
}
return current;
}
function transformThis(path) {
const parent = path.scope.getFunctionParent();
let thisId;
path.traverse({
ThisExpression(path) {
const current = getTargetFunctionParent(path, parent);
if (current === parent) {
thisId || (thisId = path.scope.generateUidIdentifier("self$"));
path.replaceWith(thisId);
}
},
JSXElement(path) {
let source = path.get("openingElement").get("name");
while (source.isJSXMemberExpression()) {
source = source.get("object");
}
if (source.isJSXIdentifier() && source.node.name === "this") {
const current = getTargetFunctionParent(path, parent);
if (current === parent) {
thisId || (thisId = path.scope.generateUidIdentifier("self$"));
source.replaceWith(t__namespace.jsxIdentifier(thisId.name));
if (path.node.closingElement) {
path.node.closingElement.name = path.node.openingElement.name;
}
}
}
}
});
return (node) => {
if (thisId) {
if (!parent || parent.block.type === "ClassMethod") {
const decl = t__namespace.variableDeclaration("const", [
t__namespace.variableDeclarator(thisId, t__namespace.thisExpression())]);
if (parent) {
const stmt = path.getStatementParent();
stmt.insertBefore(decl);
} else {
return t__namespace.callExpression(
t__namespace.arrowFunctionExpression([], t__namespace.blockStatement([decl, t__namespace.returnStatement(node)])),
[]);
}
} else {
parent.push({
id: thisId,
init: t__namespace.thisExpression(),
kind: "const"
});
}
}
return node;
};
}
function transformNode(path, info = {}) {
const config = getConfig(path);
const node = path.node;
let staticValue;
if (t__namespace.isJSXElement(node)) {
return transformElement(config, path, info);
} else if (t__namespace.isJSXFragment(node)) {
let results = { template: "", declarations: [], exprs: [], dynamics: [] };
// <><div /><Component /></>
transformFragmentChildren(path.get("children"), results, config);
return results;
} else if (t__namespace.isJSXText(node) || (staticValue = getStaticExpression(path)) !== false) {
const text =
staticValue !== undefined ?
info.doNotEscape ?
staticValue.toString() :
escapeHTML(staticValue.toString()) :
trimWhitespace(node.extra.raw);
if (!text.length) return null;
const results = {
template: text,
declarations: [],
exprs: [],
dynamics: [],
postExprs: [],
text: true
};
if (!info.skipId && config.generate !== "ssr")
results.id = path.scope.generateUidIdentifier("el$");
return results;
} else if (t__namespace.isJSXExpressionContainer(node)) {
if (t__namespace.isJSXEmptyExpression(node.expression)) return null;
if (
!isDynamic(path.get("expression"), {
checkMember: true,
checkTags: !!info.componentChild,
native: !info.componentChild
}))
{
return { exprs: [node.expression], template: "" };
}
const expr =
config.wrapConditionals &&
config.generate !== "ssr" && (
t__namespace.isLogicalExpression(node.expression) || t__namespace.isConditionalExpression(node.expression)) ?
transformCondition(path.get("expression"), info.componentChild || info.fragmentChild) :
!info.componentChild && (
config.generate !== "ssr" || info.fragmentChild) &&
t__namespace.isCallExpression(node.expression) &&
!t__namespace.isCallExpression(node.expression.callee) &&
!t__namespace.isMemberExpression(node.expression.callee) &&
node.expression.arguments.length === 0 ?
node.expression.callee :
t__namespace.arrowFunctionExpression([], node.expression);
return {
exprs:
expr.length > 1 ?
[
t__namespace.callExpression(
t__namespace.arrowFunctionExpression(
[],
t__namespace.blockStatement([expr[0], t__namespace.returnStatement(expr[1])])),
[])] :
[expr],
template: "",
dynamic: true
};
} else if (t__namespace.isJSXSpreadChild(node)) {
if (
!isDynamic(path.get("expression"), {
checkMember: true,
native: !info.componentChild
}))
return { exprs: [node.expression], template: "" };
const expr = t__namespace.arrowFunctionExpression([], node.expression);
return {
exprs: [expr],
template: "",
dynamic: true
};
}
}
function getCreateTemplate(config, path, result) {
if (result.tagName && result.renderer === "dom" || config.generate === "dom") {
return createTemplate$2;
}
if (result.renderer === "ssr" || config.generate === "ssr") {
return createTemplate$1;
}
return createTemplate;
}
function transformElement(config, path, info = {}) {
const node = path.node;
let tagName = getTagName(node);
// <Component ...></Component>
if (isComponent(tagName)) return transformComponent(path);
// <div ...></div>
// const element = getTransformElemet(config, path, tagName);
const tagRenderer = (config.renderers ?? []).find((renderer) =>
renderer.elements.includes(tagName));
if (tagRenderer?.name === "dom" || getConfig(path).generate === "dom") {
return transformElement$3(path, info);
}
if (getConfig(path).generate === "ssr") {
return transformElement$2(path, info);
}
return transformElement$1(path);
}
// import parse5 from "parse5";
const parse5 = require("parse5");
/** `bodyElement` will be used as a `context` (The place where we run `innerHTML`) */
const bodyElement = parse5.parse(
`<!DOCTYPE html><html><head></head><body></body></html>`
// @ts-ignore
).childNodes[1].childNodes[1];
function innerHTML(htmlFragment) {
/** `htmlFragment` will be parsed as if it was set to the `bodyElement`'s `innerHTML` property. */
const parsedFragment = parse5.parseFragment(bodyElement, htmlFragment);
/** `serialize` returns back a string from the parsed nodes */
return parse5.serialize(parsedFragment);
}
/**
* Returns an object with information when the markup is invalid
*
* @param {string} html - The html string to validate
* @returns {{
* html: string; // html stripped of attributives and content
* browser: string; // what the browser returned from evaluating `html`
* } | null}
*/
function isInvalidMarkup(html) {
html = html
// normalize dom-expressions comments, so comments location are also validated
.replaceAll("<!>", "<!---->").
replaceAll("<!$>", "<!--$-->").
replaceAll("<!/>", "<!--/-->")
// replace text nodes
// text nodes are problematic, think "doesn't" vs "doesn&#39;t"
// we can detect if text nodes were moved by the browser when the `#text` moves
// replace text nodes that isnt in between tags by `#text`
.replace(/^[^<]+/, "#text").
replace(/[^>]+$/, "#text")
// replace text nodes in between tags by `#text`
.replace(/>[^<]+</gi, ">#text<")
// remove attributes (the lack of quotes will make it mismatch)
// attributes are not longer added to `templateWithClosingTags`
// https://github.com/solidjs/solid/issues/2338
// .replace(/<([a-z0-9-:]+)\s+[^>]+>/gi, "<$1>")
// fix escaping, so doesnt mess up the validation
// `&lt;script>a();&lt;/script>` -> `&lt;script&gt;a();&lt;/script&gt;`
.replace(/&lt;([^>]+)>/gi, "&lt;$1&gt;");
// edge cases (safe to assume they will use the partial in the right place)
// table cells
if (/^<(td|th)>/.test(html)) {
html = `<table><tbody><tr>${html}</tr></tbody></table>`;
}
// table rows
if (/^<tr>/.test(html)) {
html = `<table><tbody>${html}</tbody></table>`;
}
// table misc
if (/^<col>/.test(html)) {
html = `<table><colgroup>${html}</colgroup></table>`;
}
// table components
if (/^<(thead|tbody|tfoot|colgroup|caption)>/.test(html)) {
html = `<table>${html}</table>`;
}
// skip when equal to:
switch (html) {
// empty table components
case "<table></table>":
case "<table><thead></thead></table>":
case "<table><tbody></tbody></table>":
case "<table><thead></thead><tbody></tbody></table>":{
return;
}}
/** Parse HTML. `browser` is a string with the supposed resulting html of a real `innerHTML` call */
const browser = innerHTML(html);
if (html.toLowerCase() !== browser.toLowerCase()) {
return {
html,
browser
};
}
}
// add to the top/bottom of the module.
var postprocess = ((path, state) => {
if (state.skip) return;
if (path.scope.data.events) {
path.node.body.push(
t__namespace.expressionStatement(
t__namespace.callExpression(
registerImportMethod(path, "delegateEvents", getRendererConfig(path, "dom").moduleName),
[t__namespace.arrayExpression(Array.from(path.scope.data.events).map((e) => t__namespace.stringLiteral(e)))])));
}
if (path.scope.data.templates?.length) {
if (path.hub.file.metadata.config.validate) {
for (const template of path.scope.data.templates) {
const html = template.templateWithClosingTags;
// not sure when/why this is not a string
if (typeof html === "string") {
const result = isInvalidMarkup(html);
if (result) {
const message =
"\nThe HTML provided is malformed and will yield unexpected output when evaluated by a browser.\n";
console.warn(message);
console.warn("User HTML:\n", result.html);
console.warn("Browser HTML:\n", result.browser);
console.warn("Original HTML:\n", html);
// throw path.buildCodeFrameError();
}
}
}
}
let domTemplates = path.scope.data.templates.filter((temp) => temp.renderer === "dom");
let ssrTemplates = path.scope.data.templates.filter((temp) => temp.renderer === "ssr");
domTemplates.length > 0 && appendTemplates$1(path, domTemplates);
ssrTemplates.length > 0 && appendTemplates(path, ssrTemplates);
}
});
var config = {
moduleName: "dom",
generate: "dom",
hydratable: false,
delegateEvents: true,
delegatedEvents: [],
builtIns: [],
requireImportSource: false,
wrapConditionals: true,
omitNestedClosingTags: false,
omitLastClosingTag: true,
omitQuotes: true,
contextToCustomElements: false,
staticMarker: "@once",
effectWrapper: "effect",
memoWrapper: "memo",
validate: true,
inlineStyles: true
};
var preprocess = ((path, state) => {
const merged = path.hub.file.metadata.config = Object.assign({}, config, state.opts);
const lib = merged.requireImportSource;
if (lib) {
const comments = path.hub.file.ast.comments;
let process = false;
for (let i = 0; i < comments.length; i++) {
const comment = comments[i];
const pieces = comment.value.split("@jsxImportSource");
if (pieces.length === 2 && pieces[1].trim() === lib) {
process = true;
break;
}
}
if (!process) {
state.skip = true;
return;
}
}
});
var index = (() =>
{
return {
name: "JSX DOM Expressions",
inherits: SyntaxJSX.default,
visitor: {
JSXElement: transformJSX,
JSXFragment: transformJSX,
Program: {
enter: preprocess,
exit: postprocess
}
}
};
});
module.exports = index;