Marko v3: Provide option to disable XML escaping for an HTML attribute

This commit is contained in:
Patrick Steele-Idem 2016-02-06 18:19:28 -07:00
parent d60d82ddc5
commit cb4cbce66e
6 changed files with 64 additions and 7 deletions

View File

@ -55,7 +55,7 @@ function flattenAttrConcats(node) {
return final.concats;
}
function generateCodeForExpressionAttr(name, value, codegen) {
function generateCodeForExpressionAttr(name, value, escape, codegen) {
var flattenedConcats = flattenAttrConcats(value);
var hasLiteral = false;
@ -78,9 +78,13 @@ function generateCodeForExpressionAttr(name, value, codegen) {
part = removeEscapeFunctions(part);
part = codegen.builder.functionCall(codegen.builder.identifier('str'), [part]);
} else {
var escapeXmlAttrVar = codegen.addStaticVar('escapeXmlAttr', '__helpers.xa');
part = removeEscapeFunctions(part);
part = codegen.builder.functionCall(escapeXmlAttrVar, [part]);
if (escape !== false) {
var escapeXmlAttrVar = codegen.getEscapeXmlAttrVar();
part = codegen.builder.functionCall(escapeXmlAttrVar, [part]);
}
}
codegen.addWrite(part);
}
@ -91,9 +95,7 @@ function generateCodeForExpressionAttr(name, value, codegen) {
// let valueWithEscaping = handleEscaping(value);
let attrVar = codegen.addStaticVar('attr', '__helpers.a');
var escape = true;
if (isNoEscapeXml(value)) {
if (escape === false || isNoEscapeXml(value)) {
escape = false;
}
@ -116,6 +118,7 @@ class HtmlAttribute extends Node {
this.type = 'HtmlAttribute';
this.name = def.name;
this.value = def.value;
this.escape = def.escape;
if (typeof this.value === 'string') {
this.value = compiler.builder.parseExpression(this.value);
@ -148,6 +151,7 @@ class HtmlAttribute extends Node {
let name = this.name;
let value = this.value;
let argument = this.argument;
let escape = this.escape !== false;
if (!name) {
return;
@ -165,7 +169,7 @@ class HtmlAttribute extends Node {
} else if (value != null) {
codegen.isInAttribute = true;
generateCodeForExpressionAttr(name, value, codegen);
generateCodeForExpressionAttr(name, value, escape, codegen);
codegen.isInAttribute = false;
} else if (argument) {
codegen.addWriteLiteral(' ' + name + '(');

View File

@ -185,6 +185,10 @@ class HtmlElement extends Node {
}
}
addAttribute(attr) {
this._attributes.addAttribute(attr);
}
setAttributeValue(name, value) {
this._attributes.setAttributeValue(name, value);
}

View File

@ -0,0 +1,3 @@
out.w("<div class=\"foo" +
className +
"\">Hello World</div>");

View File

@ -0,0 +1,20 @@
'use strict';
module.exports = function(builder) {
var htmlElement = builder.htmlElement(
'div',
[
{
name: 'class',
value: builder.concat(
builder.literal('foo'),
builder.identifier('className')),
escape: false
}
],
[
builder.text(builder.literal('Hello World'))
]);
return htmlElement;
};

View File

@ -0,0 +1,3 @@
out.w("<div class=\"foo" +
className +
"\">Hello World</div>");

View File

@ -0,0 +1,23 @@
'use strict';
module.exports = function(builder) {
var htmlElement = builder.htmlElement(
'div',
[
],
[
builder.text(builder.literal('Hello World'))
]);
htmlElement.addAttribute({
name: 'class',
value: builder.concat(
builder.literal('foo'),
builder.identifier('className')),
escape: false
});
return htmlElement;
};