Fixes #230 - Marko v3: Special case class attribute to allow object or array expression

This commit is contained in:
Patrick Steele-Idem 2016-02-17 10:02:43 -07:00
parent 58dad19ede
commit b87019a90f
17 changed files with 70 additions and 44 deletions

View File

@ -79,21 +79,16 @@ function generateCodeForExpressionAttr(name, value, escape, codegen) {
}
codegen.addWriteLiteral('"');
} else {
if (name === 'style') {
if (name === 'class') {
// let builder = codegen.builder;
// let valueWithEscaping = handleEscaping(value);
let styleAttr = codegen.addStaticVar('styleAttr', '__helpers.sa');
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));
let classAttrVar = codegen.addStaticVar('classAttr', '__helpers.ca');
codegen.addWrite(codegen.builder.functionCall(classAttrVar, [value]));
} else if (name === 'style') {
// let builder = codegen.builder;
// let valueWithEscaping = handleEscaping(value);
let styleAttrVar = codegen.addStaticVar('styleAttr', '__helpers.sa');
codegen.addWrite(codegen.builder.functionCall(styleAttrVar, [value]));
} else {
// let builder = codegen.builder;
// let valueWithEscaping = handleEscaping(value);

View File

@ -21,7 +21,8 @@ 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';
var STYLE_ATTR = 'style';
var CLASS_ATTR = 'class';
function notEmpty(o) {
if (o == null) {
@ -35,6 +36,17 @@ function notEmpty(o) {
return true;
}
function classListArray(classList) {
var classNames = [];
for (var i=0, len=classList.length; i<len; i++) {
var cur = classList[i];
if (cur) {
classNames.push(cur);
}
}
return classNames.join(' ');
}
function createDeferredRenderer(handler) {
function deferredRenderer(input, out) {
deferredRenderer.renderer(input, out);
@ -187,30 +199,62 @@ module.exports = {
* 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) {
sa: function(style) {
if (!style) {
return;
return '';
}
escape = escape !== false;
if (typeof style === 'string') {
return attr(STYLE, style, escape);
return attr(STYLE_ATTR, style, false);
} 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));
parts.push(name + ':' + value);
}
}
}
return parts ? attr(STYLE, parts.join(';'), false) : '';
return parts ? attr(STYLE_ATTR, parts.join(';'), false) : '';
} else {
return '';
}
},
/**
* Internal helper method to handle the "class" attribute. The value can either
* be a string, an array or an object. For example:
*
* ca('foo bar') ==> ' class="foo bar"'
* ca({foo: true, bar: false, baz: true}) ==> ' class="foo baz"'
* ca(['foo', 'bar']) ==> ' class="foo bar"'
*/
ca: function(classNames) {
if (!classNames) {
return '';
}
if (typeof classNames === 'string') {
return attr(CLASS_ATTR, classNames, false);
} else if (isArray(classNames)) {
return attr(CLASS_ATTR, classListArray(classNames), false);
} else if (typeof classNames === 'object') {
var classList = [];
for (var name in classNames) {
if (classNames.hasOwnProperty(name)) {
var value = classNames[name];
if (value) {
classList.push(name);
}
}
}
return attr(CLASS_ATTR, classListArray(classList), false);
} else {
return '';
}
},
/**
* Loads a template
*/
@ -307,14 +351,6 @@ module.exports = {
*
*/
cl: function() {
var args = arguments;
var classNames = [];
for (var i=0, len=args.length; i<len; i++) {
var cur = args[i];
if (cur) {
classNames.push(cur);
}
}
return classNames.join(' ');
return classListArray(arguments);
}
};

View File

@ -0,0 +1 @@
<div class="a c"></div>

View File

@ -0,0 +1 @@
div class=['a', null, 'c']

View File

@ -0,0 +1 @@
exports.templateData = {};

View File

@ -0,0 +1 @@
<div class="a c"></div>

View File

@ -0,0 +1 @@
div class={a: true, b: false, c: true}

View File

@ -0,0 +1 @@
exports.templateData = {};

View File

@ -0,0 +1 @@
<div class="a c"></div>

View File

@ -0,0 +1 @@
div class='a c'

View File

@ -0,0 +1 @@
exports.templateData = {};

View File

@ -1 +0,0 @@
<div style="color:&lt;evil&gt;"></div>

View File

@ -1 +0,0 @@
div style=data.style

View File

@ -1,5 +0,0 @@
exports.templateData = {
style: {
color: '<evil>'
}
};

View File

@ -1 +0,0 @@
<div style="color:<evil>"></div>

View File

@ -1 +0,0 @@
div style="$!{data.style}"

View File

@ -1,5 +0,0 @@
exports.templateData = {
style: {
color: '<evil>'
}
};