Skip to content

Instantly share code, notes, and snippets.

@insin
Created July 31, 2012 22:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save insin/3221334 to your computer and use it in GitHub Desktop.
Save insin/3221334 to your computer and use it in GitHub Desktop.
Jade issue #610

Quick & dirty attempt at implementing the fix suggested in pugjs/pug#610

nullVariable = null
//- my actual problem - adds a 'null' class instead of omitting altogether
a.foo(class=nullVariable)
//- other stuff that's supported and needs to be handled by any fix to the above
a(class=['foo', 'bar', nullVariable])
a.foo(class=['bar', nullVariable])
a.foo.bar(class=['ter', nullVariable])
<a class="foo null"></a><a class="foo bar "></a><a class="foo bar,"></a><a class="foo bar ter,"></a>
function anonymous(locals, attrs, escape, rethrow, merge) {
attrs = attrs || jade.attrs; escape = escape || jade.escape; rethrow = rethrow || jade.rethrow; merge = merge || jade.merge;
var buf = [];
with (locals || {}) {
var interp;
var nullVariable = (null);
buf.push('<a');
buf.push(attrs({ "class": ('foo') + ' ' + (nullVariable) }, {"class":true}));
buf.push('></a><a');
buf.push(attrs({ "class": (['foo', 'bar', nullVariable]) }, {"class":true}));
buf.push('></a><a');
buf.push(attrs({ "class": ('foo') + ' ' + (['bar', nullVariable]) }, {"class":true}));
buf.push('></a><a');
buf.push(attrs({ "class": ('foo') + ' ' + ('bar') + ' ' + (['ter', nullVariable]) }, {"class":true}));
buf.push('></a>');
}
return buf.join("");
}
diff --git a/lib/compiler.js b/lib/compiler.js
index b7c28e2..ab33680 100644
--- a/lib/compiler.js
+++ b/lib/compiler.js
@@ -599,7 +599,7 @@ Compiler.prototype = {
});
if (classes.length) {
- classes = classes.join(" + ' ' + ");
+ classes = '[' + classes.join(', ') + ']'
buf.push("class: " + classes);
}
diff --git a/lib/runtime.js b/lib/runtime.js
index fb711f5..696b458 100644
--- a/lib/runtime.js
+++ b/lib/runtime.js
@@ -79,6 +79,31 @@ function nulls(val) {
}
/**
+ * Flatten classes and filter null items, in-place.
+ *
+ * @param {Array} classes
+ * @return {Array}
+ * @api private
+ */
+
+function classes(classes) {
+ for (var i = 0, l = classes.length, val; i < l; i++) {
+ val = classes[i];
+ if (val == null) {
+ l--;
+ classes.splice(i, 1);
+ i--;
+ }
+ else if (Array.isArray(val)) {
+ l += val.length - 1;
+ classes.splice.apply(classes, [i, 1].concat(val));
+ i--;
+ }
+ }
+ return classes;
+}
+
+/**
* Render the given attributes object.
*
* @param {Object} obj
@@ -110,7 +135,9 @@ exports.attrs = function attrs(obj, escaped){
} else if (0 == key.indexOf('data') && 'string' != typeof val) {
buf.push(key + "='" + JSON.stringify(val) + "'");
} else if ('class' == key && Array.isArray(val)) {
- buf.push(key + '="' + exports.escape(val.join(' ')) + '"');
+ if (classes(val).length) {
+ buf.push(key + '="' + exports.escape(val.join(' ')) + '"');
+ }
} else if (escaped && escaped[key]) {
buf.push(key + '="' + exports.escape(val) + '"');
} else {
diff --git a/test/cases/classes.html b/test/cases/classes.html
index 6faf6bc..a694487 100644
--- a/test/cases/classes.html
+++ b/test/cases/classes.html
@@ -1 +1 @@
-<a class="foo bar baz"></a><a class="foo bar baz"></a><a class="foo-bar_baz"></a>
\ No newline at end of file
+<a class="foo bar baz"></a><a class="foo bar baz"></a><a class="foo-bar_baz"></a><a class="foo"></a><a class="bar"></a><a class="ter bar"></a>
\ No newline at end of file
diff --git a/test/cases/classes.jade b/test/cases/classes.jade
index 496e791..769a47e 100644
--- a/test/cases/classes.jade
+++ b/test/cases/classes.jade
@@ -4,6 +4,20 @@ a(class=['foo', 'bar', 'baz'])
a.foo(class='bar').baz
-
-a.foo-bar_baz
\ No newline at end of file
+
+a.foo-bar_baz
+
+
+
+undefinedClass = undefined
+a.foo(class=undefined)
+
+
+
+nullClass = null
+a.bar(class=nullClass)
+
+
+
+a.ter(class=['bar', undefined])
\ No newline at end of file
<a class="foo"></a><a class="foo bar"></a><a class="foo bar"></a><a class="foo bar ter"></a>
function anonymous(locals, attrs, escape, rethrow, merge) {
attrs = attrs || jade.attrs; escape = escape || jade.escape; rethrow = rethrow || jade.rethrow; merge = merge || jade.merge;
var buf = [];
with (locals || {}) {
var interp;
var nullVariable = (null);
buf.push('<a');
buf.push(attrs({ "class": [('foo'), (nullVariable)] }, {"class":true}));
buf.push('></a><a');
buf.push(attrs({ "class": [(['foo', 'bar', nullVariable])] }, {"class":true}));
buf.push('></a><a');
buf.push(attrs({ "class": [('foo'), (['bar', nullVariable])] }, {"class":true}));
buf.push('></a><a');
buf.push(attrs({ "class": [('foo'), ('bar'), (['ter', nullVariable])] }, {"class":true}));
buf.push('></a>');
}
return buf.join("");
}
insin@balamb ~/Repos/jade (class-merge)
$ make test
...........................................................
.............
✔ 72 tests complete (574ms)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment