Permalink
Browse files

Fixed attrs. Closes #133

  • Loading branch information...
1 parent 8809c02 commit df7f0785f18808e9d7aa08b2b29f2777974d096e @tj tj committed Mar 4, 2011
Showing with 60 additions and 22 deletions.
  1. +51 −22 lib/lexer.js
  2. +9 −0 test/jade.test.js
View
@@ -266,33 +266,62 @@ Lexer.prototype = {
get attrs() {
if ('(' == this.input[0]) {
var index = this.indexOfDelimiters('(', ')')
- , str = this.input.substr(1, index-1);
+ , str = this.input.substr(1, index-1)
+ , tok = this.tok('attrs')
+ , len = str.length
+ , state = 'key'
+ , key = ''
+ , val = ''
+ , c;
+
this.consume(index + 1);
- var tok = this.tok('attrs', str)
- , attrs = tok.val.split(/ *, *(?=['"\w-]+ *[:=]|[\w-]+ *$)/);
tok.attrs = {};
- for (var i = 0, len = attrs.length; i < len; ++i) {
- var pair = attrs[i];
- // Support = and :
- var colon = pair.indexOf(':')
- , equal = pair.indexOf('=');
-
- // Boolean
- if (colon < 0 && equal < 0) {
- var key = pair
- , val = true;
- } else {
- // Split on first = or :
- var split = equal >= 0
- ? equal
- : colon;
- if (colon >= 0 && colon < equal) split = colon;
- var key = pair.substr(0, split)
- , val = pair.substr(++split, pair.length);
+ function parse(c) {
+ switch (c) {
+ case ',':
+ if ('string' == state) {
+ val += c;
+ } else {
+ state = 'key';
+ val = val.trim();
+ tok.attrs[key.trim().replace(/^['"]|['"]$/g, '')] = '' == val
+ ? true
+ : val;
+ key = val = '';
+ }
+ break;
+ case ':':
+ case '=':
+ if ('string' == state || 'val' == state) {
+ val += c;
+ } else {
+ state = 'val';
+ }
+ break;
+ case '"':
+ case "'":
+ if ('key' == state) break;
+ state = 'string' == state
+ ? 'val'
+ : 'string';
+ val += c;
+ break;
+ default:
+ switch (state) {
+ case 'key': key += c; break;
+ case 'val': val += c; break;
+ case 'string': val += c; break;
+ }
}
- tok.attrs[key.trim().replace(/^['"]|['"]$/g, '')] = val;
}
+
+ for (var i = 0; i < len; ++i) {
+ parse(str[i]);
+ }
+
+ parse(',');
+
return tok;
}
},
View
@@ -496,6 +496,15 @@ module.exports = {
assert.equal('<p data-dynamic="true"></p>', render('p(\'data-dynamic\': "true")'));
assert.equal('<p data-dynamic="true" class="name"></p>', render('p(\'class\': "name", \'data-dynamic\': "true")'));
assert.equal('<p data-dynamic="true" yay="yay" class="name"></p>', render('p(\'class\': "name", \'data-dynamic\': "true", yay)'));
+
+ assert.equal('<input checked="checked" type="checkbox"/>', render('input(checked, type="checkbox")'));
+ assert.equal('<input checked="checked" type="checkbox"/>', render('input(checked, type: "checkbox")'));
+
+ assert.equal('<a data-foo="{ foo: \'bar\', bar: \'baz\' }"></a>', render('a(data-foo : "{ foo: \'bar\', bar: \'baz\' }")'));
+ assert.equal('<a data-foo="{ foo: \'bar\', bar: \'baz\' }"></a>', render('a(data-foo = "{ foo: \'bar\', bar: \'baz\' }")'));
+
+ assert.equal('<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>', render('meta(http-equiv="X-UA-Compatible", content="IE=edge,chrome=1")'));
+ assert.equal('<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>', render('meta(http-equiv: "X-UA-Compatible", content: "IE=edge,chrome=1")'));
},
'test attr parens': function(assert){

0 comments on commit df7f078

Please sign in to comment.