mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
Template literal print fixes (#1188)
* when writing a TemplateLiteral, it should not transpile unless generated * proper escaping for template literals * add printing test for TemplateLiteral node
This commit is contained in:
parent
a52b5c6cbe
commit
37e0c912ab
@ -30,7 +30,10 @@ class HtmlJsParser {
|
||||
if (part.type === "placeholder") {
|
||||
value += "${" + part.value + "}";
|
||||
} else {
|
||||
value += part.replace(/`/g, "\\`");
|
||||
value += part.replace(
|
||||
/`|\\|\${/g,
|
||||
match => "\\" + match
|
||||
);
|
||||
}
|
||||
});
|
||||
event.value = "$nonstandard`" + value + "`";
|
||||
|
||||
@ -36,13 +36,19 @@ module.exports = function(node, codegen, vdomUtil) {
|
||||
var body = codegen.generateCode(node.body);
|
||||
var tagName = codegen.generateCode(node.tagNameExpression);
|
||||
var attributes = codegen.generateCode(node.getAttributes());
|
||||
var properties = codegen.generateCode(node.getProperties());
|
||||
var dynamicAttributes = codegen.generateCode(node.dynamicAttributes);
|
||||
var key = node.key;
|
||||
var key = codegen.generateCode(node.key);
|
||||
var properties = node.getProperties();
|
||||
var isAutoKeyed = node.isAutoKeyed;
|
||||
var runtimeFlags = node.runtimeFlags;
|
||||
var nextConstId = node.nextConstId;
|
||||
|
||||
if (properties) {
|
||||
Object.keys(properties).forEach(
|
||||
key => (properties[key] = codegen.generateCode(properties[key]))
|
||||
);
|
||||
}
|
||||
|
||||
var builder = codegen.builder;
|
||||
|
||||
var isKeyStatic = vdomUtil.isStaticValue(key);
|
||||
|
||||
@ -38,35 +38,39 @@ class TemplateLiteral extends Node {
|
||||
}
|
||||
|
||||
writeCode(writer) {
|
||||
for (let i = 0; i <= this.quasis.length; i++) {
|
||||
const quasi = this.quasis[i];
|
||||
const expr = this.expressions[i];
|
||||
if (quasi || i === 0) {
|
||||
if (i > 0) writer.write("+");
|
||||
writer.write(JSON.stringify(quasi));
|
||||
}
|
||||
if (expr) {
|
||||
writer.write("+");
|
||||
writer.write("(");
|
||||
writer.write(expr);
|
||||
writer.write(")");
|
||||
}
|
||||
}
|
||||
writer.write("\n");
|
||||
}
|
||||
|
||||
toString() {
|
||||
let code = "";
|
||||
let quote = this.nonstandard ? '"' : "`";
|
||||
let escape = new RegExp(quote, "g");
|
||||
for (let i = 0; i <= this.quasis.length; i++) {
|
||||
const quasi = this.quasis[i];
|
||||
const expr = this.expressions[i];
|
||||
if (quasi) code += quasi.replace(escape, `\\${quote}`);
|
||||
if (quasi) code += escapeQuasi(quasi, quote);
|
||||
if (expr) code += "${" + expr.toString() + "}";
|
||||
}
|
||||
return quote + code + quote;
|
||||
writer.write(quote + code + quote);
|
||||
writer.write("\n");
|
||||
}
|
||||
}
|
||||
|
||||
function escapeQuasi(quasi, quote) {
|
||||
if (!quasi) return "";
|
||||
return quasi.replace(/["`\\\n\r\u2028\u2029]|\${/g, match => {
|
||||
switch (match) {
|
||||
case quote:
|
||||
case "${":
|
||||
case "\\":
|
||||
return "\\" + match;
|
||||
case "\n":
|
||||
return "\\n";
|
||||
case "\r":
|
||||
return "\\r";
|
||||
case "\u2028":
|
||||
return "\\u2028";
|
||||
case "\u2029":
|
||||
return "\\u2029";
|
||||
default:
|
||||
return match;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = TemplateLiteral;
|
||||
|
||||
@ -24,7 +24,12 @@ module.exports = function migrator(elNode, context) {
|
||||
value:
|
||||
attr.value == null
|
||||
? attr.name
|
||||
: `${attr.name} = ${printJS(attr.value, context)}`
|
||||
: `${attr.name} = ${printJS(
|
||||
attr.value,
|
||||
context,
|
||||
null,
|
||||
true
|
||||
)}`
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
const CodeWriter = require("../../../compiler/CodeWriter");
|
||||
const CodeGenerator = require("../../../compiler/CodeGenerator");
|
||||
|
||||
module.exports = function(node, context, options) {
|
||||
const codeGenerator = new CodeGenerator(context);
|
||||
node = codeGenerator.generateCode(node);
|
||||
const writer = new CodeWriter(
|
||||
Object.assign({}, context.options, options),
|
||||
context.builder
|
||||
|
||||
8
test/codegen/fixtures/templateLiteral/expected.js
Normal file
8
test/codegen/fixtures/templateLiteral/expected.js
Normal file
@ -0,0 +1,8 @@
|
||||
`hello ${name}`
|
||||
`hello \${name}`
|
||||
`hello \\${name}`
|
||||
`hello "\`"`
|
||||
"hello ${name}"
|
||||
"hello \${name}"
|
||||
"hello \\${name}"
|
||||
"hello \"`\""
|
||||
52
test/codegen/fixtures/templateLiteral/index.js
Normal file
52
test/codegen/fixtures/templateLiteral/index.js
Normal file
@ -0,0 +1,52 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = function(builder) {
|
||||
var templateLiteral = builder.templateLiteral(
|
||||
["hello ", ""],
|
||||
[builder.identifier("name")]
|
||||
);
|
||||
var templateLiteralEscape = builder.templateLiteral(["hello ${name}"], []);
|
||||
var templateLiteralEscape2 = builder.templateLiteral(
|
||||
["hello \\", ""],
|
||||
[builder.identifier("name")]
|
||||
);
|
||||
var templateLiteralEscapeQuotes = builder.templateLiteral(
|
||||
['hello "`"'],
|
||||
[]
|
||||
);
|
||||
|
||||
var nsTemplateLiteral = builder.templateLiteral(
|
||||
["hello ", ""],
|
||||
[builder.identifier("name")]
|
||||
);
|
||||
var nsTemplateLiteralEscape = builder.templateLiteral(
|
||||
["hello ${name}"],
|
||||
[]
|
||||
);
|
||||
var nsTemplateLiteralEscape2 = builder.templateLiteral(
|
||||
["hello \\", ""],
|
||||
[builder.identifier("name")]
|
||||
);
|
||||
var nsTemplateLiteralEscapeQuotes = builder.templateLiteral(
|
||||
['hello "`"'],
|
||||
[]
|
||||
);
|
||||
|
||||
nsTemplateLiteral.nonstandard = true;
|
||||
nsTemplateLiteralEscape.nonstandard = true;
|
||||
nsTemplateLiteralEscape2.nonstandard = true;
|
||||
nsTemplateLiteralEscapeQuotes.nonstandard = true;
|
||||
|
||||
return [
|
||||
templateLiteral,
|
||||
templateLiteralEscape,
|
||||
templateLiteralEscape2,
|
||||
templateLiteralEscapeQuotes,
|
||||
nsTemplateLiteral,
|
||||
nsTemplateLiteralEscape,
|
||||
nsTemplateLiteralEscape2,
|
||||
nsTemplateLiteralEscapeQuotes
|
||||
];
|
||||
};
|
||||
|
||||
module.exports.skipCodegen = true;
|
||||
@ -30,6 +30,7 @@ autotest("fixtures", fixture => {
|
||||
test(done => {
|
||||
var main = require(resolve("index.js"));
|
||||
var generateCodeFunc = main;
|
||||
var skipCodegen = main.skipCodegen === true;
|
||||
|
||||
var context = new CompileContext(
|
||||
"dummy",
|
||||
@ -40,7 +41,7 @@ autotest("fixtures", fixture => {
|
||||
var codeWriter = createCodeWriter(context);
|
||||
|
||||
var ast = generateCodeFunc(builder, codegen);
|
||||
var finalAST = codegen.generateCode(ast);
|
||||
var finalAST = skipCodegen ? ast : codegen.generateCode(ast);
|
||||
|
||||
codeWriter.write(finalAST);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user