diff --git a/compiler/ast/HtmlAttribute.js b/compiler/ast/HtmlAttribute.js index 62b8e852a..fee8d5dd4 100644 --- a/compiler/ast/HtmlAttribute.js +++ b/compiler/ast/HtmlAttribute.js @@ -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 + '('); diff --git a/compiler/ast/HtmlElement.js b/compiler/ast/HtmlElement.js index 71d65dd5a..1f6df4aa9 100644 --- a/compiler/ast/HtmlElement.js +++ b/compiler/ast/HtmlElement.js @@ -185,6 +185,10 @@ class HtmlElement extends Node { } } + addAttribute(attr) { + this._attributes.addAttribute(attr); + } + setAttributeValue(name, value) { this._attributes.setAttributeValue(name, value); } diff --git a/test/fixtures/codegen/autotest/attr-no-escape/expected.js b/test/fixtures/codegen/autotest/attr-no-escape/expected.js new file mode 100644 index 000000000..c335fafd9 --- /dev/null +++ b/test/fixtures/codegen/autotest/attr-no-escape/expected.js @@ -0,0 +1,3 @@ +out.w("
Hello World
"); diff --git a/test/fixtures/codegen/autotest/attr-no-escape/index.js b/test/fixtures/codegen/autotest/attr-no-escape/index.js new file mode 100644 index 000000000..4391c9f90 --- /dev/null +++ b/test/fixtures/codegen/autotest/attr-no-escape/index.js @@ -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; +}; \ No newline at end of file diff --git a/test/fixtures/codegen/autotest/htmlElement-addAttribute/expected.js b/test/fixtures/codegen/autotest/htmlElement-addAttribute/expected.js new file mode 100644 index 000000000..c335fafd9 --- /dev/null +++ b/test/fixtures/codegen/autotest/htmlElement-addAttribute/expected.js @@ -0,0 +1,3 @@ +out.w("
Hello World
"); diff --git a/test/fixtures/codegen/autotest/htmlElement-addAttribute/index.js b/test/fixtures/codegen/autotest/htmlElement-addAttribute/index.js new file mode 100644 index 000000000..8948c19a7 --- /dev/null +++ b/test/fixtures/codegen/autotest/htmlElement-addAttribute/index.js @@ -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; +}; \ No newline at end of file