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;
|
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) {
|
if (this._code.length === startPos) {
|
||||||
// No code was generated. Remove any code that was previously added
|
// No code was generated. Remove any code that was previously added
|
||||||
|
|||||||
@ -38,7 +38,7 @@ class CompileError {
|
|||||||
pos = '';
|
pos = '';
|
||||||
}
|
}
|
||||||
var str = pos + this.message;
|
var str = pos + this.message;
|
||||||
if (this.node) {
|
if (pos == null && this.node) {
|
||||||
str += ' (' + this.node.toString() + ')';
|
str += ' (' + this.node.toString() + ')';
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
|
|||||||
@ -20,9 +20,9 @@ class HtmlJsParser {
|
|||||||
onattributeplaceholder(event) {
|
onattributeplaceholder(event) {
|
||||||
// placeholder within attribute
|
// placeholder within attribute
|
||||||
if (event.escape) {
|
if (event.escape) {
|
||||||
event.expression = 'escapeXml(' + event.expression + ')';
|
event.expression = '$escapeXml(' + event.expression + ')';
|
||||||
} else {
|
} else {
|
||||||
event.expression = 'noEscapeXml(' + event.expression + ')';
|
event.expression = '$noEscapeXml(' + event.expression + ')';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
var HtmlElement = require('./HtmlElement');
|
var HtmlElement = require('./HtmlElement');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var removeDashes = require('../util/removeDashes');
|
var removeDashes = require('../util/removeDashes');
|
||||||
|
var removeEscapeFunctions = require('../util/removeEscapeFunctions');
|
||||||
|
|
||||||
function removeExt(filename) {
|
function removeExt(filename) {
|
||||||
var ext = path.extname(filename);
|
var ext = path.extname(filename);
|
||||||
@ -20,6 +21,11 @@ function buildInputProps(node, context) {
|
|||||||
var attrName = attr.name;
|
var attrName = attr.name;
|
||||||
|
|
||||||
var attrDef = attr.def || context.taglibLookup.getAttribute(node.tagName, 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 propName;
|
||||||
var parentPropName;
|
var parentPropName;
|
||||||
@ -52,9 +58,9 @@ function buildInputProps(node, context) {
|
|||||||
|
|
||||||
if (parentPropName) {
|
if (parentPropName) {
|
||||||
let parent = inputProps[parentPropName] = (inputProps[parentPropName] = {});
|
let parent = inputProps[parentPropName] = (inputProps[parentPropName] = {});
|
||||||
parent[propName] = attr.value;
|
parent[propName] = attrValue;
|
||||||
} else {
|
} else {
|
||||||
inputProps[propName] = attr.value;
|
inputProps[propName] = attrValue;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ class FunctionCall extends Node {
|
|||||||
this.callee = def.callee;
|
this.callee = def.callee;
|
||||||
|
|
||||||
ok(this.callee, '"callee" is required');
|
ok(this.callee, '"callee" is required');
|
||||||
|
|
||||||
this.args = def.args;
|
this.args = def.args;
|
||||||
|
|
||||||
if (this.args && !Array.isArray(this.args)) {
|
if (this.args && !Array.isArray(this.args)) {
|
||||||
|
|||||||
@ -3,8 +3,8 @@ var Node = require('./Node');
|
|||||||
var Literal = require('./Literal');
|
var Literal = require('./Literal');
|
||||||
var ok = require('assert').ok;
|
var ok = require('assert').ok;
|
||||||
var escapeXmlAttr = require('raptor-util/escapeXml').attr;
|
var escapeXmlAttr = require('raptor-util/escapeXml').attr;
|
||||||
var compiler = require('../');
|
|
||||||
var parseExpression = require('../util/parseExpression');
|
var parseExpression = require('../util/parseExpression');
|
||||||
|
var removeEscapeFunctions = require('../util/removeEscapeFunctions');
|
||||||
|
|
||||||
function isStringLiteral(node) {
|
function isStringLiteral(node) {
|
||||||
return node.type === 'Literal' && typeof node.value === 'string';
|
return node.type === 'Literal' && typeof node.value === 'string';
|
||||||
@ -13,18 +13,12 @@ function isStringLiteral(node) {
|
|||||||
function isNoEscapeXml(node) {
|
function isNoEscapeXml(node) {
|
||||||
return node.type === 'FunctionCall' &&
|
return node.type === 'FunctionCall' &&
|
||||||
node.callee.type === 'Identifier' &&
|
node.callee.type === 'Identifier' &&
|
||||||
node.callee.name === 'noEscapeXml';
|
node.callee.name === '$noEscapeXml';
|
||||||
}
|
|
||||||
|
|
||||||
function isEscapeXml(node) {
|
|
||||||
return node.type === 'FunctionCall' &&
|
|
||||||
node.callee.type === 'Identifier' &&
|
|
||||||
node.callee.name === 'escapeXml';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isStringExpression(node) {
|
function isStringExpression(node) {
|
||||||
return node.type === 'FunctionCall' && node.callee.type === 'Identifier' &&
|
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) {
|
function flattenAttrConcats(node) {
|
||||||
@ -61,33 +55,6 @@ function flattenAttrConcats(node) {
|
|||||||
return final.concats;
|
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) {
|
function generateCodeForExpressionAttr(name, value, codegen) {
|
||||||
var flattenedConcats = flattenAttrConcats(value);
|
var flattenedConcats = flattenAttrConcats(value);
|
||||||
var hasLiteral = false;
|
var hasLiteral = false;
|
||||||
|
|||||||
@ -157,9 +157,11 @@ class HtmlElement extends Node {
|
|||||||
if (openTagOnly) {
|
if (openTagOnly) {
|
||||||
codegen.generateCode(startTag);
|
codegen.generateCode(startTag);
|
||||||
} else {
|
} else {
|
||||||
codegen.generateCode(startTag);
|
return [
|
||||||
codegen.generateCode(body);
|
startTag,
|
||||||
codegen.generateCode(endTag);
|
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",
|
"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) {
|
exports.render = function(input, out) {
|
||||||
out.write('Hello ' + input.name + '!');
|
out.write('Hello ' + input.name + '!');
|
||||||
|
if (input.adult === true) {
|
||||||
|
out.write(' (adult)');
|
||||||
|
} else if (input.adult === false) {
|
||||||
|
out.write(' (child)');
|
||||||
|
}
|
||||||
|
|
||||||
if (input.renderBody) {
|
if (input.renderBody) {
|
||||||
out.write(' BODY: ');
|
out.write(' BODY: ');
|
||||||
input.renderBody(out);
|
input.renderBody(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
Loading…
x
Reference in New Issue
Block a user