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