1 | var cache, coffee, coffeecup, coffeescript_helpers, compiler, elements, merge_elements, skeleton,
|
2 | __slice = Array.prototype.slice,
|
3 | __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; },
|
4 | __hasProp = Object.prototype.hasOwnProperty,
|
5 | __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; };
|
6 |
|
7 | if (typeof window !== "undefined" && window !== null) {
|
8 | coffeecup = window.coffeecup = {};
|
9 | coffee = typeof CoffeeScript !== "undefined" && CoffeeScript !== null ? CoffeeScript : null;
|
10 | } else {
|
11 | coffeecup = exports;
|
12 | coffee = require('coffee-script');
|
13 | compiler = require(__dirname + '/compiler');
|
14 | compiler.setup(coffeecup);
|
15 | }
|
16 |
|
17 | coffeecup.version = '0.3.10';
|
18 |
|
19 | coffeecup.doctypes = {
|
20 | 'default': '<!DOCTYPE html>',
|
21 | '5': '<!DOCTYPE html>',
|
22 | 'xml': '<?xml version="1.0" encoding="utf-8" ?>',
|
23 | 'transitional': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
|
24 | 'strict': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
|
25 | 'frameset': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
|
26 | '1.1': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
|
27 | 'basic': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',
|
28 | 'mobile': '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">',
|
29 | 'ce': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "ce-html-1.0-transitional.dtd">'
|
30 | };
|
31 |
|
32 | coffeescript_helpers = "var __slice = Array.prototype.slice;\nvar __hasProp = Object.prototype.hasOwnProperty;\nvar __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };\nvar __extends = function(child, parent) {\n for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }\n function ctor() { this.constructor = child; }\n ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype;\n return child; };\nvar __indexOf = Array.prototype.indexOf || function(item) {\n for (var i = 0, l = this.length; i < l; i++) {\n if (this[i] === item) return i;\n } return -1; };".replace(/\n/g, '');
|
33 |
|
34 | elements = {
|
35 | regular: 'a abbr address article aside audio b bdi bdo blockquote body button\
|
36 | canvas caption cite code colgroup datalist dd del details dfn div dl dt em\
|
37 | fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header hgroup\
|
38 | html i iframe ins kbd label legend li map mark menu meter nav noscript object\
|
39 | ol optgroup option output p pre progress q rp rt ruby s samp script section\
|
40 | select small span strong style sub summary sup table tbody td textarea tfoot\
|
41 | th thead time title tr u ul video',
|
42 | svg: 'a altGlyph altGlyphDef altGlyphItem animate animateColor animateMotion\
|
43 | animateTransform circle clipPath color-profile cursor defs desc ellipse\
|
44 | feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix\
|
45 | feDiffuseLighting feDisplacementMap feDistantLight feFlood feFuncA feFuncB\
|
46 | feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology\
|
47 | feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence\
|
48 | filter font font-face font-face-format font-face-name font-face-src\
|
49 | font-face-uri foreignObject g glyph glyphRef hkern image line linearGradient\
|
50 | marker mask metadata missing-glyph mpath path pattern polygon polyline\
|
51 | radialGradient rect script set stop style svg symbol text textPath\
|
52 | title tref tspan use view vkern',
|
53 | "void": 'area base br col command embed hr img input keygen link meta param\
|
54 | source track wbr',
|
55 | obsolete: 'applet acronym bgsound dir frameset noframes isindex listing\
|
56 | nextid noembed plaintext rb strike xmp big blink center font marquee multicol\
|
57 | nobr spacer tt',
|
58 | obsolete_void: 'basefont frame'
|
59 | };
|
60 |
|
61 | merge_elements = function() {
|
62 | var a, args, element, result, _i, _j, _len, _len2, _ref;
|
63 | args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
64 | result = [];
|
65 | for (_i = 0, _len = args.length; _i < _len; _i++) {
|
66 | a = args[_i];
|
67 | _ref = elements[a].split(' ');
|
68 | for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) {
|
69 | element = _ref[_j];
|
70 | if (__indexOf.call(result, element) < 0) result.push(element);
|
71 | }
|
72 | }
|
73 | return result;
|
74 | };
|
75 |
|
76 | coffeecup.tags = merge_elements('regular', 'obsolete', 'void', 'obsolete_void', 'svg');
|
77 |
|
78 | coffeecup.self_closing = merge_elements('void', 'obsolete_void');
|
79 |
|
80 | skeleton = function(data) {
|
81 | var coffeescript, comment, doctype, h, ie, stylus, tag, text, yield, __cc;
|
82 | if (data == null) data = {};
|
83 | if (data.format == null) data.format = false;
|
84 | if (data.autoescape == null) data.autoescape = false;
|
85 | __cc = {
|
86 | buffer: [],
|
87 | esc: function(txt) {
|
88 | if (data.autoescape) {
|
89 | return h(txt);
|
90 | } else {
|
91 | return txt.toString();
|
92 | }
|
93 | },
|
94 | tabs: 0,
|
95 | repeat: function(string, count) {
|
96 | return Array(count + 1).join(string);
|
97 | },
|
98 | indent: function() {
|
99 | if (data.format) return text(this.repeat(' ', this.tabs));
|
100 | },
|
101 | tag: function(name, args) {
|
102 | var combo, i, _i, _len;
|
103 | combo = [name];
|
104 | for (_i = 0, _len = args.length; _i < _len; _i++) {
|
105 | i = args[_i];
|
106 | combo.push(i);
|
107 | }
|
108 | return tag.apply(data, combo);
|
109 | },
|
110 | render_idclass: function(str) {
|
111 | var c, classes, i, id, _i, _j, _len, _len2, _ref;
|
112 | classes = [];
|
113 | _ref = str.split('.');
|
114 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
115 | i = _ref[_i];
|
116 | if (__indexOf.call(i, '#') >= 0) {
|
117 | id = i.replace('#', '');
|
118 | } else {
|
119 | if (i !== '') classes.push(i);
|
120 | }
|
121 | }
|
122 | if (id) text(" id=\"" + id + "\"");
|
123 | if (classes.length > 0) {
|
124 | text(" class=\"");
|
125 | for (_j = 0, _len2 = classes.length; _j < _len2; _j++) {
|
126 | c = classes[_j];
|
127 | if (c !== classes[0]) text(' ');
|
128 | text(c);
|
129 | }
|
130 | return text('"');
|
131 | }
|
132 | },
|
133 | render_attrs: function(obj, prefix) {
|
134 | var k, v, _results;
|
135 | if (prefix == null) prefix = '';
|
136 | _results = [];
|
137 | for (k in obj) {
|
138 | v = obj[k];
|
139 | if (typeof v === 'boolean' && v) v = k;
|
140 | if (typeof v === 'function') v = "(" + v + ").call(this);";
|
141 | if (typeof v === 'object' && !(v instanceof Array)) {
|
142 | _results.push(this.render_attrs(v, prefix + k + '-'));
|
143 | } else if (v) {
|
144 | _results.push(text(" " + (prefix + k) + "=\"" + (this.esc(v)) + "\""));
|
145 | } else {
|
146 | _results.push(void 0);
|
147 | }
|
148 | }
|
149 | return _results;
|
150 | },
|
151 | render_contents: function(contents, safe) {
|
152 | var result;
|
153 | if (safe == null) safe = false;
|
154 | switch (typeof contents) {
|
155 | case 'string':
|
156 | case 'number':
|
157 | case 'boolean':
|
158 | return text(safe ? contents : this.esc(contents));
|
159 | case 'function':
|
160 | if (data.format) text('\n');
|
161 | this.tabs++;
|
162 | result = contents.call(data);
|
163 | if (typeof result === 'string') {
|
164 | this.indent();
|
165 | text(safe ? result : this.esc(result));
|
166 | if (data.format) text('\n');
|
167 | }
|
168 | this.tabs--;
|
169 | return this.indent();
|
170 | }
|
171 | },
|
172 | render_tag: function(name, idclass, attrs, contents) {
|
173 | this.indent();
|
174 | text("<" + name);
|
175 | if (idclass) this.render_idclass(idclass);
|
176 | if (attrs) this.render_attrs(attrs);
|
177 | if (__indexOf.call(this.self_closing, name) >= 0) {
|
178 | text(' />');
|
179 | if (data.format) text('\n');
|
180 | } else {
|
181 | text('>');
|
182 | this.render_contents(contents);
|
183 | text("</" + name + ">");
|
184 | if (data.format) text('\n');
|
185 | }
|
186 | return null;
|
187 | }
|
188 | };
|
189 | tag = function() {
|
190 | var a, args, attrs, contents, idclass, name, _i, _len;
|
191 | name = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
192 | for (_i = 0, _len = args.length; _i < _len; _i++) {
|
193 | a = args[_i];
|
194 | switch (typeof a) {
|
195 | case 'function':
|
196 | contents = a;
|
197 | break;
|
198 | case 'object':
|
199 | attrs = a;
|
200 | break;
|
201 | case 'number':
|
202 | case 'boolean':
|
203 | contents = a;
|
204 | break;
|
205 | case 'string':
|
206 | if (args.length === 1) {
|
207 | contents = a;
|
208 | } else {
|
209 | if (a === args[0]) {
|
210 | idclass = a;
|
211 | } else {
|
212 | contents = a;
|
213 | }
|
214 | }
|
215 | }
|
216 | }
|
217 | return __cc.render_tag(name, idclass, attrs, contents);
|
218 | };
|
219 | yield = function(f) {
|
220 | var old_buffer, temp_buffer;
|
221 | temp_buffer = [];
|
222 | old_buffer = __cc.buffer;
|
223 | __cc.buffer = temp_buffer;
|
224 | f();
|
225 | __cc.buffer = old_buffer;
|
226 | return temp_buffer.join('');
|
227 | };
|
228 | h = function(txt) {
|
229 | return txt.toString().replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
230 | };
|
231 | doctype = function(type) {
|
232 | if (type == null) type = 'default';
|
233 | text(__cc.doctypes[type]);
|
234 | if (data.format) return text('\n');
|
235 | };
|
236 | text = function(txt) {
|
237 | __cc.buffer.push(txt.toString());
|
238 | return null;
|
239 | };
|
240 | comment = function(cmt) {
|
241 | text("<!--" + cmt + "-->");
|
242 | if (data.format) return text('\n');
|
243 | };
|
244 | coffeescript = function(param) {
|
245 | switch (typeof param) {
|
246 | case 'function':
|
247 | return script("" + __cc.coffeescript_helpers + "(" + param + ").call(this);");
|
248 | case 'string':
|
249 | return script({
|
250 | type: 'text/coffeescript'
|
251 | }, function() {
|
252 | return param;
|
253 | });
|
254 | case 'object':
|
255 | param.type = 'text/coffeescript';
|
256 | return script(param);
|
257 | }
|
258 | };
|
259 | stylus = function(s) {
|
260 | text('<style>');
|
261 | if (data.format) text('\n');
|
262 | data.stylus.render(s, {
|
263 | compress: !data.format
|
264 | }, function(err, css) {
|
265 | if (err) throw err;
|
266 | return text(css);
|
267 | });
|
268 | text('</style>');
|
269 | if (data.format) return text('\n');
|
270 | };
|
271 | ie = function(condition, contents) {
|
272 | __cc.indent();
|
273 | text("<!--[if " + condition + "]>");
|
274 | __cc.render_contents(contents);
|
275 | text("<![endif]-->");
|
276 | if (data.format) return text('\n');
|
277 | };
|
278 | return null;
|
279 | };
|
280 |
|
281 | skeleton = skeleton.toString().replace(/function\s*\(.*\)\s*\{/, '').replace(/return null;\s*\}$/, '');
|
282 |
|
283 | skeleton = coffeescript_helpers + skeleton;
|
284 |
|
285 | coffeecup.compile = function(template, options) {
|
286 | var code, hardcoded_locals, k, t, tag_functions, tags_used, v, _i, _j, _len, _len2, _ref, _ref2;
|
287 | if (options == null) options = {};
|
288 | if (typeof template === 'function') {
|
289 | template = template.toString();
|
290 | } else if (typeof template === 'string' && (coffee != null)) {
|
291 | template = coffee.compile(template, {
|
292 | bare: true
|
293 | });
|
294 | template = "function(){" + template + "}";
|
295 | }
|
296 | hardcoded_locals = '';
|
297 | if (options.hardcode) {
|
298 | _ref = options.hardcode;
|
299 | for (k in _ref) {
|
300 | v = _ref[k];
|
301 | if (typeof v === 'function') {
|
302 | hardcoded_locals += "var " + k + " = function(){return (" + v + ").apply(data, arguments);};";
|
303 | } else {
|
304 | hardcoded_locals += "var " + k + " = " + (JSON.stringify(v)) + ";";
|
305 | }
|
306 | }
|
307 | }
|
308 | if (options.optimize && (compiler != null)) {
|
309 | return compiler.compile(template, hardcoded_locals, options);
|
310 | }
|
311 | tag_functions = '';
|
312 | tags_used = [];
|
313 | _ref2 = coffeecup.tags;
|
314 | for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
315 | t = _ref2[_i];
|
316 | if (template.indexOf(t) > -1 || hardcoded_locals.indexOf(t) > -1) {
|
317 | tags_used.push(t);
|
318 | }
|
319 | }
|
320 | tag_functions += "var " + (tags_used.join(',')) + ";";
|
321 | for (_j = 0, _len2 = tags_used.length; _j < _len2; _j++) {
|
322 | t = tags_used[_j];
|
323 | tag_functions += "" + t + " = function(){return __cc.tag('" + t + "', arguments);};";
|
324 | }
|
325 | code = tag_functions + hardcoded_locals + skeleton;
|
326 | code += "__cc.doctypes = " + (JSON.stringify(coffeecup.doctypes)) + ";";
|
327 | code += "__cc.coffeescript_helpers = " + (JSON.stringify(coffeescript_helpers)) + ";";
|
328 | code += "__cc.self_closing = " + (JSON.stringify(coffeecup.self_closing)) + ";";
|
329 | if (options.locals) code += 'with(data.locals){';
|
330 | code += "(" + template + ").call(data);";
|
331 | if (options.locals) code += '}';
|
332 | code += "return __cc.buffer.join('');";
|
333 | return new Function('data', code);
|
334 | };
|
335 |
|
336 | cache = {};
|
337 |
|
338 | coffeecup.render = function(template, data, options) {
|
339 | var k, tpl, v;
|
340 | if (data == null) data = {};
|
341 | if (options == null) options = {};
|
342 | for (k in options) {
|
343 | v = options[k];
|
344 | data[k] = v;
|
345 | }
|
346 | if (data.cache == null) data.cache = false;
|
347 | data.stylus = require('stylus');
|
348 | if (data.optimize && !data.cache) data.optimize = false;
|
349 | if (data.cache && (cache[template] != null)) {
|
350 | tpl = cache[template];
|
351 | } else if (data.cache) {
|
352 | tpl = cache[template] = coffeecup.compile(template, data);
|
353 | } else {
|
354 | tpl = coffeecup.compile(template, data);
|
355 | }
|
356 | return tpl(data);
|
357 | };
|
358 |
|
359 | if (typeof window === "undefined" || window === null) {
|
360 | coffeecup.adapters = {
|
361 | simple: coffeecup.render,
|
362 | meryl: coffeecup.render,
|
363 | express: {
|
364 | TemplateError: (function(_super) {
|
365 |
|
366 | __extends(_Class, _super);
|
367 |
|
368 | function _Class(message) {
|
369 | this.message = message;
|
370 | Error.call(this, this.message);
|
371 | Error.captureStackTrace(this, arguments.callee);
|
372 | }
|
373 |
|
374 | _Class.prototype.name = 'TemplateError';
|
375 |
|
376 | return _Class;
|
377 |
|
378 | })(Error),
|
379 | compile: function(template, data) {
|
380 | var TemplateError, tpl;
|
381 | if (data.hardcode == null) data.hardcode = {};
|
382 | data.hardcode.partial = function() {
|
383 | return text(this.partial.apply(this, arguments));
|
384 | };
|
385 | TemplateError = this.TemplateError;
|
386 | try {
|
387 | tpl = coffeecup.compile(template, data);
|
388 | } catch (e) {
|
389 | throw new TemplateError("Error compiling " + data.filename + ": " + e.message);
|
390 | }
|
391 | return function() {
|
392 | try {
|
393 | return tpl.apply(null, arguments);
|
394 | } catch (e) {
|
395 | throw new TemplateError("Error rendering " + data.filename + ": " + e.message);
|
396 | }
|
397 | };
|
398 | }
|
399 | }
|
400 | };
|
401 | }
|