mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
Marko v3: Better handling of escaping for custom tags input
This commit is contained in:
parent
5d123c2013
commit
294c6335be
@ -288,7 +288,11 @@ class Generator {
|
||||
|
||||
let startPos = this._code.length;
|
||||
|
||||
this.generateCode(node);
|
||||
if (Array.isArray(node) || (node instanceof Container)) {
|
||||
this.generateStatements(node);
|
||||
} else {
|
||||
this.generateCode(node);
|
||||
}
|
||||
|
||||
if (this._code.length === startPos) {
|
||||
// No code was generated. Remove any code that was previously added
|
||||
|
||||
@ -38,7 +38,7 @@ class CompileError {
|
||||
pos = '';
|
||||
}
|
||||
var str = pos + this.message;
|
||||
if (this.node) {
|
||||
if (pos == null && this.node) {
|
||||
str += ' (' + this.node.toString() + ')';
|
||||
}
|
||||
return str;
|
||||
|
||||
@ -20,9 +20,9 @@ class HtmlJsParser {
|
||||
onattributeplaceholder(event) {
|
||||
// placeholder within attribute
|
||||
if (event.escape) {
|
||||
event.expression = 'escapeXml(' + event.expression + ')';
|
||||
event.expression = '$escapeXml(' + event.expression + ')';
|
||||
} else {
|
||||
event.expression = 'noEscapeXml(' + event.expression + ')';
|
||||
event.expression = '$noEscapeXml(' + event.expression + ')';
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
var HtmlElement = require('./HtmlElement');
|
||||
var path = require('path');
|
||||
var removeDashes = require('../util/removeDashes');
|
||||
var removeEscapeFunctions = require('../util/removeEscapeFunctions');
|
||||
|
||||
function removeExt(filename) {
|
||||
var ext = path.extname(filename);
|
||||
@ -20,6 +21,11 @@ function buildInputProps(node, context) {
|
||||
var attrName = attr.name;
|
||||
|
||||
var attrDef = attr.def || context.taglibLookup.getAttribute(node.tagName, attr.name);
|
||||
var attrValue = removeEscapeFunctions(attr.value);
|
||||
|
||||
if (!attrDef) {
|
||||
return; // Skip over attributes that are not supported
|
||||
}
|
||||
|
||||
var propName;
|
||||
var parentPropName;
|
||||
@ -52,9 +58,9 @@ function buildInputProps(node, context) {
|
||||
|
||||
if (parentPropName) {
|
||||
let parent = inputProps[parentPropName] = (inputProps[parentPropName] = {});
|
||||
parent[propName] = attr.value;
|
||||
parent[propName] = attrValue;
|
||||
} else {
|
||||
inputProps[propName] = attr.value;
|
||||
inputProps[propName] = attrValue;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ class FunctionCall extends Node {
|
||||
this.callee = def.callee;
|
||||
|
||||
ok(this.callee, '"callee" is required');
|
||||
|
||||
|
||||
this.args = def.args;
|
||||
|
||||
if (this.args && !Array.isArray(this.args)) {
|
||||
|
||||
@ -3,8 +3,8 @@ var Node = require('./Node');
|
||||
var Literal = require('./Literal');
|
||||
var ok = require('assert').ok;
|
||||
var escapeXmlAttr = require('raptor-util/escapeXml').attr;
|
||||
var compiler = require('../');
|
||||
var parseExpression = require('../util/parseExpression');
|
||||
var removeEscapeFunctions = require('../util/removeEscapeFunctions');
|
||||
|
||||
function isStringLiteral(node) {
|
||||
return node.type === 'Literal' && typeof node.value === 'string';
|
||||
@ -13,18 +13,12 @@ function isStringLiteral(node) {
|
||||
function isNoEscapeXml(node) {
|
||||
return node.type === 'FunctionCall' &&
|
||||
node.callee.type === 'Identifier' &&
|
||||
node.callee.name === 'noEscapeXml';
|
||||
}
|
||||
|
||||
function isEscapeXml(node) {
|
||||
return node.type === 'FunctionCall' &&
|
||||
node.callee.type === 'Identifier' &&
|
||||
node.callee.name === 'escapeXml';
|
||||
node.callee.name === '$noEscapeXml';
|
||||
}
|
||||
|
||||
function isStringExpression(node) {
|
||||
return node.type === 'FunctionCall' && node.callee.type === 'Identifier' &&
|
||||
(node.callee.name === 'noEscapeXml' || node.callee.name === 'escapeXml');
|
||||
(node.callee.name === '$noEscapeXml' || node.callee.name === '$escapeXml');
|
||||
}
|
||||
|
||||
function flattenAttrConcats(node) {
|
||||
@ -61,33 +55,6 @@ function flattenAttrConcats(node) {
|
||||
return final.concats;
|
||||
}
|
||||
|
||||
// function handleEscaping(node) {
|
||||
//
|
||||
// function handleEscapingHelper(node, escaping) {
|
||||
// if (node.type === 'Literal') {
|
||||
// } else if (isEscapeXml(node)) {
|
||||
// return handleEscapingHelper(node.arguments[0], true);
|
||||
// } else if (isNoEscapeXml(node)) {
|
||||
// return handleEscapingHelper(node.arguments[0], escaping false);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// var finalNode = handleEscapingHelper(node, true /* default to escaping */);
|
||||
// return finalNode;
|
||||
// }
|
||||
|
||||
function removeEscapeFunctions(node) {
|
||||
var walker = compiler.createWalker({
|
||||
enter: function(node, parent) {
|
||||
if (isNoEscapeXml(node) || isEscapeXml(node)) {
|
||||
return node.args[0];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return walker.walk(node);
|
||||
}
|
||||
|
||||
function generateCodeForExpressionAttr(name, value, codegen) {
|
||||
var flattenedConcats = flattenAttrConcats(value);
|
||||
var hasLiteral = false;
|
||||
|
||||
@ -157,9 +157,11 @@ class HtmlElement extends Node {
|
||||
if (openTagOnly) {
|
||||
codegen.generateCode(startTag);
|
||||
} else {
|
||||
codegen.generateCode(startTag);
|
||||
codegen.generateCode(body);
|
||||
codegen.generateCode(endTag);
|
||||
return [
|
||||
startTag,
|
||||
body,
|
||||
endTag
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
17
compiler/util/removeEscapeFunctions.js
Normal file
17
compiler/util/removeEscapeFunctions.js
Normal file
@ -0,0 +1,17 @@
|
||||
var compiler = require('../');
|
||||
|
||||
function removeEscapeFunctions(node) {
|
||||
var walker = compiler.createWalker({
|
||||
enter: function(node, parent) {
|
||||
if (node.type === 'FunctionCall' &&
|
||||
node.callee.type === 'Identifier' &&
|
||||
(node.callee.name === '$noEscapeXml' || node.callee.name === '$escapeXml')) {
|
||||
return node.args[0];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return walker.walk(node);
|
||||
}
|
||||
|
||||
module.exports = removeEscapeFunctions;
|
||||
@ -1 +0,0 @@
|
||||
<ul><li>Hello world! adult=false</li><li>Hello universe! adult=true</li><li>Hello Dynamic: universe! adult=false</li></ul>
|
||||
@ -1,13 +0,0 @@
|
||||
<var name="dynamic" value="data.dynamic"/>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<test-simpleHello name="world"/>
|
||||
</li>
|
||||
<li>
|
||||
<test-simpleHello name="${dynamic}" adult="true"/>
|
||||
</li>
|
||||
<li>
|
||||
<test-simpleHello name="Dynamic: ${dynamic}" adult="false"/>
|
||||
</li>
|
||||
</ul>
|
||||
@ -1,3 +0,0 @@
|
||||
exports.templateData = {
|
||||
"dynamic": "universe"
|
||||
};
|
||||
1
test/fixtures/render/autotest/custom-tag-data-placeholders/expected.html
vendored
Normal file
1
test/fixtures/render/autotest/custom-tag-data-placeholders/expected.html
vendored
Normal file
@ -0,0 +1 @@
|
||||
<ul><li>Hello <World>!</li><li>Hello <Frank>! (adult)</li><li>Hello Foo <Frank>! (child)</li></ul>
|
||||
13
test/fixtures/render/autotest/custom-tag-data-placeholders/template.marko
vendored
Normal file
13
test/fixtures/render/autotest/custom-tag-data-placeholders/template.marko
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
<var dynamic='<Frank>'/>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<test-hello name="<World>"/>
|
||||
</li>
|
||||
<li>
|
||||
<test-hello name="${dynamic}" adult=true/>
|
||||
</li>
|
||||
<li>
|
||||
<test-hello name="Foo ${dynamic}" adult=false/>
|
||||
</li>
|
||||
</ul>
|
||||
1
test/fixtures/render/autotest/custom-tag-data-placeholders/test.js
vendored
Normal file
1
test/fixtures/render/autotest/custom-tag-data-placeholders/test.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
exports.templateData = {};
|
||||
@ -1,4 +1,5 @@
|
||||
{
|
||||
"renderer": "./renderer.js",
|
||||
"@name": "string"
|
||||
"@name": "string",
|
||||
"@adult": "boolean"
|
||||
}
|
||||
7
test/fixtures/taglib/test-hello/renderer.js
vendored
7
test/fixtures/taglib/test-hello/renderer.js
vendored
@ -1,7 +1,14 @@
|
||||
exports.render = function(input, out) {
|
||||
out.write('Hello ' + input.name + '!');
|
||||
if (input.adult === true) {
|
||||
out.write(' (adult)');
|
||||
} else if (input.adult === false) {
|
||||
out.write(' (child)');
|
||||
}
|
||||
|
||||
if (input.renderBody) {
|
||||
out.write(' BODY: ');
|
||||
input.renderBody(out);
|
||||
}
|
||||
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user