1 | <!DOCTYPE html> <html> <head> <title>coffeecup.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> coffeecup.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">¶</a> </div> <p><strong>CoffeeCup</strong> lets you to write HTML templates in 100% pure
|
2 | <a href="http://coffeescript.org">CoffeeScript</a>.</p>
|
3 |
|
4 | <p>You can run it on <a href="http://nodejs.org">node.js</a> or the browser, or compile your
|
5 | templates down to self-contained javascript functions, that will take in data
|
6 | and options and return generated HTML on any JS runtime.</p>
|
7 |
|
8 | <p>The concept is directly stolen from the amazing
|
9 | <a href="http://markaby.rubyforge.org/">Markaby</a> by Tim Fletcher and why the lucky
|
10 | stiff.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">if</span> <span class="nb">window</span><span class="o">?</span>
|
11 | <span class="nv">coffeekup = </span><span class="nb">window</span><span class="p">.</span><span class="nv">coffeekup = </span><span class="p">{}</span>
|
12 | <span class="nv">coffee = </span><span class="k">if</span> <span class="nx">CoffeeScript</span><span class="o">?</span> <span class="k">then</span> <span class="nx">CoffeeScript</span> <span class="k">else</span> <span class="kc">null</span>
|
13 | <span class="k">else</span>
|
14 | <span class="nv">coffeekup = </span><span class="nx">exports</span>
|
15 | <span class="nv">coffee = </span><span class="nx">require</span> <span class="s1">'coffee-script'</span>
|
16 |
|
17 | <span class="nv">coffeekup.version = </span><span class="s1">'0.3.1edge'</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">¶</a> </div> <p>Values available to the <code>doctype</code> function inside a template.
|
18 | Ex.: <code>doctype 'strict'</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">coffeekup.doctypes =</span>
|
19 | <span class="s1">'default'</span><span class="o">:</span> <span class="s1">'<!DOCTYPE html>'</span>
|
20 | <span class="s1">'5'</span><span class="o">:</span> <span class="s1">'<!DOCTYPE html>'</span>
|
21 | <span class="s1">'xml'</span><span class="o">:</span> <span class="s1">'<?xml version="1.0" encoding="utf-8" ?>'</span>
|
22 | <span class="s1">'transitional'</span><span class="o">:</span> <span class="s1">'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'</span>
|
23 | <span class="s1">'strict'</span><span class="o">:</span> <span class="s1">'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'</span>
|
24 | <span class="s1">'frameset'</span><span class="o">:</span> <span class="s1">'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">'</span>
|
25 | <span class="s1">'1.1'</span><span class="o">:</span> <span class="s1">'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'</span><span class="p">,</span>
|
26 | <span class="s1">'basic'</span><span class="o">:</span> <span class="s1">'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">'</span>
|
27 | <span class="s1">'mobile'</span><span class="o">:</span> <span class="s1">'<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">'</span>
|
28 | <span class="s1">'ce'</span><span class="o">:</span> <span class="s1">'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "ce-html-1.0-transitional.dtd">'</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">¶</a> </div> <p>CoffeeScript-generated JavaScript may contain anyone of these; but when we
|
29 | take a function to string form to manipulate it, and then recreate it through
|
30 | the <code>Function()</code> constructor, it loses access to its parent scope and
|
31 | consequently to any helpers it might need. So we need to reintroduce these
|
32 | inside any "rewritten" function.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">coffeescript_helpers = </span><span class="s2">"""</span>
|
33 | <span class="s2"> var __slice = Array.prototype.slice;</span>
|
34 | <span class="s2"> var __hasProp = Object.prototype.hasOwnProperty;</span>
|
35 | <span class="s2"> var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };</span>
|
36 | <span class="s2"> var __extends = function(child, parent) {</span>
|
37 | <span class="s2"> for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }</span>
|
38 | <span class="s2"> function ctor() { this.constructor = child; }</span>
|
39 | <span class="s2"> ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype;</span>
|
40 | <span class="s2"> return child; };</span>
|
41 | <span class="s2"> var __indexOf = Array.prototype.indexOf || function(item) {</span>
|
42 | <span class="s2"> for (var i = 0, l = this.length; i < l; i++) {</span>
|
43 | <span class="s2"> if (this[i] === item) return i;</span>
|
44 | <span class="s2"> } return -1; };</span>
|
45 | <span class="s2">"""</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/\n/g</span><span class="p">,</span> <span class="s1">''</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">¶</a> </div> <p>Private HTML element reference.
|
46 | Please mind the gap (1 space at the beginning of each subsequent line).</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">elements =</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">¶</a> </div> <p>Valid HTML 5 elements requiring a closing tag.
|
47 | Note: the <code>var</code> element is out for obvious reasons, please use <code>tag 'var'</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">regular: </span><span class="s1">'a abbr address article aside audio b bdi bdo blockquote body button</span>
|
48 | <span class="s1"> canvas caption cite code colgroup datalist dd del details dfn div dl dt em</span>
|
49 | <span class="s1"> fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header hgroup</span>
|
50 | <span class="s1"> html i iframe ins kbd label legend li map mark menu meter nav noscript object</span>
|
51 | <span class="s1"> ol optgroup option output p pre progress q rp rt ruby s samp script section</span>
|
52 | <span class="s1"> select small span strong style sub summary sup table tbody td textarea tfoot</span>
|
53 | <span class="s1"> th thead time title tr u ul video'</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">¶</a> </div> <p>Valid self-closing HTML 5 elements.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">void: </span><span class="s1">'area base br col command embed hr img input keygen link meta param</span>
|
54 | <span class="s1"> source track wbr'</span>
|
55 |
|
56 | <span class="nv">obsolete: </span><span class="s1">'applet acronym bgsound dir frameset noframes isindex listing</span>
|
57 | <span class="s1"> nextid noembed plaintext rb strike xmp big blink center font marquee multicol</span>
|
58 | <span class="s1"> nobr spacer tt'</span>
|
59 |
|
60 | <span class="nv">obsolete_void: </span><span class="s1">'basefont frame'</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">¶</a> </div> <p>Create a unique list of element names merging the desired groups.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">merge_elements = </span><span class="nf">(args...) -></span>
|
61 | <span class="nv">result = </span><span class="p">[]</span>
|
62 | <span class="k">for</span> <span class="nx">a</span> <span class="k">in</span> <span class="nx">args</span>
|
63 | <span class="k">for</span> <span class="nx">element</span> <span class="k">in</span> <span class="nx">elements</span><span class="p">[</span><span class="nx">a</span><span class="p">].</span><span class="nx">split</span> <span class="s1">' '</span>
|
64 | <span class="nx">result</span><span class="p">.</span><span class="nx">push</span> <span class="nx">element</span> <span class="nx">unless</span> <span class="nx">element</span> <span class="k">in</span> <span class="nx">result</span>
|
65 | <span class="nx">result</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">¶</a> </div> <p>Public/customizable list of possible elements.
|
66 | For each name in this list that is also present in the input template code,
|
67 | a function with the same name will be added to the compiled template.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">coffeekup.tags = </span><span class="nx">merge_elements</span> <span class="s1">'regular'</span><span class="p">,</span> <span class="s1">'obsolete'</span><span class="p">,</span> <span class="s1">'void'</span><span class="p">,</span> <span class="s1">'obsolete_void'</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">¶</a> </div> <p>Public/customizable list of elements that should be rendered self-closed.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">coffeekup.self_closing = </span><span class="nx">merge_elements</span> <span class="s1">'void'</span><span class="p">,</span> <span class="s1">'obsolete_void'</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">¶</a> </div> <p>This is the basic material from which compiled templates will be formed.
|
68 | It will be manipulated in its string form at the <code>coffeekup.compile</code> function
|
69 | to generate the final template function. </p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">skeleton = </span><span class="nf">(data = {}) -></span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">¶</a> </div> <p>Whether to generate formatted HTML with indentation and line breaks, or
|
70 | just the natural "faux-minified" output.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">data</span><span class="p">.</span><span class="nx">format</span> <span class="o">?=</span> <span class="kc">off</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">¶</a> </div> <p>Whether to autoescape all content or let you handle it on a case by case
|
71 | basis with the <code>h</code> function.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">data</span><span class="p">.</span><span class="nx">autoescape</span> <span class="o">?=</span> <span class="kc">off</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">¶</a> </div> <p>Internal coffeekup stuff.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">__ck =</span>
|
72 | <span class="nv">buffer: </span><span class="p">[]</span>
|
73 |
|
74 | <span class="nv">esc: </span><span class="nf">(txt) -></span>
|
75 | <span class="k">if</span> <span class="nx">data</span><span class="p">.</span><span class="nx">autoescape</span> <span class="k">then</span> <span class="nx">h</span><span class="p">(</span><span class="nx">txt</span><span class="p">)</span> <span class="k">else</span> <span class="nb">String</span><span class="p">(</span><span class="nx">txt</span><span class="p">)</span>
|
76 |
|
77 | <span class="nv">tabs: </span><span class="mi">0</span>
|
78 |
|
79 | <span class="nv">repeat: </span><span class="nf">(string, count) -></span> <span class="nb">Array</span><span class="p">(</span><span class="nx">count</span> <span class="o">+</span> <span class="mi">1</span><span class="p">).</span><span class="nx">join</span> <span class="nx">string</span>
|
80 |
|
81 | <span class="nv">indent: </span><span class="o">-></span> <span class="nx">text</span> <span class="nx">@repeat</span><span class="p">(</span><span class="s1">' '</span><span class="p">,</span> <span class="nx">@tabs</span><span class="p">)</span> <span class="k">if</span> <span class="nx">data</span><span class="p">.</span><span class="nx">format</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">¶</a> </div> <p>Adapter to keep the builtin tag functions DRY.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">tag: </span><span class="nf">(name, args) -></span>
|
82 | <span class="nv">combo = </span><span class="p">[</span><span class="nx">name</span><span class="p">]</span>
|
83 | <span class="nx">combo</span><span class="p">.</span><span class="nx">push</span> <span class="nx">i</span> <span class="k">for</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">args</span>
|
84 | <span class="nx">tag</span><span class="p">.</span><span class="nx">apply</span> <span class="nx">data</span><span class="p">,</span> <span class="nx">combo</span>
|
85 |
|
86 | <span class="nv">render_idclass: </span><span class="nf">(str) -></span>
|
87 | <span class="nv">classes = </span><span class="p">[]</span>
|
88 |
|
89 | <span class="k">for</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">str</span><span class="p">.</span><span class="nx">split</span> <span class="s1">'.'</span>
|
90 | <span class="k">if</span> <span class="s1">'#'</span> <span class="k">in</span> <span class="nx">i</span>
|
91 | <span class="nv">id = </span><span class="nx">i</span><span class="p">.</span><span class="nx">replace</span> <span class="s1">'#'</span><span class="p">,</span> <span class="s1">''</span>
|
92 | <span class="k">else</span>
|
93 | <span class="nx">classes</span><span class="p">.</span><span class="nx">push</span> <span class="nx">i</span> <span class="nx">unless</span> <span class="nx">i</span> <span class="o">is</span> <span class="s1">''</span>
|
94 |
|
95 | <span class="nx">text</span> <span class="s2">" id=\"#{id}\""</span> <span class="k">if</span> <span class="nx">id</span>
|
96 |
|
97 | <span class="k">if</span> <span class="nx">classes</span><span class="p">.</span><span class="nx">length</span> <span class="o">></span> <span class="mi">0</span>
|
98 | <span class="nx">text</span> <span class="s2">" class=\""</span>
|
99 | <span class="k">for</span> <span class="nx">c</span> <span class="k">in</span> <span class="nx">classes</span>
|
100 | <span class="nx">text</span> <span class="s1">' '</span> <span class="nx">unless</span> <span class="nx">c</span> <span class="o">is</span> <span class="nx">classes</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
101 | <span class="nx">text</span> <span class="nx">c</span>
|
102 | <span class="nx">text</span> <span class="s1">'"'</span>
|
103 |
|
104 | <span class="nv">render_attrs: </span><span class="nf">(obj, prefix = '') -></span>
|
105 | <span class="k">for</span> <span class="nx">k</span><span class="p">,</span> <span class="nx">v</span> <span class="k">of</span> <span class="nx">obj</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">¶</a> </div> <p><code>true</code> is rendered as <code>selected="selected"</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">v = </span><span class="nx">k</span> <span class="k">if</span> <span class="k">typeof</span> <span class="nx">v</span> <span class="o">is</span> <span class="s1">'boolean'</span> <span class="o">and</span> <span class="nx">v</span>
|
106 | </pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">¶</a> </div> <p>Functions are rendered in an executable form.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">v = </span><span class="s2">"(#{v}).call(this);"</span> <span class="k">if</span> <span class="k">typeof</span> <span class="nx">v</span> <span class="o">is</span> <span class="s1">'function'</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">¶</a> </div> <p>Prefixed attribute.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="k">typeof</span> <span class="nx">v</span> <span class="o">is</span> <span class="s1">'object'</span> <span class="o">and</span> <span class="nx">v</span> <span class="o">not</span> <span class="k">instanceof</span> <span class="nb">Array</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">¶</a> </div> <p><code>data: {icon: 'foo'}</code> is rendered as <code>data-icon="foo"</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">@render_attrs</span><span class="p">(</span><span class="nx">v</span><span class="p">,</span> <span class="nx">prefix</span> <span class="o">+</span> <span class="nx">k</span> <span class="o">+</span> <span class="s1">'-'</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">¶</a> </div> <p><code>undefined</code>, <code>false</code> and <code>null</code> result in the attribute not being rendered.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">else</span> <span class="k">if</span> <span class="nx">v</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">¶</a> </div> <p>strings, numbers, arrays and functions are rendered "as is".</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">text</span> <span class="s2">" #{prefix + k}=\"#{@esc(v)}\""</span>
|
107 |
|
108 | <span class="nv">render_contents: </span><span class="nf">(contents) -></span>
|
109 | <span class="k">switch</span> <span class="k">typeof</span> <span class="nx">contents</span>
|
110 | <span class="k">when</span> <span class="s1">'string'</span><span class="p">,</span> <span class="s1">'number'</span><span class="p">,</span> <span class="s1">'boolean'</span>
|
111 | <span class="nx">text</span> <span class="nx">@esc</span><span class="p">(</span><span class="nx">contents</span><span class="p">)</span>
|
112 | <span class="k">when</span> <span class="s1">'function'</span>
|
113 | <span class="nx">text</span> <span class="s1">'\n'</span> <span class="k">if</span> <span class="nx">data</span><span class="p">.</span><span class="nx">format</span>
|
114 | <span class="nx">@tabs</span><span class="o">++</span>
|
115 | <span class="nv">result = </span><span class="nx">contents</span><span class="p">.</span><span class="nx">call</span> <span class="nx">data</span>
|
116 | <span class="k">if</span> <span class="k">typeof</span> <span class="nx">result</span> <span class="o">is</span> <span class="s1">'string'</span>
|
117 | <span class="nx">@indent</span><span class="p">()</span>
|
118 | <span class="nx">text</span> <span class="nx">@esc</span><span class="p">(</span><span class="nx">result</span><span class="p">)</span>
|
119 | <span class="nx">text</span> <span class="s1">'\n'</span> <span class="k">if</span> <span class="nx">data</span><span class="p">.</span><span class="nx">format</span>
|
120 | <span class="nx">@tabs</span><span class="o">--</span>
|
121 | <span class="nx">@indent</span><span class="p">()</span>
|
122 |
|
123 | <span class="nv">render_tag: </span><span class="nf">(name, idclass, attrs, contents) -></span>
|
124 | <span class="nx">@indent</span><span class="p">()</span>
|
125 |
|
126 | <span class="nx">text</span> <span class="s2">"<#{name}"</span>
|
127 | <span class="nx">@render_idclass</span><span class="p">(</span><span class="nx">idclass</span><span class="p">)</span> <span class="k">if</span> <span class="nx">idclass</span>
|
128 | <span class="nx">@render_attrs</span><span class="p">(</span><span class="nx">attrs</span><span class="p">)</span> <span class="k">if</span> <span class="nx">attrs</span>
|
129 |
|
130 | <span class="k">if</span> <span class="nx">name</span> <span class="k">in</span> <span class="nx">@self_closing</span>
|
131 | <span class="nx">text</span> <span class="s1">' />'</span>
|
132 | <span class="nx">text</span> <span class="s1">'\n'</span> <span class="k">if</span> <span class="nx">data</span><span class="p">.</span><span class="nx">format</span>
|
133 | <span class="k">else</span>
|
134 | <span class="nx">text</span> <span class="s1">'>'</span>
|
135 |
|
136 | <span class="nx">@render_contents</span><span class="p">(</span><span class="nx">contents</span><span class="p">)</span>
|
137 |
|
138 | <span class="nx">text</span> <span class="s2">"</#{name}>"</span>
|
139 | <span class="nx">text</span> <span class="s1">'\n'</span> <span class="k">if</span> <span class="nx">data</span><span class="p">.</span><span class="nx">format</span>
|
140 |
|
141 | <span class="kc">null</span>
|
142 |
|
143 | <span class="nv">tag = </span><span class="nf">(name, args...) -></span>
|
144 | <span class="k">for</span> <span class="nx">a</span> <span class="k">in</span> <span class="nx">args</span>
|
145 | <span class="k">switch</span> <span class="k">typeof</span> <span class="nx">a</span>
|
146 | <span class="k">when</span> <span class="s1">'function'</span>
|
147 | <span class="nv">contents = </span><span class="nx">a</span>
|
148 | <span class="k">when</span> <span class="s1">'object'</span>
|
149 | <span class="nv">attrs = </span><span class="nx">a</span>
|
150 | <span class="k">when</span> <span class="s1">'number'</span><span class="p">,</span> <span class="s1">'boolean'</span>
|
151 | <span class="nv">contents = </span><span class="nx">a</span>
|
152 | <span class="k">when</span> <span class="s1">'string'</span>
|
153 | <span class="k">if</span> <span class="nx">args</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">1</span>
|
154 | <span class="nv">contents = </span><span class="nx">a</span>
|
155 | <span class="k">else</span>
|
156 | <span class="k">if</span> <span class="nx">a</span> <span class="o">is</span> <span class="nx">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
157 | <span class="nv">idclass = </span><span class="nx">a</span>
|
158 | <span class="k">else</span>
|
159 | <span class="nv">contents = </span><span class="nx">a</span>
|
160 |
|
161 | <span class="nx">__ck</span><span class="p">.</span><span class="nx">render_tag</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">idclass</span><span class="p">,</span> <span class="nx">attrs</span><span class="p">,</span> <span class="nx">contents</span><span class="p">)</span>
|
162 |
|
163 | <span class="nv">yield = </span><span class="nf">(f) -></span>
|
164 | <span class="nv">temp_buffer = </span><span class="p">[]</span>
|
165 | <span class="nv">old_buffer = </span><span class="nx">__ck</span><span class="p">.</span><span class="nx">buffer</span>
|
166 | <span class="nv">__ck.buffer = </span><span class="nx">temp_buffer</span>
|
167 | <span class="nx">f</span><span class="p">()</span>
|
168 | <span class="nv">__ck.buffer = </span><span class="nx">old_buffer</span>
|
169 | <span class="nx">temp_buffer</span><span class="p">.</span><span class="nx">join</span> <span class="s1">''</span>
|
170 |
|
171 | <span class="nv">h = </span><span class="nf">(txt) -></span>
|
172 | <span class="nb">String</span><span class="p">(</span><span class="nx">txt</span><span class="p">).</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/&/g</span><span class="p">,</span> <span class="s1">'&amp;'</span><span class="p">)</span>
|
173 | <span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/</g</span><span class="p">,</span> <span class="s1">'&lt;'</span><span class="p">)</span>
|
174 | <span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/>/g</span><span class="p">,</span> <span class="s1">'&gt;'</span><span class="p">)</span>
|
175 | <span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/"/g</span><span class="p">,</span> <span class="s1">'&quot;'</span><span class="p">)</span>
|
176 |
|
177 | <span class="nv">doctype = </span><span class="nf">(type = 'default') -></span>
|
178 | <span class="nx">text</span> <span class="nx">__ck</span><span class="p">.</span><span class="nx">doctypes</span><span class="p">[</span><span class="nx">type</span><span class="p">]</span>
|
179 | <span class="nx">text</span> <span class="s1">'\n'</span> <span class="k">if</span> <span class="nx">data</span><span class="p">.</span><span class="nx">format</span>
|
180 |
|
181 | <span class="nv">text = </span><span class="nf">(txt) -></span>
|
182 | <span class="nx">__ck</span><span class="p">.</span><span class="nx">buffer</span><span class="p">.</span><span class="nx">push</span> <span class="nb">String</span><span class="p">(</span><span class="nx">txt</span><span class="p">)</span>
|
183 | <span class="kc">null</span>
|
184 |
|
185 | <span class="nv">comment = </span><span class="nf">(cmt) -></span>
|
186 | <span class="nx">text</span> <span class="s2">"<!--#{cmt}-->"</span>
|
187 | <span class="nx">text</span> <span class="s1">'\n'</span> <span class="k">if</span> <span class="nx">data</span><span class="p">.</span><span class="nx">format</span>
|
188 |
|
189 | <span class="nv">coffeescript = </span><span class="nf">(param) -></span>
|
190 | <span class="k">switch</span> <span class="k">typeof</span> <span class="nx">param</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">¶</a> </div> <p><code>coffeescript -> alert 'hi'</code> becomes:
|
191 | <code><script>;(function () {return alert('hi');})();</script></code></p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">when</span> <span class="s1">'function'</span>
|
192 | <span class="nx">script</span> <span class="s2">"#{__ck.coffeescript_helpers}(#{param}).call(this);"</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">¶</a> </div> <p><code>coffeescript "alert 'hi'"</code> becomes:
|
193 | <code><script type="text/coffeescript">alert 'hi'</script></code></p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">when</span> <span class="s1">'string'</span>
|
194 | <span class="nx">script</span> <span class="nv">type: </span><span class="s1">'text/coffeescript'</span><span class="p">,</span> <span class="o">-></span> <span class="nx">param</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">¶</a> </div> <p><code>coffeescript src: 'script.coffee'</code> becomes:
|
195 | <code><script type="text/coffeescript" src="script.coffee"></script></code></p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">when</span> <span class="s1">'object'</span>
|
196 | <span class="nv">param.type = </span><span class="s1">'text/coffeescript'</span>
|
197 | <span class="nx">script</span> <span class="nx">param</span>
|
198 | </pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">¶</a> </div> <p>Conditional IE comments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ie = </span><span class="nf">(condition, contents) -></span>
|
199 | <span class="nx">__ck</span><span class="p">.</span><span class="nx">indent</span><span class="p">()</span>
|
200 |
|
201 | <span class="nx">text</span> <span class="s2">"<!--[if #{condition}]>"</span>
|
202 | <span class="nx">__ck</span><span class="p">.</span><span class="nx">render_contents</span><span class="p">(</span><span class="nx">contents</span><span class="p">)</span>
|
203 | <span class="nx">text</span> <span class="s2">"<![endif]-->"</span>
|
204 | <span class="nx">text</span> <span class="s1">'\n'</span> <span class="k">if</span> <span class="nx">data</span><span class="p">.</span><span class="nx">format</span>
|
205 |
|
206 | <span class="kc">null</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">¶</a> </div> <p>Stringify the skeleton and unwrap it from its enclosing <code>function(){}</code>, then
|
207 | add the CoffeeScript helpers.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">skeleton = </span><span class="nb">String</span><span class="p">(</span><span class="nx">skeleton</span><span class="p">)</span>
|
208 | <span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/function\s*\(.*\)\s*\{/</span><span class="p">,</span> <span class="s1">''</span><span class="p">)</span>
|
209 | <span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/return null;\s*\}$/</span><span class="p">,</span> <span class="s1">''</span><span class="p">)</span>
|
210 |
|
211 | <span class="nv">skeleton = </span><span class="nx">coffeescript_helpers</span> <span class="o">+</span> <span class="nx">skeleton</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-26">¶</a> </div> <p>Compiles a template into a standalone JavaScript function.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">coffeekup.compile = </span><span class="nf">(template, options = {}) -></span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-27">¶</a> </div> <p>The template can be provided as either a function or a CoffeeScript string
|
212 | (in the latter case, the CoffeeScript compiler must be available).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="k">typeof</span> <span class="nx">template</span> <span class="o">is</span> <span class="s1">'function'</span> <span class="k">then</span> <span class="nv">template = </span><span class="nb">String</span><span class="p">(</span><span class="nx">template</span><span class="p">)</span>
|
213 | <span class="k">else</span> <span class="k">if</span> <span class="k">typeof</span> <span class="nx">template</span> <span class="o">is</span> <span class="s1">'string'</span> <span class="o">and</span> <span class="nx">coffee</span><span class="o">?</span>
|
214 | <span class="nv">template = </span><span class="nx">coffee</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">template</span><span class="p">,</span> <span class="nv">bare: </span><span class="kc">yes</span>
|
215 | <span class="nv">template = </span><span class="s2">"function(){#{template}}"</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-28">¶</a> </div> <p>If an object <code>hardcode</code> is provided, insert the stringified value
|
216 | of each variable directly in the function body. This is a less flexible but
|
217 | faster alternative to the standard method of using <code>with</code> (see below). </p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">hardcoded_locals = </span><span class="s1">''</span>
|
218 |
|
219 | <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">hardcode</span>
|
220 | <span class="k">for</span> <span class="nx">k</span><span class="p">,</span> <span class="nx">v</span> <span class="k">of</span> <span class="nx">options</span><span class="p">.</span><span class="nx">hardcode</span>
|
221 | <span class="k">if</span> <span class="k">typeof</span> <span class="nx">v</span> <span class="o">is</span> <span class="s1">'function'</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-29">¶</a> </div> <p>Make sure these functions have access to <code>data</code> as <code>@/this</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">hardcoded_locals</span> <span class="o">+=</span> <span class="s2">"var #{k} = function(){return (#{v}).apply(data, arguments);};"</span>
|
222 | <span class="k">else</span> <span class="nx">hardcoded_locals</span> <span class="o">+=</span> <span class="s2">"var #{k} = #{JSON.stringify v};"</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-30">¶</a> </div> <p>Add a function for each tag this template references. We don't want to have
|
223 | all hundred-odd tags wasting space in the compiled function.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">tag_functions = </span><span class="s1">''</span>
|
224 | <span class="nv">tags_used = </span><span class="p">[]</span>
|
225 |
|
226 | <span class="k">for</span> <span class="nx">t</span> <span class="k">in</span> <span class="nx">coffeekup</span><span class="p">.</span><span class="nx">tags</span>
|
227 | <span class="k">if</span> <span class="nx">template</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">t</span><span class="p">)</span> <span class="o">></span> <span class="o">-</span><span class="mi">1</span> <span class="o">or</span> <span class="nx">hardcoded_locals</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">t</span><span class="p">)</span> <span class="o">></span> <span class="o">-</span><span class="mi">1</span>
|
228 | <span class="nx">tags_used</span><span class="p">.</span><span class="nx">push</span> <span class="nx">t</span>
|
229 |
|
230 | <span class="nx">tag_functions</span> <span class="o">+=</span> <span class="s2">"var #{tags_used.join ','};"</span>
|
231 | <span class="k">for</span> <span class="nx">t</span> <span class="k">in</span> <span class="nx">tags_used</span>
|
232 | <span class="nx">tag_functions</span> <span class="o">+=</span> <span class="s2">"#{t} = function(){return __ck.tag('#{t}', arguments);};"</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-31">¶</a> </div> <h1>Main function assembly.</h1> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">code = </span><span class="s2">""</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-32">¶</a> </div> <p>If bare is used, the main mechanism is stripped from template</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">unless</span> <span class="nx">options</span><span class="p">.</span><span class="nx">bare</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">options</span><span class="p">.</span><span class="nx">core</span>
|
233 | <span class="nx">code</span> <span class="o">+=</span> <span class="nx">tag_functions</span> <span class="o">+</span> <span class="nx">hardcoded_locals</span> <span class="o">+</span> <span class="nx">skeleton</span>
|
234 | <span class="nx">code</span> <span class="o">+=</span> <span class="s2">"__ck.doctypes = #{JSON.stringify coffeekup.doctypes};"</span>
|
235 | <span class="nx">code</span> <span class="o">+=</span> <span class="s2">"__ck.coffeescript_helpers = #{JSON.stringify coffeescript_helpers};"</span>
|
236 | <span class="nx">code</span> <span class="o">+=</span> <span class="s2">"__ck.self_closing = #{JSON.stringify coffeekup.self_closing};"</span>
|
237 |
|
238 | <span class="nx">unless</span> <span class="nx">options</span><span class="p">.</span><span class="nx">core</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">options</span><span class="p">.</span><span class="nx">bare</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-33">¶</a> </div> <p>If <code>locals</code> is set, wrap the template inside a <code>with</code> block. This is the
|
239 | most flexible but slower approach to specifying local variables.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">code</span> <span class="o">+=</span> <span class="s1">'with(data.locals){'</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">locals</span>
|
240 | <span class="nx">code</span> <span class="o">+=</span> <span class="s2">"(#{template}).call(data);"</span>
|
241 | <span class="nx">code</span> <span class="o">+=</span> <span class="s1">'}'</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">locals</span>
|
242 | <span class="nx">code</span> <span class="o">+=</span> <span class="s2">"return __ck.buffer.join('');"</span>
|
243 |
|
244 | <span class="k">new</span> <span class="nb">Function</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="nx">code</span><span class="p">)</span>
|
245 |
|
246 | <span class="nv">cache = </span><span class="p">{}</span></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-34">¶</a> </div> <p>Template in, HTML out. Accepts functions or strings as does <code>coffeekup.compile</code>.</p>
|
247 |
|
248 | <p>Accepts an option <code>cache</code>, by default <code>false</code>. If set to <code>false</code> templates will
|
249 | be recompiled each time.</p>
|
250 |
|
251 | <p><code>options</code> is just a convenience parameter to pass options separately from the
|
252 | data, but the two will be merged and passed down to the compiler (which uses
|
253 | <code>locals</code> and <code>hardcode</code>), and the template (which understands <code>locals</code>, <code>format</code>
|
254 | and <code>autoescape</code>).</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">coffeekup.render = </span><span class="nf">(template, data = {}, options = {}) -></span>
|
255 | <span class="nx">data</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">=</span> <span class="nx">v</span> <span class="k">for</span> <span class="nx">k</span><span class="p">,</span> <span class="nx">v</span> <span class="k">of</span> <span class="nx">options</span>
|
256 | <span class="nx">data</span><span class="p">.</span><span class="nx">cache</span> <span class="o">?=</span> <span class="kc">off</span>
|
257 |
|
258 | <span class="k">if</span> <span class="nx">data</span><span class="p">.</span><span class="nx">cache</span> <span class="o">and</span> <span class="nx">cache</span><span class="p">[</span><span class="nx">template</span><span class="p">]</span><span class="o">?</span> <span class="k">then</span> <span class="nv">tpl = </span><span class="nx">cache</span><span class="p">[</span><span class="nx">template</span><span class="p">]</span>
|
259 | <span class="k">else</span> <span class="k">if</span> <span class="nx">data</span><span class="p">.</span><span class="nx">cache</span> <span class="k">then</span> <span class="nv">tpl = </span><span class="nx">cache</span><span class="p">[</span><span class="nx">template</span><span class="p">]</span> <span class="o">=</span> <span class="nx">coffeekup</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">template</span><span class="p">,</span> <span class="nx">data</span><span class="p">)</span>
|
260 | <span class="k">else</span> <span class="nv">tpl = </span><span class="nx">coffeekup</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">template</span><span class="p">,</span> <span class="nx">data</span><span class="p">)</span>
|
261 | <span class="nx">tpl</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span>
|
262 |
|
263 | <span class="nx">unless</span> <span class="nb">window</span><span class="o">?</span>
|
264 | <span class="nv">coffeekup.adapters =</span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-35">¶</a> </div> <p>Legacy adapters for when coffeekup expected data in the <code>context</code> attribute.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">simple: </span><span class="nx">coffeekup</span><span class="p">.</span><span class="nx">render</span>
|
265 | <span class="nv">meryl: </span><span class="nx">coffeekup</span><span class="p">.</span><span class="nx">render</span>
|
266 |
|
267 | <span class="nv">express:</span>
|
268 | <span class="nv">TemplateError: </span><span class="k">class</span> <span class="k">extends</span> <span class="nb">Error</span>
|
269 | <span class="nv">constructor: </span><span class="nf">(@message) -></span>
|
270 | <span class="nb">Error</span><span class="p">.</span><span class="nx">call</span> <span class="k">this</span><span class="p">,</span> <span class="nx">@message</span>
|
271 | <span class="nb">Error</span><span class="p">.</span><span class="nx">captureStackTrace</span> <span class="k">this</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">.</span><span class="nx">callee</span>
|
272 | <span class="nv">name: </span><span class="s1">'TemplateError'</span>
|
273 |
|
274 | <span class="nv">compile: </span><span class="nf">(template, data) -></span> </pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-36">¶</a> </div> <p>Allows <code>partial 'foo'</code> instead of <code>text @partial 'foo'</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">data</span><span class="p">.</span><span class="nx">hardcode</span> <span class="o">?=</span> <span class="p">{}</span>
|
275 | <span class="nv">data.hardcode.partial = </span><span class="o">-></span>
|
276 | <span class="nx">text</span> <span class="nx">@partial</span><span class="p">.</span><span class="nx">apply</span> <span class="err">@</span><span class="p">,</span> <span class="nx">arguments</span>
|
277 |
|
278 | <span class="nv">TemplateError = </span><span class="nx">@TemplateError</span>
|
279 | <span class="k">try</span> <span class="nv">tpl = </span><span class="nx">coffeekup</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">template</span><span class="p">,</span> <span class="nx">data</span><span class="p">)</span>
|
280 | <span class="k">catch</span> <span class="nx">e</span> <span class="k">then</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">TemplateError</span> <span class="s2">"Error compiling #{data.filename}: #{e.message}"</span>
|
281 |
|
282 | <span class="k">return</span> <span class="o">-></span>
|
283 | <span class="k">try</span> <span class="nx">tpl</span> <span class="nx">arguments</span><span class="p">...</span>
|
284 | <span class="k">catch</span> <span class="nx">e</span> <span class="k">then</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">TemplateError</span> <span class="s2">"Error rendering #{data.filename}: #{e.message}"</span>
|
285 |
|
286 | </pre></div> </td> </tr> </tbody> </table> </div> </body> </html> |
\ | No newline at end of file |