marko 6.1.24 → 6.2.0
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/dist/common/helpers.d.ts +1 -0
- package/dist/debug/dom.js +59 -2
- package/dist/debug/dom.mjs +57 -3
- package/dist/debug/html.js +38 -11
- package/dist/debug/html.mjs +35 -12
- package/dist/dom/control-flow.d.ts +1 -0
- package/dist/dom/dom.d.ts +2 -0
- package/dist/dom.d.ts +2 -2
- package/dist/dom.js +34 -1
- package/dist/dom.mjs +34 -1
- package/dist/html/attrs.d.ts +1 -0
- package/dist/html/content.d.ts +1 -0
- package/dist/html/inlined-runtimes.d.ts +1 -1
- package/dist/html/inlined-runtimes.debug.d.ts +1 -1
- package/dist/html/writer.d.ts +2 -0
- package/dist/html.d.ts +3 -3
- package/dist/html.js +25 -6
- package/dist/html.mjs +25 -6
- package/dist/translator/core/index.d.ts +1 -0
- package/dist/translator/core/show.d.ts +17 -0
- package/dist/translator/core/style.d.ts +6 -0
- package/dist/translator/index.d.ts +1 -0
- package/dist/translator/index.js +400 -42
- package/dist/translator/util/style-interpolation.d.ts +3 -0
- package/package.json +1 -1
package/dist/translator/index.js
CHANGED
|
@@ -800,7 +800,8 @@ function isControlFlowTag(tag) {
|
|
|
800
800
|
case "else":
|
|
801
801
|
case "for":
|
|
802
802
|
case "await":
|
|
803
|
-
case "try":
|
|
803
|
+
case "try":
|
|
804
|
+
case "show": return true;
|
|
804
805
|
}
|
|
805
806
|
return false;
|
|
806
807
|
}
|
|
@@ -1536,10 +1537,12 @@ function getNodeContentType(path, extraMember, contentInfo) {
|
|
|
1536
1537
|
case "html-comment": return 0;
|
|
1537
1538
|
case "html-script":
|
|
1538
1539
|
case "html-style": return 3;
|
|
1540
|
+
case "style": return tag.node.body.body.some((child) => _marko_compiler.types.isMarkoPlaceholder(child)) ? 3 : null;
|
|
1539
1541
|
case "for":
|
|
1540
1542
|
case "if":
|
|
1541
1543
|
case "await":
|
|
1542
|
-
case "try":
|
|
1544
|
+
case "try":
|
|
1545
|
+
case "show": return 1;
|
|
1543
1546
|
default: return null;
|
|
1544
1547
|
}
|
|
1545
1548
|
else if ((0, _marko_compiler_babel_utils.isNativeTag)(tag)) return 3;
|
|
@@ -1645,7 +1648,9 @@ function isNativeNode(tag) {
|
|
|
1645
1648
|
if (isCoreTag(tag)) switch (tag.node.name.value) {
|
|
1646
1649
|
case "html-comment":
|
|
1647
1650
|
case "html-script":
|
|
1648
|
-
case "html-style":
|
|
1651
|
+
case "html-style":
|
|
1652
|
+
case "show": return true;
|
|
1653
|
+
case "style": return tag.node.body.body.some((child) => _marko_compiler.types.isMarkoPlaceholder(child));
|
|
1649
1654
|
default: return false;
|
|
1650
1655
|
}
|
|
1651
1656
|
return analyzeTagNameType(tag) === 0;
|
|
@@ -2242,6 +2247,7 @@ const pureDOMFunctions = new Set([
|
|
|
2242
2247
|
"_child_setup",
|
|
2243
2248
|
"_if",
|
|
2244
2249
|
"_if_closure",
|
|
2250
|
+
"_show",
|
|
2245
2251
|
"_try",
|
|
2246
2252
|
"_dynamic_tag",
|
|
2247
2253
|
"_dynamic_tag_content",
|
|
@@ -3876,7 +3882,8 @@ function isNonHTMLText(placeholder) {
|
|
|
3876
3882
|
if (isCoreTag(parentTag)) switch (parentTag.node.name.value) {
|
|
3877
3883
|
case "html-comment":
|
|
3878
3884
|
case "html-script":
|
|
3879
|
-
case "html-style":
|
|
3885
|
+
case "html-style":
|
|
3886
|
+
case "style": return true;
|
|
3880
3887
|
}
|
|
3881
3888
|
else if (isTextOnlyNativeTag(parentTag)) return true;
|
|
3882
3889
|
}
|
|
@@ -3888,7 +3895,7 @@ function isTextOnlyNativeTag(tag) {
|
|
|
3888
3895
|
}
|
|
3889
3896
|
//#endregion
|
|
3890
3897
|
//#region src/translator/core/for.ts
|
|
3891
|
-
const kStatefulReason$
|
|
3898
|
+
const kStatefulReason$2 = Symbol("<for> stateful reason");
|
|
3892
3899
|
var for_default = {
|
|
3893
3900
|
analyze(tag) {
|
|
3894
3901
|
const tagSection = getOrCreateSection(tag);
|
|
@@ -3933,7 +3940,7 @@ var for_default = {
|
|
|
3933
3940
|
}
|
|
3934
3941
|
const nodeBinding = getOptimizedOnlyChildNodeBinding(tag, tagSection);
|
|
3935
3942
|
const tagExtra = mergeReferences(tagSection, tag.node, getAllTagReferenceNodes(tag.node));
|
|
3936
|
-
addSerializeExpr(tagSection, tagExtra, kStatefulReason$
|
|
3943
|
+
addSerializeExpr(tagSection, tagExtra, kStatefulReason$2);
|
|
3937
3944
|
if (paramsBinding) {
|
|
3938
3945
|
setBindingDownstream(paramsBinding, tagExtra);
|
|
3939
3946
|
const byAttr = getKnownAttrValues(tag.node).by;
|
|
@@ -3992,7 +3999,7 @@ var for_default = {
|
|
|
3992
3999
|
forTagArgs.push(_marko_compiler.types.arrowFunctionExpression(params, _marko_compiler.types.blockStatement(bodyStatements)));
|
|
3993
4000
|
if (branchSerializeReason) {
|
|
3994
4001
|
const skipParentEnd = onlyChildParentTagName && markerSerializeReason;
|
|
3995
|
-
const statefulSerializeArg = getSerializeGuard(tagSection, getSerializeReason(tagSection, kStatefulReason$
|
|
4002
|
+
const statefulSerializeArg = getSerializeGuard(tagSection, getSerializeReason(tagSection, kStatefulReason$2), !(skipParentEnd || singleChild));
|
|
3996
4003
|
const markerSerializeArg = getSerializeGuard(tagSection, markerSerializeReason, !statefulSerializeArg);
|
|
3997
4004
|
forTagArgs.push(forAttrs.by || _marko_compiler.types.numericLiteral(0), getScopeIdIdentifier(tagSection), getScopeAccessorLiteral(nodeBinding), getSerializeGuard(tagSection, branchSerializeReason, !markerSerializeArg), markerSerializeArg, statefulSerializeArg);
|
|
3998
4005
|
if (skipParentEnd) {
|
|
@@ -5117,7 +5124,7 @@ function toFirstStatementOrBlock(body) {
|
|
|
5117
5124
|
}
|
|
5118
5125
|
//#endregion
|
|
5119
5126
|
//#region src/translator/core/if.ts
|
|
5120
|
-
const kStatefulReason = Symbol("<if> stateful reason");
|
|
5127
|
+
const kStatefulReason$1 = Symbol("<if> stateful reason");
|
|
5121
5128
|
const BRANCHES_LOOKUP = /* @__PURE__ */ new WeakMap();
|
|
5122
5129
|
const IfTag = {
|
|
5123
5130
|
analyze(tag) {
|
|
@@ -5142,7 +5149,7 @@ const IfTag = {
|
|
|
5142
5149
|
if (branchTag.node.attributes.length) mergeReferenceNodes.push(branchTag.node.attributes[0].value);
|
|
5143
5150
|
}
|
|
5144
5151
|
mergeReferences(ifTagSection, ifTag.node, mergeReferenceNodes);
|
|
5145
|
-
addSerializeExpr(ifTagSection, ifTagExtra, kStatefulReason);
|
|
5152
|
+
addSerializeExpr(ifTagSection, ifTagExtra, kStatefulReason$1);
|
|
5146
5153
|
}
|
|
5147
5154
|
},
|
|
5148
5155
|
translate: translateByTarget({
|
|
@@ -5200,7 +5207,7 @@ const IfTag = {
|
|
|
5200
5207
|
if (branchSerializeReasons) {
|
|
5201
5208
|
const skipParentEnd = onlyChildParentTagName && markerSerializeReason;
|
|
5202
5209
|
if (skipParentEnd) getParentTag(ifTag).node.extra[kSkipEndTag] = true;
|
|
5203
|
-
const statefulSerializeArg = getSerializeGuard(ifTagSection, getSerializeReason(ifTagSection, kStatefulReason), !(skipParentEnd || singleChild));
|
|
5210
|
+
const statefulSerializeArg = getSerializeGuard(ifTagSection, getSerializeReason(ifTagSection, kStatefulReason$1), !(skipParentEnd || singleChild));
|
|
5204
5211
|
const markerSerializeArg = getSerializeGuard(ifTagSection, markerSerializeReason, !statefulSerializeArg);
|
|
5205
5212
|
const cbNode = _marko_compiler.types.arrowFunctionExpression([], _marko_compiler.types.blockStatement([statement]));
|
|
5206
5213
|
statement = _marko_compiler.types.expressionStatement(callRuntime("_if", cbNode, getScopeIdIdentifier(ifTagSection), getScopeAccessorLiteral(nodeBinding), getSerializeGuardForAny(ifTagSection, branchSerializeReasons, !markerSerializeArg), markerSerializeArg, statefulSerializeArg, skipParentEnd ? _marko_compiler.types.stringLiteral(`</${onlyChildParentTagName}>`) : singleChild ? _marko_compiler.types.numericLiteral(0) : void 0, singleChild ? _marko_compiler.types.numericLiteral(1) : void 0));
|
|
@@ -5312,14 +5319,14 @@ function assertValidCondition(tag) {
|
|
|
5312
5319
|
(0, _marko_compiler_babel_utils.assertNoVar)(tag);
|
|
5313
5320
|
(0, _marko_compiler_babel_utils.assertNoArgs)(tag);
|
|
5314
5321
|
(0, _marko_compiler_babel_utils.assertNoParams)(tag);
|
|
5315
|
-
assertHasBody(tag);
|
|
5322
|
+
assertHasBody$1(tag);
|
|
5316
5323
|
assertNoSpreadAttrs(tag);
|
|
5317
5324
|
switch (getTagName(tag)) {
|
|
5318
5325
|
case "if":
|
|
5319
|
-
assertHasValueAttribute(tag);
|
|
5326
|
+
assertHasValueAttribute$1(tag);
|
|
5320
5327
|
break;
|
|
5321
5328
|
case "else-if":
|
|
5322
|
-
assertHasValueAttribute(tag);
|
|
5329
|
+
assertHasValueAttribute$1(tag);
|
|
5323
5330
|
assertHasPrecedingCondition(tag);
|
|
5324
5331
|
break;
|
|
5325
5332
|
case "else":
|
|
@@ -5333,10 +5340,10 @@ function assertHasPrecedingCondition(tag) {
|
|
|
5333
5340
|
while (prev.node && prev.isMarkoComment()) prev = prev.getPrevSibling();
|
|
5334
5341
|
if (!isConditionTag(prev) || getTagName(prev) === "else" && !prev.node.attributes.length) throw tag.buildCodeFrameError(`The [\`<${getTagName(tag)}>\` tag](https://markojs.com/docs/reference/core-tag#if--else) must have a preceding \`<if=cond>\` or \`<else if=cond>\`.`);
|
|
5335
5342
|
}
|
|
5336
|
-
function assertHasBody(tag) {
|
|
5343
|
+
function assertHasBody$1(tag) {
|
|
5337
5344
|
if (!(tag.node.body.body.length || tag.node.attributeTags.length)) throw tag.get("name").buildCodeFrameError(`The [\`${getTagName(tag)}\` tag](https://markojs.com/docs/reference/core-tag#if--else) requires [body content](https://markojs.com/docs/reference/language#tag-content).`);
|
|
5338
5345
|
}
|
|
5339
|
-
function assertHasValueAttribute(tag) {
|
|
5346
|
+
function assertHasValueAttribute$1(tag) {
|
|
5340
5347
|
const { node } = tag;
|
|
5341
5348
|
const [valueAttr] = node.attributes;
|
|
5342
5349
|
if (!_marko_compiler.types.isMarkoAttribute(valueAttr) || !valueAttr.default) throw tag.get("name").buildCodeFrameError(`The [\`${getTagName(tag)}\` tag](https://markojs.com/docs/reference/core-tag#if--else) requires a [\`value=\` attribute](https://markojs.com/docs/reference/language#shorthand-value).`);
|
|
@@ -5674,7 +5681,7 @@ var program_default = {
|
|
|
5674
5681
|
const isDOMPageEntry = output === "dom" && entry === "page" || output === "hydrate";
|
|
5675
5682
|
const isServerEntry = output === "html" && entry === "page";
|
|
5676
5683
|
if (entry && !markoOpts.linkAssets) throw program.buildCodeFrameError("The \"entry\" option requires the `linkAssets` compiler option to be configured.");
|
|
5677
|
-
if (runtimeId && !/^[
|
|
5684
|
+
if (runtimeId && !/^[_a-z][_a-z0-9]*$/i.test(runtimeId)) throw program.buildCodeFrameError(`Invalid runtimeId: "${runtimeId}". The runtimeId must start with a letter or underscore and only contain letters, numbers, and underscores.`);
|
|
5678
5685
|
if (isLoadEntry) {
|
|
5679
5686
|
const entryFile = program.hub.file;
|
|
5680
5687
|
const { filename } = entryFile.opts;
|
|
@@ -8209,6 +8216,163 @@ var server_default = {
|
|
|
8209
8216
|
}]
|
|
8210
8217
|
};
|
|
8211
8218
|
//#endregion
|
|
8219
|
+
//#region src/translator/core/show.ts
|
|
8220
|
+
const kStatefulReason = Symbol("<show> stateful reason");
|
|
8221
|
+
const kStartBinding = Symbol("<show> range start binding");
|
|
8222
|
+
const kStaticDisplay = Symbol("<show> static display");
|
|
8223
|
+
const kSingleNodeBody = Symbol("<show> single node body");
|
|
8224
|
+
const kDisplayRef = Symbol("<show> hoisted display reference");
|
|
8225
|
+
var show_default = {
|
|
8226
|
+
analyze: {
|
|
8227
|
+
enter(tag) {
|
|
8228
|
+
assertValidShow(tag);
|
|
8229
|
+
const tagExtra = tag.node.extra ??= {};
|
|
8230
|
+
const display = tag.node.attributes[0].value;
|
|
8231
|
+
const displayEval = evaluate(display);
|
|
8232
|
+
tagExtra[kSingleNodeBody] = isSingleNodeBody(tag);
|
|
8233
|
+
if (displayEval.confident) tagExtra[kStaticDisplay] = !!displayEval.computed;
|
|
8234
|
+
if (tagExtra[kStaticDisplay] === true) return;
|
|
8235
|
+
const tagSection = getOrCreateSection(tag);
|
|
8236
|
+
if (getOnlyChildParentTagName(tag)) getOptimizedOnlyChildNodeBinding(tag, tagSection);
|
|
8237
|
+
else tagExtra[kStartBinding] = createBinding("#text", 0, tagSection);
|
|
8238
|
+
if (tagExtra[kStaticDisplay] === void 0) {
|
|
8239
|
+
mergeReferences(tagSection, tag.node, [display]);
|
|
8240
|
+
addSerializeExpr(tagSection, tagExtra, kStatefulReason);
|
|
8241
|
+
}
|
|
8242
|
+
},
|
|
8243
|
+
exit(tag) {
|
|
8244
|
+
const tagExtra = tag.node.extra;
|
|
8245
|
+
if (tagExtra[kStaticDisplay] === true) return;
|
|
8246
|
+
const tagSection = getSection(tag);
|
|
8247
|
+
const nodeBinding = getOptimizedOnlyChildNodeBinding(tag, tagSection);
|
|
8248
|
+
if (tagExtra[kStaticDisplay] === void 0) addSerializeExpr(tagSection, tagExtra, nodeBinding);
|
|
8249
|
+
}
|
|
8250
|
+
},
|
|
8251
|
+
translate: translateByTarget({
|
|
8252
|
+
html: {
|
|
8253
|
+
enter(tag) {
|
|
8254
|
+
const tagExtra = tag.node.extra;
|
|
8255
|
+
flushBefore(tag);
|
|
8256
|
+
const staticDisplay = tagExtra[kStaticDisplay];
|
|
8257
|
+
if (staticDisplay === true) return;
|
|
8258
|
+
if (staticDisplay === false) {
|
|
8259
|
+
writeTo(tag)`<t hidden>`;
|
|
8260
|
+
return;
|
|
8261
|
+
}
|
|
8262
|
+
const display = tag.node.attributes[0].value;
|
|
8263
|
+
if (!_marko_compiler.types.isIdentifier(display) && !isLiteral(display)) {
|
|
8264
|
+
const displayRef = generateUidIdentifier("show");
|
|
8265
|
+
tag.insertBefore(_marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(displayRef, display)]));
|
|
8266
|
+
tagExtra[kDisplayRef] = displayRef;
|
|
8267
|
+
}
|
|
8268
|
+
},
|
|
8269
|
+
exit(tag) {
|
|
8270
|
+
const tagExtra = tag.node.extra;
|
|
8271
|
+
const staticDisplay = tagExtra[kStaticDisplay];
|
|
8272
|
+
if (staticDisplay === false) writeTo(tag)`</t>`;
|
|
8273
|
+
flushInto(tag);
|
|
8274
|
+
const bodyStatements = tag.node.body.body;
|
|
8275
|
+
if (staticDisplay !== void 0) {
|
|
8276
|
+
for (const replacement of tag.replaceWithMultiple(bodyStatements)) replacement.skip();
|
|
8277
|
+
return;
|
|
8278
|
+
}
|
|
8279
|
+
const tagSection = getSection(tag);
|
|
8280
|
+
const display = tagExtra[kDisplayRef] || tag.node.attributes[0].value;
|
|
8281
|
+
const nodeBinding = getOptimizedOnlyChildNodeBinding(tag, tagSection);
|
|
8282
|
+
const onlyChildParentTagName = getOnlyChildParentTagName(tag);
|
|
8283
|
+
const singleNode = tagExtra[kSingleNodeBody];
|
|
8284
|
+
const statefulReason = getSerializeReason(tagSection, kStatefulReason);
|
|
8285
|
+
const markerSerializeReason = getSerializeReason(tagSection, nodeBinding);
|
|
8286
|
+
const skipParentEnd = onlyChildParentTagName && markerSerializeReason;
|
|
8287
|
+
if (skipParentEnd) getParentTag(tag).node.extra[kSkipEndTag] = true;
|
|
8288
|
+
const statefulSerializeArg = getSerializeGuard(tagSection, statefulReason, !(skipParentEnd || singleNode));
|
|
8289
|
+
const markerSerializeArg = getSerializeGuard(tagSection, markerSerializeReason, !statefulSerializeArg);
|
|
8290
|
+
let startMark;
|
|
8291
|
+
if (!singleNode) {
|
|
8292
|
+
startMark = getSerializeGuard(tagSection, markerSerializeReason, false);
|
|
8293
|
+
if (skipParentEnd) startMark = _marko_compiler.types.logicalExpression("&&", startMark, getSerializeGuard(tagSection, statefulReason, false));
|
|
8294
|
+
}
|
|
8295
|
+
for (const replacement of tag.replaceWithMultiple([
|
|
8296
|
+
_marko_compiler.types.expressionStatement(callRuntime("_show_start", _marko_compiler.types.cloneNode(display, true), startMark)),
|
|
8297
|
+
...bodyStatements,
|
|
8298
|
+
_marko_compiler.types.expressionStatement(callRuntime("_show_end", getScopeIdIdentifier(tagSection), getScopeAccessorLiteral(nodeBinding), display, markerSerializeArg, statefulSerializeArg, skipParentEnd ? _marko_compiler.types.stringLiteral(`</${onlyChildParentTagName}>`) : singleNode ? _marko_compiler.types.numericLiteral(0) : void 0, singleNode ? _marko_compiler.types.numericLiteral(1) : void 0))
|
|
8299
|
+
])) replacement.skip();
|
|
8300
|
+
}
|
|
8301
|
+
},
|
|
8302
|
+
dom: {
|
|
8303
|
+
enter(tag) {
|
|
8304
|
+
if (tag.node.extra[kStartBinding]) {
|
|
8305
|
+
visit(tag, 37);
|
|
8306
|
+
enterShallow(tag);
|
|
8307
|
+
}
|
|
8308
|
+
},
|
|
8309
|
+
exit(tag) {
|
|
8310
|
+
const tagExtra = tag.node.extra;
|
|
8311
|
+
if (tagExtra[kStaticDisplay] === true) {
|
|
8312
|
+
tag.remove();
|
|
8313
|
+
return;
|
|
8314
|
+
}
|
|
8315
|
+
const tagSection = getSection(tag);
|
|
8316
|
+
const nodeBinding = getOptimizedOnlyChildNodeBinding(tag, tagSection);
|
|
8317
|
+
const startBinding = tagExtra[kStartBinding];
|
|
8318
|
+
const display = tagExtra[kStaticDisplay] === false ? _marko_compiler.types.booleanLiteral(false) : tag.node.attributes[0].value;
|
|
8319
|
+
if (startBinding) {
|
|
8320
|
+
visit(tag, 37);
|
|
8321
|
+
enterShallow(tag);
|
|
8322
|
+
}
|
|
8323
|
+
const signal = getSignal(tagSection, nodeBinding, "show");
|
|
8324
|
+
signal.build = () => {
|
|
8325
|
+
return callRuntime("_show", getScopeAccessorLiteral(nodeBinding, true), startBinding ? getScopeAccessorLiteral(startBinding, true) : void 0);
|
|
8326
|
+
};
|
|
8327
|
+
addValue(tagSection, tagExtra.referencedBindings, signal, display);
|
|
8328
|
+
tag.remove();
|
|
8329
|
+
}
|
|
8330
|
+
}
|
|
8331
|
+
}),
|
|
8332
|
+
parseOptions: { controlFlow: true },
|
|
8333
|
+
autocomplete: [{
|
|
8334
|
+
snippet: "show=${1:condition}",
|
|
8335
|
+
description: "Use to render content that is always mounted but only displayed when the condition is met.",
|
|
8336
|
+
descriptionMoreURL: "https://markojs.com/docs/reference/core-tag#show"
|
|
8337
|
+
}]
|
|
8338
|
+
};
|
|
8339
|
+
function isSingleNodeBody(tag) {
|
|
8340
|
+
let elements = 0;
|
|
8341
|
+
for (const child of tag.get("body").get("body")) {
|
|
8342
|
+
if (child.isMarkoComment()) continue;
|
|
8343
|
+
if (child.isMarkoTag() && analyzeTagNameType(child) === 0 && _marko_compiler.types.isStringLiteral(child.node.name)) elements++;
|
|
8344
|
+
else return false;
|
|
8345
|
+
}
|
|
8346
|
+
return elements === 1;
|
|
8347
|
+
}
|
|
8348
|
+
function isLiteral(expr) {
|
|
8349
|
+
switch (expr.type) {
|
|
8350
|
+
case "BooleanLiteral":
|
|
8351
|
+
case "NumericLiteral":
|
|
8352
|
+
case "StringLiteral":
|
|
8353
|
+
case "NullLiteral": return true;
|
|
8354
|
+
default: return false;
|
|
8355
|
+
}
|
|
8356
|
+
}
|
|
8357
|
+
function assertValidShow(tag) {
|
|
8358
|
+
(0, _marko_compiler_babel_utils.assertNoVar)(tag);
|
|
8359
|
+
(0, _marko_compiler_babel_utils.assertNoArgs)(tag);
|
|
8360
|
+
(0, _marko_compiler_babel_utils.assertNoParams)(tag);
|
|
8361
|
+
assertNoSpreadAttrs(tag);
|
|
8362
|
+
assertHasBody(tag);
|
|
8363
|
+
assertHasValueAttribute(tag);
|
|
8364
|
+
}
|
|
8365
|
+
function assertHasBody(tag) {
|
|
8366
|
+
if (!tag.node.body.body.length) throw tag.get("name").buildCodeFrameError(`The [\`<${getTagName(tag)}>\` tag](https://markojs.com/docs/reference/core-tag#show) requires [body content](https://markojs.com/docs/reference/language#tag-content).`);
|
|
8367
|
+
if (tag.node.body.attributeTags) throw tag.get("name").buildCodeFrameError(`The [\`<${getTagName(tag)}>\` tag](https://markojs.com/docs/reference/core-tag#show) does not support [attribute tags](https://markojs.com/docs/reference/language#attribute-tags).`);
|
|
8368
|
+
}
|
|
8369
|
+
function assertHasValueAttribute(tag) {
|
|
8370
|
+
const { node } = tag;
|
|
8371
|
+
const [valueAttr] = node.attributes;
|
|
8372
|
+
if (!_marko_compiler.types.isMarkoAttribute(valueAttr) || !valueAttr.default) throw tag.get("name").buildCodeFrameError(`The [\`<${getTagName(tag)}>\` tag](https://markojs.com/docs/reference/core-tag#show) requires a [\`value=\` attribute](https://markojs.com/docs/reference/language#shorthand-value).`);
|
|
8373
|
+
if (node.attributes.length > 1) throw tag.get("name").buildCodeFrameError(`The [\`<${getTagName(tag)}>\` tag](https://markojs.com/docs/reference/core-tag#show) only supports the [\`value=\` attribute](https://markojs.com/docs/reference/language#shorthand-value).`);
|
|
8374
|
+
}
|
|
8375
|
+
//#endregion
|
|
8212
8376
|
//#region src/translator/core/static.ts
|
|
8213
8377
|
var static_default = {
|
|
8214
8378
|
parse(tag) {
|
|
@@ -8231,36 +8395,109 @@ var static_default = {
|
|
|
8231
8395
|
}]
|
|
8232
8396
|
};
|
|
8233
8397
|
//#endregion
|
|
8398
|
+
//#region src/translator/util/style-interpolation.ts
|
|
8399
|
+
const htmlStyleTagAlternateMsg = " For a native html [`<style>` tag](https://markojs.com/docs/reference/core-tag#style) use the `html-style` core tag instead.";
|
|
8400
|
+
function checkStyleInterpolations(tag) {
|
|
8401
|
+
const { body } = tag.node.body;
|
|
8402
|
+
let stringQuote = "";
|
|
8403
|
+
let inComment = false;
|
|
8404
|
+
let groupDepth = 0;
|
|
8405
|
+
let blockDepth = 0;
|
|
8406
|
+
let valueColon = false;
|
|
8407
|
+
let runPlaceholder;
|
|
8408
|
+
let runAfterColon = false;
|
|
8409
|
+
let runDecl = false;
|
|
8410
|
+
const endRun = (selector) => {
|
|
8411
|
+
if (runPlaceholder && !runAfterColon && (selector || runDecl)) throw tag.hub.buildError(runPlaceholder, selector ? styleSelectorMsg : stylePropertyMsg);
|
|
8412
|
+
valueColon = false;
|
|
8413
|
+
runPlaceholder = void 0;
|
|
8414
|
+
};
|
|
8415
|
+
for (let i = 0; i < body.length; i++) {
|
|
8416
|
+
const child = body[i];
|
|
8417
|
+
if (_marko_compiler.types.isMarkoPlaceholder(child)) {
|
|
8418
|
+
if (stringQuote) throw tag.hub.buildError(child, styleStringMsg);
|
|
8419
|
+
if (!runPlaceholder) {
|
|
8420
|
+
runPlaceholder = child;
|
|
8421
|
+
runAfterColon = valueColon;
|
|
8422
|
+
runDecl = blockDepth > 0;
|
|
8423
|
+
}
|
|
8424
|
+
const prev = body[i - 1];
|
|
8425
|
+
if (_marko_compiler.types.isMarkoText(prev) && cssGluedBefore.test(prev.value)) throw tag.hub.buildError(child, styleGluedBeforeMsg);
|
|
8426
|
+
const next = body[i + 1];
|
|
8427
|
+
if (_marko_compiler.types.isMarkoText(next) && cssGluedValue.test(next.value)) throw tag.hub.buildError(child, styleGluedMsg);
|
|
8428
|
+
continue;
|
|
8429
|
+
}
|
|
8430
|
+
const text = child.value;
|
|
8431
|
+
for (let j = 0; j < text.length; j++) {
|
|
8432
|
+
const c = text[j];
|
|
8433
|
+
if (inComment) {
|
|
8434
|
+
if (c === "*" && text[j + 1] === "/") {
|
|
8435
|
+
inComment = false;
|
|
8436
|
+
j++;
|
|
8437
|
+
}
|
|
8438
|
+
} else if (stringQuote) {
|
|
8439
|
+
if (c === "\\") j++;
|
|
8440
|
+
else if (c === stringQuote) stringQuote = "";
|
|
8441
|
+
} else if (c === "\\") j++;
|
|
8442
|
+
else if (c === "/" && text[j + 1] === "*") {
|
|
8443
|
+
inComment = true;
|
|
8444
|
+
j++;
|
|
8445
|
+
} else if (c === "\"" || c === "'") stringQuote = c;
|
|
8446
|
+
else if (c === "(" || c === "[") groupDepth++;
|
|
8447
|
+
else if (c === ")" || c === "]") {
|
|
8448
|
+
if (groupDepth) groupDepth--;
|
|
8449
|
+
} else if (!groupDepth) switch (c) {
|
|
8450
|
+
case ":":
|
|
8451
|
+
if (blockDepth) valueColon = true;
|
|
8452
|
+
break;
|
|
8453
|
+
case "{":
|
|
8454
|
+
endRun(true);
|
|
8455
|
+
blockDepth++;
|
|
8456
|
+
break;
|
|
8457
|
+
case ";":
|
|
8458
|
+
endRun(!blockDepth);
|
|
8459
|
+
break;
|
|
8460
|
+
case "}":
|
|
8461
|
+
endRun(false);
|
|
8462
|
+
if (blockDepth) blockDepth--;
|
|
8463
|
+
break;
|
|
8464
|
+
}
|
|
8465
|
+
}
|
|
8466
|
+
}
|
|
8467
|
+
endRun(!blockDepth);
|
|
8468
|
+
}
|
|
8469
|
+
const styleInterpolationMsg = "A `${...}` interpolation in a [`<style>` tag](https://markojs.com/docs/reference/core-tag#style) is substituted as a `var(--…)` custom property reference, which";
|
|
8470
|
+
const styleSelectorMsg = `${styleInterpolationMsg} only resolves in a declaration value, not in a selector or at-rule prelude. For a native html [\`<style>\` tag](https://markojs.com/docs/reference/core-tag#style) use the \`html-style\` core tag instead.`;
|
|
8471
|
+
const stylePropertyMsg = `${styleInterpolationMsg} cannot be used as a property name. For a native html [\`<style>\` tag](https://markojs.com/docs/reference/core-tag#style) use the \`html-style\` core tag instead.`;
|
|
8472
|
+
const styleStringMsg = `${styleInterpolationMsg} is not substituted inside a quoted CSS string — the literal text \`var(--…)\` would be rendered instead of the value. For a native html [\`<style>\` tag](https://markojs.com/docs/reference/core-tag#style) use the \`html-style\` core tag instead.`;
|
|
8473
|
+
const styleGluedMsg = `${styleInterpolationMsg} CSS does not re-tokenize, so a unit written directly after it (eg \`\${x}px\`) becomes the invalid \`var(--…)px\`. Move the unit into the interpolated value (so it resolves to eg \`"10px"\`) or use \`calc(var(--…) * 1px)\`.`;
|
|
8474
|
+
const styleGluedBeforeMsg = `${styleInterpolationMsg} CSS does not re-tokenize, so text written directly before it (eg \`10\${x}\`) merges with the \`var(--…)\` into a single invalid token. Add whitespace before the interpolation or move the text into the interpolated value.`;
|
|
8475
|
+
const cssGluedValue = /^(?:[%.\d]|(?:p[xtc]|in|[cm]m|q|r?em|ex|ch|r?lh|v[whib]|vmin|vmax|fr|deg|g?rad|turn|m?s|k?hz|dp(?:i|cm|px)|cq[whib]|cqmin|cqmax)(?![\w-]))/i;
|
|
8476
|
+
const cssGluedBefore = /[\w%]$/;
|
|
8477
|
+
//#endregion
|
|
8234
8478
|
//#region src/translator/core/style.ts
|
|
8235
8479
|
const STYLE_EXT_REG = /^style((?:\.[a-zA-Z0-9$_-]+)+)?/;
|
|
8236
|
-
const htmlStyleTagAlternateMsg = " For a native html [`<style>` tag](https://markojs.com/docs/reference/core-tag#style) use the `html-style` core tag instead.";
|
|
8237
8480
|
var style_default = {
|
|
8238
8481
|
analyze(tag) {
|
|
8239
8482
|
(0, _marko_compiler_babel_utils.assertNoArgs)(tag);
|
|
8240
8483
|
(0, _marko_compiler_babel_utils.assertNoParams)(tag);
|
|
8241
8484
|
(0, _marko_compiler_babel_utils.assertNoAttributeTags)(tag);
|
|
8242
8485
|
const { node, hub: { file } } = tag;
|
|
8243
|
-
|
|
8244
|
-
|
|
8245
|
-
|
|
8246
|
-
|
|
8486
|
+
assertNoStyleAttributes(tag);
|
|
8487
|
+
const names = collectDynamicStyleNames(tag);
|
|
8488
|
+
if (names) {
|
|
8489
|
+
checkStyleInterpolations(tag);
|
|
8490
|
+
checkDynamicStylePlacement(tag);
|
|
8247
8491
|
}
|
|
8248
|
-
|
|
8249
|
-
const importPath = getStyleImportPath(file, node);
|
|
8492
|
+
const importPath = getStyleImportPath(file, node, names);
|
|
8250
8493
|
(node.extra ??= {}).styleImportPath = importPath;
|
|
8251
8494
|
if (importPath) addAssetImport(file, importPath);
|
|
8495
|
+
if (names) analyzeDynamicStyle(tag, names);
|
|
8252
8496
|
},
|
|
8253
|
-
translate(
|
|
8254
|
-
|
|
8255
|
-
|
|
8256
|
-
|
|
8257
|
-
else if (_marko_compiler.types.isIdentifier(node.var)) (0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.importDeclaration([_marko_compiler.types.importNamespaceSpecifier(node.var)], _marko_compiler.types.stringLiteral(importPath)));
|
|
8258
|
-
else {
|
|
8259
|
-
const varDecl = _marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(node.var, (0, _marko_compiler_babel_utils.importStar)(file, importPath, "style"))]);
|
|
8260
|
-
(0, _marko_compiler_babel_utils.getProgram)().node.body.push(isOutputDOM() ? varDecl : _marko_compiler.types.markoScriptlet([varDecl], true));
|
|
8261
|
-
}
|
|
8262
|
-
tag.remove();
|
|
8263
|
-
},
|
|
8497
|
+
translate: translateByTarget({
|
|
8498
|
+
html: { exit: translateHTML$1 },
|
|
8499
|
+
dom: { exit: translateDOM$1 }
|
|
8500
|
+
}),
|
|
8264
8501
|
parseOptions: {
|
|
8265
8502
|
html: false,
|
|
8266
8503
|
text: true,
|
|
@@ -8269,34 +8506,154 @@ var style_default = {
|
|
|
8269
8506
|
},
|
|
8270
8507
|
attributes: {}
|
|
8271
8508
|
};
|
|
8509
|
+
function analyzeDynamicStyle(tag, names) {
|
|
8510
|
+
const { node } = tag;
|
|
8511
|
+
const section = getOrCreateSection(tag);
|
|
8512
|
+
const binding = createBinding("#style", 0, section);
|
|
8513
|
+
node.extra.dynamicStyle = {
|
|
8514
|
+
names,
|
|
8515
|
+
binding
|
|
8516
|
+
};
|
|
8517
|
+
let exprExtras = mergeReferences(section, node, []);
|
|
8518
|
+
for (const value of dynamicStyleValues(node)) exprExtras = push(exprExtras, value.extra ??= {});
|
|
8519
|
+
addSerializeExpr(section, exprExtras, binding);
|
|
8520
|
+
}
|
|
8521
|
+
function collectDynamicStyleNames(tag) {
|
|
8522
|
+
let names;
|
|
8523
|
+
let index = 0;
|
|
8524
|
+
for (const child of tag.node.body.body) if (_marko_compiler.types.isMarkoPlaceholder(child)) {
|
|
8525
|
+
if (!names) {
|
|
8526
|
+
names = [];
|
|
8527
|
+
index = dynamicStyleNameOffset(tag);
|
|
8528
|
+
}
|
|
8529
|
+
names.push(dynamicStyleName(tag, index++));
|
|
8530
|
+
} else if (!_marko_compiler.types.isMarkoText(child)) throw tag.hub.buildError(child, "The [`<style>` tag](https://markojs.com/docs/reference/core-tag#style) only supports text and `${...}` interpolations." + htmlStyleTagAlternateMsg);
|
|
8531
|
+
return names;
|
|
8532
|
+
}
|
|
8533
|
+
function dynamicStyleNameOffset(tag) {
|
|
8534
|
+
const { start } = tag.node;
|
|
8535
|
+
let offset = 0;
|
|
8536
|
+
if (start != null) _marko_compiler.types.traverseFast((0, _marko_compiler_babel_utils.getProgram)().node, (node) => {
|
|
8537
|
+
const dynamicStyle = node.extra?.dynamicStyle;
|
|
8538
|
+
if (dynamicStyle && node.start != null && node.start < start) offset += dynamicStyle.names.length;
|
|
8539
|
+
});
|
|
8540
|
+
return offset;
|
|
8541
|
+
}
|
|
8542
|
+
const styleNameUnsafeReg = /[^a-zA-Z0-9_]/g;
|
|
8543
|
+
const encodeStyleNameChar = (c) => "-" + c.charCodeAt(0).toString(36);
|
|
8544
|
+
function dynamicStyleName(tag, index) {
|
|
8545
|
+
const { file } = tag.hub;
|
|
8546
|
+
const id = (0, _marko_compiler_babel_utils.getTemplateId)(file.markoOpts, file.opts.filename, index.toString(36));
|
|
8547
|
+
return "--" + ((file.markoOpts.runtimeId || "M_") + id).replace(styleNameUnsafeReg, encodeStyleNameChar);
|
|
8548
|
+
}
|
|
8549
|
+
function checkDynamicStylePlacement(tag) {
|
|
8550
|
+
for (const sibling of tag.getAllPrevSiblings()) {
|
|
8551
|
+
if (isCoreTagName(sibling, "style")) continue;
|
|
8552
|
+
if (sibling.isMarkoText() ? /\S/.test(sibling.node.value) : getNodeContentType(sibling, "startType") !== null) {
|
|
8553
|
+
(0, _marko_compiler_babel_utils.diagnosticWarn)(tag, { label: "The `${...}` values of a [`<style>` tag](https://markojs.com/docs/reference/core-tag#style) only apply to elements rendered after it, so the content before this tag will not receive them. Move the `<style>` tag above the content it styles." });
|
|
8554
|
+
return;
|
|
8555
|
+
}
|
|
8556
|
+
}
|
|
8557
|
+
}
|
|
8558
|
+
function assertNoStyleAttributes(tag) {
|
|
8559
|
+
const { node } = tag;
|
|
8560
|
+
const extClass = (STYLE_EXT_REG.exec(node.rawValue || "")?.[1]?.slice(1))?.replace(/\./g, " ");
|
|
8561
|
+
for (const attr of node.attributes) {
|
|
8562
|
+
if (attr.start == null && attr.type === "MarkoAttribute" && attr.name === "class" && attr.value.type === "StringLiteral" && attr.value.value === extClass) continue;
|
|
8563
|
+
throw tag.hub.buildError(attr.value, "The `style` does not support html attributes." + htmlStyleTagAlternateMsg);
|
|
8564
|
+
}
|
|
8565
|
+
}
|
|
8566
|
+
function translateHTML$1(tag) {
|
|
8567
|
+
const { node } = tag;
|
|
8568
|
+
const dynamic = node.extra?.dynamicStyle;
|
|
8569
|
+
if (dynamic) {
|
|
8570
|
+
const { binding } = dynamic;
|
|
8571
|
+
const section = getSection(tag);
|
|
8572
|
+
writeTo(tag)`${callRuntime("_style_html", buildStyleDecls(node))}`;
|
|
8573
|
+
markNode(tag, binding, getSerializeReason(section, binding));
|
|
8574
|
+
}
|
|
8575
|
+
emitStyleImport(tag);
|
|
8576
|
+
tag.remove();
|
|
8577
|
+
}
|
|
8578
|
+
function translateDOM$1(tag) {
|
|
8579
|
+
const { node } = tag;
|
|
8580
|
+
const dynamic = node.extra?.dynamicStyle;
|
|
8581
|
+
if (dynamic) {
|
|
8582
|
+
const { names, binding } = dynamic;
|
|
8583
|
+
const section = getSection(tag);
|
|
8584
|
+
const write = writeTo(tag);
|
|
8585
|
+
const readEl = () => createScopeReadExpression(binding);
|
|
8586
|
+
visit(tag, 32);
|
|
8587
|
+
write`<style>`;
|
|
8588
|
+
addStatement("render", section, void 0, [_marko_compiler.types.expressionStatement(callRuntime("_attr_nonce", scopeIdentifier, getScopeAccessorLiteral(binding))), _marko_compiler.types.expressionStatement(callRuntime("_style_shell", scopeIdentifier, getScopeAccessorLiteral(binding)))], void 0, true);
|
|
8589
|
+
dynamicStyleValues(node).forEach((value, i) => {
|
|
8590
|
+
const valueRef = value.extra?.referencedBindings;
|
|
8591
|
+
addStatement("render", section, valueRef, _marko_compiler.types.expressionStatement(callRuntime("_style_rule_item", readEl(), _marko_compiler.types.stringLiteral(names[i]), value)), void 0, !valueRef);
|
|
8592
|
+
});
|
|
8593
|
+
write`</style>`;
|
|
8594
|
+
}
|
|
8595
|
+
emitStyleImport(tag);
|
|
8596
|
+
tag.remove();
|
|
8597
|
+
}
|
|
8598
|
+
function dynamicStyleValues(node) {
|
|
8599
|
+
const values = [];
|
|
8600
|
+
for (const child of node.body.body) if (_marko_compiler.types.isMarkoPlaceholder(child)) values.push(child.value);
|
|
8601
|
+
return values;
|
|
8602
|
+
}
|
|
8603
|
+
function emitStyleImport(tag) {
|
|
8604
|
+
const { node, hub: { file } } = tag;
|
|
8605
|
+
const importPath = node.extra?.styleImportPath;
|
|
8606
|
+
if (!importPath) return;
|
|
8607
|
+
if (!node.var) (0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.importDeclaration([], _marko_compiler.types.stringLiteral(importPath)));
|
|
8608
|
+
else if (_marko_compiler.types.isIdentifier(node.var)) (0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.importDeclaration([_marko_compiler.types.importNamespaceSpecifier(node.var)], _marko_compiler.types.stringLiteral(importPath)));
|
|
8609
|
+
else {
|
|
8610
|
+
const varDecl = _marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(node.var, (0, _marko_compiler_babel_utils.importStar)(file, importPath, "style"))]);
|
|
8611
|
+
(0, _marko_compiler_babel_utils.getProgram)().node.body.push(isOutputDOM() ? varDecl : _marko_compiler.types.markoScriptlet([varDecl], true));
|
|
8612
|
+
}
|
|
8613
|
+
}
|
|
8614
|
+
function buildStyleDecls(node) {
|
|
8615
|
+
const { names } = node.extra.dynamicStyle;
|
|
8616
|
+
const parts = [];
|
|
8617
|
+
dynamicStyleValues(node).forEach((value, i) => {
|
|
8618
|
+
parts.push(`${names[i]}:`);
|
|
8619
|
+
parts.push(callRuntime("_escape_style_value", value));
|
|
8620
|
+
parts.push(";");
|
|
8621
|
+
});
|
|
8622
|
+
return normalizeStringExpression(parts);
|
|
8623
|
+
}
|
|
8272
8624
|
/**
|
|
8273
8625
|
* Resolves a `<style>` block's text content to its client side import path
|
|
8274
8626
|
* (eg `./template.marko.css`) by handing the css off to the configured
|
|
8275
8627
|
* `resolveVirtualDependency` hook.
|
|
8276
8628
|
*/
|
|
8277
|
-
function getStyleImportPath(file, node) {
|
|
8629
|
+
function getStyleImportPath(file, node, names) {
|
|
8278
8630
|
const { resolveVirtualDependency } = file.markoOpts;
|
|
8279
8631
|
if (!resolveVirtualDependency) return;
|
|
8280
8632
|
const { filename, sourceMaps } = file.opts;
|
|
8281
8633
|
let ext = STYLE_EXT_REG.exec(node.rawValue || "")?.[1] || ".css";
|
|
8282
8634
|
if (node.var && !/\.module\./.test(ext)) ext = ".module" + ext;
|
|
8283
|
-
|
|
8635
|
+
const magicString = sourceMaps ? new magic_string.default(file.code, { filename }) : void 0;
|
|
8284
8636
|
let code = "";
|
|
8285
8637
|
let last = 0;
|
|
8286
8638
|
let map;
|
|
8639
|
+
let nameIndex = 0;
|
|
8287
8640
|
for (const child of node.body.body) {
|
|
8288
|
-
|
|
8289
|
-
|
|
8641
|
+
const placeholder = _marko_compiler.types.isMarkoPlaceholder(child);
|
|
8642
|
+
const text = placeholder ? `var(${names[nameIndex++]})` : child.value;
|
|
8643
|
+
if (magicString) {
|
|
8290
8644
|
const start = (0, _marko_compiler_babel_utils.getStart)(file, child);
|
|
8291
|
-
if (start
|
|
8292
|
-
|
|
8645
|
+
if (start === null) magicString.appendLeft(last, text);
|
|
8646
|
+
else {
|
|
8647
|
+
const end = (0, _marko_compiler_babel_utils.getEnd)(file, child);
|
|
8293
8648
|
if (start > last) magicString.remove(last, start);
|
|
8294
|
-
|
|
8649
|
+
if (placeholder) magicString.update(start, end, text);
|
|
8650
|
+
last = end;
|
|
8295
8651
|
}
|
|
8296
|
-
}
|
|
8652
|
+
} else code += text;
|
|
8297
8653
|
}
|
|
8298
8654
|
if (magicString) {
|
|
8299
8655
|
if (file.code.length > last) magicString.remove(last, file.code.length);
|
|
8656
|
+
code = magicString.toString();
|
|
8300
8657
|
map = magicString.generateMap({
|
|
8301
8658
|
source: filename,
|
|
8302
8659
|
includeContent: true
|
|
@@ -8424,6 +8781,7 @@ var core_default = {
|
|
|
8424
8781
|
"<return>": return_default,
|
|
8425
8782
|
"<script>": script_default,
|
|
8426
8783
|
"<server>": server_default,
|
|
8784
|
+
"<show>": show_default,
|
|
8427
8785
|
"<static>": static_default,
|
|
8428
8786
|
"<style>": style_default,
|
|
8429
8787
|
"<try>": try_default
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { types as t } from "@marko/compiler";
|
|
2
|
+
export declare const htmlStyleTagAlternateMsg = " For a native html [`<style>` tag](https://markojs.com/docs/reference/core-tag#style) use the `html-style` core tag instead.";
|
|
3
|
+
export declare function checkStyleInterpolations(tag: t.NodePath<t.MarkoTag>): void;
|