diff --git a/compiler/ast/HtmlAttribute.js b/compiler/ast/HtmlAttribute.js index a71e56337..4851199fe 100644 --- a/compiler/ast/HtmlAttribute.js +++ b/compiler/ast/HtmlAttribute.js @@ -79,21 +79,37 @@ function generateCodeForExpressionAttr(name, value, escape, codegen) { } codegen.addWriteLiteral('"'); } else { + if (name === 'style') { + // let builder = codegen.builder; + // let valueWithEscaping = handleEscaping(value); + let styleAttr = codegen.addStaticVar('styleAttr', '__helpers.sa'); - // let builder = codegen.builder; - // let valueWithEscaping = handleEscaping(value); - let attrVar = codegen.addStaticVar('attr', '__helpers.a'); + if (escape === false || isNoEscapeXml(value)) { + escape = false; + } - if (escape === false || isNoEscapeXml(value)) { - escape = false; + let styleAttrArgs = [value]; + + if (escape === false) { + styleAttrArgs.push(codegen.builder.literal(false)); + } + codegen.addWrite(codegen.builder.functionCall(styleAttr, styleAttrArgs)); + } else { + // let builder = codegen.builder; + // let valueWithEscaping = handleEscaping(value); + let attrVar = codegen.addStaticVar('attr', '__helpers.a'); + + if (escape === false || isNoEscapeXml(value)) { + escape = false; + } + + let attrArgs = [codegen.builder.literal(name), value]; + + if (escape === false) { + attrArgs.push(codegen.builder.literal(false)); + } + codegen.addWrite(codegen.builder.functionCall(attrVar, attrArgs)); } - - let attrArgs = [codegen.builder.literal(name), value]; - - if (escape === false) { - attrArgs.push(codegen.builder.literal(false)); - } - codegen.addWrite(codegen.builder.functionCall(attrVar, attrArgs)); } } diff --git a/runtime/helpers.js b/runtime/helpers.js index 7a3a3ba13..ce9141e3c 100644 --- a/runtime/helpers.js +++ b/runtime/helpers.js @@ -21,6 +21,7 @@ var runtime = require('./'); // Circular dependency, but that is okay var attr = require('raptor-util/attr'); var attrs = require('raptor-util/attrs'); var isArray = Array.isArray; +var STYLE = 'style'; function notEmpty(o) { if (o == null) { @@ -178,6 +179,38 @@ module.exports = { * @private */ as: attrs, + + /** + * Internal helper method to handle the "style" attribute. The value can either + * be a string or an object with style propertes. For example: + * + * sa('color: red; font-weight: bold') ==> ' style="color: red; font-weight: bold"' + * sa({color: 'red', 'font-weight': 'bold'}) ==> ' style="color: red; font-weight: bold"' + */ + sa: function(style, escape) { + if (!style) { + return; + } + + escape = escape !== false; + + if (typeof style === 'string') { + return attr(STYLE, style, escape); + } else if (typeof style === 'object') { + var parts = []; + for (var name in style) { + if (style.hasOwnProperty(name)) { + var value = style[name]; + if (value) { + parts.push(name + ':' + (escape ? escapeXmlAttr(value) : value)); + } + } + } + return parts ? attr(STYLE, parts.join(';'), false) : ''; + } else { + return ''; + } + }, /** * Loads a template */ diff --git a/test/fixtures/render/autotest/style-attr-object-escape/expected.html b/test/fixtures/render/autotest/style-attr-object-escape/expected.html new file mode 100644 index 000000000..8d866cf4f --- /dev/null +++ b/test/fixtures/render/autotest/style-attr-object-escape/expected.html @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/fixtures/render/autotest/style-attr-object-escape/template.marko b/test/fixtures/render/autotest/style-attr-object-escape/template.marko new file mode 100644 index 000000000..2191218ce --- /dev/null +++ b/test/fixtures/render/autotest/style-attr-object-escape/template.marko @@ -0,0 +1 @@ +div style=data.style \ No newline at end of file diff --git a/test/fixtures/render/autotest/style-attr-object-escape/test.js b/test/fixtures/render/autotest/style-attr-object-escape/test.js new file mode 100644 index 000000000..5a2f4c28f --- /dev/null +++ b/test/fixtures/render/autotest/style-attr-object-escape/test.js @@ -0,0 +1,5 @@ +exports.templateData = { + style: { + color: '' + } +}; diff --git a/test/fixtures/render/autotest/style-attr-object-no-escape/expected.html b/test/fixtures/render/autotest/style-attr-object-no-escape/expected.html new file mode 100644 index 000000000..4f2e9396c --- /dev/null +++ b/test/fixtures/render/autotest/style-attr-object-no-escape/expected.html @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/fixtures/render/autotest/style-attr-object-no-escape/template.marko b/test/fixtures/render/autotest/style-attr-object-no-escape/template.marko new file mode 100644 index 000000000..6a27503c6 --- /dev/null +++ b/test/fixtures/render/autotest/style-attr-object-no-escape/template.marko @@ -0,0 +1 @@ +div style="$!{data.style}" \ No newline at end of file diff --git a/test/fixtures/render/autotest/style-attr-object-no-escape/test.js b/test/fixtures/render/autotest/style-attr-object-no-escape/test.js new file mode 100644 index 000000000..5a2f4c28f --- /dev/null +++ b/test/fixtures/render/autotest/style-attr-object-no-escape/test.js @@ -0,0 +1,5 @@ +exports.templateData = { + style: { + color: '' + } +}; diff --git a/test/fixtures/render/autotest/style-attr-object/expected.html b/test/fixtures/render/autotest/style-attr-object/expected.html new file mode 100644 index 000000000..281095f09 --- /dev/null +++ b/test/fixtures/render/autotest/style-attr-object/expected.html @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/fixtures/render/autotest/style-attr-object/template.marko b/test/fixtures/render/autotest/style-attr-object/template.marko new file mode 100644 index 000000000..21b8d3019 --- /dev/null +++ b/test/fixtures/render/autotest/style-attr-object/template.marko @@ -0,0 +1 @@ +div style={color: 'red', 'font-weight': 'bold'} \ No newline at end of file diff --git a/test/fixtures/render/autotest/style-attr-object/test.js b/test/fixtures/render/autotest/style-attr-object/test.js new file mode 100644 index 000000000..c4013b344 --- /dev/null +++ b/test/fixtures/render/autotest/style-attr-object/test.js @@ -0,0 +1 @@ +exports.templateData = {}; diff --git a/test/fixtures/render/autotest/style-attr-string-dynamic/expected.html b/test/fixtures/render/autotest/style-attr-string-dynamic/expected.html new file mode 100644 index 000000000..7efdb8b5f --- /dev/null +++ b/test/fixtures/render/autotest/style-attr-string-dynamic/expected.html @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/fixtures/render/autotest/style-attr-string-dynamic/template.marko b/test/fixtures/render/autotest/style-attr-string-dynamic/template.marko new file mode 100644 index 000000000..2191218ce --- /dev/null +++ b/test/fixtures/render/autotest/style-attr-string-dynamic/template.marko @@ -0,0 +1 @@ +div style=data.style \ No newline at end of file diff --git a/test/fixtures/render/autotest/style-attr-string-dynamic/test.js b/test/fixtures/render/autotest/style-attr-string-dynamic/test.js new file mode 100644 index 000000000..f4a8e6f07 --- /dev/null +++ b/test/fixtures/render/autotest/style-attr-string-dynamic/test.js @@ -0,0 +1,3 @@ +exports.templateData = { + style: 'color: red' +}; diff --git a/test/fixtures/render/autotest/style-attr-string/expected.html b/test/fixtures/render/autotest/style-attr-string/expected.html new file mode 100644 index 000000000..0cb217464 --- /dev/null +++ b/test/fixtures/render/autotest/style-attr-string/expected.html @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/fixtures/render/autotest/style-attr-string/template.marko b/test/fixtures/render/autotest/style-attr-string/template.marko new file mode 100644 index 000000000..214773eb2 --- /dev/null +++ b/test/fixtures/render/autotest/style-attr-string/template.marko @@ -0,0 +1 @@ +div style="font-weight: bold;" \ No newline at end of file diff --git a/test/fixtures/render/autotest/style-attr-string/test.js b/test/fixtures/render/autotest/style-attr-string/test.js new file mode 100644 index 000000000..c4013b344 --- /dev/null +++ b/test/fixtures/render/autotest/style-attr-string/test.js @@ -0,0 +1 @@ +exports.templateData = {};