diff --git a/.changeset/light-snakes-design.md b/.changeset/light-snakes-design.md new file mode 100644 index 0000000000..53cc955c95 --- /dev/null +++ b/.changeset/light-snakes-design.md @@ -0,0 +1,8 @@ +--- +"@marko/translator-default": minor +"@marko/babel-utils": minor +"@marko/compiler": minor +"marko": minor +--- + +Add compute node helper to replace babels `evaluate` helper. This helper is less aggressive and doesn't suffer from the false positives that popped up with babels version. diff --git a/.changeset/nice-comics-taste.md b/.changeset/nice-comics-taste.md new file mode 100644 index 0000000000..3d253dd74e --- /dev/null +++ b/.changeset/nice-comics-taste.md @@ -0,0 +1,6 @@ +--- +"@marko/translator-default": patch +"marko": patch +--- + +Avoid adding trailing semicolon to style attribute output. diff --git a/packages/babel-utils/index.d.ts b/packages/babel-utils/index.d.ts index 785a0f779c..9d6186a2f7 100644 --- a/packages/babel-utils/index.d.ts +++ b/packages/babel-utils/index.d.ts @@ -375,3 +375,15 @@ interface SelectFix { }[]; initialValue?: string; } + +type Computed = + | undefined + | number + | string + | boolean + | RegExp + | bigint + | null + | { [x: string]: Computed } + | Computed[]; +export function computeNode(node: t.Node): undefined | { value: Computed }; diff --git a/packages/babel-utils/src/compute.js b/packages/babel-utils/src/compute.js new file mode 100644 index 0000000000..2ef481db69 --- /dev/null +++ b/packages/babel-utils/src/compute.js @@ -0,0 +1,194 @@ +/** + * @param {import("@babel/types").Node} node + */ +export function computeNode(node) { + switch (node.type) { + case "StringLiteral": + case "NumericLiteral": + case "BooleanLiteral": + return { value: node.value }; + case "RegExpLiteral": + return { value: new RegExp(node.pattern, node.flags) }; + case "NullLiteral": + return { value: null }; + case "Identifier": + switch (node.name) { + case "undefined": + return { value: undefined }; + case "NaN": + return { value: NaN }; + case "Infinity": + return { value: Infinity }; + default: + return; + } + case "BigIntLiteral": + return { value: BigInt(node.value) }; + case "BinaryExpression": { + const left = computeNode(node.left); + if (!left) return; + const right = computeNode(node.right); + if (!right) return; + switch (node.operator) { + case "+": + return { value: left.value + right.value }; + case "-": + return { value: left.value - right.value }; + case "*": + return { value: left.value * right.value }; + case "/": + return { value: left.value / right.value }; + case "%": + return { value: left.value % right.value }; + case "**": + return { value: left.value ** right.value }; + case "|": + return { value: left.value | right.value }; + case "&": + return { value: left.value & right.value }; + case "^": + return { value: left.value ^ right.value }; + case "<<": + return { value: left.value << right.value }; + case ">>": + return { value: left.value >> right.value }; + case ">>>": + return { value: left.value >>> right.value }; + case "==": + return { value: left.value == right.value }; + case "!=": + return { value: left.value != right.value }; + case "===": + return { value: left.value === right.value }; + case "!==": + return { value: left.value !== right.value }; + case "<": + return { value: left.value < right.value }; + case "<=": + return { value: left.value <= right.value }; + case ">": + return { value: left.value > right.value }; + case ">=": + return { value: left.value >= right.value }; + default: + return; + } + } + case "UnaryExpression": { + const arg = computeNode(node.argument); + if (!arg) return; + switch (node.operator) { + case "+": + return { value: +arg.value }; + case "-": + return { value: -arg.value }; + case "~": + return { value: ~arg.value }; + case "!": + return { value: !arg.value }; + case "typeof": + return { value: typeof arg.value }; + case "void": + return { value: void arg.value }; + default: + return; + } + } + case "LogicalExpression": { + const left = computeNode(node.left); + if (!left) return; + const right = computeNode(node.right); + if (!right) return; + switch (node.operator) { + case "&&": + return { value: left.value && right.value }; + case "||": + return { value: left.value || right.value }; + case "??": + return { value: left.value ?? right.value }; + default: + return; + } + } + case "ConditionalExpression": { + const test = computeNode(node.test); + if (!test) return; + const consequent = computeNode(node.consequent); + if (!consequent) return; + const alternate = computeNode(node.alternate); + if (!alternate) return; + return { value: test.value ? consequent.value : alternate.value }; + } + case "TemplateLiteral": { + let value = node.quasis[0].cooked; + for (let i = 0; i < node.expressions.length; i++) { + const expr = computeNode(node.expressions[i]); + if (!expr) return; + value += expr.value + node.quasis[i + 1].cooked; + } + return { value }; + } + case "ObjectExpression": { + const value = {}; + for (const prop of node.properties) { + if (prop.decorators) return; + switch (prop.type) { + case "ObjectProperty": { + let key; + if (prop.computed) { + const keyNode = computeNode(prop.key); + if (!keyNode) return; + key = keyNode.value + ""; + } else { + switch (prop.key.type) { + case "Identifier": + key = prop.key.name; + break; + case "StringLiteral": + key = prop.key.value; + break; + default: + return; + } + } + + const propValue = computeNode(prop.value); + if (!propValue) return; + value[key] = propValue.value; + break; + } + case "SpreadElement": { + const arg = computeNode(prop.argument); + if (!arg) return; + Object.assign(value, arg.value); + break; + } + } + } + + return { value }; + } + case "ArrayExpression": { + const value = []; + for (const elem of node.elements) { + if (elem) { + if (elem.type === "SpreadElement") { + const arg = computeNode(elem.argument); + if (typeof arg?.value?.[Symbol.iterator] !== "function") return; + for (const item of arg.value) { + value.push(item); + } + } else { + const elemValue = computeNode(elem); + if (!elemValue) return; + value.push(elemValue.value); + } + } else { + value.length++; + } + } + + return { value }; + } + } +} diff --git a/packages/babel-utils/src/index.js b/packages/babel-utils/src/index.js index 1a5f7dc0a8..8c4593f17e 100644 --- a/packages/babel-utils/src/index.js +++ b/packages/babel-utils/src/index.js @@ -27,6 +27,7 @@ export { assertNoVar, assertNoAttributeTags, } from "./assert"; +export { computeNode } from "./compute"; export { normalizeTemplateString } from "./template-string"; export { getLoc, getLocRange, withLoc } from "./loc"; diff --git a/packages/marko/src/runtime/helpers/style-value.js b/packages/marko/src/runtime/helpers/style-value.js index 79afd56aa7..368edc923e 100644 --- a/packages/marko/src/runtime/helpers/style-value.js +++ b/packages/marko/src/runtime/helpers/style-value.js @@ -14,11 +14,15 @@ module.exports = function styleHelper(style) { if (type !== "string") { var styles = ""; + var sep = ""; if (Array.isArray(style)) { for (var i = 0, len = style.length; i < len; i++) { var next = styleHelper(style[i]); - if (next) styles += next + (next[next.length - 1] !== ";" ? ";" : ""); + if (next) { + styles += sep + next; + sep = ";"; + } } } else if (type === "object") { for (var name in style) { @@ -28,7 +32,8 @@ module.exports = function styleHelper(style) { value += "px"; } - styles += changeCase.___camelToDashCase(name) + ":" + value + ";"; + styles += sep + changeCase.___camelToDashCase(name) + ":" + value; + sep = ";"; } } } diff --git a/packages/marko/test/components-browser/fixtures/input-persisted-nested-component/test.js b/packages/marko/test/components-browser/fixtures/input-persisted-nested-component/test.js index 6cec8f3961..5c95aa5f82 100644 --- a/packages/marko/test/components-browser/fixtures/input-persisted-nested-component/test.js +++ b/packages/marko/test/components-browser/fixtures/input-persisted-nested-component/test.js @@ -5,9 +5,9 @@ module.exports = function (helpers) { color: "red", }); - expect(component.el.getAttribute("style")).to.equal("color:red;"); + expect(component.el.getAttribute("style")).to.equal("color:red"); expect(component.getComponent("counter").el.getAttribute("style")).to.equal( - "color:red;" + "color:red" ); expect( component.getComponent("counter").el.querySelector(".count").innerHTML @@ -16,9 +16,9 @@ module.exports = function (helpers) { component.getComponent("counter").increment(); component.getComponent("counter").update(); - expect(component.el.getAttribute("style")).to.equal("color:red;"); + expect(component.el.getAttribute("style")).to.equal("color:red"); expect(component.getComponent("counter").el.getAttribute("style")).to.equal( - "color:red;" + "color:red" ); expect( component.getComponent("counter").el.querySelector(".count").innerHTML diff --git a/packages/marko/test/components-browser/fixtures/input-persisted/test.js b/packages/marko/test/components-browser/fixtures/input-persisted/test.js index 9e176360a8..3d11c07bcb 100644 --- a/packages/marko/test/components-browser/fixtures/input-persisted/test.js +++ b/packages/marko/test/components-browser/fixtures/input-persisted/test.js @@ -6,13 +6,13 @@ module.exports = function (helpers) { }); expect(component.getEl("current").getAttribute("style")).to.equal( - "color:#09c;" + "color:#09c" ); component.increment(); component.update(); expect(component.getEl("current").getAttribute("style")).to.equal( - "color:#09c;" + "color:#09c" ); }; diff --git a/packages/marko/test/components-pages/fixtures/component-input-ref/tests.js b/packages/marko/test/components-pages/fixtures/component-input-ref/tests.js index a22befad94..511bd89d74 100644 --- a/packages/marko/test/components-pages/fixtures/component-input-ref/tests.js +++ b/packages/marko/test/components-pages/fixtures/component-input-ref/tests.js @@ -4,10 +4,10 @@ it("should serialize component input down to the browser", function () { expect(window.barComponent.getComponent("foo")).to.equal(window.fooComponent); expect(window.fooComponent.input.color).to.equal("#800"); expect(window.fooComponent.el.textContent).to.equal("The current count is 0"); - expect(window.fooComponent.el.getAttribute("style")).to.equal("color:#800;"); + expect(window.fooComponent.el.getAttribute("style")).to.equal("color:#800"); window.fooComponent.increment(); window.fooComponent.update(); expect(window.fooComponent.el.textContent).to.equal("The current count is 1"); - expect(window.fooComponent.el.getAttribute("style")).to.equal("color:#800;"); + expect(window.fooComponent.el.getAttribute("style")).to.equal("color:#800"); expect(window.barComponent.getComponent("foo")).to.equal(window.fooComponent); }); diff --git a/packages/marko/test/components-pages/fixtures/component-input/tests.js b/packages/marko/test/components-pages/fixtures/component-input/tests.js index 2b7df043a1..b2f1c5aeb2 100644 --- a/packages/marko/test/components-pages/fixtures/component-input/tests.js +++ b/packages/marko/test/components-pages/fixtures/component-input/tests.js @@ -3,9 +3,9 @@ var expect = require("chai").expect; it("should serialize component input down to the browser", function () { expect(window.fooComponent.input.color).to.equal("#800"); expect(window.fooComponent.el.textContent).to.equal("The current count is 0"); - expect(window.fooComponent.el.getAttribute("style")).to.equal("color:#800;"); + expect(window.fooComponent.el.getAttribute("style")).to.equal("color:#800"); window.fooComponent.increment(); window.fooComponent.update(); expect(window.fooComponent.el.textContent).to.equal("The current count is 1"); - expect(window.fooComponent.el.getAttribute("style")).to.equal("color:#800;"); + expect(window.fooComponent.el.getAttribute("style")).to.equal("color:#800"); }); diff --git a/packages/marko/test/components-pages/fixtures/runtime-id/tests.js b/packages/marko/test/components-pages/fixtures/runtime-id/tests.js index 3f748a1df0..51856648cd 100644 --- a/packages/marko/test/components-pages/fixtures/runtime-id/tests.js +++ b/packages/marko/test/components-pages/fixtures/runtime-id/tests.js @@ -7,9 +7,9 @@ it("should serialize component input down to the browser", function () { expect(window.fooComponent.input.color).to.equal("#800"); expect(window.fooComponent.el.textContent).to.equal("The current count is 0"); - expect(window.fooComponent.el.getAttribute("style")).to.equal("color:#800;"); + expect(window.fooComponent.el.getAttribute("style")).to.equal("color:#800"); window.fooComponent.increment(); window.fooComponent.update(); expect(window.fooComponent.el.textContent).to.equal("The current count is 1"); - expect(window.fooComponent.el.getAttribute("style")).to.equal("color:#800;"); + expect(window.fooComponent.el.getAttribute("style")).to.equal("color:#800"); }); diff --git a/packages/marko/test/render/fixtures/attrs-normalize-for-native-tag/expected.html b/packages/marko/test/render/fixtures/attrs-normalize-for-native-tag/expected.html index c8de4f84bf..d62ab664b1 100644 --- a/packages/marko/test/render/fixtures/attrs-normalize-for-native-tag/expected.html +++ b/packages/marko/test/render/fixtures/attrs-normalize-for-native-tag/expected.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/packages/marko/test/render/fixtures/attrs-normalize-for-native-tag/vdom-expected.html b/packages/marko/test/render/fixtures/attrs-normalize-for-native-tag/vdom-expected.html index 344b4c9b0b..cad0fad412 100644 --- a/packages/marko/test/render/fixtures/attrs-normalize-for-native-tag/vdom-expected.html +++ b/packages/marko/test/render/fixtures/attrs-normalize-for-native-tag/vdom-expected.html @@ -1 +1 @@ - + diff --git a/packages/marko/test/render/fixtures/dynamic-tag-object-class-style/expected.html b/packages/marko/test/render/fixtures/dynamic-tag-object-class-style/expected.html index 9cb35092d0..1f739ee52c 100644 --- a/packages/marko/test/render/fixtures/dynamic-tag-object-class-style/expected.html +++ b/packages/marko/test/render/fixtures/dynamic-tag-object-class-style/expected.html @@ -1 +1 @@ -My nested content \ No newline at end of file +My nested content \ No newline at end of file diff --git a/packages/marko/test/render/fixtures/dynamic-tag-object-class-style/vdom-expected.html b/packages/marko/test/render/fixtures/dynamic-tag-object-class-style/vdom-expected.html index ae82c0a8c0..4d897184a2 100644 --- a/packages/marko/test/render/fixtures/dynamic-tag-object-class-style/vdom-expected.html +++ b/packages/marko/test/render/fixtures/dynamic-tag-object-class-style/vdom-expected.html @@ -1,2 +1,2 @@ - + "My nested content" diff --git a/packages/marko/test/render/fixtures/shorthand-div-id-dynamic/expected.html b/packages/marko/test/render/fixtures/shorthand-div-id-dynamic/expected.html index da125c09e8..331c15bfe1 100644 --- a/packages/marko/test/render/fixtures/shorthand-div-id-dynamic/expected.html +++ b/packages/marko/test/render/fixtures/shorthand-div-id-dynamic/expected.html @@ -1 +1 @@ -
Hello Frank!
\ No newline at end of file +
Hello Frank!
\ No newline at end of file diff --git a/packages/marko/test/render/fixtures/shorthand-div-id-dynamic/vdom-expected.html b/packages/marko/test/render/fixtures/shorthand-div-id-dynamic/vdom-expected.html index 76cd27f93d..f025b0e886 100644 --- a/packages/marko/test/render/fixtures/shorthand-div-id-dynamic/vdom-expected.html +++ b/packages/marko/test/render/fixtures/shorthand-div-id-dynamic/vdom-expected.html @@ -1,2 +1,2 @@ -
+
"Hello Frank!" diff --git a/packages/marko/test/render/fixtures/shorthand-div-id/expected.html b/packages/marko/test/render/fixtures/shorthand-div-id/expected.html index 0a5e17ab36..d6d205e70d 100644 --- a/packages/marko/test/render/fixtures/shorthand-div-id/expected.html +++ b/packages/marko/test/render/fixtures/shorthand-div-id/expected.html @@ -1 +1 @@ -
Hello Frank!
\ No newline at end of file +
Hello Frank!
\ No newline at end of file diff --git a/packages/marko/test/render/fixtures/shorthand-div-id/vdom-expected.html b/packages/marko/test/render/fixtures/shorthand-div-id/vdom-expected.html index cb649b93ab..39a8fc06f2 100644 --- a/packages/marko/test/render/fixtures/shorthand-div-id/vdom-expected.html +++ b/packages/marko/test/render/fixtures/shorthand-div-id/vdom-expected.html @@ -1,2 +1,2 @@ -
+
"Hello Frank!" diff --git a/packages/marko/test/render/fixtures/shorthand-div.foo/expected.html b/packages/marko/test/render/fixtures/shorthand-div.foo/expected.html index dc957e185f..84360ac5df 100644 --- a/packages/marko/test/render/fixtures/shorthand-div.foo/expected.html +++ b/packages/marko/test/render/fixtures/shorthand-div.foo/expected.html @@ -1 +1 @@ -
Hello Frank!
\ No newline at end of file +
Hello Frank!
\ No newline at end of file diff --git a/packages/marko/test/render/fixtures/shorthand-div.foo/vdom-expected.html b/packages/marko/test/render/fixtures/shorthand-div.foo/vdom-expected.html index 3d4028b01f..c03cde2156 100644 --- a/packages/marko/test/render/fixtures/shorthand-div.foo/vdom-expected.html +++ b/packages/marko/test/render/fixtures/shorthand-div.foo/vdom-expected.html @@ -1,2 +1,2 @@ -
+
"Hello Frank!" diff --git a/packages/marko/test/render/fixtures/spread-attribute-class-style-html-tag/expected.html b/packages/marko/test/render/fixtures/spread-attribute-class-style-html-tag/expected.html index b321a1b55a..5a71c917d1 100644 --- a/packages/marko/test/render/fixtures/spread-attribute-class-style-html-tag/expected.html +++ b/packages/marko/test/render/fixtures/spread-attribute-class-style-html-tag/expected.html @@ -1 +1 @@ -
Hello spread
\ No newline at end of file +
Hello spread
\ No newline at end of file diff --git a/packages/marko/test/render/fixtures/spread-attribute-class-style-html-tag/vdom-expected.html b/packages/marko/test/render/fixtures/spread-attribute-class-style-html-tag/vdom-expected.html index 8799c2efef..6f0daf0dee 100644 --- a/packages/marko/test/render/fixtures/spread-attribute-class-style-html-tag/vdom-expected.html +++ b/packages/marko/test/render/fixtures/spread-attribute-class-style-html-tag/vdom-expected.html @@ -1,2 +1,2 @@ -
+
"Hello spread" diff --git a/packages/marko/test/render/fixtures/style-attr-array-mixed/expected.html b/packages/marko/test/render/fixtures/style-attr-array-mixed/expected.html index 9347e5b964..8961a8fc36 100644 --- a/packages/marko/test/render/fixtures/style-attr-array-mixed/expected.html +++ b/packages/marko/test/render/fixtures/style-attr-array-mixed/expected.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/packages/marko/test/render/fixtures/style-attr-array-mixed/vdom-expected.html b/packages/marko/test/render/fixtures/style-attr-array-mixed/vdom-expected.html index bbea43e50c..f4d4b0fb2c 100644 --- a/packages/marko/test/render/fixtures/style-attr-array-mixed/vdom-expected.html +++ b/packages/marko/test/render/fixtures/style-attr-array-mixed/vdom-expected.html @@ -1 +1 @@ -
+
diff --git a/packages/marko/test/render/fixtures/style-attr-object-units/expected.html b/packages/marko/test/render/fixtures/style-attr-object-units/expected.html index 566038959b..0f79fed12f 100644 --- a/packages/marko/test/render/fixtures/style-attr-object-units/expected.html +++ b/packages/marko/test/render/fixtures/style-attr-object-units/expected.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/packages/marko/test/render/fixtures/style-attr-object-units/vdom-expected.html b/packages/marko/test/render/fixtures/style-attr-object-units/vdom-expected.html index d2b4ec49e5..63e299a602 100644 --- a/packages/marko/test/render/fixtures/style-attr-object-units/vdom-expected.html +++ b/packages/marko/test/render/fixtures/style-attr-object-units/vdom-expected.html @@ -1 +1 @@ -
+
diff --git a/packages/marko/test/render/fixtures/style-attr-object/expected.html b/packages/marko/test/render/fixtures/style-attr-object/expected.html index 9347e5b964..8961a8fc36 100644 --- a/packages/marko/test/render/fixtures/style-attr-object/expected.html +++ b/packages/marko/test/render/fixtures/style-attr-object/expected.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/packages/marko/test/render/fixtures/style-attr-object/vdom-expected.html b/packages/marko/test/render/fixtures/style-attr-object/vdom-expected.html index bbea43e50c..f4d4b0fb2c 100644 --- a/packages/marko/test/render/fixtures/style-attr-object/vdom-expected.html +++ b/packages/marko/test/render/fixtures/style-attr-object/vdom-expected.html @@ -1 +1 @@ -
+
diff --git a/packages/marko/test/render/fixtures/style-attr-string/expected.html b/packages/marko/test/render/fixtures/style-attr-string/expected.html index 0cb2174642..10befaf96e 100644 --- a/packages/marko/test/render/fixtures/style-attr-string/expected.html +++ b/packages/marko/test/render/fixtures/style-attr-string/expected.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/packages/marko/test/render/fixtures/style-attr-string/vdom-expected.html b/packages/marko/test/render/fixtures/style-attr-string/vdom-expected.html index c414d7f299..0839640a96 100644 --- a/packages/marko/test/render/fixtures/style-attr-string/vdom-expected.html +++ b/packages/marko/test/render/fixtures/style-attr-string/vdom-expected.html @@ -1 +1 @@ -
+
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("
"); }, { diff --git a/packages/translator-default/test/fixtures/data-migration/snapshots/html-expected.js b/packages/translator-default/test/fixtures/data-migration/snapshots/html-expected.js index aa435e1a32..43dbeffe93 100644 --- a/packages/translator-default/test/fixtures/data-migration/snapshots/html-expected.js +++ b/packages/translator-default/test/fixtures/data-migration/snapshots/html-expected.js @@ -30,7 +30,7 @@ _marko_template._ = _marko_renderer(function (input, out, _componentDef, _compon if (true) { const data = "bar"; out.w("Hello "); - out.w("bar"); + out.w(_marko_escapeXml(data)); } out.w("
"); }, { diff --git a/packages/translator-default/test/fixtures/data-migration/snapshots/htmlProduction-expected.js b/packages/translator-default/test/fixtures/data-migration/snapshots/htmlProduction-expected.js index 7594963277..aec00337fc 100644 --- a/packages/translator-default/test/fixtures/data-migration/snapshots/htmlProduction-expected.js +++ b/packages/translator-default/test/fixtures/data-migration/snapshots/htmlProduction-expected.js @@ -23,7 +23,7 @@ _marko_template._ = _marko_renderer(function (input, out, _componentDef, _compon out.w(`Hello ${_marko_escapeXml(input)}`); if (true) { const data = "bar"; - out.w("Hello bar"); + out.w(`Hello ${_marko_escapeXml(data)}`); } out.w("
"); }, { diff --git a/packages/translator-default/test/fixtures/error-at-tags-top-level/snapshots/vdomProduction-expected.js b/packages/translator-default/test/fixtures/error-at-tags-top-level/snapshots/vdomProduction-expected.js new file mode 100644 index 0000000000..5cedd92d06 --- /dev/null +++ b/packages/translator-default/test/fixtures/error-at-tags-top-level/snapshots/vdomProduction-expected.js @@ -0,0 +1,24 @@ +import { t as _t } from "marko/dist/runtime/vdom/index.js"; +const _marko_componentType = "DvY2Lw0O", + _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("@header", { + "class": "my-header" +}, null, null, 1, 1).t("Header content"); +const _marko_node2 = _marko_createElement("@footer", { + "class": "my-footer" +}, null, null, 1, 1).t("Footer content"); +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.n(_marko_node, _component); + out.n(_marko_node2, _component); +}, { + t: _marko_componentType, + i: true +}, _marko_component); +import _marko_defineComponent from "marko/dist/runtime/components/defineComponent.js"; +_marko_template.Component = _marko_defineComponent(_marko_component, _marko_template._); \ No newline at end of file diff --git a/packages/translator-default/test/fixtures/sanity-check/snapshots/cjs-expected.js b/packages/translator-default/test/fixtures/sanity-check/snapshots/cjs-expected.js index 97be26ad26..d51d506113 100644 --- a/packages/translator-default/test/fixtures/sanity-check/snapshots/cjs-expected.js +++ b/packages/translator-default/test/fixtures/sanity-check/snapshots/cjs-expected.js @@ -58,7 +58,7 @@ _marko_template._ = (0, _renderer.default)(function (input, out, _componentDef, out.w(`
`); + }]))} style=a:b>
`); out.w(""); (0, _dynamicTag.default)(out, _b.default, null, out => { out.w("
"); diff --git a/packages/translator-default/test/fixtures/sanity-check/snapshots/html-expected.js b/packages/translator-default/test/fixtures/sanity-check/snapshots/html-expected.js index b1887590b7..ef933083c5 100644 --- a/packages/translator-default/test/fixtures/sanity-check/snapshots/html-expected.js +++ b/packages/translator-default/test/fixtures/sanity-check/snapshots/html-expected.js @@ -52,7 +52,7 @@ _marko_template._ = _marko_renderer(function (input, out, _componentDef, _compon out.w(`
`); + }]))} style=a:b>
`); out.w(""); _marko_dynamic_tag(out, a, null, out => { out.w("
"); diff --git a/packages/translator-default/test/fixtures/sanity-check/snapshots/htmlProduction-expected.js b/packages/translator-default/test/fixtures/sanity-check/snapshots/htmlProduction-expected.js index a913890e4e..a4bae9f697 100644 --- a/packages/translator-default/test/fixtures/sanity-check/snapshots/htmlProduction-expected.js +++ b/packages/translator-default/test/fixtures/sanity-check/snapshots/htmlProduction-expected.js @@ -40,7 +40,7 @@ _marko_template._ = _marko_renderer(function (input, out, _componentDef, _compon out.w(`
`); + }]))} style=a:b>
`); _marko_dynamic_tag(out, a, null, out => { out.w("
"); }, null, null, _componentDef, "@x"); diff --git a/packages/translator-default/test/fixtures/sanity-check/snapshots/vdom-expected.js b/packages/translator-default/test/fixtures/sanity-check/snapshots/vdom-expected.js index 8e4667a2cb..1248cc8a20 100644 --- a/packages/translator-default/test/fixtures/sanity-check/snapshots/vdom-expected.js +++ b/packages/translator-default/test/fixtures/sanity-check/snapshots/vdom-expected.js @@ -66,7 +66,7 @@ _marko_template._ = _marko_renderer(function (input, out, _componentDef, _compon b: c, d }]), - "style": "a:b;" + "style": "a:b" }, "8", _component, 0, 1); out.e("input", { "type": "text" @@ -109,7 +109,7 @@ _marko_template._ = _marko_renderer(function (input, out, _componentDef, _compon }, out, _componentDef, "14"); out.be("div", _marko_attrs({ "class": "b c", - "a": "[object Object]", + "a": "{\"a\":1}", "c": "${d}", ...e, ...f(), diff --git a/packages/translator-default/test/fixtures/sanity-check/snapshots/vdomProduction-expected.js b/packages/translator-default/test/fixtures/sanity-check/snapshots/vdomProduction-expected.js index f55a209433..5e98018e35 100644 --- a/packages/translator-default/test/fixtures/sanity-check/snapshots/vdomProduction-expected.js +++ b/packages/translator-default/test/fixtures/sanity-check/snapshots/vdomProduction-expected.js @@ -85,7 +85,7 @@ _marko_template._ = _marko_renderer(function (input, out, _componentDef, _compon b: c, d }]), - "style": "a:b;" + "style": "a:b" }, "8", _component, 0, 1); out.n(_marko_node, _component); _marko_dynamic_tag(out, a, null, out => { @@ -126,7 +126,7 @@ _marko_template._ = _marko_renderer(function (input, out, _componentDef, _compon }, out, _componentDef, "14"); out.be("div", _marko_attrs({ "class": "b c", - "a": "[object Object]", + "a": "{\"a\":1}", "c": "${d}", ...e, ...f(), diff --git a/packages/translator-default/test/fixtures/shorthand-classname/snapshots/vdomProduction-expected.js b/packages/translator-default/test/fixtures/shorthand-classname/snapshots/vdomProduction-expected.js index 29d33d2638..dc8f2d3bc4 100644 --- a/packages/translator-default/test/fixtures/shorthand-classname/snapshots/vdomProduction-expected.js +++ b/packages/translator-default/test/fixtures/shorthand-classname/snapshots/vdomProduction-expected.js @@ -2,21 +2,25 @@ import { t as _t } from "marko/dist/runtime/vdom/index.js"; const _marko_componentType = "WqUsRyBC", _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("div", { + "class": "shorthand" +}, "0", null, 0, 1); +const _marko_node2 = _marko_createElement("div", { + "class": "shorthand1 shorthand2" +}, "1", null, 0, 1); +const _marko_node3 = _marko_createElement("div", { + "class": "shorthand1 shorthand2 inline" +}, "2", null, 0, 1); import _marko_class_merge from "marko/dist/runtime/helpers/class-value.js"; 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("div", { - "class": "shorthand" - }, "0", _component, 0, 1); - out.e("div", { - "class": "shorthand1 shorthand2" - }, "1", _component, 0, 1); - out.e("div", { - "class": "shorthand1 shorthand2 inline" - }, "2", _component, 0, 1); + out.n(_marko_node, _component); + out.n(_marko_node2, _component); + out.n(_marko_node3, _component); out.e("div", { "class": _marko_class_merge(["shorthand1 shorthand2", dynamic1]) }, "3", _component, 0, 1); diff --git a/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/cjs-expected.js b/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/cjs-expected.js index 54d2f486e9..91a528d424 100644 --- a/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/cjs-expected.js +++ b/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/cjs-expected.js @@ -12,13 +12,13 @@ var _default = _marko_template; exports.default = _default; const _marko_component = {}; _marko_template._ = (0, _renderer.default)(function (input, out, _componentDef, _component, state, $global) { - out.w("
"); - out.w("
"); - out.w("
"); + out.w("
"); + out.w("
"); + out.w("
"); out.w(`
`); - out.w("
"); + })} style=c:1px>`); + out.w("
"); }, { t: _marko_componentType, i: true, diff --git a/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/html-expected.js b/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/html-expected.js index ced65f2984..00071c49a0 100644 --- a/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/html-expected.js +++ b/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/html-expected.js @@ -6,13 +6,13 @@ import _marko_props from "marko/src/runtime/html/helpers/data-marko.js"; import _marko_renderer from "marko/src/runtime/components/renderer.js"; const _marko_component = {}; _marko_template._ = _marko_renderer(function (input, out, _componentDef, _component, state, $global) { - out.w("
"); - out.w("
"); - out.w("
"); + out.w("
"); + out.w("
"); + out.w("
"); out.w(``); - out.w("
"); + })} style=c:1px>`); + out.w("
"); }, { t: _marko_componentType, i: true, diff --git a/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/htmlProduction-expected.js b/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/htmlProduction-expected.js index 47c65b7748..2637be3b3f 100644 --- a/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/htmlProduction-expected.js +++ b/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/htmlProduction-expected.js @@ -6,9 +6,9 @@ import _marko_props from "marko/dist/runtime/html/helpers/data-marko.js"; import _marko_renderer from "marko/dist/runtime/components/renderer.js"; const _marko_component = {}; _marko_template._ = _marko_renderer(function (input, out, _componentDef, _component, state, $global) { - out.w(`
`); + })} style=c:1px>
`); }, { t: _marko_componentType, i: true diff --git a/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/vdom-expected.js b/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/vdom-expected.js index 8100435ab3..9650e73df9 100644 --- a/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/vdom-expected.js +++ b/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/vdom-expected.js @@ -9,25 +9,25 @@ _marko_registerComponent(_marko_componentType, () => _marko_template); const _marko_component = {}; _marko_template._ = _marko_renderer(function (input, out, _componentDef, _component, state, $global) { out.e("div", { - "style": "c:1px;", + "style": "c:1px", "class": "b", "id": "a" }, "0", _component, 0, 1); out.e("div", { - "style": "c:1px;", + "style": "c:1px", "id": "a" }, "1", _component, 0, 1); out.e("div", { - "style": "c:1px;" + "style": "c:1px" }, "2", _component, 0, 1); out.e("div", { - "style": "c:1px;" + "style": "c:1px" }, "3", _component, 0, 0, { pa: ["style"] }); out.e("div", { "a": "1", - "style": "c:1px;" + "style": "c:1px" }, "4", _component, 0, 0); }, { t: _marko_componentType, diff --git a/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/vdomProduction-expected.js b/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/vdomProduction-expected.js index ed9cdde5f1..52be92cc5b 100644 --- a/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/vdomProduction-expected.js +++ b/packages/translator-default/test/fixtures/simple-attrs-tag/snapshots/vdomProduction-expected.js @@ -2,33 +2,38 @@ import { t as _t } from "marko/dist/runtime/vdom/index.js"; const _marko_componentType = "YUZPhHIa", _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("div", { + "style": "c:1px", + "class": "b", + "id": "a" +}, "0", null, 0, 1); +const _marko_node2 = _marko_createElement("div", { + "style": "c:1px", + "id": "a" +}, "1", null, 0, 1); +const _marko_node3 = _marko_createElement("div", { + "style": "c:1px" +}, "2", null, 0, 1); import "marko/dist/runtime/vdom/preserve-attrs.js"; +const _marko_node4 = _marko_createElement("div", { + "a": "1", + "style": "c:1px" +}, "4", null, 0, 0); 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.n(_marko_node, _component); + out.n(_marko_node2, _component); + out.n(_marko_node3, _component); out.e("div", { - "style": "c:1px;", - "class": "b", - "id": "a" - }, "0", _component, 0, 1); - out.e("div", { - "style": "c:1px;", - "id": "a" - }, "1", _component, 0, 1); - out.e("div", { - "style": "c:1px;" - }, "2", _component, 0, 1); - out.e("div", { - "style": "c:1px;" + "style": "c:1px" }, "3", _component, 0, 0, { pa: ["style"] }); - out.e("div", { - "a": "1", - "style": "c:1px;" - }, "4", _component, 0, 0); + out.n(_marko_node4, _component); }, { t: _marko_componentType, i: true diff --git a/packages/translator-default/test/fixtures/style-block-empty/snapshots/vdomProduction-expected.js b/packages/translator-default/test/fixtures/style-block-empty/snapshots/vdomProduction-expected.js index dda16f8104..d9e4cbc098 100644 --- a/packages/translator-default/test/fixtures/style-block-empty/snapshots/vdomProduction-expected.js +++ b/packages/translator-default/test/fixtures/style-block-empty/snapshots/vdomProduction-expected.js @@ -2,14 +2,16 @@ import { t as _t } from "marko/dist/runtime/vdom/index.js"; const _marko_componentType = "iTWeM9Hv", _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("div", { + "class": "test" +}, "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("div", { - "class": "test" - }, "0", _component, 0, 1); + out.n(_marko_node, _component); }, { t: _marko_componentType, i: true diff --git a/packages/translator-default/test/fixtures/style-block-with-styles/snapshots/vdomProduction-expected.js b/packages/translator-default/test/fixtures/style-block-with-styles/snapshots/vdomProduction-expected.js index e0df1fdc09..addb6efdad 100644 --- a/packages/translator-default/test/fixtures/style-block-with-styles/snapshots/vdomProduction-expected.js +++ b/packages/translator-default/test/fixtures/style-block-with-styles/snapshots/vdomProduction-expected.js @@ -2,14 +2,16 @@ import { t as _t } from "marko/dist/runtime/vdom/index.js"; const _marko_componentType = "ZsW3uNOB", _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("div", { + "class": "test" +}, "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("div", { - "class": "test" - }, "0", _component, 0, 1); + out.n(_marko_node, _component); }, { t: _marko_componentType, i: true