diff --git a/packages/translator-default/src/placeholder/index[html].js b/packages/translator-default/src/placeholder/index[html].js
index 99ab9b20c2..74c2207a28 100644
--- a/packages/translator-default/src/placeholder/index[html].js
+++ b/packages/translator-default/src/placeholder/index[html].js
@@ -1,5 +1,10 @@
import { types as t } from "@marko/compiler";
-import { getTagDef, importDefault, importNamed } from "@marko/babel-utils";
+import {
+ computeNode,
+ getTagDef,
+ importDefault,
+ importNamed,
+} from "@marko/babel-utils";
import toString from "marko/src/runtime/helpers/to-string";
import { x as escapeXML } from "marko/src/runtime/html/helpers/escape-xml";
import escapeScript from "marko/src/runtime/html/helpers/escape-script-placeholder";
@@ -31,15 +36,15 @@ export default function (path) {
node,
hub: { file },
} = path;
- const { confident, value: computed } = path.get("value").evaluate();
+ const computed = computeNode(node.value);
let { escape, value } = node;
if (escape) {
const tagName = findParentTagName(path);
const escapeType = ESCAPE_TYPES[tagName] || ESCAPE_TYPES.html;
- value = confident
- ? t.stringLiteral(escapeType.fn(computed))
+ value = computed
+ ? t.stringLiteral(escapeType.fn(computed.value))
: t.callExpression(
escapeType.name
? importNamed(
@@ -52,8 +57,8 @@ export default function (path) {
[value]
);
} else {
- value = confident
- ? t.stringLiteral(toString(computed))
+ value = computed
+ ? t.stringLiteral(toString(computed.value))
: t.callExpression(
importDefault(
file,
diff --git a/packages/translator-default/src/placeholder/index[vdom].js b/packages/translator-default/src/placeholder/index[vdom].js
index 8e7a68e141..60b48fc416 100644
--- a/packages/translator-default/src/placeholder/index[vdom].js
+++ b/packages/translator-default/src/placeholder/index[vdom].js
@@ -1,3 +1,4 @@
+import { computeNode } from "@marko/babel-utils";
import write from "../util/vdom-out-write";
import withPreviousLocation from "../util/with-previous-location";
@@ -5,9 +6,9 @@ export default function (path) {
const { node } = path;
const { escape, value } = node;
const method = escape ? "t" : "h";
- const { confident, value: computed } = path.get("value").evaluate();
+ const computed = computeNode(value);
- if (confident && !computed) {
+ if (computed && computed.value == null) {
path.remove();
} else {
path.replaceWith(
diff --git a/packages/translator-default/src/tag/attribute/directives/class.js b/packages/translator-default/src/tag/attribute/directives/class.js
index f789cc4d7c..261867859a 100644
--- a/packages/translator-default/src/tag/attribute/directives/class.js
+++ b/packages/translator-default/src/tag/attribute/directives/class.js
@@ -1,5 +1,5 @@
import { types as t } from "@marko/compiler";
-import { importDefault, isNativeTag } from "@marko/babel-utils";
+import { computeNode, importDefault, isNativeTag } from "@marko/babel-utils";
import classToString from "marko/src/runtime/helpers/class-value";
import withPreviousLocation from "../../../util/with-previous-location";
@@ -9,27 +9,29 @@ export default {
hub: { file },
} = tag;
if (!isNativeTag(tag)) return;
- if (value.isStringLiteral()) return;
- const { confident, value: computed } = value.evaluate();
-
- const s = classToString(computed);
- value.replaceWith(
- confident
- ? s
- ? t.stringLiteral(s)
- : t.nullLiteral()
- : withPreviousLocation(
- t.callExpression(
- importDefault(
- file,
- "marko/src/runtime/helpers/class-value.js",
- "marko_class_merge"
- ),
- [value.node]
+ const computed = computeNode(value.node);
+ if (computed) {
+ const str = classToString(computed.value);
+ if (str) {
+ value.replaceWith(t.stringLiteral(str));
+ } else {
+ value.parentPath.remove();
+ }
+ } else {
+ value.replaceWith(
+ withPreviousLocation(
+ t.callExpression(
+ importDefault(
+ file,
+ "marko/src/runtime/helpers/class-value.js",
+ "marko_class_merge"
),
- value.node
- )
- );
+ [value.node]
+ ),
+ value.node
+ )
+ );
+ }
},
};
diff --git a/packages/translator-default/src/tag/attribute/directives/style.js b/packages/translator-default/src/tag/attribute/directives/style.js
index da0995c2fe..0d044f613e 100644
--- a/packages/translator-default/src/tag/attribute/directives/style.js
+++ b/packages/translator-default/src/tag/attribute/directives/style.js
@@ -1,5 +1,5 @@
import { types as t } from "@marko/compiler";
-import { importDefault, isNativeTag } from "@marko/babel-utils";
+import { computeNode, importDefault, isNativeTag } from "@marko/babel-utils";
import styleToString from "marko/src/runtime/helpers/style-value";
import withPreviousLocation from "../../../util/with-previous-location";
@@ -8,24 +8,30 @@ export default {
const {
hub: { file },
} = tag;
- if (value.isStringLiteral()) return;
if (!isNativeTag(tag)) return;
- const { confident, value: computed } = value.evaluate();
- value.replaceWith(
- withPreviousLocation(
- confident
- ? t.stringLiteral(styleToString(computed) || "")
- : t.callExpression(
- importDefault(
- file,
- "marko/src/runtime/helpers/style-value.js",
- "marko_style_merge"
- ),
- [value.node]
+ const computed = computeNode(value.node);
+ if (computed) {
+ const str = styleToString(computed.value);
+ if (str) {
+ value.replaceWith(t.stringLiteral(str));
+ } else {
+ value.parentPath.remove();
+ }
+ } else {
+ value.replaceWith(
+ withPreviousLocation(
+ t.callExpression(
+ importDefault(
+ file,
+ "marko/src/runtime/helpers/style-value.js",
+ "marko_style_merge"
),
- value.node
- )
- );
+ [value.node]
+ ),
+ value.node
+ )
+ );
+ }
},
};
diff --git a/packages/translator-default/src/tag/native-tag[html]/attributes.js b/packages/translator-default/src/tag/native-tag[html]/attributes.js
index 22d2af20f5..e918323248 100644
--- a/packages/translator-default/src/tag/native-tag[html]/attributes.js
+++ b/packages/translator-default/src/tag/native-tag[html]/attributes.js
@@ -50,12 +50,21 @@ export default function (path, attrs) {
const attr = attrs[i];
const { name, value } = attr.node;
if (attrValues.has(name)) continue;
- const { confident, computed } = evaluateAttr(attr);
- attrValues.set(name, {
- confident,
- computed,
- value,
- });
+ const computed = evaluateAttr(attr);
+ attrValues.set(
+ name,
+ computed
+ ? {
+ confident: true,
+ computed: computed.value,
+ value,
+ }
+ : {
+ confident: false,
+ computed: undefined,
+ value,
+ }
+ );
}
for (const [name, { confident, computed, value }] of [
diff --git a/packages/translator-default/src/tag/native-tag[vdom]/index.js b/packages/translator-default/src/tag/native-tag[vdom]/index.js
index 666e45c07a..a4cdf7fb5a 100644
--- a/packages/translator-default/src/tag/native-tag[vdom]/index.js
+++ b/packages/translator-default/src/tag/native-tag[vdom]/index.js
@@ -44,13 +44,13 @@ export function tagArguments(path, isStatic) {
}
seen.add(name);
- const { confident, computed } = evaluateAttr(attr);
+ const computed = evaluateAttr(attr);
- if (confident) {
- if (computed == null || computed === false) {
+ if (computed) {
+ if (computed.value === undefined) {
if (!hasSpread) attr.remove();
} else {
- attr.set("value", t.stringLiteral(computed));
+ attr.set("value", t.stringLiteral(computed.value));
}
}
}
diff --git a/packages/translator-default/src/tag/util.js b/packages/translator-default/src/tag/util.js
index 45de7915cc..5eb903fa0c 100644
--- a/packages/translator-default/src/tag/util.js
+++ b/packages/translator-default/src/tag/util.js
@@ -1,5 +1,7 @@
import { types as t } from "@marko/compiler";
-import { getTagDef } from "@marko/babel-utils";
+import { computeNode, getTagDef } from "@marko/babel-utils";
+import classToString from "marko/src/runtime/helpers/class-value";
+import styleToString from "marko/src/runtime/helpers/style-value";
export function getAttrs(path, preserveNames, skipRenderBody) {
const { node } = path;
@@ -156,31 +158,47 @@ export function buildEventHandlerArray(path) {
}
export function evaluateAttr(attr) {
- const name = attr.get("name").node;
- const value = attr.get("value");
- let confident = false;
- let computed = undefined;
-
- if (name) {
- if (value.isRegExpLiteral()) {
- confident = true;
- computed = value.get("pattern").node;
- } else {
- const evaluated = value.evaluate();
- ({ confident, value: computed } = evaluated);
+ if (attr.node.name) {
+ const computed = computeNode(attr.node.value);
+ if (computed) {
+ const { value } = computed;
+ switch (attr.node.name) {
+ case "class":
+ return {
+ value: classToString(value)
+ ?.replace(/(\s)\s/, "$1")
+ .trim(),
+ };
+ case "style":
+ return {
+ value: styleToString(value)
+ ?.replace(/(\s)\s/, "$1")
+ .trim()
+ .replace(/;$/, ""),
+ };
+ }
- if (computed === true) {
- computed = "";
- } else if (computed != null && computed !== false) {
- computed = computed + "";
+ if (value == null || value === false) {
+ return { value: undefined };
}
+
+ if (value === true) {
+ return { value: "" };
+ }
+
+ if (typeof value === "object") {
+ switch (value.toString) {
+ case Object.prototype.toString:
+ case Array.prototype.toString:
+ return { value: JSON.stringify(value) };
+ case RegExp.prototype.toString:
+ return { value: value.source };
+ }
+ }
+
+ return { value: value + "" };
}
}
-
- return {
- confident,
- computed,
- };
}
function camelCase(string) {
diff --git a/packages/translator-default/src/util/optimize-vdom-create.js b/packages/translator-default/src/util/optimize-vdom-create.js
index ff8f730f97..60973f8f7f 100644
--- a/packages/translator-default/src/util/optimize-vdom-create.js
+++ b/packages/translator-default/src/util/optimize-vdom-create.js
@@ -1,6 +1,7 @@
import { decode } from "he";
import { types as t } from "@marko/compiler";
import {
+ computeNode,
getTagDef,
importDefault,
isLoopTag,
@@ -9,8 +10,13 @@ import {
import { getKeyManager } from "./key-manager";
import write from "./vdom-out-write";
import { tagArguments } from "../tag/native-tag[vdom]";
-import directives from "../tag/attribute/directives";
+const skipDirectives = new Set([
+ "no-update",
+ "no-update-if",
+ "no-update-body",
+ "no-update-body-if",
+]);
const staticNodes = new WeakSet();
const mergeStaticCreateVisitor = {
@@ -22,10 +28,14 @@ const mergeStaticCreateVisitor = {
);
},
MarkoPlaceholder(path, state) {
- const { value } = path.get("value").evaluate();
+ const computed = computeNode(path.node.value);
state.currentRoot = t.callExpression(
t.memberExpression(state.currentRoot, t.identifier("t")),
- [t.stringLiteral(value != null ? value.toString() : "")]
+ [
+ t.stringLiteral(
+ computed && computed.value != null ? `${computed.value}` : ""
+ ),
+ ]
);
},
MarkoTag(path, state) {
@@ -44,8 +54,8 @@ const analyzeStaticVisitor = {
},
MarkoPlaceholder(path) {
if (path.node.escape) {
- const { confident } = path.get("value").evaluate();
- if (confident) {
+ const computed = computeNode(path.node.value);
+ if (computed) {
staticNodes.add(path.node);
}
}
@@ -68,24 +78,18 @@ const analyzeStaticVisitor = {
// check attributes
isStatic =
isStatic &&
- path.get("attributes").every((attr) => {
- if (
- !t.isMarkoAttribute(attr) ||
- attr.node.arguments ||
- attr.node.modifier ||
- directives[attr.node.name]
- )
- return false;
-
- const attrValue = attr.get("value");
- const exclude =
- t.isObjectExpression(attrValue) ||
- t.isArrayExpression(attrValue) ||
- t.isRegExpLiteral(attrValue);
- if (exclude) return false;
- const { confident } = attrValue.evaluate();
- return confident;
- });
+ path
+ .get("attributes")
+ .every(
+ (attr) =>
+ t.isMarkoAttribute(attr) &&
+ !(
+ attr.node.arguments ||
+ attr.node.modifier ||
+ skipDirectives.has(attr.node.name) ||
+ !computeNode(attr.node.value)
+ )
+ );
// check children
isStatic =
diff --git a/packages/translator-default/test/fixtures/attr-class/snapshots/vdomProduction-expected.js b/packages/translator-default/test/fixtures/attr-class/snapshots/vdomProduction-expected.js
index 1df9bfbbb2..e92ef60129 100644
--- a/packages/translator-default/test/fixtures/attr-class/snapshots/vdomProduction-expected.js
+++ b/packages/translator-default/test/fixtures/attr-class/snapshots/vdomProduction-expected.js
@@ -3,6 +3,13 @@ const _marko_componentType = "TKoJdMQb",
_marko_template = _t(_marko_componentType);
export default _marko_template;
import _marko_class_merge from "marko/dist/runtime/helpers/class-value.js";
+import _marko_createElement from "marko/dist/runtime/vdom/helpers/v-element.js";
+const _marko_node = _marko_createElement("div", {
+ "class": "a b"
+}, "1", null, 0, 1);
+const _marko_node2 = _marko_createElement("div", {
+ "class": "a b c"
+}, "2", null, 0, 1);
import _customTag from "./components/custom-tag.marko";
import _marko_tag from "marko/dist/runtime/helpers/render-tag.js";
import _marko_self_iterator from "marko/dist/runtime/helpers/self-iterator.js";
@@ -18,12 +25,8 @@ _marko_template._ = _marko_renderer(function (input, out, _componentDef, _compon
d
}])
}, "0", _component, 0, 1);
- out.e("div", {
- "class": "a b"
- }, "1", _component, 0, 1);
- out.e("div", {
- "class": "a b c"
- }, "2", _component, 0, 1);
+ out.n(_marko_node, _component);
+ out.n(_marko_node2, _component);
_marko_tag(_customTag, {
"class": ["a", {
b: c,
diff --git a/packages/translator-default/test/fixtures/attr-style/snapshots/cjs-expected.js b/packages/translator-default/test/fixtures/attr-style/snapshots/cjs-expected.js
index 3334956e5f..902cf16c39 100644
--- a/packages/translator-default/test/fixtures/attr-style/snapshots/cjs-expected.js
+++ b/packages/translator-default/test/fixtures/attr-style/snapshots/cjs-expected.js
@@ -20,7 +20,7 @@ _marko_template._ = (0, _renderer.default)(function (input, out, _componentDef,
out.w(`
`);
- out.w("
");
+ out.w("
");
out.w("
");
(0, _renderTag.default)(_customTag2.default, {
"style": {
diff --git a/packages/translator-default/test/fixtures/attr-style/snapshots/html-expected.js b/packages/translator-default/test/fixtures/attr-style/snapshots/html-expected.js
index 6ad3b65f31..802dd675e4 100644
--- a/packages/translator-default/test/fixtures/attr-style/snapshots/html-expected.js
+++ b/packages/translator-default/test/fixtures/attr-style/snapshots/html-expected.js
@@ -14,7 +14,7 @@ _marko_template._ = _marko_renderer(function (input, out, _componentDef, _compon
out.w(`
`);
- out.w("
");
+ out.w("
");
out.w("
");
_marko_tag(_customTag, {
"style": {
diff --git a/packages/translator-default/test/fixtures/attr-style/snapshots/htmlProduction-expected.js b/packages/translator-default/test/fixtures/attr-style/snapshots/htmlProduction-expected.js
index 5fab17a4a5..58eb2f943f 100644
--- a/packages/translator-default/test/fixtures/attr-style/snapshots/htmlProduction-expected.js
+++ b/packages/translator-default/test/fixtures/attr-style/snapshots/htmlProduction-expected.js
@@ -13,7 +13,7 @@ const _marko_component = {};
_marko_template._ = _marko_renderer(function (input, out, _componentDef, _component, state, $global) {
out.w(`
`);
+ }))}>
`);
_marko_tag(_customTag, {
"style": {
color: input.color
diff --git a/packages/translator-default/test/fixtures/attr-style/snapshots/vdom-expected.js b/packages/translator-default/test/fixtures/attr-style/snapshots/vdom-expected.js
index ac9682b43e..e09e875c0a 100644
--- a/packages/translator-default/test/fixtures/attr-style/snapshots/vdom-expected.js
+++ b/packages/translator-default/test/fixtures/attr-style/snapshots/vdom-expected.js
@@ -18,7 +18,7 @@ _marko_template._ = _marko_renderer(function (input, out, _componentDef, _compon
})
}, "0", _component, 0, 1);
out.e("div", {
- "style": "width:100px;"
+ "style": "width:100px"
}, "1", _component, 0, 1);
out.e("div", {
"style": "color: green"
diff --git a/packages/translator-default/test/fixtures/attr-style/snapshots/vdomProduction-expected.js b/packages/translator-default/test/fixtures/attr-style/snapshots/vdomProduction-expected.js
index 74bca0069e..99deab68a2 100644
--- a/packages/translator-default/test/fixtures/attr-style/snapshots/vdomProduction-expected.js
+++ b/packages/translator-default/test/fixtures/attr-style/snapshots/vdomProduction-expected.js
@@ -3,6 +3,13 @@ const _marko_componentType = "Up7A+MWi",
_marko_template = _t(_marko_componentType);
export default _marko_template;
import _marko_style_merge from "marko/dist/runtime/helpers/style-value.js";
+import _marko_createElement from "marko/dist/runtime/vdom/helpers/v-element.js";
+const _marko_node = _marko_createElement("div", {
+ "style": "width:100px"
+}, "1", null, 0, 1);
+const _marko_node2 = _marko_createElement("div", {
+ "style": "color: green"
+}, "2", null, 0, 1);
import _customTag from "./components/custom-tag.marko";
import _marko_tag from "marko/dist/runtime/helpers/render-tag.js";
import _marko_self_iterator from "marko/dist/runtime/helpers/self-iterator.js";
@@ -17,12 +24,8 @@ _marko_template._ = _marko_renderer(function (input, out, _componentDef, _compon
color: input.color
})
}, "0", _component, 0, 1);
- out.e("div", {
- "style": "width:100px;"
- }, "1", _component, 0, 1);
- out.e("div", {
- "style": "color: green"
- }, "2", _component, 0, 1);
+ out.n(_marko_node, _component);
+ out.n(_marko_node2, _component);
_marko_tag(_customTag, {
"style": {
color: input.color
diff --git a/packages/translator-default/test/fixtures/custom-tag-transform/snapshots/vdomProduction-expected.js b/packages/translator-default/test/fixtures/custom-tag-transform/snapshots/vdomProduction-expected.js
index 155594f330..a760debc2d 100644
--- a/packages/translator-default/test/fixtures/custom-tag-transform/snapshots/vdomProduction-expected.js
+++ b/packages/translator-default/test/fixtures/custom-tag-transform/snapshots/vdomProduction-expected.js
@@ -2,14 +2,16 @@ import { t as _t } from "marko/dist/runtime/vdom/index.js";
const _marko_componentType = "5fhDZgMT",
_marko_template = _t(_marko_componentType);
export default _marko_template;
+import _marko_createElement from "marko/dist/runtime/vdom/helpers/v-element.js";
+const _marko_node = _marko_createElement("span", {
+ "style": "display:block"
+}, "0", null, 0, 1);
import _marko_renderer from "marko/dist/runtime/components/renderer.js";
import { r as _marko_registerComponent } from "marko/dist/runtime/components/registry";
_marko_registerComponent(_marko_componentType, () => _marko_template);
const _marko_component = {};
_marko_template._ = _marko_renderer(function (input, out, _componentDef, _component, state, $global) {
- out.e("span", {
- "style": "display:block"
- }, "0", _component, 0, 1);
+ out.n(_marko_node, _component);
}, {
t: _marko_componentType,
i: true
diff --git a/packages/translator-default/test/fixtures/data-migration/snapshots/cjs-expected.js b/packages/translator-default/test/fixtures/data-migration/snapshots/cjs-expected.js
index 1147819710..d2713b003b 100644
--- a/packages/translator-default/test/fixtures/data-migration/snapshots/cjs-expected.js
+++ b/packages/translator-default/test/fixtures/data-migration/snapshots/cjs-expected.js
@@ -36,7 +36,7 @@ _marko_template._ = (0, _renderer.default)(function (input, out, _componentDef,
if (true) {
const data = "bar";
out.w("Hello ");
- out.w("bar");
+ out.w((0, _escapeXml.x)(data));
}
out.w("