marko 6.4.1 → 6.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cheatsheet.md +1 -1
- package/dist/common/constants/accessor-prop.d.ts +1 -0
- package/dist/common/constants/accessor-prop.debug.d.ts +1 -0
- package/dist/common/errors.d.ts +1 -0
- package/dist/common/opt.d.ts +1 -0
- package/dist/common/types.d.ts +1 -0
- package/dist/debug/dom/catch.feat.js +1 -1
- package/dist/debug/dom/catch.feat.mjs +1 -1
- package/dist/debug/dom/controllable-input.feat.js +1 -1
- package/dist/debug/dom/controllable-input.feat.mjs +1 -1
- package/dist/debug/dom/controllable-open.feat.js +1 -1
- package/dist/debug/dom/controllable-open.feat.mjs +1 -1
- package/dist/debug/dom/controllable-select.feat.js +1 -1
- package/dist/debug/dom/controllable-select.feat.mjs +1 -1
- package/dist/debug/dom/controllable-textarea.feat.js +1 -1
- package/dist/debug/dom/controllable-textarea.feat.mjs +1 -1
- package/dist/debug/dom/controllable.feat.js +1 -1
- package/dist/debug/dom/controllable.feat.mjs +1 -1
- package/dist/debug/dom/dynamic-tag-script.feat.js +1 -1
- package/dist/debug/dom/dynamic-tag-script.feat.mjs +1 -1
- package/dist/debug/dom/dynamic-tag-var.feat.js +6 -2
- package/dist/debug/dom/dynamic-tag-var.feat.mjs +6 -2
- package/dist/debug/dom/lazy.feat.js +1 -1
- package/dist/debug/dom/lazy.feat.mjs +1 -1
- package/dist/debug/dom/placeholder.feat.js +1 -1
- package/dist/debug/dom/placeholder.feat.mjs +1 -1
- package/dist/debug/{dom-ClV4kVOO.js → dom-C7F3yZTh.js} +119 -24
- package/dist/debug/{dom-LFrKxOk5.mjs → dom-uEY0J_H9.mjs} +78 -25
- package/dist/debug/dom.js +16 -4
- package/dist/debug/dom.mjs +14 -5
- package/dist/debug/html.js +288 -78
- package/dist/debug/html.mjs +288 -79
- package/dist/dom/catch.feat.js +4 -4
- package/dist/dom/catch.feat.mjs +1 -1
- package/dist/dom/control-flow.d.ts +2 -2
- package/dist/dom/controllable-input.feat.js +2 -2
- package/dist/dom/controllable-input.feat.mjs +1 -1
- package/dist/dom/controllable-open.feat.js +2 -2
- package/dist/dom/controllable-open.feat.mjs +1 -1
- package/dist/dom/controllable-select.feat.js +2 -2
- package/dist/dom/controllable-select.feat.mjs +1 -1
- package/dist/dom/controllable-textarea.feat.js +2 -2
- package/dist/dom/controllable-textarea.feat.mjs +1 -1
- package/dist/dom/controllable.feat.js +2 -2
- package/dist/dom/controllable.feat.mjs +1 -1
- package/dist/dom/dom.d.ts +1 -0
- package/dist/dom/dynamic-tag-script.feat.js +2 -2
- package/dist/dom/dynamic-tag-script.feat.mjs +1 -1
- package/dist/dom/dynamic-tag-var.feat.js +4 -2
- package/dist/dom/dynamic-tag-var.feat.mjs +4 -3
- package/dist/dom/lazy.feat.js +1 -1
- package/dist/dom/lazy.feat.mjs +1 -1
- package/dist/dom/load.d.ts +1 -0
- package/dist/dom/placeholder.feat.js +3 -3
- package/dist/dom/placeholder.feat.mjs +1 -1
- package/dist/dom/queue.d.ts +4 -1
- package/dist/{dom-CNglVi8P.js → dom-CtIT8Mpr.js} +201 -138
- package/dist/{dom-DfP3MCo0.mjs → dom-DHg9YChM.mjs} +60 -27
- package/dist/dom.d.ts +3 -3
- package/dist/dom.js +41 -34
- package/dist/dom.mjs +12 -5
- package/dist/html/assets.d.ts +12 -6
- package/dist/html/attrs.d.ts +1 -0
- package/dist/html/compat.d.ts +10 -2
- package/dist/html/serializer.d.ts +1 -0
- package/dist/html/writer.d.ts +8 -0
- package/dist/html.d.ts +1 -1
- package/dist/html.js +207 -62
- package/dist/html.mjs +207 -62
- package/dist/translator/index.js +432 -213
- package/dist/translator/util/bindings.d.ts +9 -1
- package/dist/translator/util/constants/structure-kind.d.ts +1 -0
- package/dist/translator/util/known-tag.d.ts +2 -1
- package/dist/translator/util/module-read.d.ts +21 -0
- package/dist/translator/util/references.d.ts +1 -0
- package/dist/translator/util/runtime.d.ts +2 -0
- package/dist/translator/util/sections.d.ts +5 -1
- package/dist/translator/util/structure.d.ts +1 -0
- package/package.json +3 -3
- package/tags-html.d.ts +6 -5
package/dist/translator/index.js
CHANGED
|
@@ -156,6 +156,7 @@ var accessor_prop_debug_exports = /* @__PURE__ */ __exportAll({
|
|
|
156
156
|
AbortScopes: () => AbortScopes$1,
|
|
157
157
|
AwaitCounter: () => AwaitCounter$1,
|
|
158
158
|
BranchAccessor: () => BranchAccessor$1,
|
|
159
|
+
BranchRenders: () => BranchRenders$1,
|
|
159
160
|
BranchScopes: () => BranchScopes$2,
|
|
160
161
|
CatchContent: () => CatchContent$1,
|
|
161
162
|
ClosestBranch: () => ClosestBranch$1,
|
|
@@ -189,6 +190,7 @@ const AbortControllers$1 = "#AbortControllers";
|
|
|
189
190
|
const AbortScopes$1 = "#AbortScopes";
|
|
190
191
|
const AwaitCounter$1 = "#AwaitCounter";
|
|
191
192
|
const BranchAccessor$1 = "#BranchAccessor";
|
|
193
|
+
const BranchRenders$1 = "#BranchRenders";
|
|
192
194
|
const BranchScopes$2 = "#BranchScopes";
|
|
193
195
|
const CatchContent$1 = "#CatchContent";
|
|
194
196
|
const ClosestBranch$1 = "#ClosestBranch";
|
|
@@ -797,6 +799,11 @@ function isInvokedFunction(expr) {
|
|
|
797
799
|
return false;
|
|
798
800
|
}
|
|
799
801
|
//#endregion
|
|
802
|
+
//#region src/translator/util/is-static.ts
|
|
803
|
+
function isStatic(path) {
|
|
804
|
+
return path.isImportDeclaration() || path.isExportDeclaration() || path.isMarkoScriptlet({ static: true });
|
|
805
|
+
}
|
|
806
|
+
//#endregion
|
|
800
807
|
//#region src/translator/util/binding-has-prop.ts
|
|
801
808
|
function getSectionRendererIdentifier(section) {
|
|
802
809
|
return isSectionRendererElided(section) ? void 0 : _marko_compiler.types.identifier(section.name);
|
|
@@ -829,6 +836,7 @@ function getPropertyPathAlias(binding, properties) {
|
|
|
829
836
|
const Node = "node";
|
|
830
837
|
const Text = "text";
|
|
831
838
|
const Child = "child";
|
|
839
|
+
const ModuleRead = "moduleRead";
|
|
832
840
|
const SectionRef = "sectionRef";
|
|
833
841
|
const ExportRef = "exportRef";
|
|
834
842
|
//#endregion
|
|
@@ -968,7 +976,7 @@ var function_default = { analyze(fn) {
|
|
|
968
976
|
fnExtra.exprRoot = exprRoot.node.extra ??= {};
|
|
969
977
|
fnExtra.name = node.id?.name || (isMarkoAttribute(markoRoot) ? markoRoot.node.default ? _marko_compiler.types.toIdentifier((markoRoot.parentPath.has("var") ? markoRoot.parentPath.get("var") : markoRoot.parentPath.get("name")).toString()) : markoRoot.node.name : _marko_compiler.types.isVariableDeclarator(fn.parent) && _marko_compiler.types.isIdentifier(fn.parent.id) ? fn.parent.id.name : _marko_compiler.types.isObjectMethod(node) && _marko_compiler.types.isIdentifier(node.key) ? node.key.name : "anonymous");
|
|
970
978
|
reserveExportRegisterId(fnExtra, fn, markoRoot);
|
|
971
|
-
if (
|
|
979
|
+
if (isStatic(markoRoot)) {
|
|
972
980
|
const refs = getStaticDeclRefs(fn);
|
|
973
981
|
if (refs.size) getReferencesByFn().set(fnExtra, refs);
|
|
974
982
|
} else getReferencesByFn().set(fnExtra, /* @__PURE__ */ new Set([fnExtra.exprRoot]));
|
|
@@ -1047,7 +1055,7 @@ function registerImportedFn({ node, ...importedFn }) {
|
|
|
1047
1055
|
(0, _marko_compiler_babel_utils.getProgram)().node.extra.isInteractive = true;
|
|
1048
1056
|
}
|
|
1049
1057
|
function reserveExportRegisterId(fnExtra, fn, markoRoot) {
|
|
1050
|
-
if (!
|
|
1058
|
+
if (!isStatic(markoRoot)) return;
|
|
1051
1059
|
const exportNames = getExportNames(fn, markoRoot);
|
|
1052
1060
|
const exportName = exportNames?.find((name) => _marko_compiler.types.isValidIdentifier(name));
|
|
1053
1061
|
if (!exportName) return;
|
|
@@ -1105,7 +1113,7 @@ function addBindingRefs(binding, refs, seen) {
|
|
|
1105
1113
|
const exprRoot = getExprRoot(ref);
|
|
1106
1114
|
const markoRoot = getMarkoRoot(exprRoot);
|
|
1107
1115
|
if (!markoRoot || canIgnoreRegister(markoRoot, exprRoot)) continue;
|
|
1108
|
-
if (
|
|
1116
|
+
if (isStatic(markoRoot)) getStaticDeclRefs(ref, refs, seen);
|
|
1109
1117
|
else refs.add(exprRoot.node.extra ??= {});
|
|
1110
1118
|
}
|
|
1111
1119
|
}
|
|
@@ -1118,14 +1126,6 @@ function registerFunction(fnExtra) {
|
|
|
1118
1126
|
function isMarkoAttribute(path) {
|
|
1119
1127
|
return path ? path.isMarkoAttribute() : false;
|
|
1120
1128
|
}
|
|
1121
|
-
function isStaticRoot(path) {
|
|
1122
|
-
switch (path.type) {
|
|
1123
|
-
case "MarkoScriptlet": return path.node.static;
|
|
1124
|
-
case "ExportDefaultDeclaration":
|
|
1125
|
-
case "ExportNamedDeclaration": return true;
|
|
1126
|
-
default: return false;
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
1129
|
//#endregion
|
|
1130
1130
|
//#region src/translator/util/cyclic-memo.ts
|
|
1131
1131
|
function createCyclicMemo(compute, cycleAnswer) {
|
|
@@ -1680,6 +1680,7 @@ const pureDOMFunctions = /* @__PURE__ */ new Set([
|
|
|
1680
1680
|
"_const",
|
|
1681
1681
|
"_load_signal",
|
|
1682
1682
|
"_load_setup",
|
|
1683
|
+
"_load_setup_var",
|
|
1683
1684
|
"_load_template",
|
|
1684
1685
|
"_load_visible_trigger",
|
|
1685
1686
|
"_load_event_trigger",
|
|
@@ -1749,7 +1750,8 @@ function getHTMLRuntime() {
|
|
|
1749
1750
|
_attr_class,
|
|
1750
1751
|
_attr_style,
|
|
1751
1752
|
_escape_script,
|
|
1752
|
-
_escape_style
|
|
1753
|
+
_escape_style,
|
|
1754
|
+
escapeDoubleQuotedAttrValue
|
|
1753
1755
|
};
|
|
1754
1756
|
}
|
|
1755
1757
|
function getRuntimePath(output) {
|
|
@@ -1966,6 +1968,7 @@ var accessor_prop_exports = /* @__PURE__ */ __exportAll({
|
|
|
1966
1968
|
AbortScopes: () => "B",
|
|
1967
1969
|
AwaitCounter: () => "O",
|
|
1968
1970
|
BranchAccessor: () => "C",
|
|
1971
|
+
BranchRenders: () => "BR",
|
|
1969
1972
|
BranchScopes: () => "D",
|
|
1970
1973
|
CatchContent: () => "E",
|
|
1971
1974
|
ClosestBranch: () => "F",
|
|
@@ -2224,7 +2227,7 @@ function getOrCreateHtmlLoadWrapped(readyId, originalIdentifier, filename, trigg
|
|
|
2224
2227
|
markoOpts.linkAssets?.onAsset("load", filename, readyId);
|
|
2225
2228
|
const wrappedName = generateUid(`${originalIdentifier.name ?? "tag"}_withLoadAssets`);
|
|
2226
2229
|
loadWrapped.set(readyId, wrappedName);
|
|
2227
|
-
(0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.markoScriptlet([_marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(_marko_compiler.types.identifier(wrappedName), callRuntime("withLoadAssets", originalIdentifier, _marko_compiler.types.stringLiteral(readyId), triggers ? _marko_compiler.types.valueToNode(triggers) : void 0))])], true));
|
|
2230
|
+
(0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.markoScriptlet([_marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(_marko_compiler.types.identifier(wrappedName), callRuntime("withLoadAssets", originalIdentifier, (0, _marko_compiler_babel_utils.importNamed)((0, _marko_compiler_babel_utils.getFile)(), markoOpts.linkAssets.runtime, "flush"), _marko_compiler.types.stringLiteral(readyId), triggers ? _marko_compiler.types.valueToNode(triggers) : void 0))])], true));
|
|
2228
2231
|
return wrappedName;
|
|
2229
2232
|
}
|
|
2230
2233
|
function trackImportedRegisteredFns(importDecl) {
|
|
@@ -2640,8 +2643,16 @@ function normalizeStringExpression(parts, useIife) {
|
|
|
2640
2643
|
if (exprs.length === 1 && !curStr && !strs[0]) return exprs[0];
|
|
2641
2644
|
strs.push(curStr);
|
|
2642
2645
|
if (useIife) {
|
|
2643
|
-
const
|
|
2644
|
-
const
|
|
2646
|
+
const args = [];
|
|
2647
|
+
const params = [];
|
|
2648
|
+
const body = _marko_compiler.types.templateLiteral(strs.map((raw) => _marko_compiler.types.templateElement({ raw: escapeTemplateRaw(raw) })), exprs.map((expr) => {
|
|
2649
|
+
if (expr.type !== "Identifier") return expr;
|
|
2650
|
+
const param = _marko_compiler.types.identifier(`_w${params.length}`);
|
|
2651
|
+
params.push(param);
|
|
2652
|
+
args.push(expr);
|
|
2653
|
+
return param;
|
|
2654
|
+
}));
|
|
2655
|
+
const iife = _marko_compiler.types.callExpression(_marko_compiler.types.arrowFunctionExpression(params, body), args);
|
|
2645
2656
|
_marko_compiler.types.addComment(iife, "leading", "@__PURE__");
|
|
2646
2657
|
return iife;
|
|
2647
2658
|
}
|
|
@@ -2960,8 +2971,8 @@ function getDeclaredBindingExpression(binding, inPlace = false) {
|
|
|
2960
2971
|
if (canonicalBinding.localOf) return getDeclaredBindingExpression(canonicalBinding.localOf, inPlace);
|
|
2961
2972
|
const { aliasOf: aliased, property, declaredAlias } = canonicalBinding;
|
|
2962
2973
|
if (binding.declared) return _marko_compiler.types.identifier(binding.name);
|
|
2963
|
-
if (canonicalBinding.declared || canonicalBinding
|
|
2964
|
-
if (declaredAlias && declaredAlias
|
|
2974
|
+
if (canonicalBinding.declared || isRest(canonicalBinding)) return _marko_compiler.types.identifier(canonicalBinding.name);
|
|
2975
|
+
if (declaredAlias && !isRest(declaredAlias) && !getNearestDeclared(canonicalBinding)) return _marko_compiler.types.identifier(declaredAlias.name);
|
|
2965
2976
|
if (!aliased) return _marko_compiler.types.identifier(canonicalBinding.name);
|
|
2966
2977
|
if (property !== void 0) {
|
|
2967
2978
|
const alias = !getNearestDeclared(aliased) && aliased.declaredAlias;
|
|
@@ -3091,7 +3102,7 @@ function translateVar(tag, initialValue, kind = "const", statements) {
|
|
|
3091
3102
|
if (binding.declared) {
|
|
3092
3103
|
if (binding.section === section) allPruned = false;
|
|
3093
3104
|
else translateAliasInSection(tag, id, binding, kind);
|
|
3094
|
-
} else if (binding
|
|
3105
|
+
} else if (isRest(binding)) translateRest(tag, id, binding, kind);
|
|
3095
3106
|
});
|
|
3096
3107
|
if (allPruned) return;
|
|
3097
3108
|
removeUndeclared(tagVar, section);
|
|
@@ -3108,7 +3119,7 @@ function translateVar(tag, initialValue, kind = "const", statements) {
|
|
|
3108
3119
|
const changeBinding = binding.aliasOf.propertyAliases.get(changeName);
|
|
3109
3120
|
if (changeBinding && changeName !== changeBinding.name) {
|
|
3110
3121
|
const pattern = getDestructurePattern(id);
|
|
3111
|
-
if (pattern) pattern.unshiftContainer("properties", _marko_compiler.types.objectProperty(
|
|
3122
|
+
if (pattern) pattern.unshiftContainer("properties", _marko_compiler.types.objectProperty(toPropertyName(changeName), _marko_compiler.types.identifier(changeBinding.name)));
|
|
3112
3123
|
}
|
|
3113
3124
|
}
|
|
3114
3125
|
});
|
|
@@ -3159,11 +3170,11 @@ function translateRest(tag, id, rest, kind) {
|
|
|
3159
3170
|
}
|
|
3160
3171
|
function getRestPattern(rest, id, from, shorthand) {
|
|
3161
3172
|
const restElement = _marko_compiler.types.restElement(id);
|
|
3162
|
-
if (rest.restOffset) return _marko_compiler.types.arrayPattern([...new Array(rest.restOffset - (from.restOffset || 0)).fill(null), restElement]);
|
|
3173
|
+
if (rest.restOffset !== void 0) return _marko_compiler.types.arrayPattern([...new Array(rest.restOffset - (from.restOffset || 0)).fill(null), restElement]);
|
|
3163
3174
|
return _marko_compiler.types.objectPattern([...toArray(rest.excludeProperties, shorthand ? (name) => name === id.name ? toExcludedProperty(name) : toShorthandExcludedProperty(name) : toExcludedProperty), restElement]);
|
|
3164
3175
|
}
|
|
3165
3176
|
function withRestFallback(rest, from, value) {
|
|
3166
|
-
return from.nullable ? _marko_compiler.types.logicalExpression("||", value, rest.restOffset ? _marko_compiler.types.arrayExpression([]) : _marko_compiler.types.objectExpression([])) : value;
|
|
3177
|
+
return from.nullable ? _marko_compiler.types.logicalExpression("||", value, rest.restOffset !== void 0 ? _marko_compiler.types.arrayExpression([]) : _marko_compiler.types.objectExpression([])) : value;
|
|
3167
3178
|
}
|
|
3168
3179
|
function getSectionTarget(tag, section) {
|
|
3169
3180
|
let target = tag;
|
|
@@ -3376,7 +3387,7 @@ function getSignalFn(signal) {
|
|
|
3376
3387
|
const aliasSignal = getSignal(alias.section, alias);
|
|
3377
3388
|
if (signalHasStatements(aliasSignal)) {
|
|
3378
3389
|
signal.forwards = push(signal.forwards, aliasSignal);
|
|
3379
|
-
if (alias
|
|
3390
|
+
if (isRest(alias)) {
|
|
3380
3391
|
const aliasId = _marko_compiler.types.identifier(alias.name);
|
|
3381
3392
|
signal.render.push(_marko_compiler.types.expressionStatement(_marko_compiler.types.callExpression(aliasSignal.identifier, [
|
|
3382
3393
|
scopeIdentifier,
|
|
@@ -3912,6 +3923,52 @@ function isOnlyChild(tag) {
|
|
|
3912
3923
|
return true;
|
|
3913
3924
|
}
|
|
3914
3925
|
//#endregion
|
|
3926
|
+
//#region src/translator/util/module-read.ts
|
|
3927
|
+
const styleImportReg = /\.(?:css(?:\.[cm]?[jt]s)?|less|s[ac]ss|styl(?:us)?|pcss|postcss)(?:\?|$)/i;
|
|
3928
|
+
const kModuleRead = Symbol("module read");
|
|
3929
|
+
/** The module read an expression is, resolved on first use: translate replaces
|
|
3930
|
+
* a `<style/name>` tag. */
|
|
3931
|
+
function getModuleRead(path, expr) {
|
|
3932
|
+
return ((expr.extra ??= {})[kModuleRead] ??= resolveModuleRead(path, expr)) || void 0;
|
|
3933
|
+
}
|
|
3934
|
+
/** A module read of a stylesheet module, whose reads are class name strings. */
|
|
3935
|
+
function getStyleImportRead(path, expr) {
|
|
3936
|
+
const moduleRead = getModuleRead(path, expr);
|
|
3937
|
+
if (moduleRead && (moduleRead.request === void 0 || styleImportReg.test(moduleRead.request))) return moduleRead.read;
|
|
3938
|
+
}
|
|
3939
|
+
function toModuleReadExpression([name, ...members]) {
|
|
3940
|
+
let expr = _marko_compiler.types.identifier(name);
|
|
3941
|
+
for (const member of members) expr = _marko_compiler.types.memberExpression(expr, _marko_compiler.types.identifier(member));
|
|
3942
|
+
return expr;
|
|
3943
|
+
}
|
|
3944
|
+
function resolveModuleRead(path, expr) {
|
|
3945
|
+
switch (expr.type) {
|
|
3946
|
+
case "Identifier": {
|
|
3947
|
+
const decl = path.scope.getBinding(expr.name)?.path;
|
|
3948
|
+
const importDecl = decl?.parentPath;
|
|
3949
|
+
if (importDecl?.isImportDeclaration()) {
|
|
3950
|
+
const scriptlet = importDecl.parentPath;
|
|
3951
|
+
return scriptlet.isMarkoScriptlet() && scriptlet.node.target ? null : {
|
|
3952
|
+
read: [expr.name],
|
|
3953
|
+
request: importDecl.node.source.value
|
|
3954
|
+
};
|
|
3955
|
+
}
|
|
3956
|
+
return decl && isCoreTagName(decl, "style") && decl.node.var.type === "Identifier" ? {
|
|
3957
|
+
read: [expr.name],
|
|
3958
|
+
request: void 0
|
|
3959
|
+
} : null;
|
|
3960
|
+
}
|
|
3961
|
+
case "MemberExpression": {
|
|
3962
|
+
const object = !expr.computed && getModuleRead(path, expr.object);
|
|
3963
|
+
return object ? {
|
|
3964
|
+
read: [...object.read, expr.property.name],
|
|
3965
|
+
request: object.request
|
|
3966
|
+
} : null;
|
|
3967
|
+
}
|
|
3968
|
+
}
|
|
3969
|
+
return null;
|
|
3970
|
+
}
|
|
3971
|
+
//#endregion
|
|
3915
3972
|
//#region src/translator/util/structure.ts
|
|
3916
3973
|
const walkCodeToName = {
|
|
3917
3974
|
[32]: "get",
|
|
@@ -3958,6 +4015,12 @@ function writeTo(path) {
|
|
|
3958
4015
|
}
|
|
3959
4016
|
};
|
|
3960
4017
|
}
|
|
4018
|
+
function writeModuleReadTo(path, read) {
|
|
4019
|
+
getSection(path).structure?.push({
|
|
4020
|
+
kind: ModuleRead,
|
|
4021
|
+
read
|
|
4022
|
+
});
|
|
4023
|
+
}
|
|
3961
4024
|
function writeTextTo(path, value) {
|
|
3962
4025
|
if (value) getSection(path).structure?.push({
|
|
3963
4026
|
kind: Text,
|
|
@@ -4018,6 +4081,10 @@ function resolveStructure(section) {
|
|
|
4018
4081
|
appendLiteral(resolved.writes, op.value);
|
|
4019
4082
|
textEdge = "own";
|
|
4020
4083
|
break;
|
|
4084
|
+
case ModuleRead:
|
|
4085
|
+
resolved.writes.push(toModuleReadExpression(op.read), "");
|
|
4086
|
+
textEdge = void 0;
|
|
4087
|
+
break;
|
|
4021
4088
|
case Node: {
|
|
4022
4089
|
if (!op.binding) continue;
|
|
4023
4090
|
const withVar = hasScopeOffset(op.binding);
|
|
@@ -4266,11 +4333,6 @@ function assertSetupWorkFound(program, section, written) {
|
|
|
4266
4333
|
if (!section.hasSetupWork && setup && written.has(setup)) throw program.buildCodeFrameError("Marko internal error: analysis found no setup work for a section whose translation produced setup statements. Please open an issue with a reproduction.");
|
|
4267
4334
|
}
|
|
4268
4335
|
//#endregion
|
|
4269
|
-
//#region src/translator/util/is-static.ts
|
|
4270
|
-
function isStatic(path) {
|
|
4271
|
-
return path.isImportDeclaration() || path.isExportDeclaration() || path.isMarkoScriptlet({ static: true });
|
|
4272
|
-
}
|
|
4273
|
-
//#endregion
|
|
4274
4336
|
//#region src/translator/visitors/program/html.ts
|
|
4275
4337
|
function getTemplateContentName() {
|
|
4276
4338
|
return getSharedUid("content");
|
|
@@ -4758,7 +4820,7 @@ var custom_tag_default = {
|
|
|
4758
4820
|
if (childSection === programSection && getOrCreateSection(tag) === programSection) throw tag.get("name").buildCodeFrameError(`A template that renders itself outside a branch never terminates. Render \`<${getStaticTagName(tag.node)}>\` inside a branch that eventually stops, such as \`<if>\`.`);
|
|
4759
4821
|
if (childExtra.page) programExtra.page ??= true;
|
|
4760
4822
|
if (tagExtra.tagNameLoad) tagExtra[kLoadTagBinding] = createBinding("#text", 0, getOrCreateSection(tag));
|
|
4761
|
-
knownTagAnalyze(tag, childSection,
|
|
4823
|
+
knownTagAnalyze(tag, childSection, childExtra.paramsTree);
|
|
4762
4824
|
const tagName = getStaticTagName(tag.node);
|
|
4763
4825
|
if (tagExtra.tagNameLoad) {
|
|
4764
4826
|
marker(tag, tagExtra[kLoadTagBinding]);
|
|
@@ -4804,6 +4866,7 @@ function translateDOM$1(tag) {
|
|
|
4804
4866
|
const isLoad = !!loadConfig;
|
|
4805
4867
|
const tagName = getStaticTagName(node);
|
|
4806
4868
|
if (isLoad) {
|
|
4869
|
+
if (node.var) importRuntimeFeature("dynamic-tag-var");
|
|
4807
4870
|
const childFileName = childFile.opts.filename;
|
|
4808
4871
|
const { triggers, signals, setups } = getLoadIdentifiers();
|
|
4809
4872
|
let triggerIdent = triggers.get(loadConfig);
|
|
@@ -4826,14 +4889,14 @@ function translateDOM$1(tag) {
|
|
|
4826
4889
|
}
|
|
4827
4890
|
return signalIdent;
|
|
4828
4891
|
}, (section, childBinding) => {
|
|
4829
|
-
const setupKey = `${triggerIdent ? triggerIdent.name : ""}\0${childFileName}`;
|
|
4892
|
+
const setupKey = `${triggerIdent ? triggerIdent.name : ""}\0${childFileName}${node.var ? "\0var" : ""}`;
|
|
4830
4893
|
let setupIdent = setups.get(setupKey);
|
|
4831
4894
|
if (!setupIdent) {
|
|
4832
4895
|
setupIdent = generateUidIdentifier(`load_${tagName}_setup`);
|
|
4833
4896
|
setups.set(setupKey, setupIdent);
|
|
4834
4897
|
const setupLoadExpr = _marko_compiler.types.arrowFunctionExpression([], dynamicImport(buildLoadSetupVirtualModule(file, childFileName, childExports)));
|
|
4835
4898
|
importRuntimeFeature("catch");
|
|
4836
|
-
(0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.variableDeclaration("let", [_marko_compiler.types.variableDeclarator(setupIdent, callRuntime("_load_setup", triggerIdent ? _marko_compiler.types.addComment(_marko_compiler.types.callExpression(triggerIdent, [setupLoadExpr]), "leading", "@__PURE__") : setupLoadExpr))]));
|
|
4899
|
+
(0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.variableDeclaration("let", [_marko_compiler.types.variableDeclarator(setupIdent, callRuntime(node.var ? "_load_setup_var" : "_load_setup", triggerIdent ? _marko_compiler.types.addComment(_marko_compiler.types.callExpression(triggerIdent, [setupLoadExpr]), "leading", "@__PURE__") : setupLoadExpr))]));
|
|
4837
4900
|
}
|
|
4838
4901
|
addStatement("render", section, void 0, _marko_compiler.types.expressionStatement(_marko_compiler.types.callExpression(setupIdent, [
|
|
4839
4902
|
scopeIdentifier,
|
|
@@ -5236,6 +5299,7 @@ var program_default = {
|
|
|
5236
5299
|
},
|
|
5237
5300
|
exit(program) {
|
|
5238
5301
|
if (hasAnalyzeErrors()) return;
|
|
5302
|
+
analyzeRecursiveTags();
|
|
5239
5303
|
finalizeReferences();
|
|
5240
5304
|
const programExtra = program.node.extra;
|
|
5241
5305
|
const paramsBinding = programExtra.binding;
|
|
@@ -5786,33 +5850,51 @@ const [getKnownTags] = createSectionState("known tags", () => []);
|
|
|
5786
5850
|
const kContentSection = Symbol("known tag content section");
|
|
5787
5851
|
const kPropTree = Symbol("known tag prop tree");
|
|
5788
5852
|
const kKnownExprs = Symbol("known tag exprs");
|
|
5789
|
-
|
|
5853
|
+
const [getRecursiveTags] = createProgramState(() => []);
|
|
5854
|
+
function knownTagAnalyze(tag, contentSection, childParamsTree) {
|
|
5790
5855
|
analyzeAttributeTags(tag);
|
|
5791
5856
|
const section = getOrCreateSection(tag);
|
|
5792
5857
|
const tagBody = tag.get("body");
|
|
5793
5858
|
const tagExtra = tag.node.extra ??= {};
|
|
5794
|
-
|
|
5795
|
-
const attrExprs = /* @__PURE__ */ new Set([tagExtra]);
|
|
5859
|
+
tagExtra.nodeBinding = createBinding("#childScope", 0, section);
|
|
5796
5860
|
startSection(tagBody);
|
|
5797
5861
|
trackParamsReferences(tagBody, 2);
|
|
5798
5862
|
getKnownTags(section).push(tagExtra);
|
|
5799
5863
|
tagExtra[kContentSection] = contentSection;
|
|
5800
|
-
tagExtra[kPropTree] = propTree;
|
|
5801
|
-
if (contentSection.program === section.program) contentSection.callSections = sectionUtil.add(contentSection.callSections, section);
|
|
5802
5864
|
const varBinding = trackVarReferences(tag, 4);
|
|
5803
|
-
const
|
|
5804
|
-
|
|
5865
|
+
const recursive = isSameOrChildSection(contentSection, section);
|
|
5866
|
+
let exprs;
|
|
5867
|
+
if (contentSection.program === section.program) {
|
|
5868
|
+
contentSection.callSections = sectionUtil.add(contentSection.callSections, section);
|
|
5869
|
+
if (recursive) getRecursiveTags().push(tag);
|
|
5870
|
+
else exprs = analyzeKnownTagParams(tag, getParamsTree(contentSection));
|
|
5871
|
+
} else exprs = analyzeKnownTagParams(tag, childParamsTree);
|
|
5805
5872
|
if (varBinding) {
|
|
5806
5873
|
addSetupExpr(section);
|
|
5807
5874
|
const mutatesTagVar = !!(tag.node.var.type === "Identifier" && tag.scope.getBinding(tag.node.var.name)?.constantViolations.length);
|
|
5808
|
-
const varExpr =
|
|
5875
|
+
const varExpr = recursive || (tagExtra.defineBodySection ? contentSection.returnValueExpr : mapParamReasonToExpr(exprs, getReturnParams(contentSection)));
|
|
5876
|
+
const childScopeBinding = tagExtra.nodeBinding;
|
|
5809
5877
|
varBinding.returnedBy = childScopeBinding;
|
|
5810
5878
|
reserveId(childScopeBinding, 1);
|
|
5811
5879
|
setDerivedFrom(varBinding, varExpr);
|
|
5812
5880
|
if (mutatesTagVar || varExpr === true) addReason(getSlot(childScopeBinding), ALWAYS);
|
|
5813
5881
|
if (varExpr !== true) addReasonExprs(getSlot(childScopeBinding), varExpr);
|
|
5814
5882
|
}
|
|
5815
|
-
|
|
5883
|
+
}
|
|
5884
|
+
function analyzeRecursiveTags() {
|
|
5885
|
+
for (const tag of getRecursiveTags()) analyzeKnownTagParams(tag, getParamsTree(tag.node.extra[kContentSection]));
|
|
5886
|
+
}
|
|
5887
|
+
function getParamsTree(contentSection) {
|
|
5888
|
+
return contentSection.params && getBindingPropTree(contentSection.params, true);
|
|
5889
|
+
}
|
|
5890
|
+
function analyzeKnownTagParams(tag, propTree) {
|
|
5891
|
+
const tagExtra = tag.node.extra;
|
|
5892
|
+
const attrExprs = /* @__PURE__ */ new Set([tagExtra]);
|
|
5893
|
+
tagExtra[kPropTree] = propTree;
|
|
5894
|
+
const exprs = tagExtra[kKnownExprs] = analyzeParams(tagExtra, getSection(tag), tag, propTree, attrExprs);
|
|
5895
|
+
setTagDerivedFrom(tag, propTree?.props?.[0]?.binding, exprs);
|
|
5896
|
+
addReasonExprs(getSlot(tagExtra.nodeBinding), fromIter(attrExprs));
|
|
5897
|
+
return exprs;
|
|
5816
5898
|
}
|
|
5817
5899
|
function getReturnParams(section) {
|
|
5818
5900
|
const sources = section.returnValueExpr && getSourcesForExpr(section.returnValueExpr);
|
|
@@ -6609,19 +6691,23 @@ function addValueReferences(refs, expr) {
|
|
|
6609
6691
|
return isReferencedExtra(getCanonicalExtra(expr)) && !expr.initialValue ? bindingUtil.union(refs, getReferencedBindings(expr)) : refs;
|
|
6610
6692
|
}
|
|
6611
6693
|
function getWalkedBinding(op) {
|
|
6612
|
-
return typeof op === "object" && op.kind
|
|
6694
|
+
return typeof op === "object" && (op.kind === "node" || op.kind === "child") ? op.binding : void 0;
|
|
6613
6695
|
}
|
|
6614
6696
|
function getLastOwnSourceReturn(intersection, section) {
|
|
6615
|
-
let
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6697
|
+
let last;
|
|
6698
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6699
|
+
const track = (binding) => {
|
|
6700
|
+
if (binding.section === section && !seen.has(binding)) {
|
|
6701
|
+
seen.add(binding);
|
|
6702
|
+
const { returnedBy } = getAliasRoot(binding) || binding;
|
|
6703
|
+
if (returnedBy && (!last || last.id < returnedBy.id)) last = returnedBy;
|
|
6704
|
+
if (binding.derivedFrom) forEach(getValueReferences(binding.derivedFrom), track);
|
|
6705
|
+
forEach(binding.sources?.state, track);
|
|
6706
|
+
forEach(binding.sources?.param, track);
|
|
6707
|
+
}
|
|
6708
|
+
};
|
|
6709
|
+
forEach(intersection, track);
|
|
6710
|
+
return last;
|
|
6625
6711
|
}
|
|
6626
6712
|
function getIntersectionSource(intersection, section, resolved) {
|
|
6627
6713
|
if (!resolved.has(intersection)) {
|
|
@@ -6665,11 +6751,6 @@ function resolveBindingSources(binding) {
|
|
|
6665
6751
|
binding.sources = globalSources;
|
|
6666
6752
|
return;
|
|
6667
6753
|
}
|
|
6668
|
-
if (binding.localOf) {
|
|
6669
|
-
resolveBindingSources(binding.localOf);
|
|
6670
|
-
binding.sources = binding.localOf.sources;
|
|
6671
|
-
return;
|
|
6672
|
-
}
|
|
6673
6754
|
const aliasRoot = getAliasRoot(binding);
|
|
6674
6755
|
if (aliasRoot) {
|
|
6675
6756
|
if (!resolvedSources.has(aliasRoot)) {
|
|
@@ -6715,18 +6796,20 @@ function pruneBinding(binding) {
|
|
|
6715
6796
|
binding.pruned = false;
|
|
6716
6797
|
for (const read of binding.reads.keys()) if (isDroppableValue(read)) forEach(read.derives, pruneBinding);
|
|
6717
6798
|
forEach(binding.assignments, pruneWriter);
|
|
6799
|
+
const assignedObject = getAssignedObject(binding);
|
|
6718
6800
|
for (const [expr, reads] of binding.reads) {
|
|
6719
|
-
const owner = getReadOwner(binding.aliasOf, expr);
|
|
6801
|
+
const owner = assignedObject ? getReadOwner(assignedObject, expr) || assignedObject : getReadOwner(binding.aliasOf, expr);
|
|
6720
6802
|
if (owner) {
|
|
6721
6803
|
owner.reads.set(expr, concat(owner.reads.get(expr), reads));
|
|
6722
6804
|
binding.reads.delete(expr);
|
|
6723
6805
|
}
|
|
6724
6806
|
}
|
|
6725
|
-
let shouldPrune =
|
|
6807
|
+
let shouldPrune = true;
|
|
6726
6808
|
for (const alias of binding.aliases) if (pruneBinding(alias)) binding.aliases.delete(alias);
|
|
6727
6809
|
else if (alias.type !== 5) shouldPrune = false;
|
|
6728
6810
|
for (const [key, alias] of binding.propertyAliases) if (pruneBinding(alias)) binding.propertyAliases.delete(key);
|
|
6729
6811
|
else if (alias.type !== 5) shouldPrune = false;
|
|
6812
|
+
shouldPrune &&= !binding.reads.size && !(binding.reserveSize && some(binding.assignments, inEmittedExpr));
|
|
6730
6813
|
binding.pruned = shouldPrune;
|
|
6731
6814
|
if (shouldPrune && !hasEmittedAssignment(binding)) {
|
|
6732
6815
|
if (binding.derivedFrom) forEach(binding.derivedFrom, dropUnreadValue);
|
|
@@ -7441,7 +7524,7 @@ function getOrCreateLocalClosure(local, section) {
|
|
|
7441
7524
|
while (section.parent !== local.section) section = section.parent;
|
|
7442
7525
|
let closure = local.localClosures?.get(section);
|
|
7443
7526
|
if (!closure) {
|
|
7444
|
-
closure = createBinding(local.name,
|
|
7527
|
+
closure = createBinding(local.name, 2, section, void 0, void 0, void 0, local.loc);
|
|
7445
7528
|
closure.localOf = local;
|
|
7446
7529
|
(local.localClosures ??= /* @__PURE__ */ new Map()).set(section, closure);
|
|
7447
7530
|
}
|
|
@@ -7462,6 +7545,7 @@ function trackDomVarReferences(tag, binding) {
|
|
|
7462
7545
|
binding.originalName = tagVar.name;
|
|
7463
7546
|
if (babelBinding.constantViolations.length) for (const ref of babelBinding.constantViolations) throw ref.type === "MarkoTag" ? ref.get("var").buildCodeFrameError(`Duplicate declaration of \`${binding.originalName}\`.`) : ref.buildCodeFrameError(`\`${binding.originalName}\` is a [tag variable](https://markojs.com/docs/reference/language#tag-variables) on a native element (an element reference) and cannot be assigned to.`);
|
|
7464
7547
|
for (const ref of babelBinding.referencePaths) {
|
|
7548
|
+
assertReferencedInRender(ref, tagVar.name);
|
|
7465
7549
|
const refSection = getOrCreateSection(ref);
|
|
7466
7550
|
const invoked = isInvokedFunction(ref);
|
|
7467
7551
|
const hoisted = isReferenceHoisted(babelBinding.path, ref) ? getCommonSection(refSection, binding.section) : false;
|
|
@@ -7485,7 +7569,7 @@ function trackVarReferences(tag, type, aliased) {
|
|
|
7485
7569
|
let target = aliased && getCanonicalBinding(aliased);
|
|
7486
7570
|
if (target) {
|
|
7487
7571
|
const { excludeProperties, restOffset } = target;
|
|
7488
|
-
if (
|
|
7572
|
+
if (isRest(target)) target = target.aliasOf;
|
|
7489
7573
|
createBindingsAndTrackReferences(tagVar, target.type, tag.scope, section, target, void 0, excludeProperties, restOffset, false);
|
|
7490
7574
|
return target;
|
|
7491
7575
|
}
|
|
@@ -7503,6 +7587,7 @@ function trackParamsReferences(body, type) {
|
|
|
7503
7587
|
if (bodySection) bodySection.params = paramsBinding;
|
|
7504
7588
|
for (let i = 0; i < params.length; i++) {
|
|
7505
7589
|
const param = params[i];
|
|
7590
|
+
if (param.type === "RestElement") assertRestNotAssigned(body.scope, param.argument);
|
|
7506
7591
|
if (i === 0 && param.type === "RestElement" && param.argument.type === "Identifier") {
|
|
7507
7592
|
const { argument } = param;
|
|
7508
7593
|
paramsBinding.name = argument.name;
|
|
@@ -7544,9 +7629,10 @@ function isReferenceHoisted(bindingPath, reference) {
|
|
|
7544
7629
|
function trackReferencesForBinding(babelBinding, binding) {
|
|
7545
7630
|
const { referencePaths, constantViolations } = babelBinding;
|
|
7546
7631
|
for (const ref of referencePaths) {
|
|
7547
|
-
const refSection = getOrCreateSection(ref);
|
|
7548
7632
|
const markoRoot = getMarkoRoot(ref);
|
|
7549
|
-
|
|
7633
|
+
assertReferencedInRender(ref, ref.node.name, markoRoot);
|
|
7634
|
+
const refSection = getOrCreateSection(ref);
|
|
7635
|
+
if (!binding.declared && !isRest(binding)) {
|
|
7550
7636
|
const root = getNearestDeclared(binding);
|
|
7551
7637
|
binding.declared = !!root && ref.scope.getBinding(root.name) !== babelBinding.scope.getBinding(root.name);
|
|
7552
7638
|
}
|
|
@@ -7573,6 +7659,7 @@ function trackReferencesForBinding(babelBinding, binding) {
|
|
|
7573
7659
|
}
|
|
7574
7660
|
for (const ref of constantViolations) {
|
|
7575
7661
|
if (ref.type === "MarkoTag") throw ref.get("var").buildCodeFrameError(`Duplicate declaration of \`${binding.name}\`.`);
|
|
7662
|
+
assertReferencedInRender(ref, binding.name);
|
|
7576
7663
|
if (isReferenceHoisted(babelBinding.path, ref)) throw ref.buildCodeFrameError(`\`${binding.name}\` is declared by a tag below this assignment; a [tag variable](https://markojs.com/docs/reference/language#tag-variables) can only be assigned below its declaration. Move the declaring tag above this code.`);
|
|
7577
7664
|
if (ref.isUpdateExpression()) trackAssignment(ref.get("argument"), binding);
|
|
7578
7665
|
else if (ref.isAssignmentExpression()) {
|
|
@@ -7588,6 +7675,8 @@ function trackAssignment(assignment, binding) {
|
|
|
7588
7675
|
const fnParent = getFnParent(assignment);
|
|
7589
7676
|
if (!fnParent) throw assignment.buildCodeFrameError(`\`${binding.name}\` is a tag ${binding.type === 2 ? "parameter" : "variable"} and can only be assigned within a script or function.`);
|
|
7590
7677
|
if (binding.type === 3) throw assignment.buildCodeFrameError(`\`${binding.name}\` is a tag parameter and cannot be assigned to.`);
|
|
7678
|
+
let assigned = binding;
|
|
7679
|
+
while (isDirectAlias(assigned)) assigned = assigned.aliasOf;
|
|
7591
7680
|
const fnRoot = getFnRoot(fnParent);
|
|
7592
7681
|
const fnExtra = fnRoot && (fnRoot.node.extra ??= {});
|
|
7593
7682
|
const section = getOrCreateSection(assignment);
|
|
@@ -7595,7 +7684,7 @@ function trackAssignment(assignment, binding) {
|
|
|
7595
7684
|
forEachIdentifierPath(assignment, (id) => {
|
|
7596
7685
|
if (id.node.name === binding.name) {
|
|
7597
7686
|
const idExtra = id.node.extra ??= {};
|
|
7598
|
-
idExtra.assignment =
|
|
7687
|
+
idExtra.assignment = assigned;
|
|
7599
7688
|
idExtra.section = section;
|
|
7600
7689
|
idExtra.exprRoot = getExprRoot(fnRoot || assignment).node.extra ??= {};
|
|
7601
7690
|
idExtra.fnRoot = fnExtra;
|
|
@@ -7604,16 +7693,19 @@ function trackAssignment(assignment, binding) {
|
|
|
7604
7693
|
fnExtra.section = section;
|
|
7605
7694
|
fnExtra.exprRoot = idExtra.exprRoot;
|
|
7606
7695
|
}
|
|
7607
|
-
if (
|
|
7608
|
-
if (
|
|
7609
|
-
const changePropName =
|
|
7610
|
-
const changeBinding =
|
|
7696
|
+
if (assigned.aliasOf && assigned.property !== void 0) {
|
|
7697
|
+
if (assigned.aliasOf === assigned.section.params) throw assignment.buildCodeFrameError(`\`${binding.name}\` is a tag parameter and cannot be assigned to.`);
|
|
7698
|
+
const changePropName = assigned.property + "Change";
|
|
7699
|
+
const changeBinding = assigned.aliasOf.propertyAliases.get(changePropName) || createBinding(generateUid(changePropName), assigned.type, assigned.section, assigned.aliasOf, changePropName, void 0, id.node.loc, assigned.declared);
|
|
7611
7700
|
idExtra.assignmentTo = changeBinding;
|
|
7612
7701
|
addReadToExpression(id, changeBinding, void 0);
|
|
7613
7702
|
}
|
|
7614
7703
|
}
|
|
7615
7704
|
});
|
|
7616
7705
|
}
|
|
7706
|
+
function assertReferencedInRender(ref, name, markoRoot = getMarkoRoot(ref)) {
|
|
7707
|
+
if (markoRoot && isStatic(markoRoot)) throw ref.buildCodeFrameError(`\`${name}\` exists only while the template renders, so module level code ([\`static\`, \`server\` and \`client\`](https://markojs.com/docs/reference/language#static) and [\`export\`](https://markojs.com/docs/reference/language#export) statements), which runs once as the template loads, cannot reference it. Reference it in the template instead, passing it to module level functions as an argument.`);
|
|
7708
|
+
}
|
|
7617
7709
|
function setReferencesScope(path) {
|
|
7618
7710
|
const fnRoot = getFnRoot(path);
|
|
7619
7711
|
if (fnRoot) (fnRoot.node.extra ??= {}).referencesScope = true;
|
|
@@ -7628,8 +7720,7 @@ function createBindingsAndTrackReferences(lVal, type, scope, section, aliased, p
|
|
|
7628
7720
|
createBindingsAndTrackReferences(lVal.left, type, scope, section, aliased, property, excludeProperties, restOffset, declared);
|
|
7629
7721
|
break;
|
|
7630
7722
|
case "Identifier": {
|
|
7631
|
-
const binding = (lVal.extra ??= {}).binding = createBinding(lVal.name, type, section, aliased, property, excludeProperties, lVal.loc, declared);
|
|
7632
|
-
if (restOffset) binding.restOffset = restOffset;
|
|
7723
|
+
const binding = (lVal.extra ??= {}).binding = createBinding(lVal.name, type, section, aliased, property, excludeProperties, lVal.loc, declared, restOffset);
|
|
7633
7724
|
trackReferencesForBinding(scope.getBinding(lVal.name), binding);
|
|
7634
7725
|
break;
|
|
7635
7726
|
}
|
|
@@ -7639,8 +7730,10 @@ function createBindingsAndTrackReferences(lVal, type, scope, section, aliased, p
|
|
|
7639
7730
|
const { properties } = lVal;
|
|
7640
7731
|
const hasRest = properties.length > 0 && properties[properties.length - 1].type === "RestElement";
|
|
7641
7732
|
const declaresPattern = declared || hasRest;
|
|
7642
|
-
for (const prop of lVal.properties) if (prop.type === "RestElement")
|
|
7643
|
-
|
|
7733
|
+
for (const prop of lVal.properties) if (prop.type === "RestElement") {
|
|
7734
|
+
assertRestNotAssigned(scope, prop.argument);
|
|
7735
|
+
createBindingsAndTrackReferences(prop.argument, type, scope, section, patternBinding, void 0, excludeProperties, void 0, declaresPattern);
|
|
7736
|
+
} else {
|
|
7644
7737
|
let key;
|
|
7645
7738
|
if (!prop.computed && prop.key.type === "Identifier") key = prop.key.name;
|
|
7646
7739
|
else if (prop.key.type === "StringLiteral") key = prop.key.value;
|
|
@@ -7660,6 +7753,7 @@ function createBindingsAndTrackReferences(lVal, type, scope, section, aliased, p
|
|
|
7660
7753
|
index++;
|
|
7661
7754
|
if (element) {
|
|
7662
7755
|
if (element.type === "RestElement") {
|
|
7756
|
+
assertRestNotAssigned(scope, element.argument);
|
|
7663
7757
|
excludeProperties = index > 0 ? addNumericPropertiesUntil(excludeProperties, index) : void 0;
|
|
7664
7758
|
createBindingsAndTrackReferences(element.argument, type, scope, section, patternBinding, void 0, excludeProperties, index, declaresPattern);
|
|
7665
7759
|
} else if (_marko_compiler.types.isLVal(element)) {
|
|
@@ -7678,16 +7772,29 @@ function createBindingsAndTrackReferences(lVal, type, scope, section, aliased, p
|
|
|
7678
7772
|
function isAssignment(ref) {
|
|
7679
7773
|
return ref.type !== "MarkoTag";
|
|
7680
7774
|
}
|
|
7775
|
+
function assertRestNotAssigned(scope, rest) {
|
|
7776
|
+
if (rest.type === "Identifier") {
|
|
7777
|
+
const assignment = scope.getBinding(rest.name).constantViolations.find(isAssignment);
|
|
7778
|
+
if (assignment) throw assignment.buildCodeFrameError(`\`${rest.name}\` is a rest element, which has no [change handler](https://markojs.com/docs/reference/language#shorthand-change-handlers-two-way-binding) to receive a new value, so it cannot be assigned to. Assign the properties of the value it is destructured from instead.`);
|
|
7779
|
+
}
|
|
7780
|
+
}
|
|
7681
7781
|
function trackReference(referencePath, binding) {
|
|
7682
7782
|
let root = referencePath;
|
|
7683
7783
|
let reference = binding;
|
|
7684
7784
|
while (true) {
|
|
7685
7785
|
const { parent } = root;
|
|
7686
|
-
if (!_marko_compiler.types.isMemberExpression(parent) && !_marko_compiler.types.isOptionalMemberExpression(parent)
|
|
7786
|
+
if (!_marko_compiler.types.isMemberExpression(parent) && !_marko_compiler.types.isOptionalMemberExpression(parent)) break;
|
|
7687
7787
|
let prop = getMemberExpressionPropString(parent);
|
|
7788
|
+
if (isAssignedMember(root.parentPath)) {
|
|
7789
|
+
let object = reference;
|
|
7790
|
+
while (isDirectAlias(object)) object = object.aliasOf;
|
|
7791
|
+
if (isRest(object)) throw root.parentPath.buildCodeFrameError(`\`${referencePath.node.name}\` is a rest element, a copy rebuilt from the value it is destructured from whenever that changes, so assigning its members would be lost. Assign the property on that value instead, or keep your own copy in a \`<let>\`.`);
|
|
7792
|
+
addAssignedProperty(object, prop);
|
|
7793
|
+
break;
|
|
7794
|
+
}
|
|
7688
7795
|
if (prop === void 0) break;
|
|
7689
|
-
if (reference.aliasOf && reference
|
|
7690
|
-
if (reference.restOffset) {
|
|
7796
|
+
if (reference.aliasOf && isRest(reference)) {
|
|
7797
|
+
if (reference.restOffset !== void 0) {
|
|
7691
7798
|
if (isIndexProperty(prop)) {
|
|
7692
7799
|
prop = `${+prop + reference.restOffset}`;
|
|
7693
7800
|
reference = reference.aliasOf;
|
|
@@ -7702,7 +7809,7 @@ function trackReference(referencePath, binding) {
|
|
|
7702
7809
|
(referencePath.node.extra ??= {}).binding = binding;
|
|
7703
7810
|
addReadToExpression(root, reference, void 0);
|
|
7704
7811
|
}
|
|
7705
|
-
function
|
|
7812
|
+
function isAssignedMember(member) {
|
|
7706
7813
|
const { node, parent } = member;
|
|
7707
7814
|
switch (parent.type) {
|
|
7708
7815
|
case "AssignmentExpression":
|
|
@@ -7830,7 +7937,9 @@ function untrackExtra(exprExtra) {
|
|
|
7830
7937
|
if (reads) {
|
|
7831
7938
|
readsByExpr.delete(exprExtra);
|
|
7832
7939
|
getFunctionReadsByExpression().delete(exprExtra);
|
|
7833
|
-
forEach(reads, (read) =>
|
|
7940
|
+
forEach(reads, (read) => {
|
|
7941
|
+
for (let cur = read.binding; cur; cur = cur.aliasOf) cur.reads.delete(exprExtra);
|
|
7942
|
+
});
|
|
7834
7943
|
}
|
|
7835
7944
|
}
|
|
7836
7945
|
function dropContent(body) {
|
|
@@ -7990,7 +8099,7 @@ function getKnownExprsAt(exprs, binding) {
|
|
|
7990
8099
|
//#region src/translator/util/bindings.ts
|
|
7991
8100
|
const [getBindings] = createProgramState(() => /* @__PURE__ */ new Set());
|
|
7992
8101
|
const [getNextBindingId, setNextBindingId] = createProgramState(() => 0);
|
|
7993
|
-
function createBinding(name, type, refSection, aliased, property, excludeProperties, loc = null, refDeclared = false) {
|
|
8102
|
+
function createBinding(name, type, refSection, aliased, property, excludeProperties, loc = null, refDeclared = false, restOffset) {
|
|
7994
8103
|
const id = getNextBindingId();
|
|
7995
8104
|
const section = aliased ? aliased.section : refSection;
|
|
7996
8105
|
const sameSection = refSection === section;
|
|
@@ -8009,6 +8118,7 @@ function createBinding(name, type, refSection, aliased, property, excludePropert
|
|
|
8009
8118
|
closureId: void 0,
|
|
8010
8119
|
assignments: void 0,
|
|
8011
8120
|
excludeProperties,
|
|
8121
|
+
assignedProperties: void 0,
|
|
8012
8122
|
sources: void 0,
|
|
8013
8123
|
intersection: void 0,
|
|
8014
8124
|
derivedFrom: void 0,
|
|
@@ -8022,11 +8132,11 @@ function createBinding(name, type, refSection, aliased, property, excludePropert
|
|
|
8022
8132
|
declaredAlias: void 0,
|
|
8023
8133
|
localOf: void 0,
|
|
8024
8134
|
localClosures: void 0,
|
|
8025
|
-
restOffset
|
|
8135
|
+
restOffset,
|
|
8026
8136
|
returnedBy: void 0,
|
|
8027
8137
|
reserveSize: 0,
|
|
8028
8138
|
scopeAccessor: void 0,
|
|
8029
|
-
nullable: !sameSection || excludeProperties === void 0,
|
|
8139
|
+
nullable: !sameSection || excludeProperties === void 0 && restOffset === void 0,
|
|
8030
8140
|
pruned: void 0,
|
|
8031
8141
|
exposed: false,
|
|
8032
8142
|
hasLazyReads: false
|
|
@@ -8053,6 +8163,18 @@ function getOrCreatePropertyAlias(binding, property) {
|
|
|
8053
8163
|
while (isDirectAlias(binding)) binding = binding.aliasOf;
|
|
8054
8164
|
return binding.propertyAliases.get(property) || createBinding(`${binding.name}_${property.replace(/[^a-zA-Z0-9_$]/g, "_")}`, binding.type, binding.section, binding, property);
|
|
8055
8165
|
}
|
|
8166
|
+
function addAssignedProperty(binding, property) {
|
|
8167
|
+
if (binding.assignedProperties !== true) binding.assignedProperties = property === void 0 || propsUtil.add(binding.assignedProperties, property);
|
|
8168
|
+
}
|
|
8169
|
+
function getAssignedObject(binding) {
|
|
8170
|
+
let object;
|
|
8171
|
+
for (let alias = binding; alias.aliasOf && !isRest(alias); alias = alias.aliasOf) if (alias.property !== void 0) {
|
|
8172
|
+
let parent = alias.aliasOf;
|
|
8173
|
+
while (isDirectAlias(parent)) parent = parent.aliasOf;
|
|
8174
|
+
if (parent.assignedProperties === true || propsUtil.has(parent.assignedProperties, alias.property)) object = alias.aliasOf;
|
|
8175
|
+
}
|
|
8176
|
+
return object;
|
|
8177
|
+
}
|
|
8056
8178
|
function getPropertyAlias(binding, properties) {
|
|
8057
8179
|
return reduce(properties, getExistingPropertyAlias, binding);
|
|
8058
8180
|
}
|
|
@@ -8111,12 +8233,15 @@ function getNearestDeclared(binding) {
|
|
|
8111
8233
|
for (let cur = binding; cur; cur = cur.aliasOf) if (cur.declared) return cur;
|
|
8112
8234
|
}
|
|
8113
8235
|
function isDirectAlias(binding) {
|
|
8114
|
-
return binding.aliasOf !== void 0 && binding.property === void 0 && binding
|
|
8236
|
+
return binding.aliasOf !== void 0 && binding.property === void 0 && !isRest(binding);
|
|
8237
|
+
}
|
|
8238
|
+
function isRest(binding) {
|
|
8239
|
+
return binding.excludeProperties !== void 0 || binding.restOffset !== void 0;
|
|
8115
8240
|
}
|
|
8116
8241
|
function getDebugScopeAccess(binding) {
|
|
8117
8242
|
let root = binding;
|
|
8118
8243
|
let access = "";
|
|
8119
|
-
while (!(root.loc || root.declared) && root.aliasOf && root
|
|
8244
|
+
while (!(root.loc || root.declared) && root.aliasOf && !isRest(root)) {
|
|
8120
8245
|
if (root.property !== void 0) access = toAccess(root.property) + access;
|
|
8121
8246
|
root = root.aliasOf;
|
|
8122
8247
|
}
|
|
@@ -8132,7 +8257,7 @@ function getDebugName(binding) {
|
|
|
8132
8257
|
if (isTemplateParam(binding)) {
|
|
8133
8258
|
let root = binding;
|
|
8134
8259
|
let access = "";
|
|
8135
|
-
while (root.aliasOf !== root.section.params && root
|
|
8260
|
+
while (root.aliasOf !== root.section.params && !isRest(root)) {
|
|
8136
8261
|
if (root.property !== void 0) access = toAccess(root.property) + access;
|
|
8137
8262
|
root = root.aliasOf;
|
|
8138
8263
|
}
|
|
@@ -8150,11 +8275,11 @@ function getDebugNamesAsIdentifier(refs) {
|
|
|
8150
8275
|
function getDebugNameAsIdentifier(binding) {
|
|
8151
8276
|
let root = binding;
|
|
8152
8277
|
let access = "";
|
|
8153
|
-
if (isTemplateParam(binding)) while (root.aliasOf !== root.section.params && root
|
|
8278
|
+
if (isTemplateParam(binding)) while (root.aliasOf !== root.section.params && !isRest(root)) {
|
|
8154
8279
|
if (root.property !== void 0) access = `_${root.property.replace(/[^a-z0-9_$]/gi, "_") + access}`;
|
|
8155
8280
|
root = root.aliasOf;
|
|
8156
8281
|
}
|
|
8157
|
-
else while (!(root.loc || root.declared) && root.aliasOf && root
|
|
8282
|
+
else while (!(root.loc || root.declared) && root.aliasOf && !isRest(root)) {
|
|
8158
8283
|
if (root.property !== void 0) access = `_${root.property.replace(/[^a-z0-9_$]/gi, "_") + access}`;
|
|
8159
8284
|
root = root.aliasOf;
|
|
8160
8285
|
}
|
|
@@ -8164,7 +8289,7 @@ function isInvokeOnlyBinding(binding) {
|
|
|
8164
8289
|
return !someAlias(binding, isReadBeyondInvoking, void 0);
|
|
8165
8290
|
}
|
|
8166
8291
|
function isReadBeyondInvoking(binding) {
|
|
8167
|
-
if (binding.assignments || binding.hoists || binding.getters.size || binding.propertyAliases.size || binding
|
|
8292
|
+
if (binding.assignments || binding.hoists || binding.getters.size || binding.propertyAliases.size || isRest(binding)) return true;
|
|
8168
8293
|
for (const expr of binding.reads.keys()) if (!expr.invokeOnly) return true;
|
|
8169
8294
|
return false;
|
|
8170
8295
|
}
|
|
@@ -9878,9 +10003,11 @@ var referenced_identifier_default = {
|
|
|
9878
10003
|
const { name } = identifier.node;
|
|
9879
10004
|
if (identifier.scope.hasBinding(name)) return;
|
|
9880
10005
|
if (name === "$global") {
|
|
10006
|
+
assertReferencedInRender(identifier, name);
|
|
9881
10007
|
setReferencesScope(identifier);
|
|
9882
10008
|
trackGlobalReference(identifier);
|
|
9883
10009
|
} else if (name === "$signal") {
|
|
10010
|
+
assertReferencedInRender(identifier, name);
|
|
9884
10011
|
const section = getOrCreateSection(identifier);
|
|
9885
10012
|
section.hasAbortSignal = true;
|
|
9886
10013
|
setReferencesScope(identifier);
|
|
@@ -10063,7 +10190,7 @@ var native_tag_default = {
|
|
|
10063
10190
|
} else {
|
|
10064
10191
|
assertValidNativeEventHandlerAttr(tag, attr);
|
|
10065
10192
|
if (isChangeHandlerAttr) valueExtra.retained = true;
|
|
10066
|
-
if (!evaluate(attr.value).confident) {
|
|
10193
|
+
if (!isStaticDelimitedAttr(tag, attr) && !evaluate(attr.value).confident) {
|
|
10067
10194
|
hasDynamicAttributes = true;
|
|
10068
10195
|
addSetupExpr(tagSection, attr.value);
|
|
10069
10196
|
} else if (attr.name === "content" && tagName !== "meta") addSetupExpr(tagSection, attr.value);
|
|
@@ -10137,13 +10264,21 @@ var native_tag_default = {
|
|
|
10137
10264
|
const { confident, computed } = evaluate(value);
|
|
10138
10265
|
if (confident) write`${getStaticAttrMarkup(name, computed)}`;
|
|
10139
10266
|
else if (name === "class" || name === "style") {
|
|
10140
|
-
const meta =
|
|
10141
|
-
|
|
10142
|
-
|
|
10143
|
-
|
|
10144
|
-
|
|
10145
|
-
|
|
10146
|
-
|
|
10267
|
+
const meta = trackDelimitedAttrValue(tag, name, value);
|
|
10268
|
+
const { staticParts } = meta;
|
|
10269
|
+
if (getDelimitedAttrItems(name, meta) && staticParts.length) {
|
|
10270
|
+
if (staticParts.every(isLiteralPart)) write`${getStaticAttrMarkup(name, staticParts)}`;
|
|
10271
|
+
else {
|
|
10272
|
+
write` class="`;
|
|
10273
|
+
for (let i = 0; i < staticParts.length; i++) {
|
|
10274
|
+
const part = staticParts[i];
|
|
10275
|
+
if (i) write` `;
|
|
10276
|
+
if (isLiteralPart(part)) write`${getHTMLRuntime().escapeDoubleQuotedAttrValue(part)}`;
|
|
10277
|
+
else writeModuleReadTo(tag, part);
|
|
10278
|
+
}
|
|
10279
|
+
write`"`;
|
|
10280
|
+
}
|
|
10281
|
+
}
|
|
10147
10282
|
}
|
|
10148
10283
|
}
|
|
10149
10284
|
write`>`;
|
|
@@ -10245,7 +10380,7 @@ var native_tag_default = {
|
|
|
10245
10380
|
write`${callRuntime("_attr_option_value", value)}`;
|
|
10246
10381
|
continue;
|
|
10247
10382
|
}
|
|
10248
|
-
write`${confident ? getStaticAttrMarkup(name, computed) : factorAttrConditional(buildAttrExpression(name, value))}`;
|
|
10383
|
+
write`${confident ? getStaticAttrMarkup(name, computed) : factorAttrConditional(buildAttrExpression(tag, name, value))}`;
|
|
10249
10384
|
}
|
|
10250
10385
|
if (handlers) for (const index of handlers) addHTMLEffectCall(tagSection, getReferencedBindings(attributes[index].value.extra));
|
|
10251
10386
|
const isOpenOnly = !!(tagDef && tagDef.parseOptions?.openTagOnly);
|
|
@@ -10332,37 +10467,27 @@ var native_tag_default = {
|
|
|
10332
10467
|
const valueReferences = getReferencedBindings(value.extra);
|
|
10333
10468
|
switch (name) {
|
|
10334
10469
|
case "class":
|
|
10335
|
-
case "style":
|
|
10336
|
-
const helper = `_attr_${name}`;
|
|
10470
|
+
case "style":
|
|
10337
10471
|
if (!confident) {
|
|
10338
|
-
const
|
|
10339
|
-
const
|
|
10340
|
-
|
|
10341
|
-
|
|
10342
|
-
|
|
10343
|
-
};
|
|
10344
|
-
|
|
10345
|
-
|
|
10346
|
-
|
|
10347
|
-
|
|
10348
|
-
|
|
10349
|
-
|
|
10350
|
-
|
|
10351
|
-
|
|
10352
|
-
|
|
10353
|
-
} else {
|
|
10354
|
-
const props = [];
|
|
10355
|
-
for (const key of keys) {
|
|
10356
|
-
const value = meta.dynamicValues[key];
|
|
10357
|
-
props.push(_marko_compiler.types.objectProperty(toPropertyName(key), value));
|
|
10358
|
-
}
|
|
10359
|
-
stmt = _marko_compiler.types.expressionStatement(callRuntime(`_attr_${name}_items`, nodeExpr, _marko_compiler.types.objectExpression(props)));
|
|
10360
|
-
}
|
|
10472
|
+
const meta = trackDelimitedAttrValue(tag, name, value);
|
|
10473
|
+
const items = getDelimitedAttrItems(name, meta);
|
|
10474
|
+
const calls = [];
|
|
10475
|
+
const assert = buildClassTogglesAssert(meta);
|
|
10476
|
+
if (assert) calls.push(assert);
|
|
10477
|
+
if (!items) calls.push(callRuntime(`_attr_${name}`, createScopeReadExpression(nodeBinding), value));
|
|
10478
|
+
else {
|
|
10479
|
+
const single = [];
|
|
10480
|
+
for (const { key, value } of items) if (isLiteralPart(key) && !/\s/.test(key)) single.push({
|
|
10481
|
+
key,
|
|
10482
|
+
value
|
|
10483
|
+
});
|
|
10484
|
+
else calls.push(callRuntime("_attr_class_names", createScopeReadExpression(nodeBinding), toClassPartExpression(key), value));
|
|
10485
|
+
if (single.length === 1) calls.push(callRuntime(`_attr_${name}_item`, createScopeReadExpression(nodeBinding), _marko_compiler.types.stringLiteral(single[0].key), single[0].value));
|
|
10486
|
+
else if (single.length) calls.push(callRuntime(`_attr_${name}_items`, createScopeReadExpression(nodeBinding), _marko_compiler.types.objectExpression(single.map(({ key, value }) => _marko_compiler.types.objectProperty(toPropertyName(key), value)))));
|
|
10361
10487
|
}
|
|
10362
|
-
|
|
10488
|
+
for (const call of calls) addStatement("render", tagSection, valueReferences, _marko_compiler.types.expressionStatement(call), true);
|
|
10363
10489
|
}
|
|
10364
10490
|
break;
|
|
10365
|
-
}
|
|
10366
10491
|
default: if (confident) break;
|
|
10367
10492
|
else addStatement("render", tagSection, valueReferences, _marko_compiler.types.expressionStatement(callRuntime("_attr", createScopeReadExpression(nodeBinding), _marko_compiler.types.stringLiteral(name), value)), true);
|
|
10368
10493
|
}
|
|
@@ -10637,13 +10762,13 @@ function getStaticAttrMarkup(name, computed) {
|
|
|
10637
10762
|
default: return getHTMLRuntime()._attr(name, computed);
|
|
10638
10763
|
}
|
|
10639
10764
|
}
|
|
10640
|
-
function buildAttrExpression(name, value) {
|
|
10641
|
-
if (value.type === "ConditionalExpression") return _marko_compiler.types.conditionalExpression(value.test, buildAttrExpression(name, value.consequent), buildAttrExpression(name, value.alternate));
|
|
10765
|
+
function buildAttrExpression(tag, name, value) {
|
|
10766
|
+
if (value.type === "ConditionalExpression") return _marko_compiler.types.conditionalExpression(value.test, buildAttrExpression(tag, name, value.consequent), buildAttrExpression(tag, name, value.alternate));
|
|
10642
10767
|
const { confident, computed } = evaluate(value);
|
|
10643
10768
|
if (confident) return _marko_compiler.types.stringLiteral(getStaticAttrMarkup(name, computed));
|
|
10644
10769
|
switch (name) {
|
|
10645
|
-
case "class": return
|
|
10646
|
-
case "style": return
|
|
10770
|
+
case "class": return buildClassAttrExpression(tag, value) || callRuntime("_attr_class", value);
|
|
10771
|
+
case "style": return buildStyleAttrAnd(value) || callRuntime("_attr_style", value);
|
|
10647
10772
|
default: return buildLogicalAttr(name, value) || callRuntime("_attr", _marko_compiler.types.stringLiteral(name), value);
|
|
10648
10773
|
}
|
|
10649
10774
|
}
|
|
@@ -10677,105 +10802,198 @@ function buildLogicalAttr(name, value) {
|
|
|
10677
10802
|
const attr = getHTMLRuntime()._attr(name, computed);
|
|
10678
10803
|
return callRuntime(value.operator === "&&" ? "_attr_and" : value.operator === "||" ? "_attr_or" : "_attr_nullish", _marko_compiler.types.stringLiteral(name), value.left, _marko_compiler.types.stringLiteral(attr));
|
|
10679
10804
|
}
|
|
10680
|
-
function
|
|
10805
|
+
function buildStyleAttrAnd(value) {
|
|
10681
10806
|
if (value.type === "LogicalExpression" && value.operator === "&&") {
|
|
10682
10807
|
const { confident, computed } = evaluate(value.right);
|
|
10683
|
-
if (confident) return _marko_compiler.types.conditionalExpression(value.left, _marko_compiler.types.stringLiteral(getStaticAttrMarkup(
|
|
10808
|
+
if (confident) return _marko_compiler.types.conditionalExpression(value.left, _marko_compiler.types.stringLiteral(getStaticAttrMarkup("style", computed)), _marko_compiler.types.stringLiteral(""));
|
|
10684
10809
|
}
|
|
10685
10810
|
}
|
|
10686
10811
|
const MAX_PRECOMPUTED_CLASS_TOGGLES = 4;
|
|
10687
|
-
function buildClassAttrExpression(value) {
|
|
10688
|
-
|
|
10812
|
+
function buildClassAttrExpression(tag, value) {
|
|
10813
|
+
const meta = trackDelimitedAttrValue(tag, "class", value);
|
|
10814
|
+
if (meta.dynamic) return;
|
|
10815
|
+
const markup = buildClassMarkup(meta);
|
|
10816
|
+
const assert = markup && buildClassTogglesAssert(meta);
|
|
10817
|
+
return assert ? _marko_compiler.types.sequenceExpression([assert, markup]) : markup;
|
|
10818
|
+
}
|
|
10819
|
+
function buildClassMarkup({ staticParts, dynamicValues = [] }) {
|
|
10820
|
+
if (dynamicValues.length > MAX_PRECOMPUTED_CLASS_TOGGLES) {
|
|
10821
|
+
if (staticParts.length) return callRuntime("_attr_class", buildClassString(staticParts, dynamicValues));
|
|
10822
|
+
return;
|
|
10823
|
+
}
|
|
10824
|
+
const combos = [];
|
|
10825
|
+
for (let mask = 0; mask < 1 << dynamicValues.length; mask++) {
|
|
10826
|
+
const parts = [...staticParts];
|
|
10827
|
+
for (let i = 0; i < dynamicValues.length; i++) {
|
|
10828
|
+
const { key, alternate } = dynamicValues[i];
|
|
10829
|
+
const part = mask & 1 << i ? key : alternate;
|
|
10830
|
+
if (part) parts.push(part);
|
|
10831
|
+
}
|
|
10832
|
+
combos.push(parts);
|
|
10833
|
+
}
|
|
10834
|
+
if (combos.every((parts) => parts.every(isLiteralPart))) return buildPrecomputedClass(combos.map((parts) => getHTMLRuntime()._attr_class(parts.join(" "))), dynamicValues);
|
|
10835
|
+
const table = getHoistedClassMarkup(combos);
|
|
10836
|
+
return dynamicValues.length ? _marko_compiler.types.memberExpression(table, buildToggleIndex(dynamicValues), true) : table;
|
|
10837
|
+
}
|
|
10838
|
+
function buildPrecomputedClass(combos, toggles) {
|
|
10839
|
+
if (!toggles.length) return _marko_compiler.types.stringLiteral(combos[0]);
|
|
10840
|
+
if (toggles.length === 1) return _marko_compiler.types.conditionalExpression(toggles[0].value, _marko_compiler.types.stringLiteral(combos[1]), _marko_compiler.types.stringLiteral(combos[0]));
|
|
10841
|
+
const end = commonAttrPrefixEnd(combos);
|
|
10842
|
+
const table = generateUidIdentifier("class");
|
|
10843
|
+
(0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.markoScriptlet([_marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(table, _marko_compiler.types.arrayExpression(combos.map((combo) => _marko_compiler.types.stringLiteral(combo.slice(end)))))])], true));
|
|
10844
|
+
const lookup = _marko_compiler.types.memberExpression(_marko_compiler.types.cloneNode(table), buildToggleIndex(toggles), true);
|
|
10845
|
+
return normalizeStringExpression([combos[0].slice(0, end), lookup]);
|
|
10846
|
+
}
|
|
10847
|
+
const [getHoistedClassMarkups] = createProgramState(() => /* @__PURE__ */ new Map());
|
|
10848
|
+
function getHoistedClassMarkup(combos) {
|
|
10849
|
+
const key = JSON.stringify(combos);
|
|
10850
|
+
const hoisted = getHoistedClassMarkups();
|
|
10851
|
+
let id = hoisted.get(key);
|
|
10852
|
+
if (!id) {
|
|
10853
|
+
const markups = combos.map((parts) => parts.length ? callRuntime("_attr_class", buildClassString(parts, [])) : _marko_compiler.types.stringLiteral(""));
|
|
10854
|
+
hoisted.set(key, id = generateUidIdentifier("class"));
|
|
10855
|
+
(0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.markoScriptlet([_marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(id, markups.length === 1 ? markups[0] : _marko_compiler.types.arrayExpression(markups))])], true));
|
|
10856
|
+
}
|
|
10857
|
+
return _marko_compiler.types.cloneNode(id);
|
|
10858
|
+
}
|
|
10859
|
+
function buildClassTogglesAssert({ staticParts, dynamicValues }) {
|
|
10860
|
+
if (isOptimize() || !dynamicValues || [...staticParts, ...dynamicValues.flatMap(({ key, alternate }) => [key, alternate])].every((part) => part === void 0 || isLiteralPart(part))) return;
|
|
10861
|
+
return callRuntime("_assert_class_toggles", buildClassString(staticParts, []), _marko_compiler.types.arrayExpression(dynamicValues.map(({ key, alternate }) => buildClassString(alternate ? [key, alternate] : [key], []))));
|
|
10862
|
+
}
|
|
10863
|
+
function buildToggleIndex(toggles) {
|
|
10864
|
+
let index = _marko_compiler.types.conditionalExpression(toggles[0].value, _marko_compiler.types.numericLiteral(1), _marko_compiler.types.numericLiteral(0));
|
|
10865
|
+
for (let i = 1; i < toggles.length; i++) index = _marko_compiler.types.binaryExpression("+", index, _marko_compiler.types.conditionalExpression(toggles[i].value, _marko_compiler.types.numericLiteral(1 << i), _marko_compiler.types.numericLiteral(0)));
|
|
10866
|
+
return index;
|
|
10867
|
+
}
|
|
10868
|
+
function buildClassString(parts, toggles) {
|
|
10869
|
+
const strs = [];
|
|
10870
|
+
for (let i = 0; i < parts.length; i++) {
|
|
10871
|
+
if (i) strs.push(" ");
|
|
10872
|
+
strs.push(toClassPartExpression(parts[i]));
|
|
10873
|
+
}
|
|
10874
|
+
for (const { key, value, alternate } of toggles) strs.push(_marko_compiler.types.conditionalExpression(value, toSpacedClassPart(key), toSpacedClassPart(alternate)));
|
|
10875
|
+
return normalizeStringExpression(strs) || _marko_compiler.types.stringLiteral("");
|
|
10876
|
+
}
|
|
10877
|
+
function toClassPartExpression(part) {
|
|
10878
|
+
return isLiteralPart(part) ? _marko_compiler.types.stringLiteral(part) : toModuleReadExpression(part);
|
|
10879
|
+
}
|
|
10880
|
+
function toSpacedClassPart(part) {
|
|
10881
|
+
return part === void 0 ? _marko_compiler.types.stringLiteral("") : isLiteralPart(part) ? _marko_compiler.types.stringLiteral(" " + part) : _marko_compiler.types.binaryExpression("+", _marko_compiler.types.stringLiteral(" "), toModuleReadExpression(part));
|
|
10882
|
+
}
|
|
10883
|
+
const delimitedAttrStringify = {
|
|
10884
|
+
class: [" ", stringifyClassObject],
|
|
10885
|
+
style: [";", stringifyStyleObject]
|
|
10886
|
+
};
|
|
10887
|
+
function assertUniqueClassToggles(tag, attr, { staticParts, dynamicValues = [] }) {
|
|
10888
|
+
const written = new Set(staticParts.flatMap(getClassNames));
|
|
10889
|
+
for (const { key, alternate } of dynamicValues) {
|
|
10890
|
+
const names = /* @__PURE__ */ new Set([...getClassNames(key), ...getClassNames(alternate)]);
|
|
10891
|
+
for (const name of names) if (written.has(name)) throw tag.hub.buildError(attr, `The toggled class \`${name}\` is also written by another part of the \`class\` value; a toggled [class name](https://markojs.com/docs/reference/native-tag#class) may appear only once.`, Error);
|
|
10892
|
+
for (const name of names) written.add(name);
|
|
10893
|
+
}
|
|
10894
|
+
}
|
|
10895
|
+
function getClassNames(part) {
|
|
10896
|
+
return part === void 0 ? [] : isLiteralPart(part) ? part.split(/\s+/).filter(Boolean) : [part.join(".")];
|
|
10897
|
+
}
|
|
10898
|
+
function isStaticDelimitedAttr(tag, attr) {
|
|
10899
|
+
const { name, value } = attr;
|
|
10900
|
+
if (name !== "class" && name !== "style") return false;
|
|
10901
|
+
const meta = trackDelimitedAttrValue(tag, name, value);
|
|
10902
|
+
if (name === "class") assertUniqueClassToggles(tag, attr, meta);
|
|
10903
|
+
return !meta.dynamic && !meta.dynamicValues;
|
|
10904
|
+
}
|
|
10905
|
+
function getDelimitedAttrItems(name, { dynamic, dynamicValues }) {
|
|
10906
|
+
if (dynamic) return;
|
|
10907
|
+
const items = [];
|
|
10908
|
+
if (!dynamicValues) return items;
|
|
10909
|
+
const keys = /* @__PURE__ */ new Set();
|
|
10910
|
+
for (const { key, value, alternate } of dynamicValues) {
|
|
10911
|
+
if (alternate !== void 0 || name === "style" && (!isLiteralPart(key) || /\s/.test(key) || keys.size === keys.add(key).size)) return;
|
|
10912
|
+
items.push({
|
|
10913
|
+
key,
|
|
10914
|
+
value
|
|
10915
|
+
});
|
|
10916
|
+
}
|
|
10917
|
+
return items;
|
|
10918
|
+
}
|
|
10919
|
+
function isLiteralPart(part) {
|
|
10920
|
+
return typeof part === "string";
|
|
10921
|
+
}
|
|
10922
|
+
function trackDelimitedAttrValue(tag, name, value) {
|
|
10689
10923
|
const meta = {
|
|
10690
|
-
|
|
10691
|
-
|
|
10924
|
+
dynamic: false,
|
|
10925
|
+
staticParts: [],
|
|
10692
10926
|
dynamicValues: void 0
|
|
10693
10927
|
};
|
|
10694
|
-
|
|
10695
|
-
|
|
10696
|
-
const base = toDelimitedString(meta.staticItems, " ", stringifyClassObject);
|
|
10697
|
-
if (!base) return;
|
|
10698
|
-
const { _attr_class } = getHTMLRuntime();
|
|
10699
|
-
const keys = Object.keys(meta.dynamicValues);
|
|
10700
|
-
if (keys.length === 1) {
|
|
10701
|
-
const [key] = keys;
|
|
10702
|
-
return _marko_compiler.types.conditionalExpression(meta.dynamicValues[key], _marko_compiler.types.stringLiteral(_attr_class(base + " " + key)), _marko_compiler.types.stringLiteral(_attr_class(base)));
|
|
10703
|
-
}
|
|
10704
|
-
if (keys.length <= MAX_PRECOMPUTED_CLASS_TOGGLES) {
|
|
10705
|
-
const combos = [];
|
|
10706
|
-
for (let mask = 0; mask < 1 << keys.length; mask++) {
|
|
10707
|
-
let classes = base;
|
|
10708
|
-
for (let i = 0; i < keys.length; i++) if (mask & 1 << i) classes += " " + keys[i];
|
|
10709
|
-
combos.push(_attr_class(classes));
|
|
10710
|
-
}
|
|
10711
|
-
const end = commonAttrPrefixEnd(combos);
|
|
10712
|
-
const table = generateUidIdentifier("class");
|
|
10713
|
-
(0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.markoScriptlet([_marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(table, _marko_compiler.types.arrayExpression(combos.map((combo) => _marko_compiler.types.stringLiteral(combo.slice(end)))))])], true));
|
|
10714
|
-
let index = _marko_compiler.types.conditionalExpression(meta.dynamicValues[keys[0]], _marko_compiler.types.numericLiteral(1), _marko_compiler.types.numericLiteral(0));
|
|
10715
|
-
for (let i = 1; i < keys.length; i++) index = _marko_compiler.types.binaryExpression("+", index, _marko_compiler.types.conditionalExpression(meta.dynamicValues[keys[i]], _marko_compiler.types.numericLiteral(1 << i), _marko_compiler.types.numericLiteral(0)));
|
|
10716
|
-
const lookup = _marko_compiler.types.memberExpression(_marko_compiler.types.cloneNode(table), index, true);
|
|
10717
|
-
return normalizeStringExpression([combos[0].slice(0, end), lookup]);
|
|
10718
|
-
}
|
|
10719
|
-
let classes = _marko_compiler.types.stringLiteral(base);
|
|
10720
|
-
for (const key of keys) classes = _marko_compiler.types.binaryExpression("+", classes, _marko_compiler.types.conditionalExpression(meta.dynamicValues[key], _marko_compiler.types.stringLiteral(" " + key), _marko_compiler.types.stringLiteral("")));
|
|
10721
|
-
return callRuntime("_attr_class", classes);
|
|
10722
|
-
}
|
|
10723
|
-
function trackDelimitedAttrValue(expr, meta) {
|
|
10724
|
-
switch (expr.type) {
|
|
10725
|
-
case "ObjectExpression":
|
|
10726
|
-
trackDelimitedAttrObjectProperties(expr, meta);
|
|
10727
|
-
break;
|
|
10728
|
-
case "ArrayExpression":
|
|
10729
|
-
trackDelimitedAttrArrayItems(expr, meta);
|
|
10730
|
-
break;
|
|
10731
|
-
default: (meta.dynamicItems ||= []).push(expr);
|
|
10732
|
-
}
|
|
10928
|
+
trackDelimitedAttrItem(tag, name, value, meta);
|
|
10929
|
+
return meta;
|
|
10733
10930
|
}
|
|
10734
|
-
function
|
|
10735
|
-
|
|
10931
|
+
function trackDelimitedAttrItem(tag, name, item, meta) {
|
|
10932
|
+
switch (item.type) {
|
|
10736
10933
|
case "ArrayExpression":
|
|
10737
|
-
|
|
10738
|
-
|
|
10739
|
-
case "ObjectExpression":
|
|
10740
|
-
trackDelimitedAttrObjectProperties(item, meta);
|
|
10741
|
-
break;
|
|
10934
|
+
for (const child of item.elements) if (child) trackDelimitedAttrItem(tag, name, child, meta);
|
|
10935
|
+
return;
|
|
10742
10936
|
case "SpreadElement":
|
|
10743
|
-
if (item.argument.type === "ArrayExpression")
|
|
10744
|
-
else
|
|
10745
|
-
|
|
10746
|
-
|
|
10747
|
-
|
|
10748
|
-
|
|
10749
|
-
else (meta.dynamicItems ||= []).push(item);
|
|
10750
|
-
break;
|
|
10751
|
-
}
|
|
10937
|
+
if (item.argument.type === "ArrayExpression") trackDelimitedAttrItem(tag, name, item.argument, meta);
|
|
10938
|
+
else meta.dynamic = true;
|
|
10939
|
+
return;
|
|
10940
|
+
case "ObjectExpression":
|
|
10941
|
+
trackDelimitedAttrObjectProperties(tag, name, item, meta);
|
|
10942
|
+
return;
|
|
10752
10943
|
}
|
|
10753
|
-
|
|
10754
|
-
|
|
10755
|
-
|
|
10756
|
-
|
|
10944
|
+
const part = getDelimitedAttrPart(tag, name, item);
|
|
10945
|
+
if (part !== void 0) {
|
|
10946
|
+
if (part) meta.staticParts.push(part);
|
|
10947
|
+
} else if (name === "class" && item.type === "LogicalExpression") {
|
|
10948
|
+
const key = item.operator === "&&" && getDelimitedAttrPart(tag, name, item.right);
|
|
10949
|
+
if (key) addDynamicValue(meta, key, item.left, void 0);
|
|
10950
|
+
else meta.dynamic = true;
|
|
10951
|
+
} else if (name === "class" && item.type === "ConditionalExpression") {
|
|
10952
|
+
const key = getDelimitedAttrPart(tag, name, item.consequent);
|
|
10953
|
+
const alternate = getDelimitedAttrPart(tag, name, item.alternate);
|
|
10954
|
+
if (key && alternate !== void 0) addDynamicValue(meta, key, item.test, alternate || void 0);
|
|
10955
|
+
else meta.dynamic = true;
|
|
10956
|
+
} else meta.dynamic = true;
|
|
10957
|
+
}
|
|
10958
|
+
function trackDelimitedAttrObjectProperties(tag, name, obj, meta) {
|
|
10757
10959
|
for (const prop of obj.properties) {
|
|
10758
|
-
|
|
10759
|
-
|
|
10760
|
-
|
|
10761
|
-
|
|
10762
|
-
let key;
|
|
10763
|
-
if (prop.key.type === "Identifier") key = prop.key.name;
|
|
10764
|
-
else {
|
|
10765
|
-
const keyEval = evaluate(prop.key);
|
|
10766
|
-
if (keyEval.confident && typeof keyEval.computed === "string" && !/^$|\s/.test(keyEval.computed)) key = keyEval.computed + "";
|
|
10767
|
-
else {
|
|
10768
|
-
(dynamicProps ||= []).push(prop);
|
|
10769
|
-
continue;
|
|
10770
|
-
}
|
|
10960
|
+
const key = prop.type === "ObjectProperty" ? getDelimitedAttrKey(tag, name, prop) : void 0;
|
|
10961
|
+
if (!key || prop.type !== "ObjectProperty") {
|
|
10962
|
+
meta.dynamic = true;
|
|
10963
|
+
return;
|
|
10771
10964
|
}
|
|
10772
10965
|
const value = prop.value;
|
|
10773
|
-
const
|
|
10774
|
-
if (
|
|
10775
|
-
else (
|
|
10966
|
+
const { confident, computed } = evaluate(value);
|
|
10967
|
+
if (!confident) addDynamicValue(meta, key, value, void 0);
|
|
10968
|
+
else if (!isLiteralPart(key)) {
|
|
10969
|
+
if (computed) meta.staticParts.push(key);
|
|
10970
|
+
} else {
|
|
10971
|
+
const part = delimitedAttrStringify[name][1](key, computed);
|
|
10972
|
+
if (part) meta.staticParts.push(part);
|
|
10973
|
+
}
|
|
10776
10974
|
}
|
|
10777
|
-
|
|
10778
|
-
|
|
10975
|
+
}
|
|
10976
|
+
function getDelimitedAttrKey(tag, name, prop) {
|
|
10977
|
+
if (!prop.computed && prop.key.type === "Identifier") return prop.key.name;
|
|
10978
|
+
const key = prop.key;
|
|
10979
|
+
const { confident, computed } = evaluate(key);
|
|
10980
|
+
if (confident) return typeof computed === "string" || typeof computed === "number" ? computed + "" : void 0;
|
|
10981
|
+
if (name === "class") return getStyleImportRead(tag, key);
|
|
10982
|
+
}
|
|
10983
|
+
function getDelimitedAttrPart(tag, name, value) {
|
|
10984
|
+
const { confident, computed } = evaluate(value);
|
|
10985
|
+
if (confident) {
|
|
10986
|
+
const [delimiter, stringify] = delimitedAttrStringify[name];
|
|
10987
|
+
return toDelimitedString(computed, delimiter, stringify);
|
|
10988
|
+
}
|
|
10989
|
+
if (name === "class") return getStyleImportRead(tag, value);
|
|
10990
|
+
}
|
|
10991
|
+
function addDynamicValue(meta, key, value, alternate) {
|
|
10992
|
+
(meta.dynamicValues ||= []).push({
|
|
10993
|
+
key,
|
|
10994
|
+
value,
|
|
10995
|
+
alternate
|
|
10996
|
+
});
|
|
10779
10997
|
}
|
|
10780
10998
|
function buildUndefined() {
|
|
10781
10999
|
return _marko_compiler.types.unaryExpression("void", _marko_compiler.types.numericLiteral(0));
|
|
@@ -10824,9 +11042,10 @@ var dynamic_tag_default = {
|
|
|
10824
11042
|
if (tag.node.extra?.tagNameUnresolved) throw tagNotFoundError(tag);
|
|
10825
11043
|
(0, _marko_compiler_babel_utils.assertAttributesOrArgs)(tag);
|
|
10826
11044
|
const { node } = tag;
|
|
11045
|
+
if (node.var && node.extra.featureType === "class") throw tag.get("var").buildCodeFrameError(`The Marko 5 (class API) tag \`${getStaticTagName(node)}\` cannot [\`<return>\`](https://markojs.com/docs/reference/core-tag#return) a value, so it does not support a [tag variable](https://markojs.com/docs/reference/language#tag-variables). Remove the variable, or migrate the tag to the tags API.`);
|
|
10827
11046
|
const definedBodySection = node.extra?.defineBodySection;
|
|
10828
11047
|
if (definedBodySection) {
|
|
10829
|
-
knownTagAnalyze(tag, definedBodySection
|
|
11048
|
+
knownTagAnalyze(tag, definedBodySection);
|
|
10830
11049
|
child(tag, getStaticTagName(tag.node), {
|
|
10831
11050
|
kind: SectionRef,
|
|
10832
11051
|
section: definedBodySection
|
|
@@ -10960,10 +11179,10 @@ var dynamic_tag_default = {
|
|
|
10960
11179
|
const bodySection = getSectionForBody(tag.get("body"));
|
|
10961
11180
|
const signal = getSignal(section, nodeBinding, "dynamicTag");
|
|
10962
11181
|
let tagVarSignal;
|
|
10963
|
-
if (tag.node.var) {
|
|
11182
|
+
if (tag.node.var && isTagVarResumed(tag)) {
|
|
10964
11183
|
const varBinding = tag.node.var.extra.binding;
|
|
10965
11184
|
tagVarSignal = initValue(varBinding);
|
|
10966
|
-
tagVarSignal.register =
|
|
11185
|
+
tagVarSignal.register = true;
|
|
10967
11186
|
tagVarSignal.referenced = true;
|
|
10968
11187
|
tagVarSignal.buildAssignment = (valueSection, value) => {
|
|
10969
11188
|
const changeArgs = [_marko_compiler.types.memberExpression(getScopeExpression(tagVarSignal.section, valueSection), _marko_compiler.types.stringLiteral(getAccessorPrefix().BranchScopes + getScopeAccessor(nodeBinding)), true), value];
|
|
@@ -10981,9 +11200,9 @@ var dynamic_tag_default = {
|
|
|
10981
11200
|
const argsOrInput = hasTagArgs ? _marko_compiler.types.arrayExpression(args) : args[0];
|
|
10982
11201
|
if (!_marko_compiler.types.isObjectExpression(argsOrInput) || argsOrInput.properties.length) signal.extraArgs = [_marko_compiler.types.arrowFunctionExpression([], statements.length ? _marko_compiler.types.blockStatement(statements.concat(_marko_compiler.types.returnStatement(argsOrInput))) : argsOrInput)];
|
|
10983
11202
|
}
|
|
11203
|
+
enableDynamicTagVar(tag);
|
|
10984
11204
|
if (!isClassAPI) {
|
|
10985
11205
|
enableDynamicTagResume(tag);
|
|
10986
|
-
enableDynamicTagVar(tag);
|
|
10987
11206
|
enableDynamicTagControllables(tag);
|
|
10988
11207
|
}
|
|
10989
11208
|
addValue(section, getReferencedBindings(tagExtra), signal, tagExpression);
|
|
@@ -11002,9 +11221,9 @@ function enableDynamicTagControllables(tag) {
|
|
|
11002
11221
|
}
|
|
11003
11222
|
}
|
|
11004
11223
|
function enableDynamicTagVar(tag) {
|
|
11005
|
-
if (!tag.node.var || !isTagVarResumed(tag)
|
|
11224
|
+
if (!tag.node.var || !isTagVarResumed(tag)) return;
|
|
11006
11225
|
importRuntimeFeature("dynamic-tag-var");
|
|
11007
|
-
if (!tag.node.var.extra.binding.pruned) {
|
|
11226
|
+
if (analyzeTagNameType(tag, true) !== 1 && !tag.node.var.extra.binding.pruned) {
|
|
11008
11227
|
const accessor = getScopeAccessorLiteral(tag.node.extra.nodeBinding, true);
|
|
11009
11228
|
if (addRuntimeOnce(`_dynamic_tag_var_resume ${accessor.value}`)) (0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.expressionStatement(callRuntime("_dynamic_tag_var_resume", accessor)));
|
|
11010
11229
|
}
|