Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

add mustache/handlebars inline attribute support

  • Loading branch information...
commit 1a46656a9de18bc7af358e5d6450c1b2d7ffe249 1 parent 1bb7ace
@lancejpollard lancejpollard authored
View
181 lib/coffeecup.js
@@ -1,7 +1,8 @@
+// Generated by CoffeeScript 1.3.1
var cache, coffee, coffeecup, coffeescript_helpers, compiler, elements, merge_elements, skeleton,
- __slice = Array.prototype.slice,
- __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
- __hasProp = Object.prototype.hasOwnProperty,
+ __slice = [].slice,
+ __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
+ __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
if (typeof window !== "undefined" && window !== null) {
@@ -59,15 +60,17 @@ elements = {
};
merge_elements = function() {
- var a, args, element, result, _i, _j, _len, _len2, _ref;
+ var a, args, element, result, _i, _j, _len, _len1, _ref;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
result = [];
for (_i = 0, _len = args.length; _i < _len; _i++) {
a = args[_i];
_ref = elements[a].split(' ');
- for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) {
+ for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
element = _ref[_j];
- if (__indexOf.call(result, element) < 0) result.push(element);
+ if (__indexOf.call(result, element) < 0) {
+ result.push(element);
+ }
}
}
return result;
@@ -79,9 +82,15 @@ coffeecup.self_closing = merge_elements('void', 'obsolete_void');
skeleton = function(data) {
var cede, coffeescript, comment, doctype, h, ie, stylus, tag, text, __cc;
- if (data == null) data = {};
- if (data.format == null) data.format = false;
- if (data.autoescape == null) data.autoescape = false;
+ if (data == null) {
+ data = {};
+ }
+ if (data.format == null) {
+ data.format = false;
+ }
+ if (data.autoescape == null) {
+ data.autoescape = false;
+ }
__cc = {
buffer: [],
esc: function(txt) {
@@ -96,7 +105,9 @@ skeleton = function(data) {
return Array(count + 1).join(string);
},
indent: function() {
- if (data.format) return text(this.repeat(' ', this.tabs));
+ if (data.format) {
+ return text(this.repeat(' ', this.tabs));
+ }
},
tag: function(name, args) {
var combo, i, _i, _len;
@@ -108,7 +119,7 @@ skeleton = function(data) {
return tag.apply(data, combo);
},
render_idclass: function(str) {
- var c, classes, i, id, _i, _j, _len, _len2, _ref;
+ var c, classes, i, id, _i, _j, _len, _len1, _ref;
classes = [];
_ref = str.split('.');
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@@ -116,15 +127,21 @@ skeleton = function(data) {
if (__indexOf.call(i, '#') >= 0) {
id = i.replace('#', '');
} else {
- if (i !== '') classes.push(i);
+ if (i !== '') {
+ classes.push(i);
+ }
}
}
- if (id) text(" id=\"" + id + "\"");
+ if (id) {
+ text(" id=\"" + id + "\"");
+ }
if (classes.length > 0) {
text(" class=\"");
- for (_j = 0, _len2 = classes.length; _j < _len2; _j++) {
+ for (_j = 0, _len1 = classes.length; _j < _len1; _j++) {
c = classes[_j];
- if (c !== classes[0]) text(' ');
+ if (c !== classes[0]) {
+ text(' ');
+ }
text(c);
}
return text('"');
@@ -132,12 +149,18 @@ skeleton = function(data) {
},
render_attrs: function(obj, prefix) {
var k, v, _results;
- if (prefix == null) prefix = '';
+ if (prefix == null) {
+ prefix = '';
+ }
_results = [];
for (k in obj) {
v = obj[k];
- if (typeof v === 'boolean' && v) v = k;
- if (typeof v === 'function') v = "(" + v + ").call(this);";
+ if (typeof v === 'boolean' && v) {
+ v = k;
+ }
+ if (typeof v === 'function') {
+ v = "(" + v + ").call(this);";
+ }
if (typeof v === 'object' && !(v instanceof Array)) {
_results.push(this.render_attrs(v, prefix + k + '-'));
} else if (v) {
@@ -150,44 +173,61 @@ skeleton = function(data) {
},
render_contents: function(contents, safe) {
var result;
- if (safe == null) safe = false;
+ if (safe == null) {
+ safe = false;
+ }
switch (typeof contents) {
case 'string':
case 'number':
case 'boolean':
return text(safe ? contents : this.esc(contents));
case 'function':
- if (data.format) text('\n');
+ if (data.format) {
+ text('\n');
+ }
this.tabs++;
result = contents.call(data);
if (typeof result === 'string') {
this.indent();
text(safe ? result : this.esc(result));
- if (data.format) text('\n');
+ if (data.format) {
+ text('\n');
+ }
}
this.tabs--;
return this.indent();
}
},
- render_tag: function(name, idclass, attrs, contents) {
+ render_tag: function(name, idclass, attrs, inline, contents) {
this.indent();
text("<" + name);
- if (idclass) this.render_idclass(idclass);
- if (attrs) this.render_attrs(attrs);
+ if (idclass) {
+ this.render_idclass(idclass);
+ }
+ if (attrs) {
+ this.render_attrs(attrs);
+ }
+ if (inline) {
+ text(" " + inline);
+ }
if (__indexOf.call(this.self_closing, name) >= 0) {
text(' />');
- if (data.format) text('\n');
+ if (data.format) {
+ text('\n');
+ }
} else {
text('>');
this.render_contents(contents);
text("</" + name + ">");
- if (data.format) text('\n');
+ if (data.format) {
+ text('\n');
+ }
}
return null;
}
};
tag = function() {
- var a, args, attrs, contents, idclass, name, _i, _len;
+ var a, args, attrs, contents, first, idclass, inline, name, _i, _len;
name = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
for (_i = 0, _len = args.length; _i < _len; _i++) {
a = args[_i];
@@ -207,14 +247,27 @@ skeleton = function(data) {
contents = a;
} else {
if (a === args[0]) {
- idclass = a;
+ first = a.charAt(0);
+ if (first === '#' || first === '.') {
+ idclass = a.substr(0, a.indexOf(' '));
+ inline = a.substr(a.indexOf(' ') + 1);
+ if (idclass === '') {
+ idclass = inline;
+ inline = void 0;
+ }
+ } else {
+ inline = a;
+ if (inline === '') {
+ inline = void 0;
+ }
+ }
} else {
contents = a;
}
}
}
}
- return __cc.render_tag(name, idclass, attrs, contents);
+ return __cc.render_tag(name, idclass, attrs, inline, contents);
};
cede = function(f) {
var old_buffer, temp_buffer;
@@ -229,9 +282,13 @@ skeleton = function(data) {
return txt.toString().replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
};
doctype = function(type) {
- if (type == null) type = 'default';
+ if (type == null) {
+ type = 'default';
+ }
text(__cc.doctypes[type]);
- if (data.format) return text('\n');
+ if (data.format) {
+ return text('\n');
+ }
};
text = function(txt) {
__cc.buffer.push(txt.toString());
@@ -239,7 +296,9 @@ skeleton = function(data) {
};
comment = function(cmt) {
text("<!--" + cmt + "-->");
- if (data.format) return text('\n');
+ if (data.format) {
+ return text('\n');
+ }
};
coffeescript = function(param) {
switch (typeof param) {
@@ -258,22 +317,30 @@ skeleton = function(data) {
};
stylus = function(s) {
text('<style>');
- if (data.format) text('\n');
+ if (data.format) {
+ text('\n');
+ }
data.stylus.render(s, {
compress: !data.format
}, function(err, css) {
- if (err) throw err;
+ if (err) {
+ throw err;
+ }
return text(css);
});
text('</style>');
- if (data.format) return text('\n');
+ if (data.format) {
+ return text('\n');
+ }
};
ie = function(condition, contents) {
__cc.indent();
text("<!--[if " + condition + "]>");
__cc.render_contents(contents);
text("<![endif]-->");
- if (data.format) return text('\n');
+ if (data.format) {
+ return text('\n');
+ }
};
return null;
};
@@ -283,8 +350,10 @@ skeleton = skeleton.toString().replace(/function\s*\(.*\)\s*\{/, '').replace(/re
skeleton = coffeescript_helpers + skeleton;
coffeecup.compile = function(template, options) {
- var code, hardcoded_locals, k, t, tag_functions, tags_used, v, _i, _j, _len, _len2, _ref, _ref2;
- if (options == null) options = {};
+ var code, hardcoded_locals, k, t, tag_functions, tags_used, v, _i, _j, _len, _len1, _ref, _ref1;
+ if (options == null) {
+ options = {};
+ }
if (typeof template === 'function') {
template = template.toString();
} else if (typeof template === 'string' && (coffee != null)) {
@@ -310,15 +379,15 @@ coffeecup.compile = function(template, options) {
}
tag_functions = '';
tags_used = [];
- _ref2 = coffeecup.tags;
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- t = _ref2[_i];
+ _ref1 = coffeecup.tags;
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+ t = _ref1[_i];
if (template.indexOf(t) > -1 || hardcoded_locals.indexOf(t) > -1) {
tags_used.push(t);
}
}
tag_functions += "var " + (tags_used.join(',')) + ";";
- for (_j = 0, _len2 = tags_used.length; _j < _len2; _j++) {
+ for (_j = 0, _len1 = tags_used.length; _j < _len1; _j++) {
t = tags_used[_j];
tag_functions += "" + t + " = function(){return __cc.tag('" + t + "', arguments);};";
}
@@ -326,9 +395,13 @@ coffeecup.compile = function(template, options) {
code += "__cc.doctypes = " + (JSON.stringify(coffeecup.doctypes)) + ";";
code += "__cc.coffeescript_helpers = " + (JSON.stringify(coffeescript_helpers)) + ";";
code += "__cc.self_closing = " + (JSON.stringify(coffeecup.self_closing)) + ";";
- if (options.locals) code += 'with(data.locals){';
+ if (options.locals) {
+ code += 'with(data.locals){';
+ }
code += "(" + template + ").call(data);";
- if (options.locals) code += '}';
+ if (options.locals) {
+ code += '}';
+ }
code += "return __cc.buffer.join('');";
return new Function('data', code);
};
@@ -337,15 +410,23 @@ cache = {};
coffeecup.render = function(template, data, options) {
var k, tpl, v;
- if (data == null) data = {};
- if (options == null) options = {};
+ if (data == null) {
+ data = {};
+ }
+ if (options == null) {
+ options = {};
+ }
for (k in options) {
v = options[k];
data[k] = v;
}
- if (data.cache == null) data.cache = false;
+ if (data.cache == null) {
+ data.cache = false;
+ }
data.stylus = require('stylus');
- if (data.optimize && !data.cache) data.optimize = false;
+ if (data.optimize && !data.cache) {
+ data.optimize = false;
+ }
if (data.cache && (cache[template] != null)) {
tpl = cache[template];
} else if (data.cache) {
@@ -378,7 +459,9 @@ if (typeof window === "undefined" || window === null) {
})(Error),
compile: function(template, data) {
var TemplateError, tpl;
- if (data.hardcode == null) data.hardcode = {};
+ if (data.hardcode == null) {
+ data.hardcode = {};
+ }
data.hardcode.partial = function() {
return text(this.partial.apply(this, arguments));
};
View
69 lib/compiler.js
@@ -1,5 +1,6 @@
+// Generated by CoffeeScript 1.3.1
var Code, call_bound_func, coffee, coffeecup, parser, skeleton, uglify, _ref,
- __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+ __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
coffee = require('coffee-script');
@@ -19,6 +20,8 @@ call_bound_func = function(func) {
Code = (function() {
+ Code.name = 'Code';
+
function Code(parent) {
this.parent = parent;
this.nodes = [];
@@ -76,7 +79,7 @@ Code = (function() {
};
Code.prototype.merge_text = function(arg) {
- var l, ok, oldArg, prev, _ref2, _ref3;
+ var l, ok, oldArg, prev, _ref1, _ref2;
if (arg[0] === 'binary' && arg[1] === '+') {
this.merge_text(arg[2]);
arg = arg[3];
@@ -86,7 +89,7 @@ Code = (function() {
if (prev[0] === 'stat' && prev[1][0] === 'call' && prev[1][1][0] === 'name' && prev[1][1][1] === 'text') {
oldArg = prev[1][2][0];
ok = ['string', 'num'];
- if ((_ref2 = oldArg[0], __indexOf.call(ok, _ref2) >= 0) && (_ref3 = arg[0], __indexOf.call(ok, _ref3) >= 0)) {
+ if ((_ref1 = oldArg[0], __indexOf.call(ok, _ref1) >= 0) && (_ref2 = arg[0], __indexOf.call(ok, _ref2) >= 0)) {
prev[1][2][0] = ['string', oldArg[1] + arg[1]];
return;
}
@@ -97,7 +100,9 @@ Code = (function() {
Code.prototype.get_nodes = function() {
this.flush();
- if (this.parent[0] === 'stat') return ['splice', this.nodes];
+ if (this.parent[0] === 'stat') {
+ return ['splice', this.nodes];
+ }
return call_bound_func(['function', null, [], this.nodes]);
};
@@ -108,14 +113,16 @@ Code = (function() {
exports.compile = function(source, hardcoded_locals, options) {
var ast, code, compiled, escape, w;
escape = function(node) {
- if (options.autoescape) return ['call', ['name', 'h'], [node]];
+ if (options.autoescape) {
+ return ['call', ['name', 'h'], [node]];
+ }
return node;
};
ast = parser.parse(hardcoded_locals + ("(" + source + ").call(data);"));
w = uglify.ast_walker();
ast = w.with_walkers({
call: function(expr, args) {
- var arg, classes, code, comment, condition, contents, doctype, escape_all, func, i, id, idx, name, node, render_attrs, _i, _j, _k, _len, _len2, _len3, _len4, _ref2, _ref3, _ref4;
+ var arg, classes, code, comment, condition, contents, doctype, escape_all, func, i, id, idx, name, node, render_attrs, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref1, _ref2, _ref3;
name = expr[1];
if (name === 'doctype') {
code = new Code(w.parent());
@@ -155,12 +162,14 @@ exports.compile = function(source, hardcoded_locals, options) {
code.append('<![endif]-->');
return code.get_nodes();
} else if (__indexOf.call(coffeecup.tags, name) >= 0 || (name === 'tag' || name === 'coffeescript')) {
- if (name === 'tag') name = args.shift()[1];
+ if (name === 'tag') {
+ name = args.shift()[1];
+ }
if (name === 'coffeescript') {
name = 'script';
for (_i = 0, _len = args.length; _i < _len; _i++) {
arg = args[_i];
- if ((_ref2 = arg[0]) !== 'string' && _ref2 !== 'object' && _ref2 !== 'function') {
+ if ((_ref1 = arg[0]) !== 'string' && _ref1 !== 'object' && _ref1 !== 'function') {
throw new Error('Invalid argument to coffeescript function');
}
if (arg[0] === 'string' && (args.length === 1 || arg !== args[0])) {
@@ -172,7 +181,7 @@ exports.compile = function(source, hardcoded_locals, options) {
}
code = new Code(w.parent());
code.append("<" + name);
- for (_j = 0, _len2 = args.length; _j < _len2; _j++) {
+ for (_j = 0, _len1 = args.length; _j < _len1; _j++) {
arg = args[_j];
switch (arg[0]) {
case 'function':
@@ -184,9 +193,9 @@ exports.compile = function(source, hardcoded_locals, options) {
contents = ['string', "" + func + ".call(this);"];
} else {
func = w.walk(arg);
- _ref3 = func[3];
- for (idx = 0, _len3 = _ref3.length; idx < _len3; idx++) {
- node = _ref3[idx];
+ _ref2 = func[3];
+ for (idx = _k = 0, _len2 = _ref2.length; _k < _len2; idx = ++_k) {
+ node = _ref2[idx];
if (node[0] === 'return' && (node[1] != null) && node[1][0] !== 'string') {
func[3][idx][1] = escape(node[1]);
}
@@ -196,18 +205,20 @@ exports.compile = function(source, hardcoded_locals, options) {
break;
case 'object':
render_attrs = function(obj, prefix) {
- var attr, key, value, varname, _k, _len4, _ref4, _ref5, _results;
- if (prefix == null) prefix = '';
+ var attr, key, value, varname, _l, _len3, _ref3, _ref4, _results;
+ if (prefix == null) {
+ prefix = '';
+ }
_results = [];
- for (_k = 0, _len4 = obj.length; _k < _len4; _k++) {
- attr = obj[_k];
+ for (_l = 0, _len3 = obj.length; _l < _len3; _l++) {
+ attr = obj[_l];
key = attr[0];
value = attr[1];
if (value[0] === 'name' && value[1] === 'true') {
_results.push(code.append(" " + key + "=\"" + key + "\""));
- } else if (value[0] === 'name' && ((_ref4 = value[1]) === 'undefined' || _ref4 === 'null' || _ref4 === 'false')) {
+ } else if (value[0] === 'name' && ((_ref3 = value[1]) === 'undefined' || _ref3 === 'null' || _ref3 === 'false')) {
continue;
- } else if ((_ref5 = value[0]) === 'name' || _ref5 === 'dot') {
+ } else if ((_ref4 = value[0]) === 'name' || _ref4 === 'dot') {
varname = uglify.gen_code(value);
condition = "typeof " + varname + " !== 'undefined' && " + varname + " !== null && " + varname + " !== false";
code.open_if(parser.parse(condition)[1][0][1]);
@@ -235,16 +246,20 @@ exports.compile = function(source, hardcoded_locals, options) {
case 'string':
if (args.length > 1 && arg === args[0]) {
classes = [];
- _ref4 = arg[1].split('.');
- for (_k = 0, _len4 = _ref4.length; _k < _len4; _k++) {
- i = _ref4[_k];
+ _ref3 = arg[1].split('.');
+ for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
+ i = _ref3[_l];
if (__indexOf.call(i, '#') >= 0) {
id = i.replace('#', '');
} else {
- if (i !== '') classes.push(i);
+ if (i !== '') {
+ classes.push(i);
+ }
}
}
- if (id) code.append(" id=\"" + id + "\"");
+ if (id) {
+ code.append(" id=\"" + id + "\"");
+ }
if (classes.length > 0) {
code.append(" class=\"" + (classes.join(' ')) + "\"");
}
@@ -282,7 +297,9 @@ exports.compile = function(source, hardcoded_locals, options) {
} else {
code.append('>');
}
- if (contents != null) code.push(contents);
+ if (contents != null) {
+ code.push(contents);
+ }
if (!(__indexOf.call(coffeecup.self_closing, name) >= 0)) {
code.append("</" + name + ">");
}
@@ -297,7 +314,9 @@ exports.compile = function(source, hardcoded_locals, options) {
beautify: true,
indent_level: 2
});
- if (options.locals) compiled = "with(data.locals){" + compiled + "}";
+ if (options.locals) {
+ compiled = "with(data.locals){" + compiled + "}";
+ }
code = skeleton + compiled + "return __cc.buffer;";
return new Function('data', code);
};
View
1  lib/skeleton.js
@@ -1,3 +1,4 @@
+// Generated by CoffeeScript 1.3.1
var cede, h, text, __cc;
__cc = {
View
17 src/coffeecup.coffee
@@ -189,12 +189,14 @@ skeleton = (data = {}) ->
@tabs--
@indent()
- render_tag: (name, idclass, attrs, contents) ->
+ render_tag: (name, idclass, attrs, inline, contents) ->
@indent()
text "<#{name}"
@render_idclass(idclass) if idclass
@render_attrs(attrs) if attrs
+
+ text " #{inline}" if inline
if name in @self_closing
text ' />'
@@ -223,11 +225,20 @@ skeleton = (data = {}) ->
contents = a
else
if a is args[0]
- idclass = a
+ first = a.charAt(0)
+ if first == '#' || first == '.'
+ idclass = a.substr(0, a.indexOf(' '))
+ inline = a.substr(a.indexOf(' ') + 1)
+ if idclass == ''
+ idclass = inline
+ inline = undefined
+ else
+ inline = a
+ inline = undefined if inline == ''
else
contents = a
- __cc.render_tag(name, idclass, attrs, contents)
+ __cc.render_tag(name, idclass, attrs, inline, contents)
cede = (f) ->
temp_buffer = []
View
9 test/attributes.coffee
@@ -11,6 +11,15 @@ describe 'Attribute values', ->
it 'should render <br vrai="vrai" str="str" num="42" arr="1,2,3" obj-foo="bar" func="(function () {}).call(this);" />', ->
a = -> br vrai: yes, faux: no, undef: @foo, nil: null, str: 'str', num: 42, arr: [1, 2, 3], obj: {foo: 'bar'}, func: ->
cc.render(a).should.equal '<br vrai="vrai" str="str" num="42" arr="1,2,3" obj-foo="bar" func="(function () {}).call(this);" />'
+
+describe 'Inline attributes', ->
+ describe "p '#foo {{bindAttr class=isSelected}}, 'Bar'", ->
+ a = -> p '#foo {{bindAttr class="isSelected"}}', 'Bar'
+ cc.render(a).should.equal '<p id="foo" {{bindAttr class="isSelected"}}>Bar</p>'
+
+ describe "p '{{bindAttr class=isActive target=App}}, 'Bar'", ->
+ a = -> p '{{bindAttr class="isActive" target="App"}}', 'Bar'
+ cc.render(a).should.equal '<p {{bindAttr class="isActive" target="App"}}>Bar</p>'
describe 'Attributes optimized', ->
describe "a href: '/', title: 'Home'", ->
Please sign in to comment.
Something went wrong with that request. Please try again.