diff options
Diffstat (limited to 'node_modules/twig/docs/twig.html')
-rw-r--r-- | node_modules/twig/docs/twig.html | 11250 |
1 files changed, 0 insertions, 11250 deletions
diff --git a/node_modules/twig/docs/twig.html b/node_modules/twig/docs/twig.html deleted file mode 100644 index 687abbd..0000000 --- a/node_modules/twig/docs/twig.html +++ /dev/null @@ -1,11250 +0,0 @@ -<!DOCTYPE html> - -<html> -<head> - <title>twig.js</title> - <meta http-equiv="content-type" content="text/html; charset=UTF-8"> - <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"> - <link rel="stylesheet" media="all" href="docco.css" /> -</head> -<body> - <div id="container"> - <div id="background"></div> - - <ul class="sections"> - - <li id="title"> - <div class="annotation"> - <h1>twig.js</h1> - </div> - </li> - - - - <li id="section-1"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-1">¶</a> - </div> - - </div> - - <div class="content"><div class='highlight'><pre><span class="hljs-comment">/** - * Twig.js 0.8.9 - * - * @copyright 2011-2015 John Roepke and the Twig.js Contributors - * @license Available under the BSD 2-Clause License - * @link https://github.com/justjohn/twig.js - */</span> - -<span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{ - - Twig.VERSION = <span class="hljs-string">"0.8.9"</span>; - - <span class="hljs-keyword">return</span> Twig; -})(Twig || {});</pre></div></div> - - </li> - - - <li id="section-2"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-2">¶</a> - </div> - <pre><code>Twig.js -Available under the BSD <span class="hljs-number">2</span>-Clause License -https:<span class="hljs-comment">//github.com/justjohn/twig.js</span> -</code></pre> - </div> - - <div class="content"><div class='highlight'><pre> -<span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{ -<span class="hljs-meta"> "use strict"</span>;</pre></div></div> - - </li> - - - <li id="section-3"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-3">¶</a> - </div> - <h2 id="twig-core-js">twig.core.js</h2> -<p>This file handles template level tokenizing, compiling and parsing.</p> - - </div> - - <div class="content"><div class='highlight'><pre> - Twig.trace = <span class="hljs-literal">false</span>; - Twig.debug = <span class="hljs-literal">false</span>;</pre></div></div> - - </li> - - - <li id="section-4"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-4">¶</a> - </div> - <p>Default caching to true for the improved performance it offers</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.cache = <span class="hljs-literal">true</span>; - - Twig.placeholders = { - parent: <span class="hljs-string">"{{|PARENT|}}"</span> - }; - - <span class="hljs-comment">/** - * Fallback for Array.indexOf for IE8 et al - */</span> - Twig.indexOf = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">arr, searchElement <span class="hljs-comment">/*, fromIndex */</span> </span>) </span>{ - <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Array</span>.prototype.hasOwnProperty(<span class="hljs-string">"indexOf"</span>)) { - <span class="hljs-keyword">return</span> arr.indexOf(searchElement); - } - <span class="hljs-keyword">if</span> (arr === <span class="hljs-keyword">void</span> <span class="hljs-number">0</span> || arr === <span class="hljs-literal">null</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">TypeError</span>(); - } - <span class="hljs-keyword">var</span> t = <span class="hljs-built_in">Object</span>(arr); - <span class="hljs-keyword">var</span> len = t.length >>> <span class="hljs-number">0</span>; - <span class="hljs-keyword">if</span> (len === <span class="hljs-number">0</span>) { - <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>; - } - <span class="hljs-keyword">var</span> n = <span class="hljs-number">0</span>; - <span class="hljs-keyword">if</span> (<span class="hljs-built_in">arguments</span>.length > <span class="hljs-number">0</span>) { - n = <span class="hljs-built_in">Number</span>(<span class="hljs-built_in">arguments</span>[<span class="hljs-number">1</span>]); - <span class="hljs-keyword">if</span> (n !== n) { <span class="hljs-comment">// shortcut for verifying if it's NaN</span> - n = <span class="hljs-number">0</span>; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (n !== <span class="hljs-number">0</span> && n !== <span class="hljs-literal">Infinity</span> && n !== -<span class="hljs-literal">Infinity</span>) { - n = (n > <span class="hljs-number">0</span> || <span class="hljs-number">-1</span>) * <span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.abs(n)); - } - } - <span class="hljs-keyword">if</span> (n >= len) {</pre></div></div> - - </li> - - - <li id="section-5"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-5">¶</a> - </div> - <p>console.log(“indexOf not found1 “, JSON.stringify(searchElement), JSON.stringify(arr));</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>; - } - <span class="hljs-keyword">var</span> k = n >= <span class="hljs-number">0</span> ? n : <span class="hljs-built_in">Math</span>.max(len - <span class="hljs-built_in">Math</span>.abs(n), <span class="hljs-number">0</span>); - <span class="hljs-keyword">for</span> (; k < len; k++) { - <span class="hljs-keyword">if</span> (k <span class="hljs-keyword">in</span> t && t[k] === searchElement) { - <span class="hljs-keyword">return</span> k; - } - } - <span class="hljs-keyword">if</span> (arr == searchElement) { - <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; - }</pre></div></div> - - </li> - - - <li id="section-6"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-6">¶</a> - </div> - <p>console.log(“indexOf not found2 “, JSON.stringify(searchElement), JSON.stringify(arr));</p> - - </div> - - <div class="content"><div class='highlight'><pre> - <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>; - } - - Twig.forEach = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">arr, callback, thisArg</span>) </span>{ - <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Array</span>.prototype.forEach ) { - <span class="hljs-keyword">return</span> arr.forEach(callback, thisArg); - } - - <span class="hljs-keyword">var</span> T, k; - - <span class="hljs-keyword">if</span> ( arr == <span class="hljs-literal">null</span> ) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">TypeError</span>( <span class="hljs-string">" this is null or not defined"</span> ); - }</pre></div></div> - - </li> - - - <li id="section-7"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-7">¶</a> - </div> - <ol> -<li>Let O be the result of calling ToObject passing the |this| value as the argument.</li> -</ol> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> O = <span class="hljs-built_in">Object</span>(arr);</pre></div></div> - - </li> - - - <li id="section-8"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-8">¶</a> - </div> - <ol> -<li>Let lenValue be the result of calling the Get internal method of O with the argument “length”.</li> -<li>Let len be ToUint32(lenValue).</li> -</ol> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> len = O.length >>> <span class="hljs-number">0</span>; <span class="hljs-comment">// Hack to convert O.length to a UInt32</span></pre></div></div> - - </li> - - - <li id="section-9"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-9">¶</a> - </div> - <ol> -<li>If IsCallable(callback) is false, throw a TypeError exception. -See: <a href="http://es5.github.com/#x9.11">http://es5.github.com/#x9.11</a></li> -</ol> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> ( {}.toString.call(callback) != <span class="hljs-string">"[object Function]"</span> ) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">TypeError</span>( callback + <span class="hljs-string">" is not a function"</span> ); - }</pre></div></div> - - </li> - - - <li id="section-10"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-10">¶</a> - </div> - <ol> -<li>If thisArg was supplied, let T be thisArg; else let T be undefined.</li> -</ol> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> ( thisArg ) { - T = thisArg; - }</pre></div></div> - - </li> - - - <li id="section-11"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-11">¶</a> - </div> - <ol> -<li>Let k be 0</li> -</ol> - - </div> - - <div class="content"><div class='highlight'><pre> k = <span class="hljs-number">0</span>;</pre></div></div> - - </li> - - - <li id="section-12"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-12">¶</a> - </div> - <ol> -<li>Repeat, while k < len</li> -</ol> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">while</span>( k < len ) { - - <span class="hljs-keyword">var</span> kValue;</pre></div></div> - - </li> - - - <li id="section-13"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-13">¶</a> - </div> - <p>a. Let Pk be ToString(k). - This is implicit for LHS operands of the in operator -b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk. - This step can be combined with c -c. If kPresent is true, then</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> ( k <span class="hljs-keyword">in</span> O ) {</pre></div></div> - - </li> - - - <li id="section-14"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-14">¶</a> - </div> - <p>i. Let kValue be the result of calling the Get internal method of O with argument Pk.</p> - - </div> - - <div class="content"><div class='highlight'><pre> kValue = O[ k ];</pre></div></div> - - </li> - - - <li id="section-15"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-15">¶</a> - </div> - <p>ii. Call the Call internal method of callback with T as the this value and -argument list containing kValue, k, and O.</p> - - </div> - - <div class="content"><div class='highlight'><pre> callback.call( T, kValue, k, O ); - }</pre></div></div> - - </li> - - - <li id="section-16"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-16">¶</a> - </div> - <p>d. Increase k by 1.</p> - - </div> - - <div class="content"><div class='highlight'><pre> k++; - }</pre></div></div> - - </li> - - - <li id="section-17"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-17">¶</a> - </div> - <ol> -<li>return undefined</li> -</ol> - - </div> - - <div class="content"><div class='highlight'><pre> }; - - Twig.merge = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">target, source, onlyChanged</span>) </span>{ - Twig.forEach(<span class="hljs-built_in">Object</span>.keys(source), <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">key</span>) </span>{ - <span class="hljs-keyword">if</span> (onlyChanged && !(key <span class="hljs-keyword">in</span> target)) { - <span class="hljs-keyword">return</span>; - } - - target[key] = source[key] - }); - - <span class="hljs-keyword">return</span> target; - }; - - <span class="hljs-comment">/** - * Exception thrown by twig.js. - */</span> - Twig.Error = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">message</span>) </span>{ - <span class="hljs-keyword">this</span>.message = message; - <span class="hljs-keyword">this</span>.name = <span class="hljs-string">"TwigException"</span>; - <span class="hljs-keyword">this</span>.type = <span class="hljs-string">"TwigException"</span>; - }; - - <span class="hljs-comment">/** - * Get the string representation of a Twig error. - */</span> - Twig.Error.prototype.toString = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ - <span class="hljs-keyword">var</span> output = <span class="hljs-keyword">this</span>.name + <span class="hljs-string">": "</span> + <span class="hljs-keyword">this</span>.message; - - <span class="hljs-keyword">return</span> output; - }; - - <span class="hljs-comment">/** - * Wrapper for logging to the console. - */</span> - Twig.log = { - trace: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{<span class="hljs-keyword">if</span> (Twig.trace && <span class="hljs-built_in">console</span>) {<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Array</span>.prototype.slice.call(<span class="hljs-built_in">arguments</span>));}}, - debug: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{<span class="hljs-keyword">if</span> (Twig.debug && <span class="hljs-built_in">console</span>) {<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Array</span>.prototype.slice.call(<span class="hljs-built_in">arguments</span>));}} - }; - - - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">console</span> !== <span class="hljs-string">"undefined"</span>) { - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">console</span>.error !== <span class="hljs-string">"undefined"</span>) { - Twig.log.error = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ - <span class="hljs-built_in">console</span>.error.apply(<span class="hljs-built_in">console</span>, <span class="hljs-built_in">arguments</span>); - } - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">console</span>.log !== <span class="hljs-string">"undefined"</span>) { - Twig.log.error = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ - <span class="hljs-built_in">console</span>.log.apply(<span class="hljs-built_in">console</span>, <span class="hljs-built_in">arguments</span>); - } - } - } <span class="hljs-keyword">else</span> { - Twig.log.error = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{}; - } - - <span class="hljs-comment">/** - * Wrapper for child context objects in Twig. - * - * @param {Object} context Values to initialize the context with. - */</span> - Twig.ChildContext = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">context</span>) </span>{ - <span class="hljs-keyword">var</span> ChildContext = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ChildContext</span>(<span class="hljs-params"></span>) </span>{}; - ChildContext.prototype = context; - <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ChildContext(); - }; - - <span class="hljs-comment">/** - * Container for methods related to handling high level template tokens - * (for example: {{ expression }}, {% logic %}, {# comment #}, raw data) - */</span> - Twig.token = {}; - - <span class="hljs-comment">/** - * Token types. - */</span> - Twig.token.type = { - output: <span class="hljs-string">'output'</span>, - logic: <span class="hljs-string">'logic'</span>, - comment: <span class="hljs-string">'comment'</span>, - raw: <span class="hljs-string">'raw'</span>, - output_whitespace_pre: <span class="hljs-string">'output_whitespace_pre'</span>, - output_whitespace_post: <span class="hljs-string">'output_whitespace_post'</span>, - output_whitespace_both: <span class="hljs-string">'output_whitespace_both'</span>, - logic_whitespace_pre: <span class="hljs-string">'logic_whitespace_pre'</span>, - logic_whitespace_post: <span class="hljs-string">'logic_whitespace_post'</span>, - logic_whitespace_both: <span class="hljs-string">'logic_whitespace_both'</span> - }; - - <span class="hljs-comment">/** - * Token syntax definitions. - */</span> - Twig.token.definitions = [ - { - type: Twig.token.type.raw, - open: <span class="hljs-string">'{% raw %}'</span>, - close: <span class="hljs-string">'{% endraw %}'</span> - }, - { - type: Twig.token.type.raw, - open: <span class="hljs-string">'{% verbatim %}'</span>, - close: <span class="hljs-string">'{% endverbatim %}'</span> - },</pre></div></div> - - </li> - - - <li id="section-18"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-18">¶</a> - </div> - <p><em>Whitespace type tokens</em></p> -<p>These typically take the form <code>{{- expression -}}</code> or <code>{{- expression }}</code> or <code>{{ expression -}}</code>.</p> - - </div> - - <div class="content"><div class='highlight'><pre> { - type: Twig.token.type.output_whitespace_pre, - open: <span class="hljs-string">'{{-'</span>, - close: <span class="hljs-string">'}}'</span> - }, - { - type: Twig.token.type.output_whitespace_post, - open: <span class="hljs-string">'{{'</span>, - close: <span class="hljs-string">'-}}'</span> - }, - { - type: Twig.token.type.output_whitespace_both, - open: <span class="hljs-string">'{{-'</span>, - close: <span class="hljs-string">'-}}'</span> - }, - { - type: Twig.token.type.logic_whitespace_pre, - open: <span class="hljs-string">'{%-'</span>, - close: <span class="hljs-string">'%}'</span> - }, - { - type: Twig.token.type.logic_whitespace_post, - open: <span class="hljs-string">'{%'</span>, - close: <span class="hljs-string">'-%}'</span> - }, - { - type: Twig.token.type.logic_whitespace_both, - open: <span class="hljs-string">'{%-'</span>, - close: <span class="hljs-string">'-%}'</span> - },</pre></div></div> - - </li> - - - <li id="section-19"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-19">¶</a> - </div> - <p><em>Output type tokens</em></p> -<p>These typically take the form <code>{{ expression }}</code>.</p> - - </div> - - <div class="content"><div class='highlight'><pre> { - type: Twig.token.type.output, - open: <span class="hljs-string">'{{'</span>, - close: <span class="hljs-string">'}}'</span> - },</pre></div></div> - - </li> - - - <li id="section-20"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-20">¶</a> - </div> - <p><em>Logic type tokens</em></p> -<p>These typically take a form like <code>{% if expression %}</code> or <code>{% endif %}</code></p> - - </div> - - <div class="content"><div class='highlight'><pre> { - type: Twig.token.type.logic, - open: <span class="hljs-string">'{%'</span>, - close: <span class="hljs-string">'%}'</span> - },</pre></div></div> - - </li> - - - <li id="section-21"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-21">¶</a> - </div> - <p><em>Comment type tokens</em></p> -<p>These take the form <code>{# anything #}</code></p> - - </div> - - <div class="content"><div class='highlight'><pre> { - type: Twig.token.type.comment, - open: <span class="hljs-string">'{#'</span>, - close: <span class="hljs-string">'#}'</span> - } - ]; - - - <span class="hljs-comment">/** - * What characters start "strings" in token definitions. We need this to ignore token close - * strings inside an expression. - */</span> - Twig.token.strings = [<span class="hljs-string">'"'</span>, <span class="hljs-string">"'"</span>]; - - Twig.token.findStart = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">template</span>) </span>{ - <span class="hljs-keyword">var</span> output = { - position: <span class="hljs-literal">null</span>, - close_position: <span class="hljs-literal">null</span>, - def: <span class="hljs-literal">null</span> - }, - i, - token_template, - first_key_position, - close_key_position; - - <span class="hljs-keyword">for</span> (i=<span class="hljs-number">0</span>;i<Twig.token.definitions.length;i++) { - token_template = Twig.token.definitions[i]; - first_key_position = template.indexOf(token_template.open); - close_key_position = template.indexOf(token_template.close); - - Twig.log.trace(<span class="hljs-string">"Twig.token.findStart: "</span>, <span class="hljs-string">"Searching for "</span>, token_template.open, <span class="hljs-string">" found at "</span>, first_key_position);</pre></div></div> - - </li> - - - <li id="section-22"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-22">¶</a> - </div> - <p>Special handling for mismatched tokens</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (first_key_position >= <span class="hljs-number">0</span>) {</pre></div></div> - - </li> - - - <li id="section-23"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-23">¶</a> - </div> - <p>This token matches the template</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (token_template.open.length !== token_template.close.length) {</pre></div></div> - - </li> - - - <li id="section-24"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-24">¶</a> - </div> - <p>This token has mismatched closing and opening tags</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (close_key_position < <span class="hljs-number">0</span>) {</pre></div></div> - - </li> - - - <li id="section-25"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-25">¶</a> - </div> - <p>This token’s closing tag does not match the template</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">continue</span>; - } - } - }</pre></div></div> - - </li> - - - <li id="section-26"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-26">¶</a> - </div> - <p>Does this token occur before any other types?</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (first_key_position >= <span class="hljs-number">0</span> && (output.position === <span class="hljs-literal">null</span> || first_key_position < output.position)) { - output.position = first_key_position; - output.def = token_template; - output.close_position = close_key_position; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (first_key_position >= <span class="hljs-number">0</span> && output.position !== <span class="hljs-literal">null</span> && first_key_position === output.position) { - <span class="hljs-comment">/*This token exactly matches another token, - greedily match to check if this token has a greater specificity*/</span> - <span class="hljs-keyword">if</span> (token_template.open.length > output.def.open.length) {</pre></div></div> - - </li> - - - <li id="section-27"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-27">¶</a> - </div> - <p>This token’s opening tag is more specific than the previous match</p> - - </div> - - <div class="content"><div class='highlight'><pre> output.position = first_key_position; - output.def = token_template; - output.close_position = close_key_position; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (token_template.open.length === output.def.open.length) { - <span class="hljs-keyword">if</span> (token_template.close.length > output.def.close.length) {</pre></div></div> - - </li> - - - <li id="section-28"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-28">¶</a> - </div> - <p>This token’s opening tag is as specific as the previous match, -but the closing tag has greater specificity</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (close_key_position >= <span class="hljs-number">0</span> && close_key_position < output.close_position) {</pre></div></div> - - </li> - - - <li id="section-29"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-29">¶</a> - </div> - <p>This token’s closing tag exists in the template, -and it occurs sooner than the previous match</p> - - </div> - - <div class="content"><div class='highlight'><pre> output.position = first_key_position; - output.def = token_template; - output.close_position = close_key_position; - } - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (close_key_position >= <span class="hljs-number">0</span> && close_key_position < output.close_position) {</pre></div></div> - - </li> - - - <li id="section-30"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-30">¶</a> - </div> - <p>This token’s closing tag is not more specific than the previous match, -but it occurs sooner than the previous match</p> - - </div> - - <div class="content"><div class='highlight'><pre> output.position = first_key_position; - output.def = token_template; - output.close_position = close_key_position; - } - } - } - } - - <span class="hljs-keyword">delete</span> output[<span class="hljs-string">'close_position'</span>]; - - <span class="hljs-keyword">return</span> output; - }; - - Twig.token.findEnd = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">template, token_def, start</span>) </span>{ - <span class="hljs-keyword">var</span> end = <span class="hljs-literal">null</span>, - found = <span class="hljs-literal">false</span>, - offset = <span class="hljs-number">0</span>,</pre></div></div> - - </li> - - - <li id="section-31"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-31">¶</a> - </div> - <p>String position variables</p> - - </div> - - <div class="content"><div class='highlight'><pre> str_pos = <span class="hljs-literal">null</span>, - str_found = <span class="hljs-literal">null</span>, - pos = <span class="hljs-literal">null</span>, - end_offset = <span class="hljs-literal">null</span>, - this_str_pos = <span class="hljs-literal">null</span>, - end_str_pos = <span class="hljs-literal">null</span>,</pre></div></div> - - </li> - - - <li id="section-32"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-32">¶</a> - </div> - <p>For loop variables</p> - - </div> - - <div class="content"><div class='highlight'><pre> i, - l; - - <span class="hljs-keyword">while</span> (!found) { - str_pos = <span class="hljs-literal">null</span>; - str_found = <span class="hljs-literal">null</span>; - pos = template.indexOf(token_def.close, offset); - - <span class="hljs-keyword">if</span> (pos >= <span class="hljs-number">0</span>) { - end = pos; - found = <span class="hljs-literal">true</span>; - } <span class="hljs-keyword">else</span> {</pre></div></div> - - </li> - - - <li id="section-33"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-33">¶</a> - </div> - <p>throw an exception</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to find closing bracket '"</span> + token_def.close + - <span class="hljs-string">"'"</span> + <span class="hljs-string">" opened near template position "</span> + start); - }</pre></div></div> - - </li> - - - <li id="section-34"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-34">¶</a> - </div> - <p>Ignore quotes within comments; just look for the next comment close sequence, -regardless of what comes before it. <a href="https://github.com/justjohn/twig.js/issues/95">https://github.com/justjohn/twig.js/issues/95</a></p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (token_def.type === Twig.token.type.comment) { - <span class="hljs-keyword">break</span>; - }</pre></div></div> - - </li> - - - <li id="section-35"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-35">¶</a> - </div> - <p>Ignore quotes within raw tag -Fixes #283</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (token_def.type === Twig.token.type.raw) { - <span class="hljs-keyword">break</span>; - } - - l = Twig.token.strings.length; - <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i < l; i += <span class="hljs-number">1</span>) { - this_str_pos = template.indexOf(Twig.token.strings[i], offset); - - <span class="hljs-keyword">if</span> (this_str_pos > <span class="hljs-number">0</span> && this_str_pos < pos && - (str_pos === <span class="hljs-literal">null</span> || this_str_pos < str_pos)) { - str_pos = this_str_pos; - str_found = Twig.token.strings[i]; - } - }</pre></div></div> - - </li> - - - <li id="section-36"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-36">¶</a> - </div> - <p>We found a string before the end of the token, now find the string’s end and set the search offset to it</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (str_pos !== <span class="hljs-literal">null</span>) { - end_offset = str_pos + <span class="hljs-number">1</span>; - end = <span class="hljs-literal">null</span>; - found = <span class="hljs-literal">false</span>; - <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) { - end_str_pos = template.indexOf(str_found, end_offset); - <span class="hljs-keyword">if</span> (end_str_pos < <span class="hljs-number">0</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-string">"Unclosed string in template"</span>; - }</pre></div></div> - - </li> - - - <li id="section-37"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-37">¶</a> - </div> - <p>Ignore escaped quotes</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (template.substr(end_str_pos - <span class="hljs-number">1</span>, <span class="hljs-number">1</span>) !== <span class="hljs-string">"\\"</span>) { - offset = end_str_pos + <span class="hljs-number">1</span>; - <span class="hljs-keyword">break</span>; - } <span class="hljs-keyword">else</span> { - end_offset = end_str_pos + <span class="hljs-number">1</span>; - } - } - } - } - <span class="hljs-keyword">return</span> end; - }; - - <span class="hljs-comment">/** - * Convert a template into high-level tokens. - */</span> - Twig.tokenize = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">template</span>) </span>{ - <span class="hljs-keyword">var</span> tokens = [],</pre></div></div> - - </li> - - - <li id="section-38"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-38">¶</a> - </div> - <p>An offset for reporting errors locations in the template.</p> - - </div> - - <div class="content"><div class='highlight'><pre> error_offset = <span class="hljs-number">0</span>,</pre></div></div> - - </li> - - - <li id="section-39"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-39">¶</a> - </div> - <p>The start and type of the first token found in the template.</p> - - </div> - - <div class="content"><div class='highlight'><pre> found_token = <span class="hljs-literal">null</span>,</pre></div></div> - - </li> - - - <li id="section-40"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-40">¶</a> - </div> - <p>The end position of the matched token.</p> - - </div> - - <div class="content"><div class='highlight'><pre> end = <span class="hljs-literal">null</span>; - - <span class="hljs-keyword">while</span> (template.length > <span class="hljs-number">0</span>) {</pre></div></div> - - </li> - - - <li id="section-41"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-41">¶</a> - </div> - <p>Find the first occurance of any token type in the template</p> - - </div> - - <div class="content"><div class='highlight'><pre> found_token = Twig.token.findStart(template); - - Twig.log.trace(<span class="hljs-string">"Twig.tokenize: "</span>, <span class="hljs-string">"Found token: "</span>, found_token); - - <span class="hljs-keyword">if</span> (found_token.position !== <span class="hljs-literal">null</span>) {</pre></div></div> - - </li> - - - <li id="section-42"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-42">¶</a> - </div> - <p>Add a raw type token for anything before the start of the token</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (found_token.position > <span class="hljs-number">0</span>) { - tokens.push({ - type: Twig.token.type.raw, - value: template.substring(<span class="hljs-number">0</span>, found_token.position) - }); - } - template = template.substr(found_token.position + found_token.def.open.length); - error_offset += found_token.position + found_token.def.open.length;</pre></div></div> - - </li> - - - <li id="section-43"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-43">¶</a> - </div> - <p>Find the end of the token</p> - - </div> - - <div class="content"><div class='highlight'><pre> end = Twig.token.findEnd(template, found_token.def, error_offset); - - Twig.log.trace(<span class="hljs-string">"Twig.tokenize: "</span>, <span class="hljs-string">"Token ends at "</span>, end); - - tokens.push({ - type: found_token.def.type, - value: template.substring(<span class="hljs-number">0</span>, end).trim() - }); - - <span class="hljs-keyword">if</span> (template.substr( end + found_token.def.close.length, <span class="hljs-number">1</span> ) === <span class="hljs-string">"\n"</span>) { - <span class="hljs-keyword">switch</span> (found_token.def.type) { - <span class="hljs-keyword">case</span> <span class="hljs-string">"logic_whitespace_pre"</span>: - <span class="hljs-keyword">case</span> <span class="hljs-string">"logic_whitespace_post"</span>: - <span class="hljs-keyword">case</span> <span class="hljs-string">"logic_whitespace_both"</span>: - <span class="hljs-keyword">case</span> <span class="hljs-string">"logic"</span>:</pre></div></div> - - </li> - - - <li id="section-44"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-44">¶</a> - </div> - <p>Newlines directly after logic tokens are ignored</p> - - </div> - - <div class="content"><div class='highlight'><pre> end += <span class="hljs-number">1</span>; - <span class="hljs-keyword">break</span>; - } - } - - template = template.substr(end + found_token.def.close.length);</pre></div></div> - - </li> - - - <li id="section-45"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-45">¶</a> - </div> - <p>Increment the position in the template</p> - - </div> - - <div class="content"><div class='highlight'><pre> error_offset += end + found_token.def.close.length; - - } <span class="hljs-keyword">else</span> {</pre></div></div> - - </li> - - - <li id="section-46"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-46">¶</a> - </div> - <p>No more tokens -> add the rest of the template as a raw-type token</p> - - </div> - - <div class="content"><div class='highlight'><pre> tokens.push({ - type: Twig.token.type.raw, - value: template - }); - template = <span class="hljs-string">''</span>; - } - } - - <span class="hljs-keyword">return</span> tokens; - }; - - - Twig.compile = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">tokens</span>) </span>{ - <span class="hljs-keyword">try</span> {</pre></div></div> - - </li> - - - <li id="section-47"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-47">¶</a> - </div> - <p>Output and intermediate stacks</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> output = [], - stack = [],</pre></div></div> - - </li> - - - <li id="section-48"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-48">¶</a> - </div> - <p>The tokens between open and close tags</p> - - </div> - - <div class="content"><div class='highlight'><pre> intermediate_output = [], - - token = <span class="hljs-literal">null</span>, - logic_token = <span class="hljs-literal">null</span>, - unclosed_token = <span class="hljs-literal">null</span>,</pre></div></div> - - </li> - - - <li id="section-49"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-49">¶</a> - </div> - <p>Temporary previous token.</p> - - </div> - - <div class="content"><div class='highlight'><pre> prev_token = <span class="hljs-literal">null</span>,</pre></div></div> - - </li> - - - <li id="section-50"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-50">¶</a> - </div> - <p>Temporary previous output.</p> - - </div> - - <div class="content"><div class='highlight'><pre> prev_output = <span class="hljs-literal">null</span>,</pre></div></div> - - </li> - - - <li id="section-51"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-51">¶</a> - </div> - <p>Temporary previous intermediate output.</p> - - </div> - - <div class="content"><div class='highlight'><pre> prev_intermediate_output = <span class="hljs-literal">null</span>,</pre></div></div> - - </li> - - - <li id="section-52"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-52">¶</a> - </div> - <p>The previous token’s template</p> - - </div> - - <div class="content"><div class='highlight'><pre> prev_template = <span class="hljs-literal">null</span>,</pre></div></div> - - </li> - - - <li id="section-53"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-53">¶</a> - </div> - <p>Token lookahead</p> - - </div> - - <div class="content"><div class='highlight'><pre> next_token = <span class="hljs-literal">null</span>,</pre></div></div> - - </li> - - - <li id="section-54"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-54">¶</a> - </div> - <p>The output token</p> - - </div> - - <div class="content"><div class='highlight'><pre> tok_output = <span class="hljs-literal">null</span>,</pre></div></div> - - </li> - - - <li id="section-55"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-55">¶</a> - </div> - <p>Logic Token values</p> - - </div> - - <div class="content"><div class='highlight'><pre> type = <span class="hljs-literal">null</span>, - open = <span class="hljs-literal">null</span>, - next = <span class="hljs-literal">null</span>; - - <span class="hljs-keyword">var</span> compile_output = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token</span>) </span>{ - Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [token]); - <span class="hljs-keyword">if</span> (stack.length > <span class="hljs-number">0</span>) { - intermediate_output.push(token); - } <span class="hljs-keyword">else</span> { - output.push(token); - } - }; - - <span class="hljs-keyword">var</span> compile_logic = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-56"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-56">¶</a> - </div> - <p>Compile the logic token</p> - - </div> - - <div class="content"><div class='highlight'><pre> logic_token = Twig.logic.compile.apply(<span class="hljs-keyword">this</span>, [token]); - - type = logic_token.type; - open = Twig.logic.handler[type].open; - next = Twig.logic.handler[type].next; - - Twig.log.trace(<span class="hljs-string">"Twig.compile: "</span>, <span class="hljs-string">"Compiled logic token to "</span>, logic_token, - <span class="hljs-string">" next is: "</span>, next, <span class="hljs-string">" open is : "</span>, open);</pre></div></div> - - </li> - - - <li id="section-57"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-57">¶</a> - </div> - <p>Not a standalone token, check logic stack to see if this is expected</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (open !== <span class="hljs-literal">undefined</span> && !open) { - prev_token = stack.pop(); - prev_template = Twig.logic.handler[prev_token.type]; - - <span class="hljs-keyword">if</span> (Twig.indexOf(prev_template.next, type) < <span class="hljs-number">0</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(type + <span class="hljs-string">" not expected after a "</span> + prev_token.type); - } - - prev_token.output = prev_token.output || []; - - prev_token.output = prev_token.output.concat(intermediate_output); - intermediate_output = []; - - tok_output = { - type: Twig.token.type.logic, - token: prev_token - }; - <span class="hljs-keyword">if</span> (stack.length > <span class="hljs-number">0</span>) { - intermediate_output.push(tok_output); - } <span class="hljs-keyword">else</span> { - output.push(tok_output); - } - }</pre></div></div> - - </li> - - - <li id="section-58"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-58">¶</a> - </div> - <p>This token requires additional tokens to complete the logic structure.</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (next !== <span class="hljs-literal">undefined</span> && next.length > <span class="hljs-number">0</span>) { - Twig.log.trace(<span class="hljs-string">"Twig.compile: "</span>, <span class="hljs-string">"Pushing "</span>, logic_token, <span class="hljs-string">" to logic stack."</span>); - - <span class="hljs-keyword">if</span> (stack.length > <span class="hljs-number">0</span>) {</pre></div></div> - - </li> - - - <li id="section-59"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-59">¶</a> - </div> - <p>Put any currently held output into the output list of the logic operator -currently at the head of the stack before we push a new one on.</p> - - </div> - - <div class="content"><div class='highlight'><pre> prev_token = stack.pop(); - prev_token.output = prev_token.output || []; - prev_token.output = prev_token.output.concat(intermediate_output); - stack.push(prev_token); - intermediate_output = []; - }</pre></div></div> - - </li> - - - <li id="section-60"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-60">¶</a> - </div> - <p>Push the new logic token onto the logic stack</p> - - </div> - - <div class="content"><div class='highlight'><pre> stack.push(logic_token); - - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (open !== <span class="hljs-literal">undefined</span> && open) { - tok_output = { - type: Twig.token.type.logic, - token: logic_token - };</pre></div></div> - - </li> - - - <li id="section-61"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-61">¶</a> - </div> - <p>Standalone token (like {% set … %}</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (stack.length > <span class="hljs-number">0</span>) { - intermediate_output.push(tok_output); - } <span class="hljs-keyword">else</span> { - output.push(tok_output); - } - } - }; - - <span class="hljs-keyword">while</span> (tokens.length > <span class="hljs-number">0</span>) { - token = tokens.shift(); - prev_output = output[output.length - <span class="hljs-number">1</span>]; - prev_intermediate_output = intermediate_output[intermediate_output.length - <span class="hljs-number">1</span>]; - next_token = tokens[<span class="hljs-number">0</span>]; - Twig.log.trace(<span class="hljs-string">"Compiling token "</span>, token); - <span class="hljs-keyword">switch</span> (token.type) { - <span class="hljs-keyword">case</span> Twig.token.type.raw: - <span class="hljs-keyword">if</span> (stack.length > <span class="hljs-number">0</span>) { - intermediate_output.push(token); - } <span class="hljs-keyword">else</span> { - output.push(token); - } - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> Twig.token.type.logic: - compile_logic.call(<span class="hljs-keyword">this</span>, token); - <span class="hljs-keyword">break</span>;</pre></div></div> - - </li> - - - <li id="section-62"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-62">¶</a> - </div> - <p>Do nothing, comments should be ignored</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> Twig.token.type.comment: - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> Twig.token.type.output: - compile_output.call(<span class="hljs-keyword">this</span>, token); - <span class="hljs-keyword">break</span>;</pre></div></div> - - </li> - - - <li id="section-63"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-63">¶</a> - </div> - <p>Kill whitespace ahead and behind this token</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> Twig.token.type.logic_whitespace_pre: - <span class="hljs-keyword">case</span> Twig.token.type.logic_whitespace_post: - <span class="hljs-keyword">case</span> Twig.token.type.logic_whitespace_both: - <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_pre: - <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_post: - <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_both: - <span class="hljs-keyword">if</span> (token.type !== Twig.token.type.output_whitespace_post && token.type !== Twig.token.type.logic_whitespace_post) { - <span class="hljs-keyword">if</span> (prev_output) {</pre></div></div> - - </li> - - - <li id="section-64"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-64">¶</a> - </div> - <p>If the previous output is raw, pop it off</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (prev_output.type === Twig.token.type.raw) { - output.pop();</pre></div></div> - - </li> - - - <li id="section-65"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-65">¶</a> - </div> - <p>If the previous output is not just whitespace, trim it</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (prev_output.value.match(<span class="hljs-regexp">/^\s*$/</span>) === <span class="hljs-literal">null</span>) { - prev_output.value = prev_output.value.trim();</pre></div></div> - - </li> - - - <li id="section-66"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-66">¶</a> - </div> - <p>Repush the previous output</p> - - </div> - - <div class="content"><div class='highlight'><pre> output.push(prev_output); - } - } - } - - <span class="hljs-keyword">if</span> (prev_intermediate_output) {</pre></div></div> - - </li> - - - <li id="section-67"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-67">¶</a> - </div> - <p>If the previous intermediate output is raw, pop it off</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (prev_intermediate_output.type === Twig.token.type.raw) { - intermediate_output.pop();</pre></div></div> - - </li> - - - <li id="section-68"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-68">¶</a> - </div> - <p>If the previous output is not just whitespace, trim it</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (prev_intermediate_output.value.match(<span class="hljs-regexp">/^\s*$/</span>) === <span class="hljs-literal">null</span>) { - prev_intermediate_output.value = prev_intermediate_output.value.trim();</pre></div></div> - - </li> - - - <li id="section-69"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-69">¶</a> - </div> - <p>Repush the previous intermediate output</p> - - </div> - - <div class="content"><div class='highlight'><pre> intermediate_output.push(prev_intermediate_output); - } - } - } - }</pre></div></div> - - </li> - - - <li id="section-70"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-70">¶</a> - </div> - <p>Compile this token</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">switch</span> (token.type) { - <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_pre: - <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_post: - <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_both: - compile_output.call(<span class="hljs-keyword">this</span>, token); - <span class="hljs-keyword">break</span>; - <span class="hljs-keyword">case</span> Twig.token.type.logic_whitespace_pre: - <span class="hljs-keyword">case</span> Twig.token.type.logic_whitespace_post: - <span class="hljs-keyword">case</span> Twig.token.type.logic_whitespace_both: - compile_logic.call(<span class="hljs-keyword">this</span>, token); - <span class="hljs-keyword">break</span>; - } - - <span class="hljs-keyword">if</span> (token.type !== Twig.token.type.output_whitespace_pre && token.type !== Twig.token.type.logic_whitespace_pre) { - <span class="hljs-keyword">if</span> (next_token) {</pre></div></div> - - </li> - - - <li id="section-71"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-71">¶</a> - </div> - <p>If the next token is raw, shift it out</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (next_token.type === Twig.token.type.raw) { - tokens.shift();</pre></div></div> - - </li> - - - <li id="section-72"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-72">¶</a> - </div> - <p>If the next token is not just whitespace, trim it</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (next_token.value.match(<span class="hljs-regexp">/^\s*$/</span>) === <span class="hljs-literal">null</span>) { - next_token.value = next_token.value.trim();</pre></div></div> - - </li> - - - <li id="section-73"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-73">¶</a> - </div> - <p>Unshift the next token</p> - - </div> - - <div class="content"><div class='highlight'><pre> tokens.unshift(next_token); - } - } - } - } - - <span class="hljs-keyword">break</span>; - } - - Twig.log.trace(<span class="hljs-string">"Twig.compile: "</span>, <span class="hljs-string">" Output: "</span>, output, - <span class="hljs-string">" Logic Stack: "</span>, stack, - <span class="hljs-string">" Pending Output: "</span>, intermediate_output ); - }</pre></div></div> - - </li> - - - <li id="section-74"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-74">¶</a> - </div> - <p>Verify that there are no logic tokens left in the stack.</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (stack.length > <span class="hljs-number">0</span>) { - unclosed_token = stack.pop(); - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Unable to find an end tag for "</span> + unclosed_token.type + - <span class="hljs-string">", expecting one of "</span> + unclosed_token.next); - } - <span class="hljs-keyword">return</span> output; - } <span class="hljs-keyword">catch</span> (ex) { - Twig.log.error(<span class="hljs-string">"Error compiling twig template "</span> + <span class="hljs-keyword">this</span>.id + <span class="hljs-string">": "</span>); - <span class="hljs-keyword">if</span> (ex.stack) { - Twig.log.error(ex.stack); - } <span class="hljs-keyword">else</span> { - Twig.log.error(ex.toString()); - } - - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.options.rethrow) <span class="hljs-keyword">throw</span> ex; - } - }; - - <span class="hljs-comment">/** - * Parse a compiled template. - * - * @param {Array} tokens The compiled tokens. - * @param {Object} context The render context. - * - * @return {string} The parsed template. - */</span> - Twig.parse = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">tokens, context</span>) </span>{ - <span class="hljs-keyword">try</span> { - <span class="hljs-keyword">var</span> output = [],</pre></div></div> - - </li> - - - <li id="section-75"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-75">¶</a> - </div> - <p>Track logic chains</p> - - </div> - - <div class="content"><div class='highlight'><pre> chain = <span class="hljs-literal">true</span>, - that = <span class="hljs-keyword">this</span>; - - Twig.forEach(tokens, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">parseToken</span>(<span class="hljs-params">token</span>) </span>{ - Twig.log.debug(<span class="hljs-string">"Twig.parse: "</span>, <span class="hljs-string">"Parsing token: "</span>, token); - - <span class="hljs-keyword">switch</span> (token.type) { - <span class="hljs-keyword">case</span> Twig.token.type.raw: - output.push(Twig.filters.raw(token.value)); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> Twig.token.type.logic: - <span class="hljs-keyword">var</span> logic_token = token.token, - logic = Twig.logic.parse.apply(that, [logic_token, context, chain]); - - <span class="hljs-keyword">if</span> (logic.chain !== <span class="hljs-literal">undefined</span>) { - chain = logic.chain; - } - <span class="hljs-keyword">if</span> (logic.context !== <span class="hljs-literal">undefined</span>) { - context = logic.context; - } - <span class="hljs-keyword">if</span> (logic.output !== <span class="hljs-literal">undefined</span>) { - output.push(logic.output); - } - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> Twig.token.type.comment:</pre></div></div> - - </li> - - - <li id="section-76"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-76">¶</a> - </div> - <p>Do nothing, comments should be ignored</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">break</span>;</pre></div></div> - - </li> - - - <li id="section-77"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-77">¶</a> - </div> - <p>Fall through whitespace to output</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_pre: - <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_post: - <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_both: - <span class="hljs-keyword">case</span> Twig.token.type.output: - Twig.log.debug(<span class="hljs-string">"Twig.parse: "</span>, <span class="hljs-string">"Output token: "</span>, token.stack);</pre></div></div> - - </li> - - - <li id="section-78"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-78">¶</a> - </div> - <p>Parse the given expression in the given context</p> - - </div> - - <div class="content"><div class='highlight'><pre> output.push(Twig.expression.parse.apply(that, [token.stack, context])); - <span class="hljs-keyword">break</span>; - } - }); - <span class="hljs-keyword">return</span> Twig.output.apply(<span class="hljs-keyword">this</span>, [output]); - } <span class="hljs-keyword">catch</span> (ex) { - Twig.log.error(<span class="hljs-string">"Error parsing twig template "</span> + <span class="hljs-keyword">this</span>.id + <span class="hljs-string">": "</span>); - <span class="hljs-keyword">if</span> (ex.stack) { - Twig.log.error(ex.stack); - } <span class="hljs-keyword">else</span> { - Twig.log.error(ex.toString()); - } - - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.options.rethrow) <span class="hljs-keyword">throw</span> ex; - - <span class="hljs-keyword">if</span> (Twig.debug) { - <span class="hljs-keyword">return</span> ex.toString(); - } - } - }; - - <span class="hljs-comment">/** - * Tokenize and compile a string template. - * - * @param {string} data The template. - * - * @return {Array} The compiled tokens. - */</span> - Twig.prepare = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data</span>) </span>{ - <span class="hljs-keyword">var</span> tokens, raw_tokens;</pre></div></div> - - </li> - - - <li id="section-79"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-79">¶</a> - </div> - <p>Tokenize</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.log.debug(<span class="hljs-string">"Twig.prepare: "</span>, <span class="hljs-string">"Tokenizing "</span>, data); - raw_tokens = Twig.tokenize.apply(<span class="hljs-keyword">this</span>, [data]);</pre></div></div> - - </li> - - - <li id="section-80"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-80">¶</a> - </div> - <p>Compile</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.log.debug(<span class="hljs-string">"Twig.prepare: "</span>, <span class="hljs-string">"Compiling "</span>, raw_tokens); - tokens = Twig.compile.apply(<span class="hljs-keyword">this</span>, [raw_tokens]); - - Twig.log.debug(<span class="hljs-string">"Twig.prepare: "</span>, <span class="hljs-string">"Compiled "</span>, tokens); - - <span class="hljs-keyword">return</span> tokens; - }; - - <span class="hljs-comment">/** - * Join the output token's stack and escape it if needed - * - * @param {Array} Output token's stack - * - * @return {string|String} Autoescaped output - */</span> - Twig.output = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">output</span>) </span>{ - <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">this</span>.options.autoescape) { - <span class="hljs-keyword">return</span> output.join(<span class="hljs-string">""</span>); - } - - <span class="hljs-keyword">var</span> strategy = <span class="hljs-string">'html'</span>; - <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> <span class="hljs-keyword">this</span>.options.autoescape == <span class="hljs-string">'string'</span>) - strategy = <span class="hljs-keyword">this</span>.options.autoescape;</pre></div></div> - - </li> - - - <li id="section-81"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-81">¶</a> - </div> - <p>[].map would be better but it’s not supported by IE8-</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> escaped_output = []; - Twig.forEach(output, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">str</span>) </span>{ - <span class="hljs-keyword">if</span> (str && (str.twig_markup !== <span class="hljs-literal">true</span> && str.twig_markup != strategy)) { - str = Twig.filters.escape(str, [ strategy ]); - } - escaped_output.push(str); - }); - <span class="hljs-keyword">return</span> Twig.Markup(escaped_output.join(<span class="hljs-string">""</span>)); - }</pre></div></div> - - </li> - - - <li id="section-82"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-82">¶</a> - </div> - <p>Namespace for template storage and retrieval</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.Templates = { - <span class="hljs-comment">/** - * Registered template loaders - use Twig.Templates.registerLoader to add supported loaders - * @type {Object} - */</span> - loaders: {}, - - <span class="hljs-comment">/** - * Registered template parsers - use Twig.Templates.registerParser to add supported parsers - * @type {Object} - */</span> - parsers: {}, - - <span class="hljs-comment">/** - * Cached / loaded templates - * @type {Object} - */</span> - registry: {} - }; - - <span class="hljs-comment">/** - * Is this id valid for a twig template? - * - * @param {string} id The ID to check. - * - * @throws {Twig.Error} If the ID is invalid or used. - * @return {boolean} True if the ID is valid. - */</span> - Twig.validateId = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">id</span>) </span>{ - <span class="hljs-keyword">if</span> (id === <span class="hljs-string">"prototype"</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(id + <span class="hljs-string">" is not a valid twig identifier"</span>); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Twig.cache && Twig.Templates.registry.hasOwnProperty(id)) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"There is already a template with the ID "</span> + id); - } - <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; - } - - <span class="hljs-comment">/** - * Register a template loader - * - * @example - * Twig.extend(function(Twig) { - * Twig.Templates.registerLoader('custom_loader', function(location, params, callback, error_callback) { - * // ... load the template ... - * params.data = loadedTemplateData; - * // create and return the template - * var template = new Twig.Template(params); - * if (typeof callback === 'function') { - * callback(template); - * } - * return template; - * }); - * }); - * - * @param {String} method_name The method this loader is intended for (ajax, fs) - * @param {Function} func The function to execute when loading the template - * @param {Object|undefined} scope Optional scope parameter to bind func to - * - * @throws Twig.Error - * - * @return {void} - */</span> - Twig.Templates.registerLoader = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">method_name, func, scope</span>) </span>{ - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> func !== <span class="hljs-string">'function'</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">'Unable to add loader for '</span> + method_name + <span class="hljs-string">': Invalid function reference given.'</span>); - } - <span class="hljs-keyword">if</span> (scope) { - func = func.bind(scope); - } - <span class="hljs-keyword">this</span>.loaders[method_name] = func; - }; - - <span class="hljs-comment">/** - * Remove a registered loader - * - * @param {String} method_name The method name for the loader you wish to remove - * - * @return {void} - */</span> - Twig.Templates.unRegisterLoader = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">method_name</span>) </span>{ - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.isRegisteredLoader(method_name)) { - <span class="hljs-keyword">delete</span> <span class="hljs-keyword">this</span>.loaders[method_name]; - } - }; - - <span class="hljs-comment">/** - * See if a loader is registered by its method name - * - * @param {String} method_name The name of the loader you are looking for - * - * @return {boolean} - */</span> - Twig.Templates.isRegisteredLoader = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">method_name</span>) </span>{ - <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.loaders.hasOwnProperty(method_name); - }; - - <span class="hljs-comment">/** - * Register a template parser - * - * @example - * Twig.extend(function(Twig) { - * Twig.Templates.registerParser('custom_parser', function(params) { - * // this template source can be accessed in params.data - * var template = params.data - * - * // ... custom process that modifies the template - * - * // return the parsed template - * return template; - * }); - * }); - * - * @param {String} method_name The method this parser is intended for (twig, source) - * @param {Function} func The function to execute when parsing the template - * @param {Object|undefined} scope Optional scope parameter to bind func to - * - * @throws Twig.Error - * - * @return {void} - */</span> - Twig.Templates.registerParser = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">method_name, func, scope</span>) </span>{ - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> func !== <span class="hljs-string">'function'</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">'Unable to add parser for '</span> + method_name + <span class="hljs-string">': Invalid function regerence given.'</span>); - } - - <span class="hljs-keyword">if</span> (scope) { - func = func.bind(scope); - } - - <span class="hljs-keyword">this</span>.parsers[method_name] = func; - }; - - <span class="hljs-comment">/** - * Remove a registered parser - * - * @param {String} method_name The method name for the parser you wish to remove - * - * @return {void} - */</span> - Twig.Templates.unRegisterParser = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">method_name</span>) </span>{ - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.isRegisteredParser(method_name)) { - <span class="hljs-keyword">delete</span> <span class="hljs-keyword">this</span>.parsers[method_name]; - } - }; - - <span class="hljs-comment">/** - * See if a parser is registered by its method name - * - * @param {String} method_name The name of the parser you are looking for - * - * @return {boolean} - */</span> - Twig.Templates.isRegisteredParser = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">method_name</span>) </span>{ - <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.parsers.hasOwnProperty(method_name); - }; - - <span class="hljs-comment">/** - * Save a template object to the store. - * - * @param {Twig.Template} template The twig.js template to store. - */</span> - Twig.Templates.save = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">template</span>) </span>{ - <span class="hljs-keyword">if</span> (template.id === <span class="hljs-literal">undefined</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to save template with no id"</span>); - } - Twig.Templates.registry[template.id] = template; - }; - - <span class="hljs-comment">/** - * Load a previously saved template from the store. - * - * @param {string} id The ID of the template to load. - * - * @return {Twig.Template} A twig.js template stored with the provided ID. - */</span> - Twig.Templates.load = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">id</span>) </span>{ - <span class="hljs-keyword">if</span> (!Twig.Templates.registry.hasOwnProperty(id)) { - <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; - } - <span class="hljs-keyword">return</span> Twig.Templates.registry[id]; - }; - - <span class="hljs-comment">/** - * Load a template from a remote location using AJAX and saves in with the given ID. - * - * Available parameters: - * - * async: Should the HTTP request be performed asynchronously. - * Defaults to true. - * method: What method should be used to load the template - * (fs or ajax) - * parser: What method should be used to parse the template - * (twig or source) - * precompiled: Has the template already been compiled. - * - * @param {string} location The remote URL to load as a template. - * @param {Object} params The template parameters. - * @param {function} callback A callback triggered when the template finishes loading. - * @param {function} error_callback A callback triggered if an error occurs loading the template. - * - * - */</span> - Twig.Templates.loadRemote = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">location, params, callback, error_callback</span>) </span>{ - <span class="hljs-keyword">var</span> loader;</pre></div></div> - - </li> - - - <li id="section-83"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-83">¶</a> - </div> - <p>Default to async</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (params.async === <span class="hljs-literal">undefined</span>) { - params.async = <span class="hljs-literal">true</span>; - }</pre></div></div> - - </li> - - - <li id="section-84"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-84">¶</a> - </div> - <p>Default to the URL so the template is cached.</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (params.id === <span class="hljs-literal">undefined</span>) { - params.id = location; - }</pre></div></div> - - </li> - - - <li id="section-85"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-85">¶</a> - </div> - <p>Check for existing template</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (Twig.cache && Twig.Templates.registry.hasOwnProperty(params.id)) {</pre></div></div> - - </li> - - - <li id="section-86"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-86">¶</a> - </div> - <p>A template is already saved with the given id.</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> callback === <span class="hljs-string">'function'</span>) { - callback(Twig.Templates.registry[params.id]); - }</pre></div></div> - - </li> - - - <li id="section-87"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-87">¶</a> - </div> - <p>TODO: if async, return deferred promise</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> Twig.Templates.registry[params.id]; - }</pre></div></div> - - </li> - - - <li id="section-88"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-88">¶</a> - </div> - <p>if the parser name hasn’t been set, default it to twig</p> - - </div> - - <div class="content"><div class='highlight'><pre> params.parser = params.parser || <span class="hljs-string">'twig'</span>;</pre></div></div> - - </li> - - - <li id="section-89"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-89">¶</a> - </div> - <p>Assume ‘fs’ if the loader is not defined</p> - - </div> - - <div class="content"><div class='highlight'><pre> loader = <span class="hljs-keyword">this</span>.loaders[params.method] || <span class="hljs-keyword">this</span>.loaders.fs; - <span class="hljs-keyword">return</span> loader.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>); - };</pre></div></div> - - </li> - - - <li id="section-90"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-90">¶</a> - </div> - <p>Determine object type</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">is</span>(<span class="hljs-params">type, obj</span>) </span>{ - <span class="hljs-keyword">var</span> clas = <span class="hljs-built_in">Object</span>.prototype.toString.call(obj).slice(<span class="hljs-number">8</span>, <span class="hljs-number">-1</span>); - <span class="hljs-keyword">return</span> obj !== <span class="hljs-literal">undefined</span> && obj !== <span class="hljs-literal">null</span> && clas === type; - } - - <span class="hljs-comment">/** - * Create a new twig.js template. - * - * Parameters: { - * data: The template, either pre-compiled tokens or a string template - * id: The name of this template - * blocks: Any pre-existing block from a child template - * } - * - * @param {Object} params The template parameters. - */</span> - Twig.Template = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"> params </span>) </span>{ - <span class="hljs-keyword">var</span> data = params.data, - id = params.id, - blocks = params.blocks, - macros = params.macros || {}, - base = params.base, - path = params.path, - url = params.url, - name = params.name, - method = params.method,</pre></div></div> - - </li> - - - <li id="section-91"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-91">¶</a> - </div> - <p>parser options</p> - - </div> - - <div class="content"><div class='highlight'><pre> options = params.options;</pre></div></div> - - </li> - - - <li id="section-92"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-92">¶</a> - </div> - <h1 id="what-is-stored-in-a-twig-template">What is stored in a Twig.Template</h1> -<p>The Twig Template hold several chucks of data.</p> -<pre><code>{ - id: The token ID (<span class="hljs-keyword">if</span> any) - tokens: The list <span class="hljs-keyword">of</span> tokens that makes up <span class="hljs-keyword">this</span> template. - blocks: The list <span class="hljs-keyword">of</span> block <span class="hljs-keyword">this</span> template contains. - base: The base template (<span class="hljs-keyword">if</span> any) - options: { - Compiler/parser options - - strict_variables: <span class="hljs-literal">true</span>/<span class="hljs-literal">false</span> - Should missing variable/keys emit an error message. If <span class="hljs-literal">false</span>, they <span class="hljs-keyword">default</span> to <span class="hljs-literal">null</span>. - } -} -</code></pre> - </div> - - <div class="content"><div class='highlight'><pre> - <span class="hljs-keyword">this</span>.id = id; - <span class="hljs-keyword">this</span>.method = method; - <span class="hljs-keyword">this</span>.base = base; - <span class="hljs-keyword">this</span>.path = path; - <span class="hljs-keyword">this</span>.url = url; - <span class="hljs-keyword">this</span>.name = name; - <span class="hljs-keyword">this</span>.macros = macros; - <span class="hljs-keyword">this</span>.options = options; - - <span class="hljs-keyword">this</span>.reset(blocks); - - <span class="hljs-keyword">if</span> (is(<span class="hljs-string">'String'</span>, data)) { - <span class="hljs-keyword">this</span>.tokens = Twig.prepare.apply(<span class="hljs-keyword">this</span>, [data]); - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">this</span>.tokens = data; - } - - <span class="hljs-keyword">if</span> (id !== <span class="hljs-literal">undefined</span>) { - Twig.Templates.save(<span class="hljs-keyword">this</span>); - } - }; - - Twig.Template.prototype.reset = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">blocks</span>) </span>{ - Twig.log.debug(<span class="hljs-string">"Twig.Template.reset"</span>, <span class="hljs-string">"Reseting template "</span> + <span class="hljs-keyword">this</span>.id); - <span class="hljs-keyword">this</span>.blocks = {}; - <span class="hljs-keyword">this</span>.importedBlocks = []; - <span class="hljs-keyword">this</span>.originalBlockTokens = {}; - <span class="hljs-keyword">this</span>.child = { - blocks: blocks || {} - }; - <span class="hljs-keyword">this</span>.extend = <span class="hljs-literal">null</span>; - }; - - Twig.Template.prototype.render = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">context, params</span>) </span>{ - params = params || {}; - - <span class="hljs-keyword">var</span> output, - url; - - <span class="hljs-keyword">this</span>.context = context || {};</pre></div></div> - - </li> - - - <li id="section-93"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-93">¶</a> - </div> - <p>Clear any previous state</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.reset(); - <span class="hljs-keyword">if</span> (params.blocks) { - <span class="hljs-keyword">this</span>.blocks = params.blocks; - } - <span class="hljs-keyword">if</span> (params.macros) { - <span class="hljs-keyword">this</span>.macros = params.macros; - } - - output = Twig.parse.apply(<span class="hljs-keyword">this</span>, [<span class="hljs-keyword">this</span>.tokens, <span class="hljs-keyword">this</span>.context]);</pre></div></div> - - </li> - - - <li id="section-94"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-94">¶</a> - </div> - <p>Does this template extend another</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.extend) { - <span class="hljs-keyword">var</span> ext_template;</pre></div></div> - - </li> - - - <li id="section-95"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-95">¶</a> - </div> - <p>check if the template is provided inline</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> ( <span class="hljs-keyword">this</span>.options.allowInlineIncludes ) { - ext_template = Twig.Templates.load(<span class="hljs-keyword">this</span>.extend); - <span class="hljs-keyword">if</span> ( ext_template ) { - ext_template.options = <span class="hljs-keyword">this</span>.options; - } - }</pre></div></div> - - </li> - - - <li id="section-96"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-96">¶</a> - </div> - <p>check for the template file via include</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!ext_template) { - url = Twig.path.parsePath(<span class="hljs-keyword">this</span>, <span class="hljs-keyword">this</span>.extend); - - ext_template = Twig.Templates.loadRemote(url, { - method: <span class="hljs-keyword">this</span>.getLoaderMethod(), - base: <span class="hljs-keyword">this</span>.base, - <span class="hljs-keyword">async</span>: <span class="hljs-literal">false</span>, - id: url, - options: <span class="hljs-keyword">this</span>.options - }); - } - - <span class="hljs-keyword">this</span>.parent = ext_template; - - <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.parent.render(<span class="hljs-keyword">this</span>.context, { - blocks: <span class="hljs-keyword">this</span>.blocks - }); - } - - <span class="hljs-keyword">if</span> (params.output == <span class="hljs-string">'blocks'</span>) { - <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.blocks; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (params.output == <span class="hljs-string">'macros'</span>) { - <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.macros; - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">return</span> output; - } - }; - - Twig.Template.prototype.importFile = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">file</span>) </span>{ - <span class="hljs-keyword">var</span> url, sub_template; - <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">this</span>.url && <span class="hljs-keyword">this</span>.options.allowInlineIncludes) { - file = <span class="hljs-keyword">this</span>.path ? <span class="hljs-keyword">this</span>.path + <span class="hljs-string">'/'</span> + file : file; - sub_template = Twig.Templates.load(file); - - <span class="hljs-keyword">if</span> (!sub_template) { - sub_template = Twig.Templates.loadRemote(url, { - id: file, - method: <span class="hljs-keyword">this</span>.getLoaderMethod(), - <span class="hljs-keyword">async</span>: <span class="hljs-literal">false</span>, - options: <span class="hljs-keyword">this</span>.options - }); - - <span class="hljs-keyword">if</span> (!sub_template) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to find the template "</span> + file); - } - } - - sub_template.options = <span class="hljs-keyword">this</span>.options; - - <span class="hljs-keyword">return</span> sub_template; - } - - url = Twig.path.parsePath(<span class="hljs-keyword">this</span>, file);</pre></div></div> - - </li> - - - <li id="section-97"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-97">¶</a> - </div> - <p>Load blocks from an external file</p> - - </div> - - <div class="content"><div class='highlight'><pre> sub_template = Twig.Templates.loadRemote(url, { - method: <span class="hljs-keyword">this</span>.getLoaderMethod(), - base: <span class="hljs-keyword">this</span>.base, - <span class="hljs-keyword">async</span>: <span class="hljs-literal">false</span>, - options: <span class="hljs-keyword">this</span>.options, - id: url - }); - - <span class="hljs-keyword">return</span> sub_template; - }; - - Twig.Template.prototype.importBlocks = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">file, override</span>) </span>{ - <span class="hljs-keyword">var</span> sub_template = <span class="hljs-keyword">this</span>.importFile(file), - context = <span class="hljs-keyword">this</span>.context, - that = <span class="hljs-keyword">this</span>, - key; - - override = override || <span class="hljs-literal">false</span>; - - sub_template.render(context);</pre></div></div> - - </li> - - - <li id="section-98"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-98">¶</a> - </div> - <p>Mixin blocks</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.forEach(<span class="hljs-built_in">Object</span>.keys(sub_template.blocks), <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{ - <span class="hljs-keyword">if</span> (override || that.blocks[key] === <span class="hljs-literal">undefined</span>) { - that.blocks[key] = sub_template.blocks[key]; - that.importedBlocks.push(key); - } - }); - }; - - Twig.Template.prototype.importMacros = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">file</span>) </span>{ - <span class="hljs-keyword">var</span> url = Twig.path.parsePath(<span class="hljs-keyword">this</span>, file);</pre></div></div> - - </li> - - - <li id="section-99"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-99">¶</a> - </div> - <p>load remote template</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> remoteTemplate = Twig.Templates.loadRemote(url, { - method: <span class="hljs-keyword">this</span>.getLoaderMethod(), - <span class="hljs-keyword">async</span>: <span class="hljs-literal">false</span>, - id: url - }); - - <span class="hljs-keyword">return</span> remoteTemplate; - }; - - Twig.Template.prototype.getLoaderMethod = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.path) { - <span class="hljs-keyword">return</span> <span class="hljs-string">'fs'</span>; - } - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.url) { - <span class="hljs-keyword">return</span> <span class="hljs-string">'ajax'</span>; - } - <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.method || <span class="hljs-string">'fs'</span>; - }; - - Twig.Template.prototype.compile = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-100"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-100">¶</a> - </div> - <p>compile the template into raw JS</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> Twig.compiler.compile(<span class="hljs-keyword">this</span>, options); - }; - - <span class="hljs-comment">/** - * Create safe output - * - * @param {string} Content safe to output - * - * @return {String} Content wrapped into a String - */</span> - - Twig.Markup = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">content, strategy</span>) </span>{ - <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> strategy == <span class="hljs-string">'undefined'</span>) { - strategy = <span class="hljs-literal">true</span>; - } - - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> content === <span class="hljs-string">'string'</span> && content.length > <span class="hljs-number">0</span>) { - content = <span class="hljs-keyword">new</span> <span class="hljs-built_in">String</span>(content); - content.twig_markup = strategy; - } - <span class="hljs-keyword">return</span> content; - }; - - <span class="hljs-keyword">return</span> Twig; - -}) (Twig || { }); - -(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">Twig</span>) </span>{ -<span class="hljs-meta"> - 'use strict'</span>; - - Twig.Templates.registerLoader(<span class="hljs-string">'ajax'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">location, params, callback, error_callback</span>) </span>{ - <span class="hljs-keyword">var</span> template, - xmlhttp, - precompiled = params.precompiled, - parser = <span class="hljs-keyword">this</span>.parsers[params.parser] || <span class="hljs-keyword">this</span>.parser.twig; - - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> XMLHttpRequest === <span class="hljs-string">"undefined"</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">'Unsupported platform: Unable to do ajax requests '</span> + - <span class="hljs-string">'because there is no "XMLHTTPRequest" implementation'</span>); - } - - xmlhttp = <span class="hljs-keyword">new</span> XMLHttpRequest(); - xmlhttp.onreadystatechange = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ - <span class="hljs-keyword">var</span> data = <span class="hljs-literal">null</span>; - - <span class="hljs-keyword">if</span>(xmlhttp.readyState === <span class="hljs-number">4</span>) { - <span class="hljs-keyword">if</span> (xmlhttp.status === <span class="hljs-number">200</span> || (<span class="hljs-built_in">window</span>.cordova && xmlhttp.status == <span class="hljs-number">0</span>)) { - Twig.log.debug(<span class="hljs-string">"Got template "</span>, xmlhttp.responseText); - - <span class="hljs-keyword">if</span> (precompiled === <span class="hljs-literal">true</span>) { - data = <span class="hljs-built_in">JSON</span>.parse(xmlhttp.responseText); - } <span class="hljs-keyword">else</span> { - data = xmlhttp.responseText; - } - - params.url = location; - params.data = data; - - template = parser.call(<span class="hljs-keyword">this</span>, params); - - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> callback === <span class="hljs-string">'function'</span>) { - callback(template); - } - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> error_callback === <span class="hljs-string">'function'</span>) { - error_callback(xmlhttp); - } - } - } - }; - xmlhttp.open(<span class="hljs-string">"GET"</span>, location, !!params.async); - xmlhttp.send(); - - <span class="hljs-keyword">if</span> (params.async) {</pre></div></div> - - </li> - - - <li id="section-101"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-101">¶</a> - </div> - <p>TODO: return deferred promise</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">return</span> template; - } - }); - -}(Twig));(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">Twig</span>) </span>{ -<span class="hljs-meta"> 'use strict'</span>; - - <span class="hljs-keyword">var</span> fs, path; - - <span class="hljs-keyword">try</span> {</pre></div></div> - - </li> - - - <li id="section-102"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-102">¶</a> - </div> - <p>require lib dependencies at runtime</p> - - </div> - - <div class="content"><div class='highlight'><pre> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>); - path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>); - } <span class="hljs-keyword">catch</span> (e) {</pre></div></div> - - </li> - - - <li id="section-103"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-103">¶</a> - </div> - <p>NOTE: this is in a try/catch to avoid errors cross platform</p> - - </div> - - <div class="content"><div class='highlight'><pre> } - - Twig.Templates.registerLoader(<span class="hljs-string">'fs'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">location, params, callback, error_callback</span>) </span>{ - <span class="hljs-keyword">var</span> template, - data = <span class="hljs-literal">null</span>, - precompiled = params.precompiled, - parser = <span class="hljs-keyword">this</span>.parsers[params.parser] || <span class="hljs-keyword">this</span>.parser.twig; - - <span class="hljs-keyword">if</span> (!fs || !path) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">'Unsupported platform: Unable to load from file '</span> + - <span class="hljs-string">'because there is no "fs" or "path" implementation'</span>); - } - - <span class="hljs-keyword">var</span> loadTemplateFn = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">err, data</span>) </span>{ - <span class="hljs-keyword">if</span> (err) { - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> error_callback === <span class="hljs-string">'function'</span>) { - error_callback(err); - } - <span class="hljs-keyword">return</span>; - } - - <span class="hljs-keyword">if</span> (precompiled === <span class="hljs-literal">true</span>) { - data = <span class="hljs-built_in">JSON</span>.parse(data); - } - - params.data = data; - params.path = params.path || location;</pre></div></div> - - </li> - - - <li id="section-104"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-104">¶</a> - </div> - <p>template is in data</p> - - </div> - - <div class="content"><div class='highlight'><pre> template = parser.call(<span class="hljs-keyword">this</span>, params); - - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> callback === <span class="hljs-string">'function'</span>) { - callback(template); - } - }; - params.path = params.path || location; - - <span class="hljs-keyword">if</span> (params.async) { - fs.stat(params.path, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">err, stats</span>) </span>{ - <span class="hljs-keyword">if</span> (err || !stats.isFile()) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">'Unable to find template file '</span> + location); - } - fs.readFile(params.path, <span class="hljs-string">'utf8'</span>, loadTemplateFn); - });</pre></div></div> - - </li> - - - <li id="section-105"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-105">¶</a> - </div> - <p>TODO: return deferred promise</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">if</span> (!fs.statSync(params.path).isFile()) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">'Unable to find template file '</span> + location); - } - data = fs.readFileSync(params.path, <span class="hljs-string">'utf8'</span>); - loadTemplateFn(<span class="hljs-literal">undefined</span>, data); - <span class="hljs-keyword">return</span> template - } - }); - -}(Twig));(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">Twig</span>)</span>{ -<span class="hljs-meta"> 'use strict'</span>; - - Twig.Templates.registerParser(<span class="hljs-string">'source'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">params</span>) </span>{ - <span class="hljs-keyword">return</span> params.data || <span class="hljs-string">''</span>; - }); -})(Twig); -(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">Twig</span>)</span>{ -<span class="hljs-meta"> 'use strict'</span>; - - Twig.Templates.registerParser(<span class="hljs-string">'twig'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">params</span>) </span>{ - <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Twig.Template(params); - }); -})(Twig);</pre></div></div> - - </li> - - - <li id="section-106"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-106">¶</a> - </div> - <p>The following methods are from MDN and are available under a -<a href="http://www.opensource.org/licenses/mit-license.php">MIT License</a> or are -<a href="https://developer.mozilla.org/Project:Copyrights">Public Domain</a>.</p> -<p>See:</p> -<ul> -<li><a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys">Object.keys - MDN</a></li> -</ul> - - </div> - - </li> - - - <li id="section-107"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-107">¶</a> - </div> - <h2 id="twig-fills-js">twig.fills.js</h2> -<p>This file contains fills for backwards compatability.</p> - - </div> - - <div class="content"><div class='highlight'><pre>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ -<span class="hljs-meta"> "use strict"</span>;</pre></div></div> - - </li> - - - <li id="section-108"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-108">¶</a> - </div> - <p>Handle methods that don’t yet exist in every browser</p> - - </div> - - <div class="content"><div class='highlight'><pre> - <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">String</span>.prototype.trim) { - <span class="hljs-built_in">String</span>.prototype.trim = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ - <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.replace(<span class="hljs-regexp">/^\s+|\s+$/g</span>,<span class="hljs-string">''</span>); - } - }; - - <span class="hljs-keyword">if</span>(!<span class="hljs-built_in">Object</span>.keys) <span class="hljs-built_in">Object</span>.keys = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">o</span>)</span>{ - <span class="hljs-keyword">if</span> (o !== <span class="hljs-built_in">Object</span>(o)) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">TypeError</span>(<span class="hljs-string">'Object.keys called on non-object'</span>); - } - <span class="hljs-keyword">var</span> ret = [], p; - <span class="hljs-keyword">for</span> (p <span class="hljs-keyword">in</span> o) <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Object</span>.prototype.hasOwnProperty.call(o, p)) ret.push(p); - <span class="hljs-keyword">return</span> ret; - } - -})();</pre></div></div> - - </li> - - - <li id="section-109"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-109">¶</a> - </div> - <h2 id="twig-lib-js">twig.lib.js</h2> -<p>This file contains 3rd party libraries used within twig.</p> -<p>Copies of the licenses for the code included here can be found in the -LICENSES.md file.</p> - - </div> - - <div class="content"><div class='highlight'><pre> -<span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">Twig</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-110"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-110">¶</a> - </div> - <p>Namespace for libraries</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.lib = { }; - - <span class="hljs-comment">/** - sprintf() for JavaScript 1.0.3 - https://github.com/alexei/sprintf.js - **/</span> - <span class="hljs-keyword">var</span> sprintfLib = (<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ - <span class="hljs-keyword">var</span> re = { - not_string: <span class="hljs-regexp">/[^s]/</span>, - number: <span class="hljs-regexp">/[diefg]/</span>, - json: <span class="hljs-regexp">/[j]/</span>, - not_json: <span class="hljs-regexp">/[^j]/</span>, - text: <span class="hljs-regexp">/^[^\x25]+/</span>, - modulo: <span class="hljs-regexp">/^\x25{2}/</span>, - placeholder: <span class="hljs-regexp">/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijosuxX])/</span>, - key: <span class="hljs-regexp">/^([a-z_][a-z_\d]*)/i</span>, - key_access: <span class="hljs-regexp">/^\.([a-z_][a-z_\d]*)/i</span>, - index_access: <span class="hljs-regexp">/^\[(\d+)\]/</span>, - sign: <span class="hljs-regexp">/^[\+\-]/</span> - } - - <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sprintf</span>(<span class="hljs-params"></span>) </span>{ - <span class="hljs-keyword">var</span> key = <span class="hljs-built_in">arguments</span>[<span class="hljs-number">0</span>], cache = sprintf.cache - <span class="hljs-keyword">if</span> (!(cache[key] && cache.hasOwnProperty(key))) { - cache[key] = sprintf.parse(key) - } - <span class="hljs-keyword">return</span> sprintf.format.call(<span class="hljs-literal">null</span>, cache[key], <span class="hljs-built_in">arguments</span>) - } - - sprintf.format = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">parse_tree, argv</span>) </span>{ - <span class="hljs-keyword">var</span> cursor = <span class="hljs-number">1</span>, tree_length = parse_tree.length, node_type = <span class="hljs-string">""</span>, arg, output = [], i, k, match, pad, pad_character, pad_length, is_positive = <span class="hljs-literal">true</span>, sign = <span class="hljs-string">""</span> - <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i < tree_length; i++) { - node_type = get_type(parse_tree[i]) - <span class="hljs-keyword">if</span> (node_type === <span class="hljs-string">"string"</span>) { - output[output.length] = parse_tree[i] - } - <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (node_type === <span class="hljs-string">"array"</span>) { - match = parse_tree[i] <span class="hljs-comment">// convenience purposes only</span> - <span class="hljs-keyword">if</span> (match[<span class="hljs-number">2</span>]) { <span class="hljs-comment">// keyword argument</span> - arg = argv[cursor] - <span class="hljs-keyword">for</span> (k = <span class="hljs-number">0</span>; k < match[<span class="hljs-number">2</span>].length; k++) { - <span class="hljs-keyword">if</span> (!arg.hasOwnProperty(match[<span class="hljs-number">2</span>][k])) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(sprintf(<span class="hljs-string">"[sprintf] property '%s' does not exist"</span>, match[<span class="hljs-number">2</span>][k])) - } - arg = arg[match[<span class="hljs-number">2</span>][k]] - } - } - <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">1</span>]) { <span class="hljs-comment">// positional argument (explicit)</span> - arg = argv[match[<span class="hljs-number">1</span>]] - } - <span class="hljs-keyword">else</span> { <span class="hljs-comment">// positional argument (implicit)</span> - arg = argv[cursor++] - } - - <span class="hljs-keyword">if</span> (get_type(arg) == <span class="hljs-string">"function"</span>) { - arg = arg() - } - - <span class="hljs-keyword">if</span> (re.not_string.test(match[<span class="hljs-number">8</span>]) && re.not_json.test(match[<span class="hljs-number">8</span>]) && (get_type(arg) != <span class="hljs-string">"number"</span> && <span class="hljs-built_in">isNaN</span>(arg))) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">TypeError</span>(sprintf(<span class="hljs-string">"[sprintf] expecting number but found %s"</span>, get_type(arg))) - } - - <span class="hljs-keyword">if</span> (re.number.test(match[<span class="hljs-number">8</span>])) { - is_positive = arg >= <span class="hljs-number">0</span> - } - - <span class="hljs-keyword">switch</span> (match[<span class="hljs-number">8</span>]) { - <span class="hljs-keyword">case</span> <span class="hljs-string">"b"</span>: - arg = arg.toString(<span class="hljs-number">2</span>) - <span class="hljs-keyword">break</span> - <span class="hljs-keyword">case</span> <span class="hljs-string">"c"</span>: - arg = <span class="hljs-built_in">String</span>.fromCharCode(arg) - <span class="hljs-keyword">break</span> - <span class="hljs-keyword">case</span> <span class="hljs-string">"d"</span>: - <span class="hljs-keyword">case</span> <span class="hljs-string">"i"</span>: - arg = <span class="hljs-built_in">parseInt</span>(arg, <span class="hljs-number">10</span>) - <span class="hljs-keyword">break</span> - <span class="hljs-keyword">case</span> <span class="hljs-string">"j"</span>: - arg = <span class="hljs-built_in">JSON</span>.stringify(arg, <span class="hljs-literal">null</span>, match[<span class="hljs-number">6</span>] ? <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">6</span>]) : <span class="hljs-number">0</span>) - <span class="hljs-keyword">break</span> - <span class="hljs-keyword">case</span> <span class="hljs-string">"e"</span>: - arg = match[<span class="hljs-number">7</span>] ? arg.toExponential(match[<span class="hljs-number">7</span>]) : arg.toExponential() - <span class="hljs-keyword">break</span> - <span class="hljs-keyword">case</span> <span class="hljs-string">"f"</span>: - arg = match[<span class="hljs-number">7</span>] ? <span class="hljs-built_in">parseFloat</span>(arg).toFixed(match[<span class="hljs-number">7</span>]) : <span class="hljs-built_in">parseFloat</span>(arg) - <span class="hljs-keyword">break</span> - <span class="hljs-keyword">case</span> <span class="hljs-string">"g"</span>: - arg = match[<span class="hljs-number">7</span>] ? <span class="hljs-built_in">parseFloat</span>(arg).toPrecision(match[<span class="hljs-number">7</span>]) : <span class="hljs-built_in">parseFloat</span>(arg) - <span class="hljs-keyword">break</span> - <span class="hljs-keyword">case</span> <span class="hljs-string">"o"</span>: - arg = arg.toString(<span class="hljs-number">8</span>) - <span class="hljs-keyword">break</span> - <span class="hljs-keyword">case</span> <span class="hljs-string">"s"</span>: - arg = ((arg = <span class="hljs-built_in">String</span>(arg)) && match[<span class="hljs-number">7</span>] ? arg.substring(<span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>]) : arg) - <span class="hljs-keyword">break</span> - <span class="hljs-keyword">case</span> <span class="hljs-string">"u"</span>: - arg = arg >>> <span class="hljs-number">0</span> - <span class="hljs-keyword">break</span> - <span class="hljs-keyword">case</span> <span class="hljs-string">"x"</span>: - arg = arg.toString(<span class="hljs-number">16</span>) - <span class="hljs-keyword">break</span> - <span class="hljs-keyword">case</span> <span class="hljs-string">"X"</span>: - arg = arg.toString(<span class="hljs-number">16</span>).toUpperCase() - <span class="hljs-keyword">break</span> - } - <span class="hljs-keyword">if</span> (re.json.test(match[<span class="hljs-number">8</span>])) { - output[output.length] = arg - } - <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">if</span> (re.number.test(match[<span class="hljs-number">8</span>]) && (!is_positive || match[<span class="hljs-number">3</span>])) { - sign = is_positive ? <span class="hljs-string">"+"</span> : <span class="hljs-string">"-"</span> - arg = arg.toString().replace(re.sign, <span class="hljs-string">""</span>) - } - <span class="hljs-keyword">else</span> { - sign = <span class="hljs-string">""</span> - } - pad_character = match[<span class="hljs-number">4</span>] ? match[<span class="hljs-number">4</span>] === <span class="hljs-string">"0"</span> ? <span class="hljs-string">"0"</span> : match[<span class="hljs-number">4</span>].charAt(<span class="hljs-number">1</span>) : <span class="hljs-string">" "</span> - pad_length = match[<span class="hljs-number">6</span>] - (sign + arg).length - pad = match[<span class="hljs-number">6</span>] ? (pad_length > <span class="hljs-number">0</span> ? str_repeat(pad_character, pad_length) : <span class="hljs-string">""</span>) : <span class="hljs-string">""</span> - output[output.length] = match[<span class="hljs-number">5</span>] ? sign + arg + pad : (pad_character === <span class="hljs-string">"0"</span> ? sign + pad + arg : pad + sign + arg) - } - } - } - <span class="hljs-keyword">return</span> output.join(<span class="hljs-string">""</span>) - } - - sprintf.cache = {} - - sprintf.parse = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">fmt</span>) </span>{ - <span class="hljs-keyword">var</span> _fmt = fmt, match = [], parse_tree = [], arg_names = <span class="hljs-number">0</span> - <span class="hljs-keyword">while</span> (_fmt) { - <span class="hljs-keyword">if</span> ((match = re.text.exec(_fmt)) !== <span class="hljs-literal">null</span>) { - parse_tree[parse_tree.length] = match[<span class="hljs-number">0</span>] - } - <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ((match = re.modulo.exec(_fmt)) !== <span class="hljs-literal">null</span>) { - parse_tree[parse_tree.length] = <span class="hljs-string">"%"</span> - } - <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ((match = re.placeholder.exec(_fmt)) !== <span class="hljs-literal">null</span>) { - <span class="hljs-keyword">if</span> (match[<span class="hljs-number">2</span>]) { - arg_names |= <span class="hljs-number">1</span> - <span class="hljs-keyword">var</span> field_list = [], replacement_field = match[<span class="hljs-number">2</span>], field_match = [] - <span class="hljs-keyword">if</span> ((field_match = re.key.exec(replacement_field)) !== <span class="hljs-literal">null</span>) { - field_list[field_list.length] = field_match[<span class="hljs-number">1</span>] - <span class="hljs-keyword">while</span> ((replacement_field = replacement_field.substring(field_match[<span class="hljs-number">0</span>].length)) !== <span class="hljs-string">""</span>) { - <span class="hljs-keyword">if</span> ((field_match = re.key_access.exec(replacement_field)) !== <span class="hljs-literal">null</span>) { - field_list[field_list.length] = field_match[<span class="hljs-number">1</span>] - } - <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ((field_match = re.index_access.exec(replacement_field)) !== <span class="hljs-literal">null</span>) { - field_list[field_list.length] = field_match[<span class="hljs-number">1</span>] - } - <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">SyntaxError</span>(<span class="hljs-string">"[sprintf] failed to parse named argument key"</span>) - } - } - } - <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">SyntaxError</span>(<span class="hljs-string">"[sprintf] failed to parse named argument key"</span>) - } - match[<span class="hljs-number">2</span>] = field_list - } - <span class="hljs-keyword">else</span> { - arg_names |= <span class="hljs-number">2</span> - } - <span class="hljs-keyword">if</span> (arg_names === <span class="hljs-number">3</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"[sprintf] mixing positional and named placeholders is not (yet) supported"</span>) - } - parse_tree[parse_tree.length] = match - } - <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">SyntaxError</span>(<span class="hljs-string">"[sprintf] unexpected placeholder"</span>) - } - _fmt = _fmt.substring(match[<span class="hljs-number">0</span>].length) - } - <span class="hljs-keyword">return</span> parse_tree - } - - <span class="hljs-keyword">var</span> vsprintf = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">fmt, argv, _argv</span>) </span>{ - _argv = (argv || []).slice(<span class="hljs-number">0</span>) - _argv.splice(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, fmt) - <span class="hljs-keyword">return</span> sprintf.apply(<span class="hljs-literal">null</span>, _argv) - } - - <span class="hljs-comment">/** - * helpers - */</span> - <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">get_type</span>(<span class="hljs-params">variable</span>) </span>{ - <span class="hljs-keyword">return</span> <span class="hljs-built_in">Object</span>.prototype.toString.call(variable).slice(<span class="hljs-number">8</span>, <span class="hljs-number">-1</span>).toLowerCase() - } - - <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">str_repeat</span>(<span class="hljs-params">input, multiplier</span>) </span>{ - <span class="hljs-keyword">return</span> <span class="hljs-built_in">Array</span>(multiplier + <span class="hljs-number">1</span>).join(input) - } - - <span class="hljs-comment">/** - * export - */</span> - <span class="hljs-keyword">return</span> { - sprintf: sprintf, - vsprintf: vsprintf - } - })(); - - <span class="hljs-keyword">var</span> sprintf = sprintfLib.sprintf; - <span class="hljs-keyword">var</span> vsprintf = sprintfLib.vsprintf;</pre></div></div> - - </li> - - - <li id="section-111"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-111">¶</a> - </div> - <p>Expose to Twig</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.lib.sprintf = sprintf; - Twig.lib.vsprintf = vsprintf; - - - <span class="hljs-comment">/** - * jPaq - A fully customizable JavaScript/JScript library - * http://jpaq.org/ - * - * Copyright (c) 2011 Christopher West - * Licensed under the MIT license. - * http://jpaq.org/license/ - * - * Version: 1.0.6.0000W - * Revised: April 6, 2011 - */</span> - ; (<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ - <span class="hljs-keyword">var</span> shortDays = <span class="hljs-string">"Sun,Mon,Tue,Wed,Thu,Fri,Sat"</span>.split(<span class="hljs-string">","</span>); - <span class="hljs-keyword">var</span> fullDays = <span class="hljs-string">"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday"</span>.split(<span class="hljs-string">","</span>); - <span class="hljs-keyword">var</span> shortMonths = <span class="hljs-string">"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec"</span>.split(<span class="hljs-string">","</span>); - <span class="hljs-keyword">var</span> fullMonths = <span class="hljs-string">"January,February,March,April,May,June,July,August,September,October,November,December"</span>.split(<span class="hljs-string">","</span>); - <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getOrdinalFor</span>(<span class="hljs-params">intNum</span>) </span>{ - <span class="hljs-keyword">return</span> (((intNum = <span class="hljs-built_in">Math</span>.abs(intNum) % <span class="hljs-number">100</span>) % <span class="hljs-number">10</span> == <span class="hljs-number">1</span> && intNum != <span class="hljs-number">11</span>) ? <span class="hljs-string">"st"</span> - : (intNum % <span class="hljs-number">10</span> == <span class="hljs-number">2</span> && intNum != <span class="hljs-number">12</span>) ? <span class="hljs-string">"nd"</span> : (intNum % <span class="hljs-number">10</span> == <span class="hljs-number">3</span> - && intNum != <span class="hljs-number">13</span>) ? <span class="hljs-string">"rd"</span> : <span class="hljs-string">"th"</span>); - } - <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getISO8601Year</span>(<span class="hljs-params">aDate</span>) </span>{ - <span class="hljs-keyword">var</span> d = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(aDate.getFullYear() + <span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">4</span>); - <span class="hljs-keyword">if</span>((d - aDate) / <span class="hljs-number">86400000</span> < <span class="hljs-number">7</span> && (aDate.getDay() + <span class="hljs-number">6</span>) % <span class="hljs-number">7</span> < (d.getDay() + <span class="hljs-number">6</span>) % <span class="hljs-number">7</span>) - <span class="hljs-keyword">return</span> d.getFullYear(); - <span class="hljs-keyword">if</span>(aDate.getMonth() > <span class="hljs-number">0</span> || aDate.getDate() >= <span class="hljs-number">4</span>) - <span class="hljs-keyword">return</span> aDate.getFullYear(); - <span class="hljs-keyword">return</span> aDate.getFullYear() - (((aDate.getDay() + <span class="hljs-number">6</span>) % <span class="hljs-number">7</span> - aDate.getDate() > <span class="hljs-number">2</span>) ? <span class="hljs-number">1</span> : <span class="hljs-number">0</span>); - } - <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getISO8601Week</span>(<span class="hljs-params">aDate</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-112"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-112">¶</a> - </div> - <p>Get a day during the first week of the year.</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> d = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(getISO8601Year(aDate), <span class="hljs-number">0</span>, <span class="hljs-number">4</span>);</pre></div></div> - - </li> - - - <li id="section-113"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-113">¶</a> - </div> - <p>Get the first monday of the year.</p> - - </div> - - <div class="content"><div class='highlight'><pre> d.setDate(d.getDate() - (d.getDay() + <span class="hljs-number">6</span>) % <span class="hljs-number">7</span>); - <span class="hljs-keyword">return</span> <span class="hljs-built_in">parseInt</span>((aDate - d) / <span class="hljs-number">604800000</span>) + <span class="hljs-number">1</span>; - } - Twig.lib.formatDate = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">date, format</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-114"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-114">¶</a> - </div> - <p>/ <summary> -/ Gets a string for this date, formatted according to the given format -/ string. -/ </summary> -/ <param name="format" type="String"> -/ The format of the output date string. The format string works in a -/ nearly identical way to the PHP date function which is highlighted here: -/ <a href="http://php.net/manual/en/function.date.php">http://php.net/manual/en/function.date.php</a>. -/ The only difference is the fact that “u” signifies milliseconds -/ instead of microseconds. The following characters are recognized in -/ the format parameter string: -/ d - Day of the month, 2 digits with leading zeros -/ D - A textual representation of a day, three letters -/ j - Day of the month without leading zeros -/ l (lowercase ‘L’) - A full textual representation of the day of the week -/ N - ISO-8601 numeric representation of the day of the week (starting from 1) -/ S - English ordinal suffix for the day of the month, 2 characters st, -/ nd, rd or th. Works well with j. -/ w - Numeric representation of the day of the week (starting from 0) -/ z - The day of the year (starting from 0) -/ W - ISO-8601 week number of year, weeks starting on Monday -/ F - A full textual representation of a month, such as January or March -/ m - Numeric representation of a month, with leading zeros -/ M - A short textual representation of a month, three letters -/ n - Numeric representation of a month, without leading zeros -/ t - Number of days in the given month -/ L - Whether it’s a leap year -/ o - ISO-8601 year number. This has the same value as Y, except that if -/ the ISO week number (W) belongs to the previous or next year, that -/ year is used instead. -/ Y - A full numeric representation of a year, 4 digits -/ y - A two digit representation of a year -/ a - Lowercase Ante meridiem and Post meridiem -/ A - Uppercase Ante meridiem and Post meridiem -/ B - Swatch Internet time -/ g - 12-hour format of an hour without leading zeros -/ G - 24-hour format of an hour without leading zeros -/ h - 12-hour format of an hour with leading zeros -/ H - 24-hour format of an hour with leading zeros -/ i - Minutes with leading zeros -/ s - Seconds, with leading zeros -/ u - Milliseconds -/ U - Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) -/ </param> -/ <returns type="String"> -/ Returns the string for this date, formatted according to the given -/ format string. -/ </returns> -If the format was not passed, use the default toString method.</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> format !== <span class="hljs-string">"string"</span> || <span class="hljs-regexp">/^\s*$/</span>.test(format)) - <span class="hljs-keyword">return</span> date + <span class="hljs-string">""</span>; - <span class="hljs-keyword">var</span> jan1st = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(date.getFullYear(), <span class="hljs-number">0</span>, <span class="hljs-number">1</span>); - <span class="hljs-keyword">var</span> me = date; - <span class="hljs-keyword">return</span> format.replace(<span class="hljs-regexp">/[dDjlNSwzWFmMntLoYyaABgGhHisuU]/g</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">option</span>) </span>{ - <span class="hljs-keyword">switch</span>(option) {</pre></div></div> - - </li> - - - <li id="section-115"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-115">¶</a> - </div> - <p>Day of the month, 2 digits with leading zeros</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"d"</span>: <span class="hljs-keyword">return</span> (<span class="hljs-string">"0"</span> + me.getDate()).replace(<span class="hljs-regexp">/^.+(..)$/</span>, <span class="hljs-string">"$1"</span>);</pre></div></div> - - </li> - - - <li id="section-116"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-116">¶</a> - </div> - <p>A textual representation of a day, three letters</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"D"</span>: <span class="hljs-keyword">return</span> shortDays[me.getDay()];</pre></div></div> - - </li> - - - <li id="section-117"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-117">¶</a> - </div> - <p>Day of the month without leading zeros</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"j"</span>: <span class="hljs-keyword">return</span> me.getDate();</pre></div></div> - - </li> - - - <li id="section-118"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-118">¶</a> - </div> - <p>A full textual representation of the day of the week</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"l"</span>: <span class="hljs-keyword">return</span> fullDays[me.getDay()];</pre></div></div> - - </li> - - - <li id="section-119"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-119">¶</a> - </div> - <p>ISO-8601 numeric representation of the day of the week</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"N"</span>: <span class="hljs-keyword">return</span> (me.getDay() + <span class="hljs-number">6</span>) % <span class="hljs-number">7</span> + <span class="hljs-number">1</span>;</pre></div></div> - - </li> - - - <li id="section-120"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-120">¶</a> - </div> - <p>English ordinal suffix for the day of the month, 2 characters</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"S"</span>: <span class="hljs-keyword">return</span> getOrdinalFor(me.getDate());</pre></div></div> - - </li> - - - <li id="section-121"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-121">¶</a> - </div> - <p>Numeric representation of the day of the week</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"w"</span>: <span class="hljs-keyword">return</span> me.getDay();</pre></div></div> - - </li> - - - <li id="section-122"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-122">¶</a> - </div> - <p>The day of the year (starting from 0)</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"z"</span>: <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.ceil((jan1st - me) / <span class="hljs-number">86400000</span>);</pre></div></div> - - </li> - - - <li id="section-123"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-123">¶</a> - </div> - <p>ISO-8601 week number of year, weeks starting on Monday</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"W"</span>: <span class="hljs-keyword">return</span> (<span class="hljs-string">"0"</span> + getISO8601Week(me)).replace(<span class="hljs-regexp">/^.(..)$/</span>, <span class="hljs-string">"$1"</span>);</pre></div></div> - - </li> - - - <li id="section-124"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-124">¶</a> - </div> - <p>A full textual representation of a month, such as January or March</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"F"</span>: <span class="hljs-keyword">return</span> fullMonths[me.getMonth()];</pre></div></div> - - </li> - - - <li id="section-125"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-125">¶</a> - </div> - <p>Numeric representation of a month, with leading zeros</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"m"</span>: <span class="hljs-keyword">return</span> (<span class="hljs-string">"0"</span> + (me.getMonth() + <span class="hljs-number">1</span>)).replace(<span class="hljs-regexp">/^.+(..)$/</span>, <span class="hljs-string">"$1"</span>);</pre></div></div> - - </li> - - - <li id="section-126"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-126">¶</a> - </div> - <p>A short textual representation of a month, three letters</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"M"</span>: <span class="hljs-keyword">return</span> shortMonths[me.getMonth()];</pre></div></div> - - </li> - - - <li id="section-127"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-127">¶</a> - </div> - <p>Numeric representation of a month, without leading zeros</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"n"</span>: <span class="hljs-keyword">return</span> me.getMonth() + <span class="hljs-number">1</span>;</pre></div></div> - - </li> - - - <li id="section-128"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-128">¶</a> - </div> - <p>Number of days in the given month</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"t"</span>: <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(me.getFullYear(), me.getMonth() + <span class="hljs-number">1</span>, <span class="hljs-number">-1</span>).getDate();</pre></div></div> - - </li> - - - <li id="section-129"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-129">¶</a> - </div> - <p>Whether it’s a leap year</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"L"</span>: <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(me.getFullYear(), <span class="hljs-number">1</span>, <span class="hljs-number">29</span>).getDate() == <span class="hljs-number">29</span> ? <span class="hljs-number">1</span> : <span class="hljs-number">0</span>;</pre></div></div> - - </li> - - - <li id="section-130"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-130">¶</a> - </div> - <p>ISO-8601 year number. This has the same value as Y, except that if the -ISO week number (W) belongs to the previous or next year, that year is -used instead.</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"o"</span>: <span class="hljs-keyword">return</span> getISO8601Year(me);</pre></div></div> - - </li> - - - <li id="section-131"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-131">¶</a> - </div> - <p>A full numeric representation of a year, 4 digits</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"Y"</span>: <span class="hljs-keyword">return</span> me.getFullYear();</pre></div></div> - - </li> - - - <li id="section-132"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-132">¶</a> - </div> - <p>A two digit representation of a year</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"y"</span>: <span class="hljs-keyword">return</span> (me.getFullYear() + <span class="hljs-string">""</span>).replace(<span class="hljs-regexp">/^.+(..)$/</span>, <span class="hljs-string">"$1"</span>);</pre></div></div> - - </li> - - - <li id="section-133"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-133">¶</a> - </div> - <p>Lowercase Ante meridiem and Post meridiem</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"a"</span>: <span class="hljs-keyword">return</span> me.getHours() < <span class="hljs-number">12</span> ? <span class="hljs-string">"am"</span> : <span class="hljs-string">"pm"</span>;</pre></div></div> - - </li> - - - <li id="section-134"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-134">¶</a> - </div> - <p>Uppercase Ante meridiem and Post meridiem</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"A"</span>: <span class="hljs-keyword">return</span> me.getHours() < <span class="hljs-number">12</span> ? <span class="hljs-string">"AM"</span> : <span class="hljs-string">"PM"</span>;</pre></div></div> - - </li> - - - <li id="section-135"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-135">¶</a> - </div> - <p>Swatch Internet time</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"B"</span>: <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.floor((((me.getUTCHours() + <span class="hljs-number">1</span>) % <span class="hljs-number">24</span>) + me.getUTCMinutes() / <span class="hljs-number">60</span> + me.getUTCSeconds() / <span class="hljs-number">3600</span>) * <span class="hljs-number">1000</span> / <span class="hljs-number">24</span>);</pre></div></div> - - </li> - - - <li id="section-136"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-136">¶</a> - </div> - <p>12-hour format of an hour without leading zeros</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"g"</span>: <span class="hljs-keyword">return</span> me.getHours() % <span class="hljs-number">12</span> != <span class="hljs-number">0</span> ? me.getHours() % <span class="hljs-number">12</span> : <span class="hljs-number">12</span>;</pre></div></div> - - </li> - - - <li id="section-137"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-137">¶</a> - </div> - <p>24-hour format of an hour without leading zeros</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"G"</span>: <span class="hljs-keyword">return</span> me.getHours();</pre></div></div> - - </li> - - - <li id="section-138"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-138">¶</a> - </div> - <p>12-hour format of an hour with leading zeros</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"h"</span>: <span class="hljs-keyword">return</span> (<span class="hljs-string">"0"</span> + (me.getHours() % <span class="hljs-number">12</span> != <span class="hljs-number">0</span> ? me.getHours() % <span class="hljs-number">12</span> : <span class="hljs-number">12</span>)).replace(<span class="hljs-regexp">/^.+(..)$/</span>, <span class="hljs-string">"$1"</span>);</pre></div></div> - - </li> - - - <li id="section-139"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-139">¶</a> - </div> - <p>24-hour format of an hour with leading zeros</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"H"</span>: <span class="hljs-keyword">return</span> (<span class="hljs-string">"0"</span> + me.getHours()).replace(<span class="hljs-regexp">/^.+(..)$/</span>, <span class="hljs-string">"$1"</span>);</pre></div></div> - - </li> - - - <li id="section-140"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-140">¶</a> - </div> - <p>Minutes with leading zeros</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"i"</span>: <span class="hljs-keyword">return</span> (<span class="hljs-string">"0"</span> + me.getMinutes()).replace(<span class="hljs-regexp">/^.+(..)$/</span>, <span class="hljs-string">"$1"</span>);</pre></div></div> - - </li> - - - <li id="section-141"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-141">¶</a> - </div> - <p>Seconds, with leading zeros</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"s"</span>: <span class="hljs-keyword">return</span> (<span class="hljs-string">"0"</span> + me.getSeconds()).replace(<span class="hljs-regexp">/^.+(..)$/</span>, <span class="hljs-string">"$1"</span>);</pre></div></div> - - </li> - - - <li id="section-142"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-142">¶</a> - </div> - <p>Milliseconds</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"u"</span>: <span class="hljs-keyword">return</span> me.getMilliseconds();</pre></div></div> - - </li> - - - <li id="section-143"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-143">¶</a> - </div> - <p>Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"U"</span>: <span class="hljs-keyword">return</span> me.getTime() / <span class="hljs-number">1000</span>; - } - }); - }; - })(); - - Twig.lib.strip_tags = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">input, allowed</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-144"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-144">¶</a> - </div> - <p>Strips HTML and PHP tags from a string</p> -<p>version: 1109.2015 -discuss at: <a href="http://phpjs.org/functions/strip_tags">http://phpjs.org/functions/strip_tags</a></p> -<ul> -<li>original by: Kevin van Zonneveld (<a href="http://kevin.vanzonneveld.net">http://kevin.vanzonneveld.net</a>)</li> -<li>improved by: Luke Godfrey</li> -<li>input by: Pul</li> -<li>bugfixed by: Kevin van Zonneveld (<a href="http://kevin.vanzonneveld.net">http://kevin.vanzonneveld.net</a>)</li> -<li>bugfixed by: Onno Marsman</li> -<li>input by: Alex</li> -<li>bugfixed by: Kevin van Zonneveld (<a href="http://kevin.vanzonneveld.net">http://kevin.vanzonneveld.net</a>)</li> -<li>input by: Marc Palau</li> -<li>improved by: Kevin van Zonneveld (<a href="http://kevin.vanzonneveld.net">http://kevin.vanzonneveld.net</a>)</li> -<li>input by: Brett Zamir (<a href="http://brett-zamir.me">http://brett-zamir.me</a>)</li> -<li>bugfixed by: Kevin van Zonneveld (<a href="http://kevin.vanzonneveld.net">http://kevin.vanzonneveld.net</a>)</li> -<li>bugfixed by: Eric Nagel</li> -<li>input by: Bobby Drake</li> -<li>bugfixed by: Kevin van Zonneveld (<a href="http://kevin.vanzonneveld.net">http://kevin.vanzonneveld.net</a>)</li> -<li>bugfixed by: Tomasz Wesolowski</li> -<li>input by: Evertjan Garretsen</li> -<li>revised by: Rafał Kukawski (<a href="http://blog.kukawski.pl/">http://blog.kukawski.pl/</a>)</li> -<li>example 1: strip_tags(‘<p>Kevin</p> <b>van</b> <i>Zonneveld</i>‘, ‘<i><b>‘);</li> -<li>returns 1: ‘Kevin <b>van</b> <i>Zonneveld</i>‘</li> -<li>example 2: strip_tags(‘<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>‘, ‘<p>‘);</li> -<li>returns 2: ‘<p>Kevin van Zonneveld</p>‘</li> -<li>example 3: strip_tags(“<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>“, “<a>“);</li> -<li>returns 3: ‘<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>‘</li> -<li>example 4: strip_tags(‘1 < 5 5 > 1’);</li> -<li>returns 4: ‘1 < 5 5 > 1’</li> -<li>example 5: strip_tags(‘1 <br/> 1’);</li> -<li>returns 5: ‘1 1’</li> -<li>example 6: strip_tags(‘1 <br/> 1’, ‘<br>‘);</li> -<li>returns 6: ‘1 1’</li> -<li>example 7: strip_tags(‘1 <br/> 1’, ‘<br><br/>‘);</li> -<li>returns 7: ‘1 <br/> 1’</li> -</ul> - - </div> - - <div class="content"><div class='highlight'><pre> allowed = (((allowed || <span class="hljs-string">""</span>) + <span class="hljs-string">""</span>).toLowerCase().match(<span class="hljs-regexp">/<[a-z][a-z0-9]*>/g</span>) || []).join(<span class="hljs-string">''</span>); <span class="hljs-comment">// making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)</span> - <span class="hljs-keyword">var</span> tags = <span class="hljs-regexp">/<\/?([a-z][a-z0-9]*)\b[^>]*>/gi</span>, - commentsAndPhpTags = <span class="hljs-regexp">/<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi</span>; - <span class="hljs-keyword">return</span> input.replace(commentsAndPhpTags, <span class="hljs-string">''</span>).replace(tags, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">$0, $1</span>) </span>{ - <span class="hljs-keyword">return</span> allowed.indexOf(<span class="hljs-string">'<'</span> + $<span class="hljs-number">1.</span>toLowerCase() + <span class="hljs-string">'>'</span>) > <span class="hljs-number">-1</span> ? $<span class="hljs-number">0</span> : <span class="hljs-string">''</span>; - }); - } - - Twig.lib.parseISO8601Date = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">s</span>)</span>{</pre></div></div> - - </li> - - - <li id="section-145"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-145">¶</a> - </div> - <p>Taken from <a href="http://n8v.enteuxis.org/2010/12/parsing-iso-8601-dates-in-javascript/">http://n8v.enteuxis.org/2010/12/parsing-iso-8601-dates-in-javascript/</a> -parenthese matches: -year month day hours minutes seconds<br>dotmilliseconds -tzstring plusminus hours minutes</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> re = <span class="hljs-regexp">/(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d+)?(Z|([+-])(\d\d):(\d\d))/</span>; - - <span class="hljs-keyword">var</span> d = []; - d = s.match(re);</pre></div></div> - - </li> - - - <li id="section-146"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-146">¶</a> - </div> - <p>“2010-12-07T11:00:00.000-09:00” parses to: - [“2010-12-07T11:00:00.000-09:00”, “2010”, “12”, “07”, “11”, - “00”, “00”, “.000”, “-09:00”, “-“, “09”, “00”] -“2010-12-07T11:00:00.000Z” parses to: - [“2010-12-07T11:00:00.000Z”, “2010”, “12”, “07”, “11”, - “00”, “00”, “.000”, “Z”, undefined, undefined, undefined]</p> - - </div> - - <div class="content"><div class='highlight'><pre> - <span class="hljs-keyword">if</span> (! d) { - <span class="hljs-keyword">throw</span> <span class="hljs-string">"Couldn't parse ISO 8601 date string '"</span> + s + <span class="hljs-string">"'"</span>; - }</pre></div></div> - - </li> - - - <li id="section-147"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-147">¶</a> - </div> - <p>parse strings, leading zeros into proper ints</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> a = [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>,<span class="hljs-number">10</span>,<span class="hljs-number">11</span>]; - <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i <span class="hljs-keyword">in</span> a) { - d[a[i]] = <span class="hljs-built_in">parseInt</span>(d[a[i]], <span class="hljs-number">10</span>); - } - d[<span class="hljs-number">7</span>] = <span class="hljs-built_in">parseFloat</span>(d[<span class="hljs-number">7</span>]);</pre></div></div> - - </li> - - - <li id="section-148"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-148">¶</a> - </div> - <p>Date.UTC(year, month[, date[, hrs[, min[, sec[, ms]]]]]) -note that month is 0-11, not 1-12 -see <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/UTC">https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/UTC</a></p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> ms = <span class="hljs-built_in">Date</span>.UTC(d[<span class="hljs-number">1</span>], d[<span class="hljs-number">2</span>] - <span class="hljs-number">1</span>, d[<span class="hljs-number">3</span>], d[<span class="hljs-number">4</span>], d[<span class="hljs-number">5</span>], d[<span class="hljs-number">6</span>]);</pre></div></div> - - </li> - - - <li id="section-149"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-149">¶</a> - </div> - <p>if there are milliseconds, add them</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (d[<span class="hljs-number">7</span>] > <span class="hljs-number">0</span>) { - ms += <span class="hljs-built_in">Math</span>.round(d[<span class="hljs-number">7</span>] * <span class="hljs-number">1000</span>); - }</pre></div></div> - - </li> - - - <li id="section-150"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-150">¶</a> - </div> - <p>if there’s a timezone, calculate it</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (d[<span class="hljs-number">8</span>] != <span class="hljs-string">"Z"</span> && d[<span class="hljs-number">10</span>]) { - <span class="hljs-keyword">var</span> offset = d[<span class="hljs-number">10</span>] * <span class="hljs-number">60</span> * <span class="hljs-number">60</span> * <span class="hljs-number">1000</span>; - <span class="hljs-keyword">if</span> (d[<span class="hljs-number">11</span>]) { - offset += d[<span class="hljs-number">11</span>] * <span class="hljs-number">60</span> * <span class="hljs-number">1000</span>; - } - <span class="hljs-keyword">if</span> (d[<span class="hljs-number">9</span>] == <span class="hljs-string">"-"</span>) { - ms -= offset; - } - <span class="hljs-keyword">else</span> { - ms += offset; - } - } - - <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(ms); - }; - - Twig.lib.strtotime = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">text, now</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-151"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-151">¶</a> - </div> - <p> discuss at: <a href="http://phpjs.org/functions/strtotime/">http://phpjs.org/functions/strtotime/</a> - version: 1109.2016 -original by: Caio Ariede (<a href="http://caioariede.com">http://caioariede.com</a>) -improved by: Kevin van Zonneveld (<a href="http://kevin.vanzonneveld.net">http://kevin.vanzonneveld.net</a>) -improved by: Caio Ariede (<a href="http://caioariede.com">http://caioariede.com</a>) -improved by: A. Matías Quezada (<a href="http://amatiasq.com">http://amatiasq.com</a>) -improved by: preuter -improved by: Brett Zamir (<a href="http://brett-zamir.me">http://brett-zamir.me</a>) -improved by: Mirko Faber - input by: David -bugfixed by: Wagner B. Soares -bugfixed by: Artur Tchernychev -bugfixed by: Stephan Bösch-Plepelits (<a href="http://github.com/plepe">http://github.com/plepe</a>) - note: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones) - example 1: strtotime(‘+1 day’, 1129633200); - returns 1: 1129719600 - example 2: strtotime(‘+1 week 2 days 4 hours 2 seconds’, 1129633200); - returns 2: 1130425202 - example 3: strtotime(‘last month’, 1129633200); - returns 3: 1127041200 - example 4: strtotime(‘2009-05-04 08:30:00 GMT’); - returns 4: 1241425800 - example 5: strtotime(‘2009-05-04 08:30:00+00’); - returns 5: 1241425800 - example 6: strtotime(‘2009-05-04 08:30:00+02:00’); - returns 6: 1241418600 - example 7: strtotime(‘2009-05-04T08:30:00Z’); - returns 7: 1241425800</p> - - </div> - - <div class="content"><div class='highlight'><pre> - <span class="hljs-keyword">var</span> parsed, match, today, year, date, days, ranges, len, times, regex, i, fail = <span class="hljs-literal">false</span>; - - <span class="hljs-keyword">if</span> (!text) { - <span class="hljs-keyword">return</span> fail; - }</pre></div></div> - - </li> - - - <li id="section-152"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-152">¶</a> - </div> - <p>Unecessary spaces</p> - - </div> - - <div class="content"><div class='highlight'><pre> text = text.replace(<span class="hljs-regexp">/^\s+|\s+$/g</span>, <span class="hljs-string">''</span>) - .replace(<span class="hljs-regexp">/\s{2,}/g</span>, <span class="hljs-string">' '</span>) - .replace(<span class="hljs-regexp">/[\t\r\n]/g</span>, <span class="hljs-string">''</span>) - .toLowerCase();</pre></div></div> - - </li> - - - <li id="section-153"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-153">¶</a> - </div> - <p>in contrast to php, js Date.parse function interprets: -dates given as yyyy-mm-dd as in timezone: UTC, -dates with “.” or “-“ as MDY instead of DMY -dates with two-digit years differently -etc…etc… -…therefore we manually parse lots of common date formats</p> - - </div> - - <div class="content"><div class='highlight'><pre> match = text.match( - <span class="hljs-regexp">/^(\d{1,4})([\-\.\/\:])(\d{1,2})([\-\.\/\:])(\d{1,4})(?:\s(\d{1,2}):(\d{2})?:?(\d{2})?)?(?:\s([A-Z]+)?)?$/</span>); - - <span class="hljs-keyword">if</span> (match && match[<span class="hljs-number">2</span>] === match[<span class="hljs-number">4</span>]) { - <span class="hljs-keyword">if</span> (match[<span class="hljs-number">1</span>] > <span class="hljs-number">1901</span>) { - <span class="hljs-keyword">switch</span> (match[<span class="hljs-number">2</span>]) { - <span class="hljs-keyword">case</span> <span class="hljs-string">'-'</span>: - {</pre></div></div> - - </li> - - - <li id="section-154"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-154">¶</a> - </div> - <p>YYYY-M-D</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">3</span>] > <span class="hljs-number">12</span> || match[<span class="hljs-number">5</span>] > <span class="hljs-number">31</span>) { - <span class="hljs-keyword">return</span> fail; - } - - <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(match[<span class="hljs-number">1</span>], <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">3</span>], <span class="hljs-number">10</span>) - <span class="hljs-number">1</span>, match[<span class="hljs-number">5</span>], - match[<span class="hljs-number">6</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">8</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>; - } - <span class="hljs-keyword">case</span> <span class="hljs-string">'.'</span>: - {</pre></div></div> - - </li> - - - <li id="section-155"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-155">¶</a> - </div> - <p>YYYY.M.D is not parsed by strtotime()</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> fail; - } - <span class="hljs-keyword">case</span> <span class="hljs-string">'/'</span>: - {</pre></div></div> - - </li> - - - <li id="section-156"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-156">¶</a> - </div> - <p>YYYY/M/D</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">3</span>] > <span class="hljs-number">12</span> || match[<span class="hljs-number">5</span>] > <span class="hljs-number">31</span>) { - <span class="hljs-keyword">return</span> fail; - } - - <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(match[<span class="hljs-number">1</span>], <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">3</span>], <span class="hljs-number">10</span>) - <span class="hljs-number">1</span>, match[<span class="hljs-number">5</span>], - match[<span class="hljs-number">6</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">8</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>; - } - } - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">5</span>] > <span class="hljs-number">1901</span>) { - <span class="hljs-keyword">switch</span> (match[<span class="hljs-number">2</span>]) { - <span class="hljs-keyword">case</span> <span class="hljs-string">'-'</span>: - {</pre></div></div> - - </li> - - - <li id="section-157"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-157">¶</a> - </div> - <p>D-M-YYYY</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">3</span>] > <span class="hljs-number">12</span> || match[<span class="hljs-number">1</span>] > <span class="hljs-number">31</span>) { - <span class="hljs-keyword">return</span> fail; - } - - <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(match[<span class="hljs-number">5</span>], <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">3</span>], <span class="hljs-number">10</span>) - <span class="hljs-number">1</span>, match[<span class="hljs-number">1</span>], - match[<span class="hljs-number">6</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">8</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>; - } - <span class="hljs-keyword">case</span> <span class="hljs-string">'.'</span>: - {</pre></div></div> - - </li> - - - <li id="section-158"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-158">¶</a> - </div> - <p>D.M.YYYY</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">3</span>] > <span class="hljs-number">12</span> || match[<span class="hljs-number">1</span>] > <span class="hljs-number">31</span>) { - <span class="hljs-keyword">return</span> fail; - } - - <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(match[<span class="hljs-number">5</span>], <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">3</span>], <span class="hljs-number">10</span>) - <span class="hljs-number">1</span>, match[<span class="hljs-number">1</span>], - match[<span class="hljs-number">6</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">8</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>; - } - <span class="hljs-keyword">case</span> <span class="hljs-string">'/'</span>: - {</pre></div></div> - - </li> - - - <li id="section-159"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-159">¶</a> - </div> - <p>M/D/YYYY</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">1</span>] > <span class="hljs-number">12</span> || match[<span class="hljs-number">3</span>] > <span class="hljs-number">31</span>) { - <span class="hljs-keyword">return</span> fail; - } - - <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(match[<span class="hljs-number">5</span>], <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">1</span>], <span class="hljs-number">10</span>) - <span class="hljs-number">1</span>, match[<span class="hljs-number">3</span>], - match[<span class="hljs-number">6</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">8</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>; - } - } - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">switch</span> (match[<span class="hljs-number">2</span>]) { - <span class="hljs-keyword">case</span> <span class="hljs-string">'-'</span>: - {</pre></div></div> - - </li> - - - <li id="section-160"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-160">¶</a> - </div> - <p>YY-M-D</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">3</span>] > <span class="hljs-number">12</span> || match[<span class="hljs-number">5</span>] > <span class="hljs-number">31</span> || (match[<span class="hljs-number">1</span>] < <span class="hljs-number">70</span> && match[<span class="hljs-number">1</span>] > <span class="hljs-number">38</span>)) { - <span class="hljs-keyword">return</span> fail; - } - - year = match[<span class="hljs-number">1</span>] >= <span class="hljs-number">0</span> && match[<span class="hljs-number">1</span>] <= <span class="hljs-number">38</span> ? +match[<span class="hljs-number">1</span>] + <span class="hljs-number">2000</span> : match[<span class="hljs-number">1</span>]; - <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(year, <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">3</span>], <span class="hljs-number">10</span>) - <span class="hljs-number">1</span>, match[<span class="hljs-number">5</span>], - match[<span class="hljs-number">6</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">8</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>; - } - <span class="hljs-keyword">case</span> <span class="hljs-string">'.'</span>: - {</pre></div></div> - - </li> - - - <li id="section-161"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-161">¶</a> - </div> - <p>D.M.YY or H.MM.SS</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">5</span>] >= <span class="hljs-number">70</span>) {</pre></div></div> - - </li> - - - <li id="section-162"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-162">¶</a> - </div> - <p>D.M.YY</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">3</span>] > <span class="hljs-number">12</span> || match[<span class="hljs-number">1</span>] > <span class="hljs-number">31</span>) { - <span class="hljs-keyword">return</span> fail; - } - - <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(match[<span class="hljs-number">5</span>], <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">3</span>], <span class="hljs-number">10</span>) - <span class="hljs-number">1</span>, match[<span class="hljs-number">1</span>], - match[<span class="hljs-number">6</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">8</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>; - } - <span class="hljs-keyword">if</span> (match[<span class="hljs-number">5</span>] < <span class="hljs-number">60</span> && !match[<span class="hljs-number">6</span>]) {</pre></div></div> - - </li> - - - <li id="section-163"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-163">¶</a> - </div> - <p>H.MM.SS</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">1</span>] > <span class="hljs-number">23</span> || match[<span class="hljs-number">3</span>] > <span class="hljs-number">59</span>) { - <span class="hljs-keyword">return</span> fail; - } - - today = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(); - <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(today.getFullYear(), today.getMonth(), today.getDate(), - match[<span class="hljs-number">1</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">3</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">5</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>; - }</pre></div></div> - - </li> - - - <li id="section-164"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-164">¶</a> - </div> - <p>invalid format, cannot be parsed</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> fail; - } - <span class="hljs-keyword">case</span> <span class="hljs-string">'/'</span>: - {</pre></div></div> - - </li> - - - <li id="section-165"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-165">¶</a> - </div> - <p>M/D/YY</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">1</span>] > <span class="hljs-number">12</span> || match[<span class="hljs-number">3</span>] > <span class="hljs-number">31</span> || (match[<span class="hljs-number">5</span>] < <span class="hljs-number">70</span> && match[<span class="hljs-number">5</span>] > <span class="hljs-number">38</span>)) { - <span class="hljs-keyword">return</span> fail; - } - - year = match[<span class="hljs-number">5</span>] >= <span class="hljs-number">0</span> && match[<span class="hljs-number">5</span>] <= <span class="hljs-number">38</span> ? +match[<span class="hljs-number">5</span>] + <span class="hljs-number">2000</span> : match[<span class="hljs-number">5</span>]; - <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(year, <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">1</span>], <span class="hljs-number">10</span>) - <span class="hljs-number">1</span>, match[<span class="hljs-number">3</span>], - match[<span class="hljs-number">6</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">8</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>; - } - <span class="hljs-keyword">case</span> <span class="hljs-string">':'</span>: - {</pre></div></div> - - </li> - - - <li id="section-166"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-166">¶</a> - </div> - <p>HH:MM:SS</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">1</span>] > <span class="hljs-number">23</span> || match[<span class="hljs-number">3</span>] > <span class="hljs-number">59</span> || match[<span class="hljs-number">5</span>] > <span class="hljs-number">59</span>) { - <span class="hljs-keyword">return</span> fail; - } - - today = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(); - <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(today.getFullYear(), today.getMonth(), today.getDate(), - match[<span class="hljs-number">1</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">3</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">5</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>; - } - } - } - }</pre></div></div> - - </li> - - - <li id="section-167"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-167">¶</a> - </div> - <p>other formats and “now” should be parsed by Date.parse()</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (text === <span class="hljs-string">'now'</span>) { - <span class="hljs-keyword">return</span> now === <span class="hljs-literal">null</span> || <span class="hljs-built_in">isNaN</span>(now) ? <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>() - .getTime() / <span class="hljs-number">1000</span> | <span class="hljs-number">0</span> : now | <span class="hljs-number">0</span>; - } - <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">isNaN</span>(parsed = <span class="hljs-built_in">Date</span>.parse(text))) { - <span class="hljs-keyword">return</span> parsed / <span class="hljs-number">1000</span> | <span class="hljs-number">0</span>; - }</pre></div></div> - - </li> - - - <li id="section-168"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-168">¶</a> - </div> - <p>Browsers != Chrome have problems parsing ISO 8601 date strings, as they do -not accept lower case characters, space, or shortened time zones. -Therefore, fix these problems and try again. -Examples: - 2015-04-15 20:33:59+02 - 2015-04-15 20:33:59z - 2015-04-15t20:33:59+02:00</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match = text.match(<span class="hljs-regexp">/^([0-9]{4}-[0-9]{2}-[0-9]{2})[ t]([0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?)([\+-][0-9]{2}(:[0-9]{2})?|z)/</span>)) {</pre></div></div> - - </li> - - - <li id="section-169"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-169">¶</a> - </div> - <p>fix time zone information</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">4</span>] == <span class="hljs-string">'z'</span>) { - match[<span class="hljs-number">4</span>] = <span class="hljs-string">'Z'</span>; - } - <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">4</span>].match(<span class="hljs-regexp">/^([\+-][0-9]{2})$/</span>)) { - match[<span class="hljs-number">4</span>] = match[<span class="hljs-number">4</span>] + <span class="hljs-string">':00'</span>; - } - - <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">isNaN</span>(parsed = <span class="hljs-built_in">Date</span>.parse(match[<span class="hljs-number">1</span>] + <span class="hljs-string">'T'</span> + match[<span class="hljs-number">2</span>] + match[<span class="hljs-number">4</span>]))) { - <span class="hljs-keyword">return</span> parsed / <span class="hljs-number">1000</span> | <span class="hljs-number">0</span>; - } - } - - date = now ? <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(now * <span class="hljs-number">1000</span>) : <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(); - days = { - <span class="hljs-string">'sun'</span>: <span class="hljs-number">0</span>, - <span class="hljs-string">'mon'</span>: <span class="hljs-number">1</span>, - <span class="hljs-string">'tue'</span>: <span class="hljs-number">2</span>, - <span class="hljs-string">'wed'</span>: <span class="hljs-number">3</span>, - <span class="hljs-string">'thu'</span>: <span class="hljs-number">4</span>, - <span class="hljs-string">'fri'</span>: <span class="hljs-number">5</span>, - <span class="hljs-string">'sat'</span>: <span class="hljs-number">6</span> - }; - ranges = { - <span class="hljs-string">'yea'</span>: <span class="hljs-string">'FullYear'</span>, - <span class="hljs-string">'mon'</span>: <span class="hljs-string">'Month'</span>, - <span class="hljs-string">'day'</span>: <span class="hljs-string">'Date'</span>, - <span class="hljs-string">'hou'</span>: <span class="hljs-string">'Hours'</span>, - <span class="hljs-string">'min'</span>: <span class="hljs-string">'Minutes'</span>, - <span class="hljs-string">'sec'</span>: <span class="hljs-string">'Seconds'</span> - }; - - <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">lastNext</span>(<span class="hljs-params">type, range, modifier</span>) </span>{ - <span class="hljs-keyword">var</span> diff, day = days[range]; - - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> day !== <span class="hljs-string">'undefined'</span>) { - diff = day - date.getDay(); - - <span class="hljs-keyword">if</span> (diff === <span class="hljs-number">0</span>) { - diff = <span class="hljs-number">7</span> * modifier; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (diff > <span class="hljs-number">0</span> && type === <span class="hljs-string">'last'</span>) { - diff -= <span class="hljs-number">7</span>; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (diff < <span class="hljs-number">0</span> && type === <span class="hljs-string">'next'</span>) { - diff += <span class="hljs-number">7</span>; - } - - date.setDate(date.getDate() + diff); - } - } - - <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">process</span>(<span class="hljs-params">val</span>) </span>{ - <span class="hljs-keyword">var</span> splt = val.split(<span class="hljs-string">' '</span>), <span class="hljs-comment">// Todo: Reconcile this with regex using \s, taking into account browser issues with split and regexes</span> - type = splt[<span class="hljs-number">0</span>], - range = splt[<span class="hljs-number">1</span>].substring(<span class="hljs-number">0</span>, <span class="hljs-number">3</span>), - typeIsNumber = <span class="hljs-regexp">/\d+/</span>.test(type), - ago = splt[<span class="hljs-number">2</span>] === <span class="hljs-string">'ago'</span>, - num = (type === <span class="hljs-string">'last'</span> ? <span class="hljs-number">-1</span> : <span class="hljs-number">1</span>) * (ago ? <span class="hljs-number">-1</span> : <span class="hljs-number">1</span>); - - <span class="hljs-keyword">if</span> (typeIsNumber) { - num *= <span class="hljs-built_in">parseInt</span>(type, <span class="hljs-number">10</span>); - } - - <span class="hljs-keyword">if</span> (ranges.hasOwnProperty(range) && !splt[<span class="hljs-number">1</span>].match(<span class="hljs-regexp">/^mon(day|\.)?$/i</span>)) { - <span class="hljs-keyword">return</span> date[<span class="hljs-string">'set'</span> + ranges[range]](date[<span class="hljs-string">'get'</span> + ranges[range]]() + num); - } - - <span class="hljs-keyword">if</span> (range === <span class="hljs-string">'wee'</span>) { - <span class="hljs-keyword">return</span> date.setDate(date.getDate() + (num * <span class="hljs-number">7</span>)); - } - - <span class="hljs-keyword">if</span> (type === <span class="hljs-string">'next'</span> || type === <span class="hljs-string">'last'</span>) { - lastNext(type, range, num); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (!typeIsNumber) { - <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; - } - - <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; - } - - times = <span class="hljs-string">'(years?|months?|weeks?|days?|hours?|minutes?|min|seconds?|sec'</span> + - <span class="hljs-string">'|sunday|sun\\.?|monday|mon\\.?|tuesday|tue\\.?|wednesday|wed\\.?'</span> + - <span class="hljs-string">'|thursday|thu\\.?|friday|fri\\.?|saturday|sat\\.?)'</span>; - regex = <span class="hljs-string">'([+-]?\\d+\\s'</span> + times + <span class="hljs-string">'|'</span> + <span class="hljs-string">'(last|next)\\s'</span> + times + <span class="hljs-string">')(\\sago)?'</span>; - - match = text.match(<span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(regex, <span class="hljs-string">'gi'</span>)); - <span class="hljs-keyword">if</span> (!match) { - <span class="hljs-keyword">return</span> fail; - } - - <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>, len = match.length; i < len; i++) { - <span class="hljs-keyword">if</span> (!process(match[i])) { - <span class="hljs-keyword">return</span> fail; - } - }</pre></div></div> - - </li> - - - <li id="section-170"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-170">¶</a> - </div> - <p>ECMAScript 5 only -if (!match.every(process)) - return false;</p> - - </div> - - <div class="content"><div class='highlight'><pre> - <span class="hljs-keyword">return</span> (date.getTime() / <span class="hljs-number">1000</span>); - }; - - Twig.lib.is = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">type, obj</span>) </span>{ - <span class="hljs-keyword">var</span> clas = <span class="hljs-built_in">Object</span>.prototype.toString.call(obj).slice(<span class="hljs-number">8</span>, <span class="hljs-number">-1</span>); - <span class="hljs-keyword">return</span> obj !== <span class="hljs-literal">undefined</span> && obj !== <span class="hljs-literal">null</span> && clas === type; - };</pre></div></div> - - </li> - - - <li id="section-171"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-171">¶</a> - </div> - <p>shallow-copy an object</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.lib.copy = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">src</span>) </span>{ - <span class="hljs-keyword">var</span> target = {}, - key; - <span class="hljs-keyword">for</span> (key <span class="hljs-keyword">in</span> src) - target[key] = src[key]; - - <span class="hljs-keyword">return</span> target; - }; - - Twig.lib.replaceAll = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">string, search, replace</span>) </span>{ - <span class="hljs-keyword">return</span> string.split(search).join(replace); - };</pre></div></div> - - </li> - - - <li id="section-172"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-172">¶</a> - </div> - <p>chunk an array (arr) into arrays of (size) items, returns an array of arrays, or an empty array on invalid input</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.lib.chunkArray = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">arr, size</span>) </span>{ - <span class="hljs-keyword">var</span> returnVal = [], - x = <span class="hljs-number">0</span>, - len = arr.length; - - <span class="hljs-keyword">if</span> (size < <span class="hljs-number">1</span> || !Twig.lib.is(<span class="hljs-string">"Array"</span>, arr)) { - <span class="hljs-keyword">return</span> []; - } - - <span class="hljs-keyword">while</span> (x < len) { - returnVal.push(arr.slice(x, x += size)); - } - - <span class="hljs-keyword">return</span> returnVal; - }; - - Twig.lib.round = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">round</span>(<span class="hljs-params">value, precision, mode</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-173"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-173">¶</a> - </div> - <p> discuss at: <a href="http://phpjs.org/functions/round/">http://phpjs.org/functions/round/</a> -original by: Philip Peterson - revised by: Onno Marsman - revised by: T.Wild - revised by: Rafał Kukawski (<a href="http://blog.kukawski.pl/">http://blog.kukawski.pl/</a>) - input by: Greenseed - input by: meo - input by: William - input by: Josep Sanz (<a href="http://www.ws3.es/">http://www.ws3.es/</a>) -bugfixed by: Brett Zamir (<a href="http://brett-zamir.me">http://brett-zamir.me</a>) - note: Great work. Ideas for improvement: - note: - code more compliant with developer guidelines - note: - for implementing PHP constant arguments look at - note: the pathinfo() function, it offers the greatest - note: flexibility & compatibility possible - example 1: round(1241757, -3); - returns 1: 1242000 - example 2: round(3.6); - returns 2: 4 - example 3: round(2.835, 2); - returns 3: 2.84 - example 4: round(1.1749999999999, 2); - returns 4: 1.17 - example 5: round(58551.799999999996, 2); - returns 5: 58551.8</p> - - </div> - - <div class="content"><div class='highlight'><pre> - <span class="hljs-keyword">var</span> m, f, isHalf, sgn; <span class="hljs-comment">// helper variables</span> - precision |= <span class="hljs-number">0</span>; <span class="hljs-comment">// making sure precision is integer</span> - m = <span class="hljs-built_in">Math</span>.pow(<span class="hljs-number">10</span>, precision); - value *= m; - sgn = (value > <span class="hljs-number">0</span>) | -(value < <span class="hljs-number">0</span>); <span class="hljs-comment">// sign of the number</span> - isHalf = value % <span class="hljs-number">1</span> === <span class="hljs-number">0.5</span> * sgn; - f = <span class="hljs-built_in">Math</span>.floor(value); - - <span class="hljs-keyword">if</span> (isHalf) { - <span class="hljs-keyword">switch</span> (mode) { - <span class="hljs-keyword">case</span> <span class="hljs-string">'PHP_ROUND_HALF_DOWN'</span>: - value = f + (sgn < <span class="hljs-number">0</span>); <span class="hljs-comment">// rounds .5 toward zero</span> - <span class="hljs-keyword">break</span>; - <span class="hljs-keyword">case</span> <span class="hljs-string">'PHP_ROUND_HALF_EVEN'</span>: - value = f + (f % <span class="hljs-number">2</span> * sgn); <span class="hljs-comment">// rouds .5 towards the next even integer</span> - <span class="hljs-keyword">break</span>; - <span class="hljs-keyword">case</span> <span class="hljs-string">'PHP_ROUND_HALF_ODD'</span>: - value = f + !(f % <span class="hljs-number">2</span>); <span class="hljs-comment">// rounds .5 towards the next odd integer</span> - <span class="hljs-keyword">break</span>; - <span class="hljs-keyword">default</span>: - value = f + (sgn > <span class="hljs-number">0</span>); <span class="hljs-comment">// rounds .5 away from zero</span> - } - } - - <span class="hljs-keyword">return</span> (isHalf ? value : <span class="hljs-built_in">Math</span>.round(value)) / m; - }; - - Twig.lib.max = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">max</span>(<span class="hljs-params"></span>) </span>{</pre></div></div> - - </li> - - - <li id="section-174"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-174">¶</a> - </div> - <p> discuss at: <a href="http://phpjs.org/functions/max/">http://phpjs.org/functions/max/</a> -original by: Onno Marsman - revised by: Onno Marsman -improved by: Jack - note: Long code cause we’re aiming for maximum PHP compatibility - example 1: max(1, 3, 5, 6, 7); - returns 1: 7 - example 2: max([2, 4, 5]); - returns 2: 5 - example 3: max(0, ‘hello’); - returns 3: 0 - example 4: max(‘hello’, 0); - returns 4: ‘hello’ - example 5: max(-1, ‘hello’); - returns 5: ‘hello’ - example 6: max([2, 4, 8], [2, 5, 7]); - returns 6: [2, 5, 7]</p> - - </div> - - <div class="content"><div class='highlight'><pre> - <span class="hljs-keyword">var</span> ar, retVal, i = <span class="hljs-number">0</span>, - n = <span class="hljs-number">0</span>, - argv = <span class="hljs-built_in">arguments</span>, - argc = argv.length, - _obj2Array = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">obj</span>) </span>{ - <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Object</span>.prototype.toString.call(obj) === <span class="hljs-string">'[object Array]'</span>) { - <span class="hljs-keyword">return</span> obj; - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">var</span> ar = []; - <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i <span class="hljs-keyword">in</span> obj) { - <span class="hljs-keyword">if</span> (obj.hasOwnProperty(i)) { - ar.push(obj[i]); - } - } - <span class="hljs-keyword">return</span> ar; - } - }, <span class="hljs-comment">//function _obj2Array</span> - _compare = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">current, next</span>) </span>{ - <span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>, - n = <span class="hljs-number">0</span>, - tmp = <span class="hljs-number">0</span>, - nl = <span class="hljs-number">0</span>, - cl = <span class="hljs-number">0</span>; - - <span class="hljs-keyword">if</span> (current === next) { - <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> current === <span class="hljs-string">'object'</span>) { - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> next === <span class="hljs-string">'object'</span>) { - current = _obj2Array(current); - next = _obj2Array(next); - cl = current.length; - nl = next.length; - <span class="hljs-keyword">if</span> (nl > cl) { - <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (nl < cl) { - <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>; - } - <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>, n = cl; i < n; ++i) { - tmp = _compare(current[i], next[i]); - <span class="hljs-keyword">if</span> (tmp == <span class="hljs-number">1</span>) { - <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (tmp == <span class="hljs-number">-1</span>) { - <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>; - } - } - <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; - } - <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> next === <span class="hljs-string">'object'</span>) { - <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">isNaN</span>(next) && !<span class="hljs-built_in">isNaN</span>(current)) { - <span class="hljs-keyword">if</span> (current == <span class="hljs-number">0</span>) { - <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; - } - <span class="hljs-keyword">return</span> (current < <span class="hljs-number">0</span> ? <span class="hljs-number">1</span> : <span class="hljs-number">-1</span>); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">isNaN</span>(current) && !<span class="hljs-built_in">isNaN</span>(next)) { - <span class="hljs-keyword">if</span> (next == <span class="hljs-number">0</span>) { - <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; - } - <span class="hljs-keyword">return</span> (next > <span class="hljs-number">0</span> ? <span class="hljs-number">1</span> : <span class="hljs-number">-1</span>); - } - - <span class="hljs-keyword">if</span> (next == current) { - <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; - } - <span class="hljs-keyword">return</span> (next > current ? <span class="hljs-number">1</span> : <span class="hljs-number">-1</span>); - }; <span class="hljs-comment">//function _compare</span> - <span class="hljs-keyword">if</span> (argc === <span class="hljs-number">0</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'At least one value should be passed to max()'</span>); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (argc === <span class="hljs-number">1</span>) { - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> argv[<span class="hljs-number">0</span>] === <span class="hljs-string">'object'</span>) { - ar = _obj2Array(argv[<span class="hljs-number">0</span>]); - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Wrong parameter count for max()'</span>); - } - <span class="hljs-keyword">if</span> (ar.length === <span class="hljs-number">0</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Array must contain at least one element for max()'</span>); - } - } <span class="hljs-keyword">else</span> { - ar = argv; - } - - retVal = ar[<span class="hljs-number">0</span>]; - <span class="hljs-keyword">for</span> (i = <span class="hljs-number">1</span>, n = ar.length; i < n; ++i) { - <span class="hljs-keyword">if</span> (_compare(retVal, ar[i]) == <span class="hljs-number">1</span>) { - retVal = ar[i]; - } - } - - <span class="hljs-keyword">return</span> retVal; - }; - - Twig.lib.min = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">min</span>(<span class="hljs-params"></span>) </span>{</pre></div></div> - - </li> - - - <li id="section-175"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-175">¶</a> - </div> - <p> discuss at: <a href="http://phpjs.org/functions/min/">http://phpjs.org/functions/min/</a> -original by: Onno Marsman - revised by: Onno Marsman -improved by: Jack - note: Long code cause we’re aiming for maximum PHP compatibility - example 1: min(1, 3, 5, 6, 7); - returns 1: 1 - example 2: min([2, 4, 5]); - returns 2: 2 - example 3: min(0, ‘hello’); - returns 3: 0 - example 4: min(‘hello’, 0); - returns 4: ‘hello’ - example 5: min(-1, ‘hello’); - returns 5: -1 - example 6: min([2, 4, 8], [2, 5, 7]); - returns 6: [2, 4, 8]</p> - - </div> - - <div class="content"><div class='highlight'><pre> - <span class="hljs-keyword">var</span> ar, retVal, i = <span class="hljs-number">0</span>, - n = <span class="hljs-number">0</span>, - argv = <span class="hljs-built_in">arguments</span>, - argc = argv.length, - _obj2Array = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">obj</span>) </span>{ - <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Object</span>.prototype.toString.call(obj) === <span class="hljs-string">'[object Array]'</span>) { - <span class="hljs-keyword">return</span> obj; - } - <span class="hljs-keyword">var</span> ar = []; - <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i <span class="hljs-keyword">in</span> obj) { - <span class="hljs-keyword">if</span> (obj.hasOwnProperty(i)) { - ar.push(obj[i]); - } - } - <span class="hljs-keyword">return</span> ar; - }, <span class="hljs-comment">//function _obj2Array</span> - _compare = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">current, next</span>) </span>{ - <span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>, - n = <span class="hljs-number">0</span>, - tmp = <span class="hljs-number">0</span>, - nl = <span class="hljs-number">0</span>, - cl = <span class="hljs-number">0</span>; - - <span class="hljs-keyword">if</span> (current === next) { - <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> current === <span class="hljs-string">'object'</span>) { - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> next === <span class="hljs-string">'object'</span>) { - current = _obj2Array(current); - next = _obj2Array(next); - cl = current.length; - nl = next.length; - <span class="hljs-keyword">if</span> (nl > cl) { - <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (nl < cl) { - <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>; - } - <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>, n = cl; i < n; ++i) { - tmp = _compare(current[i], next[i]); - <span class="hljs-keyword">if</span> (tmp == <span class="hljs-number">1</span>) { - <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (tmp == <span class="hljs-number">-1</span>) { - <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>; - } - } - <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; - } - <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> next === <span class="hljs-string">'object'</span>) { - <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">isNaN</span>(next) && !<span class="hljs-built_in">isNaN</span>(current)) { - <span class="hljs-keyword">if</span> (current == <span class="hljs-number">0</span>) { - <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; - } - <span class="hljs-keyword">return</span> (current < <span class="hljs-number">0</span> ? <span class="hljs-number">1</span> : <span class="hljs-number">-1</span>); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">isNaN</span>(current) && !<span class="hljs-built_in">isNaN</span>(next)) { - <span class="hljs-keyword">if</span> (next == <span class="hljs-number">0</span>) { - <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; - } - <span class="hljs-keyword">return</span> (next > <span class="hljs-number">0</span> ? <span class="hljs-number">1</span> : <span class="hljs-number">-1</span>); - } - - <span class="hljs-keyword">if</span> (next == current) { - <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; - } - <span class="hljs-keyword">return</span> (next > current ? <span class="hljs-number">1</span> : <span class="hljs-number">-1</span>); - }; <span class="hljs-comment">//function _compare</span> - - <span class="hljs-keyword">if</span> (argc === <span class="hljs-number">0</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'At least one value should be passed to min()'</span>); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (argc === <span class="hljs-number">1</span>) { - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> argv[<span class="hljs-number">0</span>] === <span class="hljs-string">'object'</span>) { - ar = _obj2Array(argv[<span class="hljs-number">0</span>]); - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Wrong parameter count for min()'</span>); - } - - <span class="hljs-keyword">if</span> (ar.length === <span class="hljs-number">0</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Array must contain at least one element for min()'</span>); - } - } <span class="hljs-keyword">else</span> { - ar = argv; - } - - retVal = ar[<span class="hljs-number">0</span>]; - - <span class="hljs-keyword">for</span> (i = <span class="hljs-number">1</span>, n = ar.length; i < n; ++i) { - <span class="hljs-keyword">if</span> (_compare(retVal, ar[i]) == <span class="hljs-number">-1</span>) { - retVal = ar[i]; - } - } - - <span class="hljs-keyword">return</span> retVal; - }; - - <span class="hljs-keyword">return</span> Twig; - -})(Twig || { });</pre></div></div> - - </li> - - - <li id="section-176"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-176">¶</a> - </div> - <pre><code>Twig.js -Available under the BSD <span class="hljs-number">2</span>-Clause License -https:<span class="hljs-comment">//github.com/justjohn/twig.js</span> -</code></pre> - </div> - - </li> - - - <li id="section-177"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-177">¶</a> - </div> - <h2 id="twig-logic-js">twig.logic.js</h2> -<p>This file handles tokenizing, compiling and parsing logic tokens. {% … %}</p> - - </div> - - <div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{ -<span class="hljs-meta"> "use strict"</span>; - - <span class="hljs-comment">/** - * Namespace for logic handling. - */</span> - Twig.logic = {}; - - <span class="hljs-comment">/** - * Logic token types. - */</span> - Twig.logic.type = { - if_: <span class="hljs-string">'Twig.logic.type.if'</span>, - endif: <span class="hljs-string">'Twig.logic.type.endif'</span>, - for_: <span class="hljs-string">'Twig.logic.type.for'</span>, - endfor: <span class="hljs-string">'Twig.logic.type.endfor'</span>, - else_: <span class="hljs-string">'Twig.logic.type.else'</span>, - elseif: <span class="hljs-string">'Twig.logic.type.elseif'</span>, - set: <span class="hljs-string">'Twig.logic.type.set'</span>, - setcapture:<span class="hljs-string">'Twig.logic.type.setcapture'</span>, - endset: <span class="hljs-string">'Twig.logic.type.endset'</span>, - filter: <span class="hljs-string">'Twig.logic.type.filter'</span>, - endfilter: <span class="hljs-string">'Twig.logic.type.endfilter'</span>, - shortblock: <span class="hljs-string">'Twig.logic.type.shortblock'</span>, - block: <span class="hljs-string">'Twig.logic.type.block'</span>, - endblock: <span class="hljs-string">'Twig.logic.type.endblock'</span>, - extends_: <span class="hljs-string">'Twig.logic.type.extends'</span>, - use: <span class="hljs-string">'Twig.logic.type.use'</span>, - include: <span class="hljs-string">'Twig.logic.type.include'</span>, - spaceless: <span class="hljs-string">'Twig.logic.type.spaceless'</span>, - endspaceless: <span class="hljs-string">'Twig.logic.type.endspaceless'</span>, - macro: <span class="hljs-string">'Twig.logic.type.macro'</span>, - endmacro: <span class="hljs-string">'Twig.logic.type.endmacro'</span>, - import_: <span class="hljs-string">'Twig.logic.type.import'</span>, - <span class="hljs-keyword">from</span>: <span class="hljs-string">'Twig.logic.type.from'</span>, - embed: <span class="hljs-string">'Twig.logic.type.embed'</span>, - endembed: <span class="hljs-string">'Twig.logic.type.endembed'</span> - };</pre></div></div> - - </li> - - - <li id="section-178"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-178">¶</a> - </div> - <p>Regular expressions for handling logic tokens.</p> -<p>Properties:</p> -<pre><code> type: The type of expression this matches - - regex: A regular expression that matches the format of the token - - next: What logic tokens (if any) pop this token off the logic stack. If empty, the - logic token is assumed to not require an end tag and isn't push onto the stack. - - open: Does this tag open a logic expression or is it standalone. For example, - {% endif %} cannot exist without an opening {% if ... %} tag, so open = false. -</code></pre><p> Functions:</p> -<pre><code> compile: A <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">that</span> <span class="hljs-title">handles</span> <span class="hljs-title">compiling</span> <span class="hljs-title">the</span> <span class="hljs-title">token</span> <span class="hljs-title">into</span> <span class="hljs-title">an</span> <span class="hljs-title">output</span> <span class="hljs-title">token</span> <span class="hljs-title">ready</span> <span class="hljs-title">for</span> - <span class="hljs-title">parsing</span> <span class="hljs-title">with</span> <span class="hljs-title">the</span> <span class="hljs-title">parse</span> <span class="hljs-title">function</span>. - - <span class="hljs-title">parse</span>: <span class="hljs-title">A</span> <span class="hljs-title">function</span> <span class="hljs-title">that</span> <span class="hljs-title">parses</span> <span class="hljs-title">the</span> <span class="hljs-title">compiled</span> <span class="hljs-title">token</span> <span class="hljs-title">into</span> <span class="hljs-title">output</span> (<span class="hljs-params">HTML / whatever the - template represents</span>).</span> -</code></pre> - </div> - - <div class="content"><div class='highlight'><pre> Twig.logic.definitions = [ - { - <span class="hljs-comment">/** - * If type logic tokens. - * - * Format: {% if expression %} - */</span> - type: Twig.logic.type.if_, - regex: <span class="hljs-regexp">/^if\s+([\s\S]+)$/</span>, - next: [ - Twig.logic.type.else_, - Twig.logic.type.elseif, - Twig.logic.type.endif - ], - open: <span class="hljs-literal">true</span>, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{ - <span class="hljs-keyword">var</span> expression = token.match[<span class="hljs-number">1</span>];</pre></div></div> - - </li> - - - <li id="section-179"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-179">¶</a> - </div> - <p>Compile the expression.</p> - - </div> - - <div class="content"><div class='highlight'><pre> token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{ - type: Twig.expression.type.expression, - value: expression - }]).stack; - <span class="hljs-keyword">delete</span> token.match; - <span class="hljs-keyword">return</span> token; - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{ - <span class="hljs-keyword">var</span> output = <span class="hljs-string">''</span>,</pre></div></div> - - </li> - - - <li id="section-180"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-180">¶</a> - </div> - <p>Parse the expression</p> - - </div> - - <div class="content"><div class='highlight'><pre> result = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, context]);</pre></div></div> - - </li> - - - <li id="section-181"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-181">¶</a> - </div> - <p>Start a new logic chain</p> - - </div> - - <div class="content"><div class='highlight'><pre> chain = <span class="hljs-literal">true</span>; - - <span class="hljs-keyword">if</span> (result) { - chain = <span class="hljs-literal">false</span>;</pre></div></div> - - </li> - - - <li id="section-182"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-182">¶</a> - </div> - <p>parse if output</p> - - </div> - - <div class="content"><div class='highlight'><pre> output = Twig.parse.apply(<span class="hljs-keyword">this</span>, [token.output, context]); - } - <span class="hljs-keyword">return</span> { - chain: chain, - output: output - }; - } - }, - { - <span class="hljs-comment">/** - * Else if type logic tokens. - * - * Format: {% elseif expression %} - */</span> - type: Twig.logic.type.elseif, - regex: <span class="hljs-regexp">/^elseif\s+([^\s].*)$/</span>, - next: [ - Twig.logic.type.else_, - Twig.logic.type.elseif, - Twig.logic.type.endif - ], - open: <span class="hljs-literal">false</span>, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{ - <span class="hljs-keyword">var</span> expression = token.match[<span class="hljs-number">1</span>];</pre></div></div> - - </li> - - - <li id="section-183"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-183">¶</a> - </div> - <p>Compile the expression.</p> - - </div> - - <div class="content"><div class='highlight'><pre> token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{ - type: Twig.expression.type.expression, - value: expression - }]).stack; - <span class="hljs-keyword">delete</span> token.match; - <span class="hljs-keyword">return</span> token; - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{ - <span class="hljs-keyword">var</span> output = <span class="hljs-string">''</span>; - - <span class="hljs-keyword">if</span> (chain && Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, context]) === <span class="hljs-literal">true</span>) { - chain = <span class="hljs-literal">false</span>;</pre></div></div> - - </li> - - - <li id="section-184"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-184">¶</a> - </div> - <p>parse if output</p> - - </div> - - <div class="content"><div class='highlight'><pre> output = Twig.parse.apply(<span class="hljs-keyword">this</span>, [token.output, context]); - } - - <span class="hljs-keyword">return</span> { - chain: chain, - output: output - }; - } - }, - { - <span class="hljs-comment">/** - * Else if type logic tokens. - * - * Format: {% elseif expression %} - */</span> - type: Twig.logic.type.else_, - regex: <span class="hljs-regexp">/^else$/</span>, - next: [ - Twig.logic.type.endif, - Twig.logic.type.endfor - ], - open: <span class="hljs-literal">false</span>, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{ - <span class="hljs-keyword">var</span> output = <span class="hljs-string">''</span>; - <span class="hljs-keyword">if</span> (chain) { - output = Twig.parse.apply(<span class="hljs-keyword">this</span>, [token.output, context]); - } - <span class="hljs-keyword">return</span> { - chain: chain, - output: output - }; - } - }, - { - <span class="hljs-comment">/** - * End if type logic tokens. - * - * Format: {% endif %} - */</span> - type: Twig.logic.type.endif, - regex: <span class="hljs-regexp">/^endif$/</span>, - next: [ ], - open: <span class="hljs-literal">false</span> - }, - { - <span class="hljs-comment">/** - * For type logic tokens. - * - * Format: {% for expression %} - */</span> - type: Twig.logic.type.for_, - regex: <span class="hljs-regexp">/^for\s+([a-zA-Z0-9_,\s]+)\s+in\s+([^\s].*?)(?:\s+if\s+([^\s].*))?$/</span>, - next: [ - Twig.logic.type.else_, - Twig.logic.type.endfor - ], - open: <span class="hljs-literal">true</span>, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{ - <span class="hljs-keyword">var</span> key_value = token.match[<span class="hljs-number">1</span>], - expression = token.match[<span class="hljs-number">2</span>], - conditional = token.match[<span class="hljs-number">3</span>], - kv_split = <span class="hljs-literal">null</span>; - - token.key_var = <span class="hljs-literal">null</span>; - token.value_var = <span class="hljs-literal">null</span>; - - <span class="hljs-keyword">if</span> (key_value.indexOf(<span class="hljs-string">","</span>) >= <span class="hljs-number">0</span>) { - kv_split = key_value.split(<span class="hljs-string">','</span>); - <span class="hljs-keyword">if</span> (kv_split.length === <span class="hljs-number">2</span>) { - token.key_var = kv_split[<span class="hljs-number">0</span>].trim(); - token.value_var = kv_split[<span class="hljs-number">1</span>].trim(); - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Invalid expression in for loop: "</span> + key_value); - } - } <span class="hljs-keyword">else</span> { - token.value_var = key_value; - }</pre></div></div> - - </li> - - - <li id="section-185"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-185">¶</a> - </div> - <p>Valid expressions for a for loop - for item in expression - for key,item in expression</p> - - </div> - - </li> - - - <li id="section-186"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-186">¶</a> - </div> - <p>Compile the expression.</p> - - </div> - - <div class="content"><div class='highlight'><pre> token.expression = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{ - type: Twig.expression.type.expression, - value: expression - }]).stack;</pre></div></div> - - </li> - - - <li id="section-187"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-187">¶</a> - </div> - <p>Compile the conditional (if available)</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (conditional) { - token.conditional = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{ - type: Twig.expression.type.expression, - value: conditional - }]).stack; - } - - <span class="hljs-keyword">delete</span> token.match; - <span class="hljs-keyword">return</span> token; - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, continue_chain</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-188"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-188">¶</a> - </div> - <p>Parse expression</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> result = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.expression, context]), - output = [], - len, - index = <span class="hljs-number">0</span>, - keyset, - that = <span class="hljs-keyword">this</span>, - conditional = token.conditional, - buildLoop = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">index, len</span>) </span>{ - <span class="hljs-keyword">var</span> isConditional = conditional !== <span class="hljs-literal">undefined</span>; - <span class="hljs-keyword">return</span> { - index: index+<span class="hljs-number">1</span>, - index0: index, - revindex: isConditional?<span class="hljs-literal">undefined</span>:len-index, - revindex0: isConditional?<span class="hljs-literal">undefined</span>:len-index<span class="hljs-number">-1</span>, - first: (index === <span class="hljs-number">0</span>), - last: isConditional?<span class="hljs-literal">undefined</span>:(index === len<span class="hljs-number">-1</span>), - length: isConditional?<span class="hljs-literal">undefined</span>:len, - parent: context - }; - },</pre></div></div> - - </li> - - - <li id="section-189"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-189">¶</a> - </div> - <p>run once for each iteration of the loop</p> - - </div> - - <div class="content"><div class='highlight'><pre> loop = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key, value</span>) </span>{ - <span class="hljs-keyword">var</span> inner_context = Twig.ChildContext(context); - - inner_context[token.value_var] = value; - - <span class="hljs-keyword">if</span> (token.key_var) { - inner_context[token.key_var] = key; - }</pre></div></div> - - </li> - - - <li id="section-190"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-190">¶</a> - </div> - <p>Loop object</p> - - </div> - - <div class="content"><div class='highlight'><pre> inner_context.loop = buildLoop(index, len); - - <span class="hljs-keyword">if</span> (conditional === <span class="hljs-literal">undefined</span> || - Twig.expression.parse.apply(that, [conditional, inner_context])) - { - output.push(Twig.parse.apply(that, [token.output, inner_context])); - index += <span class="hljs-number">1</span>; - }</pre></div></div> - - </li> - - - <li id="section-191"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-191">¶</a> - </div> - <p>Delete loop-related variables from the context</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">delete</span> inner_context[<span class="hljs-string">'loop'</span>]; - <span class="hljs-keyword">delete</span> inner_context[token.value_var]; - <span class="hljs-keyword">delete</span> inner_context[token.key_var];</pre></div></div> - - </li> - - - <li id="section-192"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-192">¶</a> - </div> - <p>Merge in values that exist in context but have changed -in inner_context.</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.merge(context, inner_context, <span class="hljs-literal">true</span>); - }; - - - <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">'Array'</span>, result)) { - len = result.length; - Twig.forEach(result, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">var</span> key = index; - - loop(key, value); - }); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">'Object'</span>, result)) { - <span class="hljs-keyword">if</span> (result._keys !== <span class="hljs-literal">undefined</span>) { - keyset = result._keys; - } <span class="hljs-keyword">else</span> { - keyset = <span class="hljs-built_in">Object</span>.keys(result); - } - len = keyset.length; - Twig.forEach(keyset, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-193"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-193">¶</a> - </div> - <p>Ignore the _keys property, it’s internal to twig.js</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (key === <span class="hljs-string">"_keys"</span>) <span class="hljs-keyword">return</span>; - - loop(key, result[key]); - }); - }</pre></div></div> - - </li> - - - <li id="section-194"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-194">¶</a> - </div> - <p>Only allow else statements if no output was generated</p> - - </div> - - <div class="content"><div class='highlight'><pre> continue_chain = (output.length === <span class="hljs-number">0</span>); - - <span class="hljs-keyword">return</span> { - chain: continue_chain, - output: Twig.output.apply(<span class="hljs-keyword">this</span>, [output]) - }; - } - }, - { - <span class="hljs-comment">/** - * End if type logic tokens. - * - * Format: {% endif %} - */</span> - type: Twig.logic.type.endfor, - regex: <span class="hljs-regexp">/^endfor$/</span>, - next: [ ], - open: <span class="hljs-literal">false</span> - }, - { - <span class="hljs-comment">/** - * Set type logic tokens. - * - * Format: {% set key = expression %} - */</span> - type: Twig.logic.type.set, - regex: <span class="hljs-regexp">/^set\s+([a-zA-Z0-9_,\s]+)\s*=\s*([\s\S]+)$/</span>, - next: [ ], - open: <span class="hljs-literal">true</span>, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{ - <span class="hljs-keyword">var</span> key = token.match[<span class="hljs-number">1</span>].trim(), - expression = token.match[<span class="hljs-number">2</span>],</pre></div></div> - - </li> - - - <li id="section-195"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-195">¶</a> - </div> - <p>Compile the expression.</p> - - </div> - - <div class="content"><div class='highlight'><pre> expression_stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{ - type: Twig.expression.type.expression, - value: expression - }]).stack; - - token.key = key; - token.expression = expression_stack; - - <span class="hljs-keyword">delete</span> token.match; - <span class="hljs-keyword">return</span> token; - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, continue_chain</span>) </span>{ - <span class="hljs-keyword">var</span> value = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.expression, context]), - key = token.key; - - context[key] = value; - - <span class="hljs-keyword">return</span> { - chain: continue_chain, - context: context - }; - } - }, - { - <span class="hljs-comment">/** - * Set capture type logic tokens. - * - * Format: {% set key %} - */</span> - type: Twig.logic.type.setcapture, - regex: <span class="hljs-regexp">/^set\s+([a-zA-Z0-9_,\s]+)$/</span>, - next: [ - Twig.logic.type.endset - ], - open: <span class="hljs-literal">true</span>, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{ - <span class="hljs-keyword">var</span> key = token.match[<span class="hljs-number">1</span>].trim(); - - token.key = key; - - <span class="hljs-keyword">delete</span> token.match; - <span class="hljs-keyword">return</span> token; - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, continue_chain</span>) </span>{ - - <span class="hljs-keyword">var</span> value = Twig.parse.apply(<span class="hljs-keyword">this</span>, [token.output, context]), - key = token.key;</pre></div></div> - - </li> - - - <li id="section-196"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-196">¶</a> - </div> - <p>set on both the global and local context</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.context[key] = value; - context[key] = value; - - <span class="hljs-keyword">return</span> { - chain: continue_chain, - context: context - }; - } - }, - { - <span class="hljs-comment">/** - * End set type block logic tokens. - * - * Format: {% endset %} - */</span> - type: Twig.logic.type.endset, - regex: <span class="hljs-regexp">/^endset$/</span>, - next: [ ], - open: <span class="hljs-literal">false</span> - }, - { - <span class="hljs-comment">/** - * Filter logic tokens. - * - * Format: {% filter upper %} or {% filter lower|escape %} - */</span> - type: Twig.logic.type.filter, - regex: <span class="hljs-regexp">/^filter\s+(.+)$/</span>, - next: [ - Twig.logic.type.endfilter - ], - open: <span class="hljs-literal">true</span>, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{ - <span class="hljs-keyword">var</span> expression = <span class="hljs-string">"|"</span> + token.match[<span class="hljs-number">1</span>].trim();</pre></div></div> - - </li> - - - <li id="section-197"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-197">¶</a> - </div> - <p>Compile the expression.</p> - - </div> - - <div class="content"><div class='highlight'><pre> token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{ - type: Twig.expression.type.expression, - value: expression - }]).stack; - <span class="hljs-keyword">delete</span> token.match; - <span class="hljs-keyword">return</span> token; - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{ - <span class="hljs-keyword">var</span> unfiltered = Twig.parse.apply(<span class="hljs-keyword">this</span>, [token.output, context]), - stack = [{ - type: Twig.expression.type.string, - value: unfiltered - }].concat(token.stack); - - <span class="hljs-keyword">var</span> output = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [stack, context]); - - <span class="hljs-keyword">return</span> { - chain: chain, - output: output - }; - } - }, - { - <span class="hljs-comment">/** - * End filter logic tokens. - * - * Format: {% endfilter %} - */</span> - type: Twig.logic.type.endfilter, - regex: <span class="hljs-regexp">/^endfilter$/</span>, - next: [ ], - open: <span class="hljs-literal">false</span> - }, - { - <span class="hljs-comment">/** - * Block logic tokens. - * - * Format: {% block title %} - */</span> - type: Twig.logic.type.block, - regex: <span class="hljs-regexp">/^block\s+([a-zA-Z0-9_]+)$/</span>, - next: [ - Twig.logic.type.endblock - ], - open: <span class="hljs-literal">true</span>, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{ - token.block = token.match[<span class="hljs-number">1</span>].trim(); - <span class="hljs-keyword">delete</span> token.match; - <span class="hljs-keyword">return</span> token; - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{ - <span class="hljs-keyword">var</span> block_output, - output, - isImported = Twig.indexOf(<span class="hljs-keyword">this</span>.importedBlocks, token.block) > <span class="hljs-number">-1</span>, - hasParent = <span class="hljs-keyword">this</span>.blocks[token.block] && Twig.indexOf(<span class="hljs-keyword">this</span>.blocks[token.block], Twig.placeholders.parent) > <span class="hljs-number">-1</span>;</pre></div></div> - - </li> - - - <li id="section-198"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-198">¶</a> - </div> - <p>Don’t override previous blocks unless they’re imported with “use” -Loops should be exempted as well.</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.blocks[token.block] === <span class="hljs-literal">undefined</span> || isImported || hasParent || context.loop || token.overwrite) { - <span class="hljs-keyword">if</span> (token.expression) {</pre></div></div> - - </li> - - - <li id="section-199"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-199">¶</a> - </div> - <p>Short blocks have output as an expression on the open tag (no body)</p> - - </div> - - <div class="content"><div class='highlight'><pre> block_output = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [{ - type: Twig.expression.type.string, - value: Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.output, context]) - }, context]); - } <span class="hljs-keyword">else</span> { - block_output = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [{ - type: Twig.expression.type.string, - value: Twig.parse.apply(<span class="hljs-keyword">this</span>, [token.output, context]) - }, context]); - } - - <span class="hljs-keyword">if</span> (isImported) {</pre></div></div> - - </li> - - - <li id="section-200"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-200">¶</a> - </div> - <p>once the block is overridden, remove it from the list of imported blocks</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.importedBlocks.splice(<span class="hljs-keyword">this</span>.importedBlocks.indexOf(token.block), <span class="hljs-number">1</span>); - } - - <span class="hljs-keyword">if</span> (hasParent) { - <span class="hljs-keyword">this</span>.blocks[token.block] = Twig.Markup(<span class="hljs-keyword">this</span>.blocks[token.block].replace(Twig.placeholders.parent, block_output)); - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">this</span>.blocks[token.block] = block_output; - } - - <span class="hljs-keyword">this</span>.originalBlockTokens[token.block] = { - type: token.type, - block: token.block, - output: token.output, - overwrite: <span class="hljs-literal">true</span> - }; - }</pre></div></div> - - </li> - - - <li id="section-201"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-201">¶</a> - </div> - <p>Check if a child block has been set from a template extending this one.</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.child.blocks[token.block]) { - output = <span class="hljs-keyword">this</span>.child.blocks[token.block]; - } <span class="hljs-keyword">else</span> { - output = <span class="hljs-keyword">this</span>.blocks[token.block]; - } - - <span class="hljs-keyword">return</span> { - chain: chain, - output: output - }; - } - }, - { - <span class="hljs-comment">/** - * Block shorthand logic tokens. - * - * Format: {% block title expression %} - */</span> - type: Twig.logic.type.shortblock, - regex: <span class="hljs-regexp">/^block\s+([a-zA-Z0-9_]+)\s+(.+)$/</span>, - next: [ ], - open: <span class="hljs-literal">true</span>, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{ - token.expression = token.match[<span class="hljs-number">2</span>].trim(); - - token.output = Twig.expression.compile({ - type: Twig.expression.type.expression, - value: token.expression - }).stack; - - token.block = token.match[<span class="hljs-number">1</span>].trim(); - <span class="hljs-keyword">delete</span> token.match; - <span class="hljs-keyword">return</span> token; - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{ - <span class="hljs-keyword">return</span> Twig.logic.handler[Twig.logic.type.block].parse.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>); - } - }, - { - <span class="hljs-comment">/** - * End block logic tokens. - * - * Format: {% endblock %} - */</span> - type: Twig.logic.type.endblock, - regex: <span class="hljs-regexp">/^endblock(?:\s+([a-zA-Z0-9_]+))?$/</span>, - next: [ ], - open: <span class="hljs-literal">false</span> - }, - { - <span class="hljs-comment">/** - * Block logic tokens. - * - * Format: {% extends "template.twig" %} - */</span> - type: Twig.logic.type.extends_, - regex: <span class="hljs-regexp">/^extends\s+(.+)$/</span>, - next: [ ], - open: <span class="hljs-literal">true</span>, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{ - <span class="hljs-keyword">var</span> expression = token.match[<span class="hljs-number">1</span>].trim(); - <span class="hljs-keyword">delete</span> token.match; - - token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{ - type: Twig.expression.type.expression, - value: expression - }]).stack; - - <span class="hljs-keyword">return</span> token; - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-202"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-202">¶</a> - </div> - <p>Resolve filename</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> file = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, context]);</pre></div></div> - - </li> - - - <li id="section-203"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-203">¶</a> - </div> - <p>Set parent template</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.extend = file; - - <span class="hljs-keyword">return</span> { - chain: chain, - output: <span class="hljs-string">''</span> - }; - } - }, - { - <span class="hljs-comment">/** - * Block logic tokens. - * - * Format: {% use "template.twig" %} - */</span> - type: Twig.logic.type.use, - regex: <span class="hljs-regexp">/^use\s+(.+)$/</span>, - next: [ ], - open: <span class="hljs-literal">true</span>, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{ - <span class="hljs-keyword">var</span> expression = token.match[<span class="hljs-number">1</span>].trim(); - <span class="hljs-keyword">delete</span> token.match; - - token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{ - type: Twig.expression.type.expression, - value: expression - }]).stack; - - <span class="hljs-keyword">return</span> token; - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-204"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-204">¶</a> - </div> - <p>Resolve filename</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> file = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, context]);</pre></div></div> - - </li> - - - <li id="section-205"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-205">¶</a> - </div> - <p>Import blocks</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.importBlocks(file); - - <span class="hljs-keyword">return</span> { - chain: chain, - output: <span class="hljs-string">''</span> - }; - } - }, - { - <span class="hljs-comment">/** - * Block logic tokens. - * - * Format: {% includes "template.twig" [with {some: 'values'} only] %} - */</span> - type: Twig.logic.type.include, - regex: <span class="hljs-regexp">/^include\s+(ignore missing\s+)?(.+?)\s*(?:with\s+([\S\s]+?))?\s*(only)?$/</span>, - next: [ ], - open: <span class="hljs-literal">true</span>, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{ - <span class="hljs-keyword">var</span> match = token.match, - includeMissing = match[<span class="hljs-number">1</span>] !== <span class="hljs-literal">undefined</span>, - expression = match[<span class="hljs-number">2</span>].trim(), - withContext = match[<span class="hljs-number">3</span>], - only = ((match[<span class="hljs-number">4</span>] !== <span class="hljs-literal">undefined</span>) && match[<span class="hljs-number">4</span>].length); - - <span class="hljs-keyword">delete</span> token.match; - - token.only = only; - token.includeMissing = includeMissing; - - token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{ - type: Twig.expression.type.expression, - value: expression - }]).stack; - - <span class="hljs-keyword">if</span> (withContext !== <span class="hljs-literal">undefined</span>) { - token.withStack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{ - type: Twig.expression.type.expression, - value: withContext.trim() - }]).stack; - } - - <span class="hljs-keyword">return</span> token; - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-206"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-206">¶</a> - </div> - <p>Resolve filename</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> innerContext = {}, - withContext, - i, - template; - - <span class="hljs-keyword">if</span> (!token.only) { - innerContext = Twig.ChildContext(context); - } - - <span class="hljs-keyword">if</span> (token.withStack !== <span class="hljs-literal">undefined</span>) { - withContext = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.withStack, context]); - - <span class="hljs-keyword">for</span> (i <span class="hljs-keyword">in</span> withContext) { - <span class="hljs-keyword">if</span> (withContext.hasOwnProperty(i)) - innerContext[i] = withContext[i]; - } - } - - <span class="hljs-keyword">var</span> file = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, innerContext]); - - <span class="hljs-keyword">if</span> (file <span class="hljs-keyword">instanceof</span> Twig.Template) { - template = file; - } <span class="hljs-keyword">else</span> {</pre></div></div> - - </li> - - - <li id="section-207"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-207">¶</a> - </div> - <p>Import file</p> - - </div> - - <div class="content"><div class='highlight'><pre> template = <span class="hljs-keyword">this</span>.importFile(file); - } - - <span class="hljs-keyword">return</span> { - chain: chain, - output: template.render(innerContext) - }; - } - }, - { - type: Twig.logic.type.spaceless, - regex: <span class="hljs-regexp">/^spaceless$/</span>, - next: [ - Twig.logic.type.endspaceless - ], - open: <span class="hljs-literal">true</span>,</pre></div></div> - - </li> - - - <li id="section-208"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-208">¶</a> - </div> - <p>Parse the html and return it without any spaces between tags</p> - - </div> - - <div class="content"><div class='highlight'><pre> parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{ - <span class="hljs-keyword">var</span> <span class="hljs-comment">// Parse the output without any filter</span> - unfiltered = Twig.parse.apply(<span class="hljs-keyword">this</span>, [token.output, context]),</pre></div></div> - - </li> - - - <li id="section-209"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-209">¶</a> - </div> - <p>A regular expression to find closing and opening tags with spaces between them</p> - - </div> - - <div class="content"><div class='highlight'><pre> rBetweenTagSpaces = <span class="hljs-regexp">/>\s+</g</span>,</pre></div></div> - - </li> - - - <li id="section-210"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-210">¶</a> - </div> - <p>Replace all space between closing and opening html tags</p> - - </div> - - <div class="content"><div class='highlight'><pre> output = unfiltered.replace(rBetweenTagSpaces,<span class="hljs-string">'><'</span>).trim(); - - <span class="hljs-keyword">return</span> { - chain: chain, - output: output - }; - } - },</pre></div></div> - - </li> - - - <li id="section-211"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-211">¶</a> - </div> - <p>Add the {% endspaceless %} token</p> - - </div> - - <div class="content"><div class='highlight'><pre> { - type: Twig.logic.type.endspaceless, - regex: <span class="hljs-regexp">/^endspaceless$/</span>, - next: [ ], - open: <span class="hljs-literal">false</span> - }, - { - <span class="hljs-comment">/** - * Macro logic tokens. - * - * Format: {% maro input(name, value, type, size) %} - * - */</span> - type: Twig.logic.type.macro, - regex: <span class="hljs-regexp">/^macro\s+([a-zA-Z0-9_]+)\s*\(\s*((?:[a-zA-Z0-9_]+(?:,\s*)?)*)\s*\)$/</span>, - next: [ - Twig.logic.type.endmacro - ], - open: <span class="hljs-literal">true</span>, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{ - <span class="hljs-keyword">var</span> macroName = token.match[<span class="hljs-number">1</span>], - parameters = token.match[<span class="hljs-number">2</span>].split(<span class="hljs-regexp">/[\s,]+/</span>);</pre></div></div> - - </li> - - - <li id="section-212"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-212">¶</a> - </div> - <p>TODO: Clean up duplicate check</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i<parameters.length; i++) { - <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> j=<span class="hljs-number">0</span>; j<parameters.length; j++){ - <span class="hljs-keyword">if</span> (parameters[i] === parameters[j] && i !== j) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Duplicate arguments for parameter: "</span>+ parameters[i]); - } - } - } - - token.macroName = macroName; - token.parameters = parameters; - - <span class="hljs-keyword">delete</span> token.match; - <span class="hljs-keyword">return</span> token; - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{ - <span class="hljs-keyword">var</span> template = <span class="hljs-keyword">this</span>; - <span class="hljs-keyword">this</span>.macros[token.macroName] = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{</pre></div></div> - - </li> - - - <li id="section-213"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-213">¶</a> - </div> - <p>Pass global context and other macros</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> macroContext = { - _self: template.macros - }</pre></div></div> - - </li> - - - <li id="section-214"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-214">¶</a> - </div> - <p>Add parameters from context to macroContext</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i<token.parameters.length; i++) { - <span class="hljs-keyword">var</span> prop = token.parameters[i]; - <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">arguments</span>[i] !== <span class="hljs-string">'undefined'</span>) { - macroContext[prop] = <span class="hljs-built_in">arguments</span>[i]; - } <span class="hljs-keyword">else</span> { - macroContext[prop] = <span class="hljs-literal">undefined</span>; - } - }</pre></div></div> - - </li> - - - <li id="section-215"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-215">¶</a> - </div> - <p>Render</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> Twig.parse.apply(template, [token.output, macroContext]) - }; - - <span class="hljs-keyword">return</span> { - chain: chain, - output: <span class="hljs-string">''</span> - }; - - } - }, - { - <span class="hljs-comment">/** - * End macro logic tokens. - * - * Format: {% endmacro %} - */</span> - type: Twig.logic.type.endmacro, - regex: <span class="hljs-regexp">/^endmacro$/</span>, - next: [ ], - open: <span class="hljs-literal">false</span> - }, - { - <span class="hljs-comment">/* - * import logic tokens. - * - * Format: {% import "template.twig" as form %} - */</span> - type: Twig.logic.type.import_, - regex: <span class="hljs-regexp">/^import\s+(.+)\s+as\s+([a-zA-Z0-9_]+)$/</span>, - next: [ ], - open: <span class="hljs-literal">true</span>, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{ - <span class="hljs-keyword">var</span> expression = token.match[<span class="hljs-number">1</span>].trim(), - contextName = token.match[<span class="hljs-number">2</span>].trim(); - <span class="hljs-keyword">delete</span> token.match; - - token.expression = expression; - token.contextName = contextName; - - token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{ - type: Twig.expression.type.expression, - value: expression - }]).stack; - - <span class="hljs-keyword">return</span> token; - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{ - <span class="hljs-keyword">if</span> (token.expression !== <span class="hljs-string">"_self"</span>) { - <span class="hljs-keyword">var</span> file = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, context]); - <span class="hljs-keyword">var</span> template = <span class="hljs-keyword">this</span>.importFile(file || token.expression); - context[token.contextName] = template.render({}, {output: <span class="hljs-string">'macros'</span>}); - } - <span class="hljs-keyword">else</span> { - context[token.contextName] = <span class="hljs-keyword">this</span>.macros; - } - - <span class="hljs-keyword">return</span> { - chain: chain, - output: <span class="hljs-string">''</span> - } - - } - }, - { - <span class="hljs-comment">/* - * from logic tokens. - * - * Format: {% from "template.twig" import func as form %} - */</span> - type: Twig.logic.type.from, - regex: <span class="hljs-regexp">/^from\s+(.+)\s+import\s+([a-zA-Z0-9_, ]+)$/</span>, - next: [ ], - open: <span class="hljs-literal">true</span>, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{ - <span class="hljs-keyword">var</span> expression = token.match[<span class="hljs-number">1</span>].trim(), - macroExpressions = token.match[<span class="hljs-number">2</span>].trim().split(<span class="hljs-regexp">/[ ,]+/</span>), - macroNames = {}; - - <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i<macroExpressions.length; i++) { - <span class="hljs-keyword">var</span> res = macroExpressions[i];</pre></div></div> - - </li> - - - <li id="section-216"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-216">¶</a> - </div> - <p>match function as variable</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> macroMatch = res.match(<span class="hljs-regexp">/^([a-zA-Z0-9_]+)\s+(.+)\s+as\s+([a-zA-Z0-9_]+)$/</span>); - <span class="hljs-keyword">if</span> (macroMatch) { - macroNames[macroMatch[<span class="hljs-number">1</span>].trim()] = macroMatch[<span class="hljs-number">2</span>].trim(); - } - <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (res.match(<span class="hljs-regexp">/^([a-zA-Z0-9_]+)$/</span>)) { - macroNames[res] = res; - } - <span class="hljs-keyword">else</span> {</pre></div></div> - - </li> - - - <li id="section-217"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-217">¶</a> - </div> - <p>ignore import</p> - - </div> - - <div class="content"><div class='highlight'><pre> } - - } - - <span class="hljs-keyword">delete</span> token.match; - - token.expression = expression; - token.macroNames = macroNames; - - token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{ - type: Twig.expression.type.expression, - value: expression - }]).stack; - - <span class="hljs-keyword">return</span> token; - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{ - <span class="hljs-keyword">var</span> macros; - - <span class="hljs-keyword">if</span> (token.expression !== <span class="hljs-string">"_self"</span>) { - <span class="hljs-keyword">var</span> file = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, context]); - <span class="hljs-keyword">var</span> template = <span class="hljs-keyword">this</span>.importFile(file || token.expression); - macros = template.render({}, {output: <span class="hljs-string">'macros'</span>}); - } - <span class="hljs-keyword">else</span> { - macros = <span class="hljs-keyword">this</span>.macros; - } - - <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> macroName <span class="hljs-keyword">in</span> token.macroNames) { - <span class="hljs-keyword">if</span> (macros.hasOwnProperty(macroName)) { - context[token.macroNames[macroName]] = macros[macroName]; - } - } - - <span class="hljs-keyword">return</span> { - chain: chain, - output: <span class="hljs-string">''</span> - } - - } - }, - { - <span class="hljs-comment">/** - * The embed tag combines the behaviour of include and extends. - * It allows you to include another template's contents, just like include does. - * - * Format: {% embed "template.twig" [with {some: 'values'} only] %} - */</span> - type: Twig.logic.type.embed, - regex: <span class="hljs-regexp">/^embed\s+(ignore missing\s+)?(.+?)\s*(?:with\s+(.+?))?\s*(only)?$/</span>, - next: [ - Twig.logic.type.endembed - ], - open: <span class="hljs-literal">true</span>, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{ - <span class="hljs-keyword">var</span> match = token.match, - includeMissing = match[<span class="hljs-number">1</span>] !== <span class="hljs-literal">undefined</span>, - expression = match[<span class="hljs-number">2</span>].trim(), - withContext = match[<span class="hljs-number">3</span>], - only = ((match[<span class="hljs-number">4</span>] !== <span class="hljs-literal">undefined</span>) && match[<span class="hljs-number">4</span>].length); - - <span class="hljs-keyword">delete</span> token.match; - - token.only = only; - token.includeMissing = includeMissing; - - token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{ - type: Twig.expression.type.expression, - value: expression - }]).stack; - - <span class="hljs-keyword">if</span> (withContext !== <span class="hljs-literal">undefined</span>) { - token.withStack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{ - type: Twig.expression.type.expression, - value: withContext.trim() - }]).stack; - } - - <span class="hljs-keyword">return</span> token; - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-218"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-218">¶</a> - </div> - <p>Resolve filename</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> innerContext = {}, - withContext, - i, - template; - - <span class="hljs-keyword">if</span> (!token.only) { - <span class="hljs-keyword">for</span> (i <span class="hljs-keyword">in</span> context) { - <span class="hljs-keyword">if</span> (context.hasOwnProperty(i)) - innerContext[i] = context[i]; - } - } - - <span class="hljs-keyword">if</span> (token.withStack !== <span class="hljs-literal">undefined</span>) { - withContext = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.withStack, context]); - - <span class="hljs-keyword">for</span> (i <span class="hljs-keyword">in</span> withContext) { - <span class="hljs-keyword">if</span> (withContext.hasOwnProperty(i)) - innerContext[i] = withContext[i]; - } - } - - <span class="hljs-keyword">var</span> file = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, innerContext]); - - <span class="hljs-keyword">if</span> (file <span class="hljs-keyword">instanceof</span> Twig.Template) { - template = file; - } <span class="hljs-keyword">else</span> {</pre></div></div> - - </li> - - - <li id="section-219"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-219">¶</a> - </div> - <p>Import file</p> - - </div> - - <div class="content"><div class='highlight'><pre> template = <span class="hljs-keyword">this</span>.importFile(file); - }</pre></div></div> - - </li> - - - <li id="section-220"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-220">¶</a> - </div> - <p>reset previous blocks</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.blocks = {};</pre></div></div> - - </li> - - - <li id="section-221"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-221">¶</a> - </div> - <p>parse tokens. output will be not used</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> output = Twig.parse.apply(<span class="hljs-keyword">this</span>, [token.output, innerContext]);</pre></div></div> - - </li> - - - <li id="section-222"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-222">¶</a> - </div> - <p>render tempalte with blocks defined in embed block</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> { - chain: chain, - output: template.render(innerContext, {<span class="hljs-string">'blocks'</span>:<span class="hljs-keyword">this</span>.blocks}) - }; - } - }, - <span class="hljs-comment">/* Add the {% endembed %} token - * - */</span> - { - type: Twig.logic.type.endembed, - regex: <span class="hljs-regexp">/^endembed$/</span>, - next: [ ], - open: <span class="hljs-literal">false</span> - } - - ]; - - - <span class="hljs-comment">/** - * Registry for logic handlers. - */</span> - Twig.logic.handler = {}; - - <span class="hljs-comment">/** - * Define a new token type, available at Twig.logic.type.{type} - */</span> - Twig.logic.extendType = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">type, value</span>) </span>{ - value = value || (<span class="hljs-string">"Twig.logic.type"</span> + type); - Twig.logic.type[type] = value; - }; - - <span class="hljs-comment">/** - * Extend the logic parsing functionality with a new token definition. - * - * // Define a new tag - * Twig.logic.extend({ - * type: Twig.logic.type.{type}, - * // The pattern to match for this token - * regex: ..., - * // What token types can follow this token, leave blank if any. - * next: [ ... ] - * // Create and return compiled version of the token - * compile: function(token) { ... } - * // Parse the compiled token with the context provided by the render call - * // and whether this token chain is complete. - * parse: function(token, context, chain) { ... } - * }); - * - * @param {Object} definition The new logic expression. - */</span> - Twig.logic.extend = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">definition</span>) </span>{ - - <span class="hljs-keyword">if</span> (!definition.type) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to extend logic definition. No type provided for "</span> + definition); - } <span class="hljs-keyword">else</span> { - Twig.logic.extendType(definition.type); - } - Twig.logic.handler[definition.type] = definition; - };</pre></div></div> - - </li> - - - <li id="section-223"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-223">¶</a> - </div> - <p>Extend with built-in expressions</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">while</span> (Twig.logic.definitions.length > <span class="hljs-number">0</span>) { - Twig.logic.extend(Twig.logic.definitions.shift()); - } - - <span class="hljs-comment">/** - * Compile a logic token into an object ready for parsing. - * - * @param {Object} raw_token An uncompiled logic token. - * - * @return {Object} A compiled logic token, ready for parsing. - */</span> - Twig.logic.compile = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">raw_token</span>) </span>{ - <span class="hljs-keyword">var</span> expression = raw_token.value.trim(), - token = Twig.logic.tokenize.apply(<span class="hljs-keyword">this</span>, [expression]), - token_template = Twig.logic.handler[token.type];</pre></div></div> - - </li> - - - <li id="section-224"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-224">¶</a> - </div> - <p>Check if the token needs compiling</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (token_template.compile) { - token = token_template.compile.apply(<span class="hljs-keyword">this</span>, [token]); - Twig.log.trace(<span class="hljs-string">"Twig.logic.compile: "</span>, <span class="hljs-string">"Compiled logic token to "</span>, token); - } - - <span class="hljs-keyword">return</span> token; - }; - - <span class="hljs-comment">/** - * Tokenize logic expressions. This function matches token expressions against regular - * expressions provided in token definitions provided with Twig.logic.extend. - * - * @param {string} expression the logic token expression to tokenize - * (i.e. what's between {% and %}) - * - * @return {Object} The matched token with type set to the token type and match to the regex match. - */</span> - Twig.logic.tokenize = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">expression</span>) </span>{ - <span class="hljs-keyword">var</span> token = {}, - token_template_type = <span class="hljs-literal">null</span>, - token_type = <span class="hljs-literal">null</span>, - token_regex = <span class="hljs-literal">null</span>, - regex_array = <span class="hljs-literal">null</span>, - regex = <span class="hljs-literal">null</span>, - match = <span class="hljs-literal">null</span>;</pre></div></div> - - </li> - - - <li id="section-225"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-225">¶</a> - </div> - <p>Ignore whitespace around expressions.</p> - - </div> - - <div class="content"><div class='highlight'><pre> expression = expression.trim(); - - <span class="hljs-keyword">for</span> (token_template_type <span class="hljs-keyword">in</span> Twig.logic.handler) { - <span class="hljs-keyword">if</span> (Twig.logic.handler.hasOwnProperty(token_template_type)) {</pre></div></div> - - </li> - - - <li id="section-226"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-226">¶</a> - </div> - <p>Get the type and regex for this template type</p> - - </div> - - <div class="content"><div class='highlight'><pre> token_type = Twig.logic.handler[token_template_type].type; - token_regex = Twig.logic.handler[token_template_type].regex;</pre></div></div> - - </li> - - - <li id="section-227"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-227">¶</a> - </div> - <p>Handle multiple regular expressions per type.</p> - - </div> - - <div class="content"><div class='highlight'><pre> regex_array = []; - <span class="hljs-keyword">if</span> (token_regex <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span>) { - regex_array = token_regex; - } <span class="hljs-keyword">else</span> { - regex_array.push(token_regex); - }</pre></div></div> - - </li> - - - <li id="section-228"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-228">¶</a> - </div> - <p>Check regular expressions in the order they were specified in the definition.</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">while</span> (regex_array.length > <span class="hljs-number">0</span>) { - regex = regex_array.shift(); - match = regex.exec(expression.trim()); - <span class="hljs-keyword">if</span> (match !== <span class="hljs-literal">null</span>) { - token.type = token_type; - token.match = match; - Twig.log.trace(<span class="hljs-string">"Twig.logic.tokenize: "</span>, <span class="hljs-string">"Matched a "</span>, token_type, <span class="hljs-string">" regular expression of "</span>, match); - <span class="hljs-keyword">return</span> token; - } - } - } - }</pre></div></div> - - </li> - - - <li id="section-229"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-229">¶</a> - </div> - <p>No regex matches</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to parse '"</span> + expression.trim() + <span class="hljs-string">"'"</span>); - }; - - <span class="hljs-comment">/** - * Parse a logic token within a given context. - * - * What are logic chains? - * Logic chains represent a series of tokens that are connected, - * for example: - * {% if ... %} {% else %} {% endif %} - * - * The chain parameter is used to signify if a chain is open of closed. - * open: - * More tokens in this chain should be parsed. - * closed: - * This token chain has completed parsing and any additional - * tokens (else, elseif, etc...) should be ignored. - * - * @param {Object} token The compiled token. - * @param {Object} context The render context. - * @param {boolean} chain Is this an open logic chain. If false, that means a - * chain is closed and no further cases should be parsed. - */</span> - Twig.logic.parse = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{ - <span class="hljs-keyword">var</span> output = <span class="hljs-string">''</span>, - token_template; - - context = context || { }; - - Twig.log.debug(<span class="hljs-string">"Twig.logic.parse: "</span>, <span class="hljs-string">"Parsing logic token "</span>, token); - - token_template = Twig.logic.handler[token.type]; - - <span class="hljs-keyword">if</span> (token_template.parse) { - output = token_template.parse.apply(<span class="hljs-keyword">this</span>, [token, context, chain]); - } - <span class="hljs-keyword">return</span> output; - }; - - <span class="hljs-keyword">return</span> Twig; - -})(Twig || { });</pre></div></div> - - </li> - - - <li id="section-230"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-230">¶</a> - </div> - <pre><code>Twig.js -Available under the BSD <span class="hljs-number">2</span>-Clause License -https:<span class="hljs-comment">//github.com/justjohn/twig.js</span> -</code></pre> - </div> - - </li> - - - <li id="section-231"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-231">¶</a> - </div> - <h2 id="twig-expression-js">twig.expression.js</h2> -<p>This file handles tokenizing, compiling and parsing expressions.</p> - - </div> - - <div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{ -<span class="hljs-meta"> "use strict"</span>; - - <span class="hljs-comment">/** - * Namespace for expression handling. - */</span> - Twig.expression = { }; - - <span class="hljs-comment">/** - * Reserved word that can't be used as variable names. - */</span> - Twig.expression.reservedWords = [ - <span class="hljs-string">"true"</span>, <span class="hljs-string">"false"</span>, <span class="hljs-string">"null"</span>, <span class="hljs-string">"TRUE"</span>, <span class="hljs-string">"FALSE"</span>, <span class="hljs-string">"NULL"</span>, <span class="hljs-string">"_context"</span> - ]; - - <span class="hljs-comment">/** - * The type of tokens used in expressions. - */</span> - Twig.expression.type = { - comma: <span class="hljs-string">'Twig.expression.type.comma'</span>, - operator: { - unary: <span class="hljs-string">'Twig.expression.type.operator.unary'</span>, - binary: <span class="hljs-string">'Twig.expression.type.operator.binary'</span> - }, - string: <span class="hljs-string">'Twig.expression.type.string'</span>, - bool: <span class="hljs-string">'Twig.expression.type.bool'</span>, - array: { - start: <span class="hljs-string">'Twig.expression.type.array.start'</span>, - end: <span class="hljs-string">'Twig.expression.type.array.end'</span> - }, - object: { - start: <span class="hljs-string">'Twig.expression.type.object.start'</span>, - end: <span class="hljs-string">'Twig.expression.type.object.end'</span> - }, - parameter: { - start: <span class="hljs-string">'Twig.expression.type.parameter.start'</span>, - end: <span class="hljs-string">'Twig.expression.type.parameter.end'</span> - }, - key: { - period: <span class="hljs-string">'Twig.expression.type.key.period'</span>, - brackets: <span class="hljs-string">'Twig.expression.type.key.brackets'</span> - }, - filter: <span class="hljs-string">'Twig.expression.type.filter'</span>, - _function: <span class="hljs-string">'Twig.expression.type._function'</span>, - variable: <span class="hljs-string">'Twig.expression.type.variable'</span>, - number: <span class="hljs-string">'Twig.expression.type.number'</span>, - _null: <span class="hljs-string">'Twig.expression.type.null'</span>, - context: <span class="hljs-string">'Twig.expression.type.context'</span>, - test: <span class="hljs-string">'Twig.expression.type.test'</span> - }; - - Twig.expression.set = {</pre></div></div> - - </li> - - - <li id="section-232"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-232">¶</a> - </div> - <p>What can follow an expression (in general)</p> - - </div> - - <div class="content"><div class='highlight'><pre> operations: [ - Twig.expression.type.filter, - Twig.expression.type.operator.unary, - Twig.expression.type.operator.binary, - Twig.expression.type.array.end, - Twig.expression.type.object.end, - Twig.expression.type.parameter.end, - Twig.expression.type.comma, - Twig.expression.type.test - ], - expressions: [ - Twig.expression.type._function, - Twig.expression.type.bool, - Twig.expression.type.string, - Twig.expression.type.variable, - Twig.expression.type.number, - Twig.expression.type._null, - Twig.expression.type.context, - Twig.expression.type.parameter.start, - Twig.expression.type.array.start, - Twig.expression.type.object.start - ] - };</pre></div></div> - - </li> - - - <li id="section-233"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-233">¶</a> - </div> - <p>Most expressions allow a ‘.’ or ‘[‘ after them, so we provide a convenience set</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.expression.set.operations_extended = Twig.expression.set.operations.concat([ - Twig.expression.type.key.period, - Twig.expression.type.key.brackets]);</pre></div></div> - - </li> - - - <li id="section-234"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-234">¶</a> - </div> - <p>Some commonly used compile and parse functions.</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.expression.fn = { - compile: { - push: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{ - output.push(token); - }, - push_both: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{ - output.push(token); - stack.push(token); - } - }, - parse: { - push: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{ - stack.push(token); - }, - push_value: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{ - stack.push(token.value); - } - } - };</pre></div></div> - - </li> - - - <li id="section-235"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-235">¶</a> - </div> - <p>The regular expressions and compile/parse logic used to match tokens in expressions.</p> -<p>Properties:</p> -<pre><code> type: The type <span class="hljs-keyword">of</span> expression <span class="hljs-keyword">this</span> matches - - regex: One or more regular expressions that matche the format <span class="hljs-keyword">of</span> the token. - - next: Valid tokens that can occur next <span class="hljs-keyword">in</span> the expression. -</code></pre><p>Functions:</p> -<pre><code> compile: A <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">that</span> <span class="hljs-title">compiles</span> <span class="hljs-title">the</span> <span class="hljs-title">raw</span> <span class="hljs-title">regular</span> <span class="hljs-title">expression</span> <span class="hljs-title">match</span> <span class="hljs-title">into</span> <span class="hljs-title">a</span> <span class="hljs-title">token</span>. - - <span class="hljs-title">parse</span>: <span class="hljs-title">A</span> <span class="hljs-title">function</span> <span class="hljs-title">that</span> <span class="hljs-title">parses</span> <span class="hljs-title">the</span> <span class="hljs-title">compiled</span> <span class="hljs-title">token</span> <span class="hljs-title">into</span> <span class="hljs-title">output</span>.</span> -</code></pre> - </div> - - <div class="content"><div class='highlight'><pre> Twig.expression.definitions = [ - { - type: Twig.expression.type.test, - regex: <span class="hljs-regexp">/^is\s+(not)?\s*([a-zA-Z_][a-zA-Z0-9_]*)/</span>, - next: Twig.expression.set.operations.concat([Twig.expression.type.parameter.start]), - compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{ - token.filter = token.match[<span class="hljs-number">2</span>]; - token.modifier = token.match[<span class="hljs-number">1</span>]; - <span class="hljs-keyword">delete</span> token.match; - <span class="hljs-keyword">delete</span> token.value; - output.push(token); - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{ - <span class="hljs-keyword">var</span> value = stack.pop(), - params = token.params && Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.params, context]), - result = Twig.test(token.filter, value, params); - - <span class="hljs-keyword">if</span> (token.modifier == <span class="hljs-string">'not'</span>) { - stack.push(!result); - } <span class="hljs-keyword">else</span> { - stack.push(result); - } - } - }, - { - type: Twig.expression.type.comma,</pre></div></div> - - </li> - - - <li id="section-236"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-236">¶</a> - </div> - <p>Match a comma</p> - - </div> - - <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/^,/</span>, - next: Twig.expression.set.expressions.concat([Twig.expression.type.array.end, Twig.expression.type.object.end]), - compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{ - <span class="hljs-keyword">var</span> i = stack.length - <span class="hljs-number">1</span>, - stack_token; - - <span class="hljs-keyword">delete</span> token.match; - <span class="hljs-keyword">delete</span> token.value;</pre></div></div> - - </li> - - - <li id="section-237"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-237">¶</a> - </div> - <p>pop tokens off the stack until the start of the object</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span>(;i >= <span class="hljs-number">0</span>; i--) { - stack_token = stack.pop(); - <span class="hljs-keyword">if</span> (stack_token.type === Twig.expression.type.object.start - || stack_token.type === Twig.expression.type.parameter.start - || stack_token.type === Twig.expression.type.array.start) { - stack.push(stack_token); - <span class="hljs-keyword">break</span>; - } - output.push(stack_token); - } - output.push(token); - } - }, - { - type: Twig.expression.type.operator.binary,</pre></div></div> - - </li> - - - <li id="section-238"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-238">¶</a> - </div> - <p>Match any of +, <em>, /, -, %, ~, <, <=, >, >=, !=, ==, *</em>, ?, :, and, or, not</p> - - </div> - - <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/(^[\+\-~%\?\:]|^[!=]==?|^[!<>]=?|^\*\*?|^\/\/?|^and\s+|^or\s+|^in\s+|^not in\s+|^\.\.)/</span>, - next: Twig.expression.set.expressions.concat([Twig.expression.type.operator.unary]), - compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{ - <span class="hljs-keyword">delete</span> token.match; - - token.value = token.value.trim(); - <span class="hljs-keyword">var</span> value = token.value, - operator = Twig.expression.operator.lookup(value, token); - - Twig.log.trace(<span class="hljs-string">"Twig.expression.compile: "</span>, <span class="hljs-string">"Operator: "</span>, operator, <span class="hljs-string">" from "</span>, value); - - <span class="hljs-keyword">while</span> (stack.length > <span class="hljs-number">0</span> && - (stack[stack.length<span class="hljs-number">-1</span>].type == Twig.expression.type.operator.unary || stack[stack.length<span class="hljs-number">-1</span>].type == Twig.expression.type.operator.binary) && - ( - (operator.associativity === Twig.expression.operator.leftToRight && - operator.precidence >= stack[stack.length<span class="hljs-number">-1</span>].precidence) || - - (operator.associativity === Twig.expression.operator.rightToLeft && - operator.precidence > stack[stack.length<span class="hljs-number">-1</span>].precidence) - ) - ) { - <span class="hljs-keyword">var</span> temp = stack.pop(); - output.push(temp); - } - - <span class="hljs-keyword">if</span> (value === <span class="hljs-string">":"</span>) {</pre></div></div> - - </li> - - - <li id="section-239"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-239">¶</a> - </div> - <p>Check if this is a ternary or object key being set</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (stack[stack.length - <span class="hljs-number">1</span>] && stack[stack.length<span class="hljs-number">-1</span>].value === <span class="hljs-string">"?"</span>) {</pre></div></div> - - </li> - - - <li id="section-240"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-240">¶</a> - </div> - <p>Continue as normal for a ternary</p> - - </div> - - <div class="content"><div class='highlight'><pre> } <span class="hljs-keyword">else</span> {</pre></div></div> - - </li> - - - <li id="section-241"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-241">¶</a> - </div> - <p>This is not a ternary so we push the token to the output where it can be handled - when the assocated object is closed.</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> key_token = output.pop(); - - <span class="hljs-keyword">if</span> (key_token.type === Twig.expression.type.string || - key_token.type === Twig.expression.type.variable) { - token.key = key_token.value; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (key_token.type === Twig.expression.type.number) {</pre></div></div> - - </li> - - - <li id="section-242"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-242">¶</a> - </div> - <p>Convert integer keys into string keys</p> - - </div> - - <div class="content"><div class='highlight'><pre> token.key = key_token.value.toString(); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (key_token.type === Twig.expression.type.parameter.end && - key_token.expression) { - token.params = key_token.params; - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unexpected value before ':' of "</span> + key_token.type + <span class="hljs-string">" = "</span> + key_token.value); - } - - output.push(token); - <span class="hljs-keyword">return</span>; - } - } <span class="hljs-keyword">else</span> { - stack.push(operator); - } - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{ - <span class="hljs-keyword">if</span> (token.key) {</pre></div></div> - - </li> - - - <li id="section-243"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-243">¶</a> - </div> - <p>handle ternary ‘:’ operator</p> - - </div> - - <div class="content"><div class='highlight'><pre> stack.push(token); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (token.params) {</pre></div></div> - - </li> - - - <li id="section-244"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-244">¶</a> - </div> - <p>handle “{(expression):value}”</p> - - </div> - - <div class="content"><div class='highlight'><pre> token.key = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.params, context]); - stack.push(token); - <span class="hljs-keyword">delete</span>(token.params); - } <span class="hljs-keyword">else</span> { - Twig.expression.operator.parse(token.value, stack); - } - } - }, - { - type: Twig.expression.type.operator.unary,</pre></div></div> - - </li> - - - <li id="section-245"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-245">¶</a> - </div> - <p>Match any of not</p> - - </div> - - <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/(^not\s+)/</span>, - next: Twig.expression.set.expressions, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{ - <span class="hljs-keyword">delete</span> token.match; - - token.value = token.value.trim(); - <span class="hljs-keyword">var</span> value = token.value, - operator = Twig.expression.operator.lookup(value, token); - - Twig.log.trace(<span class="hljs-string">"Twig.expression.compile: "</span>, <span class="hljs-string">"Operator: "</span>, operator, <span class="hljs-string">" from "</span>, value); - - <span class="hljs-keyword">while</span> (stack.length > <span class="hljs-number">0</span> && - (stack[stack.length<span class="hljs-number">-1</span>].type == Twig.expression.type.operator.unary || stack[stack.length<span class="hljs-number">-1</span>].type == Twig.expression.type.operator.binary) && - ( - (operator.associativity === Twig.expression.operator.leftToRight && - operator.precidence >= stack[stack.length<span class="hljs-number">-1</span>].precidence) || - - (operator.associativity === Twig.expression.operator.rightToLeft && - operator.precidence > stack[stack.length<span class="hljs-number">-1</span>].precidence) - ) - ) { - <span class="hljs-keyword">var</span> temp = stack.pop(); - output.push(temp); - } - - stack.push(operator); - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{ - Twig.expression.operator.parse(token.value, stack); - } - }, - { - <span class="hljs-comment">/** - * Match a string. This is anything between a pair of single or double quotes. - */</span> - type: Twig.expression.type.string,</pre></div></div> - - </li> - - - <li id="section-246"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-246">¶</a> - </div> - <p>See: <a href="http://blog.stevenlevithan.com/archives/match-quoted-string">http://blog.stevenlevithan.com/archives/match-quoted-string</a></p> - - </div> - - <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/^(["'])(?:(?=(\\?))\2[\s\S])*?\1/</span>, - next: Twig.expression.set.operations, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{ - <span class="hljs-keyword">var</span> value = token.value; - <span class="hljs-keyword">delete</span> token.match</pre></div></div> - - </li> - - - <li id="section-247"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-247">¶</a> - </div> - <p>Remove the quotes from the string</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (value.substring(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>) === <span class="hljs-string">'"'</span>) { - value = value.replace(<span class="hljs-string">'\\"'</span>, <span class="hljs-string">'"'</span>); - } <span class="hljs-keyword">else</span> { - value = value.replace(<span class="hljs-string">"\\'"</span>, <span class="hljs-string">"'"</span>); - } - token.value = value.substring(<span class="hljs-number">1</span>, value.length<span class="hljs-number">-1</span>).replace( <span class="hljs-regexp">/\\n/g</span>, <span class="hljs-string">"\n"</span> ).replace( <span class="hljs-regexp">/\\r/g</span>, <span class="hljs-string">"\r"</span> ); - Twig.log.trace(<span class="hljs-string">"Twig.expression.compile: "</span>, <span class="hljs-string">"String value: "</span>, token.value); - output.push(token); - }, - parse: Twig.expression.fn.parse.push_value - }, - { - <span class="hljs-comment">/** - * Match a parameter set start. - */</span> - type: Twig.expression.type.parameter.start, - regex: <span class="hljs-regexp">/^\(/</span>, - next: Twig.expression.set.expressions.concat([Twig.expression.type.parameter.end]), - compile: Twig.expression.fn.compile.push_both, - parse: Twig.expression.fn.parse.push - }, - { - <span class="hljs-comment">/** - * Match a parameter set end. - */</span> - type: Twig.expression.type.parameter.end, - regex: <span class="hljs-regexp">/^\)/</span>, - next: Twig.expression.set.operations_extended, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{ - <span class="hljs-keyword">var</span> stack_token, - end_token = token; - - stack_token = stack.pop(); - <span class="hljs-keyword">while</span>(stack.length > <span class="hljs-number">0</span> && stack_token.type != Twig.expression.type.parameter.start) { - output.push(stack_token); - stack_token = stack.pop(); - }</pre></div></div> - - </li> - - - <li id="section-248"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-248">¶</a> - </div> - <p>Move contents of parens into preceding filter</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> param_stack = []; - <span class="hljs-keyword">while</span>(token.type !== Twig.expression.type.parameter.start) {</pre></div></div> - - </li> - - - <li id="section-249"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-249">¶</a> - </div> - <p>Add token to arguments stack</p> - - </div> - - <div class="content"><div class='highlight'><pre> param_stack.unshift(token); - token = output.pop(); - } - param_stack.unshift(token); - - <span class="hljs-keyword">var</span> is_expression = <span class="hljs-literal">false</span>;</pre></div></div> - - </li> - - - <li id="section-250"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-250">¶</a> - </div> - <p>Get the token preceding the parameters</p> - - </div> - - <div class="content"><div class='highlight'><pre> token = output[output.length<span class="hljs-number">-1</span>]; - - <span class="hljs-keyword">if</span> (token === <span class="hljs-literal">undefined</span> || - (token.type !== Twig.expression.type._function && - token.type !== Twig.expression.type.filter && - token.type !== Twig.expression.type.test && - token.type !== Twig.expression.type.key.brackets && - token.type !== Twig.expression.type.key.period)) { - - end_token.expression = <span class="hljs-literal">true</span>;</pre></div></div> - - </li> - - - <li id="section-251"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-251">¶</a> - </div> - <p>remove start and end token from stack</p> - - </div> - - <div class="content"><div class='highlight'><pre> param_stack.pop(); - param_stack.shift(); - - end_token.params = param_stack; - - output.push(end_token); - - } <span class="hljs-keyword">else</span> { - end_token.expression = <span class="hljs-literal">false</span>; - token.params = param_stack; - } - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{ - <span class="hljs-keyword">var</span> new_array = [], - array_ended = <span class="hljs-literal">false</span>, - value = <span class="hljs-literal">null</span>; - - <span class="hljs-keyword">if</span> (token.expression) { - value = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.params, context]) - stack.push(value); - - } <span class="hljs-keyword">else</span> { - - <span class="hljs-keyword">while</span> (stack.length > <span class="hljs-number">0</span>) { - value = stack.pop();</pre></div></div> - - </li> - - - <li id="section-252"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-252">¶</a> - </div> - <p>Push values into the array until the start of the array</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (value && value.type && value.type == Twig.expression.type.parameter.start) { - array_ended = <span class="hljs-literal">true</span>; - <span class="hljs-keyword">break</span>; - } - new_array.unshift(value); - } - - <span class="hljs-keyword">if</span> (!array_ended) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Expected end of parameter set."</span>); - } - - stack.push(new_array); - } - } - }, - { - <span class="hljs-comment">/** - * Match an array start. - */</span> - type: Twig.expression.type.array.start, - regex: <span class="hljs-regexp">/^\[/</span>, - next: Twig.expression.set.expressions.concat([Twig.expression.type.array.end]), - compile: Twig.expression.fn.compile.push_both, - parse: Twig.expression.fn.parse.push - }, - { - <span class="hljs-comment">/** - * Match an array end. - */</span> - type: Twig.expression.type.array.end, - regex: <span class="hljs-regexp">/^\]/</span>, - next: Twig.expression.set.operations_extended, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{ - <span class="hljs-keyword">var</span> i = stack.length - <span class="hljs-number">1</span>, - stack_token;</pre></div></div> - - </li> - - - <li id="section-253"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-253">¶</a> - </div> - <p>pop tokens off the stack until the start of the object</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span>(;i >= <span class="hljs-number">0</span>; i--) { - stack_token = stack.pop(); - <span class="hljs-keyword">if</span> (stack_token.type === Twig.expression.type.array.start) { - <span class="hljs-keyword">break</span>; - } - output.push(stack_token); - } - output.push(token); - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{ - <span class="hljs-keyword">var</span> new_array = [], - array_ended = <span class="hljs-literal">false</span>, - value = <span class="hljs-literal">null</span>; - - <span class="hljs-keyword">while</span> (stack.length > <span class="hljs-number">0</span>) { - value = stack.pop();</pre></div></div> - - </li> - - - <li id="section-254"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-254">¶</a> - </div> - <p>Push values into the array until the start of the array</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (value.type && value.type == Twig.expression.type.array.start) { - array_ended = <span class="hljs-literal">true</span>; - <span class="hljs-keyword">break</span>; - } - new_array.unshift(value); - } - <span class="hljs-keyword">if</span> (!array_ended) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Expected end of array."</span>); - } - - stack.push(new_array); - } - },</pre></div></div> - - </li> - - - <li id="section-255"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-255">¶</a> - </div> - <p>Token that represents the start of a hash map ‘}’</p> -<p>Hash maps take the form: - { “key”: ‘value’, “another_key”: item }</p> -<p>Keys must be quoted (either single or double) and values can be any expression.</p> - - </div> - - <div class="content"><div class='highlight'><pre> { - type: Twig.expression.type.object.start, - regex: <span class="hljs-regexp">/^\{/</span>, - next: Twig.expression.set.expressions.concat([Twig.expression.type.object.end]), - compile: Twig.expression.fn.compile.push_both, - parse: Twig.expression.fn.parse.push - },</pre></div></div> - - </li> - - - <li id="section-256"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-256">¶</a> - </div> - <p>Token that represents the end of a Hash Map ‘}’</p> -<p>This is where the logic for building the internal -representation of a hash map is defined.</p> - - </div> - - <div class="content"><div class='highlight'><pre> { - type: Twig.expression.type.object.end, - regex: <span class="hljs-regexp">/^\}/</span>, - next: Twig.expression.set.operations_extended, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{ - <span class="hljs-keyword">var</span> i = stack.length<span class="hljs-number">-1</span>, - stack_token;</pre></div></div> - - </li> - - - <li id="section-257"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-257">¶</a> - </div> - <p>pop tokens off the stack until the start of the object</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span>(;i >= <span class="hljs-number">0</span>; i--) { - stack_token = stack.pop(); - <span class="hljs-keyword">if</span> (stack_token && stack_token.type === Twig.expression.type.object.start) { - <span class="hljs-keyword">break</span>; - } - output.push(stack_token); - } - output.push(token); - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">end_token, stack, context</span>) </span>{ - <span class="hljs-keyword">var</span> new_object = {}, - object_ended = <span class="hljs-literal">false</span>, - token = <span class="hljs-literal">null</span>, - token_key = <span class="hljs-literal">null</span>, - has_value = <span class="hljs-literal">false</span>, - value = <span class="hljs-literal">null</span>; - - <span class="hljs-keyword">while</span> (stack.length > <span class="hljs-number">0</span>) { - token = stack.pop();</pre></div></div> - - </li> - - - <li id="section-258"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-258">¶</a> - </div> - <p>Push values into the array until the start of the object</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (token && token.type && token.type === Twig.expression.type.object.start) { - object_ended = <span class="hljs-literal">true</span>; - <span class="hljs-keyword">break</span>; - } - <span class="hljs-keyword">if</span> (token && token.type && (token.type === Twig.expression.type.operator.binary || token.type === Twig.expression.type.operator.unary) && token.key) { - <span class="hljs-keyword">if</span> (!has_value) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Missing value for key '"</span> + token.key + <span class="hljs-string">"' in object definition."</span>); - } - new_object[token.key] = value;</pre></div></div> - - </li> - - - <li id="section-259"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-259">¶</a> - </div> - <p>Preserve the order that elements are added to the map -This is necessary since JavaScript objects don’t -guarantee the order of keys</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (new_object._keys === <span class="hljs-literal">undefined</span>) new_object._keys = []; - new_object._keys.unshift(token.key);</pre></div></div> - - </li> - - - <li id="section-260"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-260">¶</a> - </div> - <p>reset value check</p> - - </div> - - <div class="content"><div class='highlight'><pre> value = <span class="hljs-literal">null</span>; - has_value = <span class="hljs-literal">false</span>; - - } <span class="hljs-keyword">else</span> { - has_value = <span class="hljs-literal">true</span>; - value = token; - } - } - <span class="hljs-keyword">if</span> (!object_ended) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unexpected end of object."</span>); - } - - stack.push(new_object); - } - },</pre></div></div> - - </li> - - - <li id="section-261"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-261">¶</a> - </div> - <p>Token representing a filter</p> -<p>Filters can follow any expression and take the form: - expression|filter(optional, args)</p> -<p>Filter parsing is done in the Twig.filters namespace.</p> - - </div> - - <div class="content"><div class='highlight'><pre> { - type: Twig.expression.type.filter,</pre></div></div> - - </li> - - - <li id="section-262"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-262">¶</a> - </div> - <p>match a | then a letter or <em>, then any number of letters, numbers, </em> or -</p> - - </div> - - <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/^\|\s?([a-zA-Z_][a-zA-Z0-9_\-]*)/</span>, - next: Twig.expression.set.operations_extended.concat([ - Twig.expression.type.parameter.start]), - compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{ - token.value = token.match[<span class="hljs-number">1</span>]; - output.push(token); - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{ - <span class="hljs-keyword">var</span> input = stack.pop(), - params = token.params && Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.params, context]); - - stack.push(Twig.filter.apply(<span class="hljs-keyword">this</span>, [token.value, input, params])); - } - }, - { - type: Twig.expression.type._function,</pre></div></div> - - </li> - - - <li id="section-263"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-263">¶</a> - </div> - <p>match any letter or <em>, then any number of letters, numbers, </em> or - followed by (</p> - - </div> - - <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/^([a-zA-Z_][a-zA-Z0-9_]*)\s*\(/</span>, - next: Twig.expression.type.parameter.start, - transform: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">match, tokens</span>) </span>{ - <span class="hljs-keyword">return</span> <span class="hljs-string">'('</span>; - }, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{ - <span class="hljs-keyword">var</span> fn = token.match[<span class="hljs-number">1</span>]; - token.fn = fn;</pre></div></div> - - </li> - - - <li id="section-264"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-264">¶</a> - </div> - <p>cleanup token</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">delete</span> token.match; - <span class="hljs-keyword">delete</span> token.value; - - output.push(token); - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{ - <span class="hljs-keyword">var</span> params = token.params && Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.params, context]), - fn = token.fn, - value; - - <span class="hljs-keyword">if</span> (Twig.functions[fn]) {</pre></div></div> - - </li> - - - <li id="section-265"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-265">¶</a> - </div> - <p>Get the function from the built-in functions</p> - - </div> - - <div class="content"><div class='highlight'><pre> value = Twig.functions[fn].apply(<span class="hljs-keyword">this</span>, params); - - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> context[fn] == <span class="hljs-string">'function'</span>) {</pre></div></div> - - </li> - - - <li id="section-266"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-266">¶</a> - </div> - <p>Get the function from the user/context defined functions</p> - - </div> - - <div class="content"><div class='highlight'><pre> value = context[fn].apply(context, params); - - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(fn + <span class="hljs-string">' function does not exist and is not defined in the context'</span>); - } - - stack.push(value); - } - },</pre></div></div> - - </li> - - - <li id="section-267"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-267">¶</a> - </div> - <p>Token representing a variable.</p> -<p>Variables can contain letters, numbers, underscores and -dashes, but must start with a letter or underscore.</p> -<p>Variables are retrieved from the render context and take -the value of ‘undefined’ if the given variable doesn’t -exist in the context.</p> - - </div> - - <div class="content"><div class='highlight'><pre> { - type: Twig.expression.type.variable,</pre></div></div> - - </li> - - - <li id="section-268"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-268">¶</a> - </div> - <p>match any letter or <em>, then any number of letters, numbers, </em> or -</p> - - </div> - - <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/^[a-zA-Z_][a-zA-Z0-9_]*/</span>, - next: Twig.expression.set.operations_extended.concat([ - Twig.expression.type.parameter.start]), - compile: Twig.expression.fn.compile.push, - validate: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">match, tokens</span>) </span>{ - <span class="hljs-keyword">return</span> (Twig.indexOf(Twig.expression.reservedWords, match[<span class="hljs-number">0</span>]) < <span class="hljs-number">0</span>); - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-269"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-269">¶</a> - </div> - <p>Get the variable from the context</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> value = Twig.expression.resolve(context[token.value], context); - stack.push(value); - } - }, - { - type: Twig.expression.type.key.period, - regex: <span class="hljs-regexp">/^\.([a-zA-Z0-9_]+)/</span>, - next: Twig.expression.set.operations_extended.concat([ - Twig.expression.type.parameter.start]), - compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{ - token.key = token.match[<span class="hljs-number">1</span>]; - <span class="hljs-keyword">delete</span> token.match; - <span class="hljs-keyword">delete</span> token.value; - - output.push(token); - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{ - <span class="hljs-keyword">var</span> params = token.params && Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.params, context]), - key = token.key, - object = stack.pop(), - value; - - <span class="hljs-keyword">if</span> (object === <span class="hljs-literal">null</span> || object === <span class="hljs-literal">undefined</span>) { - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.options.strict_variables) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Can't access a key "</span> + key + <span class="hljs-string">" on an null or undefined object."</span>); - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; - } - } - - <span class="hljs-keyword">var</span> capitalize = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{<span class="hljs-keyword">return</span> value.substr(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>).toUpperCase() + value.substr(<span class="hljs-number">1</span>);};</pre></div></div> - - </li> - - - <li id="section-270"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-270">¶</a> - </div> - <p>Get the variable from the context</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object === <span class="hljs-string">'object'</span> && key <span class="hljs-keyword">in</span> object) { - value = object[key]; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (object[<span class="hljs-string">"get"</span>+capitalize(key)] !== <span class="hljs-literal">undefined</span>) { - value = object[<span class="hljs-string">"get"</span>+capitalize(key)]; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (object[<span class="hljs-string">"is"</span>+capitalize(key)] !== <span class="hljs-literal">undefined</span>) { - value = object[<span class="hljs-string">"is"</span>+capitalize(key)]; - } <span class="hljs-keyword">else</span> { - value = <span class="hljs-literal">undefined</span>; - } - stack.push(Twig.expression.resolve(value, object, params)); - } - }, - { - type: Twig.expression.type.key.brackets, - regex: <span class="hljs-regexp">/^\[([^\]]*)\]/</span>, - next: Twig.expression.set.operations_extended.concat([ - Twig.expression.type.parameter.start]), - compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{ - <span class="hljs-keyword">var</span> match = token.match[<span class="hljs-number">1</span>]; - <span class="hljs-keyword">delete</span> token.value; - <span class="hljs-keyword">delete</span> token.match;</pre></div></div> - - </li> - - - <li id="section-271"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-271">¶</a> - </div> - <p>The expression stack for the key</p> - - </div> - - <div class="content"><div class='highlight'><pre> token.stack = Twig.expression.compile({ - value: match - }).stack; - - output.push(token); - }, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-272"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-272">¶</a> - </div> - <p>Evaluate key</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> params = token.params && Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.params, context]), - key = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, context]), - object = stack.pop(), - value; - - <span class="hljs-keyword">if</span> (object === <span class="hljs-literal">null</span> || object === <span class="hljs-literal">undefined</span>) { - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.options.strict_variables) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Can't access a key "</span> + key + <span class="hljs-string">" on an null or undefined object."</span>); - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; - } - }</pre></div></div> - - </li> - - - <li id="section-273"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-273">¶</a> - </div> - <p>Get the variable from the context</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object === <span class="hljs-string">'object'</span> && key <span class="hljs-keyword">in</span> object) { - value = object[key]; - } <span class="hljs-keyword">else</span> { - value = <span class="hljs-literal">null</span>; - } - stack.push(Twig.expression.resolve(value, object, params)); - } - }, - { - <span class="hljs-comment">/** - * Match a null value. - */</span> - type: Twig.expression.type._null,</pre></div></div> - - </li> - - - <li id="section-274"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-274">¶</a> - </div> - <p>match a number</p> - - </div> - - <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/^(null|NULL|none|NONE)/</span>, - next: Twig.expression.set.operations, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{ - <span class="hljs-keyword">delete</span> token.match; - token.value = <span class="hljs-literal">null</span>; - output.push(token); - }, - parse: Twig.expression.fn.parse.push_value - }, - { - <span class="hljs-comment">/** - * Match the context - */</span> - type: Twig.expression.type.context, - regex: <span class="hljs-regexp">/^_context/</span>, - next: Twig.expression.set.operations_extended.concat([ - Twig.expression.type.parameter.start]), - compile: Twig.expression.fn.compile.push, - parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{ - stack.push(context); - } - }, - { - <span class="hljs-comment">/** - * Match a number (integer or decimal) - */</span> - type: Twig.expression.type.number,</pre></div></div> - - </li> - - - <li id="section-275"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-275">¶</a> - </div> - <p>match a number</p> - - </div> - - <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/^\-?\d+(\.\d+)?/</span>, - next: Twig.expression.set.operations, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{ - token.value = <span class="hljs-built_in">Number</span>(token.value); - output.push(token); - }, - parse: Twig.expression.fn.parse.push_value - }, - { - <span class="hljs-comment">/** - * Match a boolean - */</span> - type: Twig.expression.type.bool, - regex: <span class="hljs-regexp">/^(true|TRUE|false|FALSE)/</span>, - next: Twig.expression.set.operations, - compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{ - token.value = (token.match[<span class="hljs-number">0</span>].toLowerCase( ) === <span class="hljs-string">"true"</span>); - <span class="hljs-keyword">delete</span> token.match; - output.push(token); - }, - parse: Twig.expression.fn.parse.push_value - } - ]; - - <span class="hljs-comment">/** - * Resolve a context value. - * - * If the value is a function, it is executed with a context parameter. - * - * @param {string} key The context object key. - * @param {Object} context The render context. - */</span> - Twig.expression.resolve = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, context, params</span>) </span>{ - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> value == <span class="hljs-string">'function'</span>) { - <span class="hljs-keyword">return</span> value.apply(context, params || []); - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">return</span> value; - } - }; - - <span class="hljs-comment">/** - * Registry for logic handlers. - */</span> - Twig.expression.handler = {}; - - <span class="hljs-comment">/** - * Define a new expression type, available at Twig.logic.type.{type} - * - * @param {string} type The name of the new type. - */</span> - Twig.expression.extendType = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">type</span>) </span>{ - Twig.expression.type[type] = <span class="hljs-string">"Twig.expression.type."</span> + type; - }; - - <span class="hljs-comment">/** - * Extend the expression parsing functionality with a new definition. - * - * Token definitions follow this format: - * { - * type: One of Twig.expression.type.[type], either pre-defined or added using - * Twig.expression.extendType - * - * next: Array of types from Twig.expression.type that can follow this token, - * - * regex: A regex or array of regex's that should match the token. - * - * compile: function(token, stack, output) called when this token is being compiled. - * Should return an object with stack and output set. - * - * parse: function(token, stack, context) called when this token is being parsed. - * Should return an object with stack and context set. - * } - * - * @param {Object} definition A token definition. - */</span> - Twig.expression.extend = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">definition</span>) </span>{ - <span class="hljs-keyword">if</span> (!definition.type) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to extend logic definition. No type provided for "</span> + definition); - } - Twig.expression.handler[definition.type] = definition; - };</pre></div></div> - - </li> - - - <li id="section-276"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-276">¶</a> - </div> - <p>Extend with built-in expressions</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">while</span> (Twig.expression.definitions.length > <span class="hljs-number">0</span>) { - Twig.expression.extend(Twig.expression.definitions.shift()); - } - - <span class="hljs-comment">/** - * Break an expression into tokens defined in Twig.expression.definitions. - * - * @param {string} expression The string to tokenize. - * - * @return {Array} An array of tokens. - */</span> - Twig.expression.tokenize = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">expression</span>) </span>{ - <span class="hljs-keyword">var</span> tokens = [],</pre></div></div> - - </li> - - - <li id="section-277"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-277">¶</a> - </div> - <p>Keep an offset of the location in the expression for error messages.</p> - - </div> - - <div class="content"><div class='highlight'><pre> exp_offset = <span class="hljs-number">0</span>,</pre></div></div> - - </li> - - - <li id="section-278"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-278">¶</a> - </div> - <p>The valid next tokens of the previous token</p> - - </div> - - <div class="content"><div class='highlight'><pre> next = <span class="hljs-literal">null</span>,</pre></div></div> - - </li> - - - <li id="section-279"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-279">¶</a> - </div> - <p>Match information</p> - - </div> - - <div class="content"><div class='highlight'><pre> type, regex, regex_array,</pre></div></div> - - </li> - - - <li id="section-280"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-280">¶</a> - </div> - <p>The possible next token for the match</p> - - </div> - - <div class="content"><div class='highlight'><pre> token_next,</pre></div></div> - - </li> - - - <li id="section-281"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-281">¶</a> - </div> - <p>Has a match been found from the definitions</p> - - </div> - - <div class="content"><div class='highlight'><pre> match_found, invalid_matches = [], match_function; - - match_function = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ - <span class="hljs-keyword">var</span> match = <span class="hljs-built_in">Array</span>.prototype.slice.apply(<span class="hljs-built_in">arguments</span>), - string = match.pop(), - offset = match.pop(); - - Twig.log.trace(<span class="hljs-string">"Twig.expression.tokenize"</span>, - <span class="hljs-string">"Matched a "</span>, type, <span class="hljs-string">" regular expression of "</span>, match); - - <span class="hljs-keyword">if</span> (next && Twig.indexOf(next, type) < <span class="hljs-number">0</span>) { - invalid_matches.push( - type + <span class="hljs-string">" cannot follow a "</span> + tokens[tokens.length - <span class="hljs-number">1</span>].type + - <span class="hljs-string">" at template:"</span> + exp_offset + <span class="hljs-string">" near '"</span> + match[<span class="hljs-number">0</span>].substring(<span class="hljs-number">0</span>, <span class="hljs-number">20</span>) + - <span class="hljs-string">"...'"</span> - );</pre></div></div> - - </li> - - - <li id="section-282"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-282">¶</a> - </div> - <p>Not a match, don’t change the expression</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> match[<span class="hljs-number">0</span>]; - }</pre></div></div> - - </li> - - - <li id="section-283"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-283">¶</a> - </div> - <p>Validate the token if a validation function is provided</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (Twig.expression.handler[type].validate && - !Twig.expression.handler[type].validate(match, tokens)) { - <span class="hljs-keyword">return</span> match[<span class="hljs-number">0</span>]; - } - - invalid_matches = []; - - tokens.push({ - type: type, - value: match[<span class="hljs-number">0</span>], - match: match - }); - - match_found = <span class="hljs-literal">true</span>; - next = token_next; - exp_offset += match[<span class="hljs-number">0</span>].length;</pre></div></div> - - </li> - - - <li id="section-284"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-284">¶</a> - </div> - <p>Does the token need to return output back to the expression string -e.g. a function match of cycle( might return the ‘(‘ back to the expression -This allows look-ahead to differentiate between token types (e.g. functions and variable names)</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (Twig.expression.handler[type].transform) { - <span class="hljs-keyword">return</span> Twig.expression.handler[type].transform(match, tokens); - } - <span class="hljs-keyword">return</span> <span class="hljs-string">''</span>; - }; - - Twig.log.debug(<span class="hljs-string">"Twig.expression.tokenize"</span>, <span class="hljs-string">"Tokenizing expression "</span>, expression); - - <span class="hljs-keyword">while</span> (expression.length > <span class="hljs-number">0</span>) { - expression = expression.trim(); - <span class="hljs-keyword">for</span> (type <span class="hljs-keyword">in</span> Twig.expression.handler) { - <span class="hljs-keyword">if</span> (Twig.expression.handler.hasOwnProperty(type)) { - token_next = Twig.expression.handler[type].next; - regex = Twig.expression.handler[type].regex;</pre></div></div> - - </li> - - - <li id="section-285"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-285">¶</a> - </div> - <p>Twig.log.trace(“Checking type “, type, “ on “, expression);</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (regex <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span>) { - regex_array = regex; - } <span class="hljs-keyword">else</span> { - regex_array = [regex]; - } - - match_found = <span class="hljs-literal">false</span>; - <span class="hljs-keyword">while</span> (regex_array.length > <span class="hljs-number">0</span>) { - regex = regex_array.pop(); - expression = expression.replace(regex, match_function); - }</pre></div></div> - - </li> - - - <li id="section-286"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-286">¶</a> - </div> - <p>An expression token has been matched. Break the for loop and start trying to - match the next template (if expression isn’t empty.)</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match_found) { - <span class="hljs-keyword">break</span>; - } - } - } - <span class="hljs-keyword">if</span> (!match_found) { - <span class="hljs-keyword">if</span> (invalid_matches.length > <span class="hljs-number">0</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(invalid_matches.join(<span class="hljs-string">" OR "</span>)); - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to parse '"</span> + expression + <span class="hljs-string">"' at template position"</span> + exp_offset); - } - } - } - - Twig.log.trace(<span class="hljs-string">"Twig.expression.tokenize"</span>, <span class="hljs-string">"Tokenized to "</span>, tokens); - <span class="hljs-keyword">return</span> tokens; - }; - - <span class="hljs-comment">/** - * Compile an expression token. - * - * @param {Object} raw_token The uncompiled token. - * - * @return {Object} The compiled token. - */</span> - Twig.expression.compile = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">raw_token</span>) </span>{ - <span class="hljs-keyword">var</span> expression = raw_token.value,</pre></div></div> - - </li> - - - <li id="section-287"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-287">¶</a> - </div> - <p>Tokenize expression</p> - - </div> - - <div class="content"><div class='highlight'><pre> tokens = Twig.expression.tokenize(expression), - token = <span class="hljs-literal">null</span>, - output = [], - stack = [], - token_template = <span class="hljs-literal">null</span>; - - Twig.log.trace(<span class="hljs-string">"Twig.expression.compile: "</span>, <span class="hljs-string">"Compiling "</span>, expression);</pre></div></div> - - </li> - - - <li id="section-288"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-288">¶</a> - </div> - <p>Push tokens into RPN stack using the Sunting-yard algorithm -See <a href="http://en.wikipedia.org/wiki/Shunting_yard_algorithm">http://en.wikipedia.org/wiki/Shunting_yard_algorithm</a></p> - - </div> - - <div class="content"><div class='highlight'><pre> - <span class="hljs-keyword">while</span> (tokens.length > <span class="hljs-number">0</span>) { - token = tokens.shift(); - token_template = Twig.expression.handler[token.type]; - - Twig.log.trace(<span class="hljs-string">"Twig.expression.compile: "</span>, <span class="hljs-string">"Compiling "</span>, token);</pre></div></div> - - </li> - - - <li id="section-289"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-289">¶</a> - </div> - <p>Compile the template</p> - - </div> - - <div class="content"><div class='highlight'><pre> token_template.compile && token_template.compile(token, stack, output); - - Twig.log.trace(<span class="hljs-string">"Twig.expression.compile: "</span>, <span class="hljs-string">"Stack is"</span>, stack); - Twig.log.trace(<span class="hljs-string">"Twig.expression.compile: "</span>, <span class="hljs-string">"Output is"</span>, output); - } - - <span class="hljs-keyword">while</span>(stack.length > <span class="hljs-number">0</span>) { - output.push(stack.pop()); - } - - Twig.log.trace(<span class="hljs-string">"Twig.expression.compile: "</span>, <span class="hljs-string">"Final output is"</span>, output); - - raw_token.stack = output; - <span class="hljs-keyword">delete</span> raw_token.value; - - <span class="hljs-keyword">return</span> raw_token; - }; - - - <span class="hljs-comment">/** - * Parse an RPN expression stack within a context. - * - * @param {Array} tokens An array of compiled expression tokens. - * @param {Object} context The render context to parse the tokens with. - * - * @return {Object} The result of parsing all the tokens. The result - * can be anything, String, Array, Object, etc... based on - * the given expression. - */</span> - Twig.expression.parse = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">tokens, context</span>) </span>{ - <span class="hljs-keyword">var</span> that = <span class="hljs-keyword">this</span>;</pre></div></div> - - </li> - - - <li id="section-290"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-290">¶</a> - </div> - <p>If the token isn’t an array, make it one.</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!(tokens <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span>)) { - tokens = [tokens]; - }</pre></div></div> - - </li> - - - <li id="section-291"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-291">¶</a> - </div> - <p>The output stack</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> stack = [], - token_template = <span class="hljs-literal">null</span>; - - Twig.forEach(tokens, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{ - token_template = Twig.expression.handler[token.type]; - - token_template.parse && token_template.parse.apply(that, [token, stack, context]); - });</pre></div></div> - - </li> - - - <li id="section-292"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-292">¶</a> - </div> - <p>Pop the final value off the stack</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> stack.pop(); - }; - - <span class="hljs-keyword">return</span> Twig; - -})( Twig || { } );</pre></div></div> - - </li> - - - <li id="section-293"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-293">¶</a> - </div> - <pre><code>Twig.js -Available under the BSD <span class="hljs-number">2</span>-Clause License -https:<span class="hljs-comment">//github.com/justjohn/twig.js</span> -</code></pre> - </div> - - </li> - - - <li id="section-294"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-294">¶</a> - </div> - <h2 id="twig-expression-operator-js">twig.expression.operator.js</h2> -<p>This file handles operator lookups and parsing.</p> - - </div> - - <div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{ -<span class="hljs-meta"> "use strict"</span>; - - <span class="hljs-comment">/** - * Operator associativity constants. - */</span> - Twig.expression.operator = { - leftToRight: <span class="hljs-string">'leftToRight'</span>, - rightToLeft: <span class="hljs-string">'rightToLeft'</span> - }; - - <span class="hljs-keyword">var</span> containment = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">a, b</span>) </span>{ - <span class="hljs-keyword">if</span> (b === <span class="hljs-literal">undefined</span> || b === <span class="hljs-literal">null</span>) { - <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (b.indexOf !== <span class="hljs-literal">undefined</span>) {</pre></div></div> - - </li> - - - <li id="section-295"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-295">¶</a> - </div> - <p>String</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> a === b || a !== <span class="hljs-string">''</span> && b.indexOf(a) > <span class="hljs-number">-1</span>; - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">var</span> el; - <span class="hljs-keyword">for</span> (el <span class="hljs-keyword">in</span> b) { - <span class="hljs-keyword">if</span> (b.hasOwnProperty(el) && b[el] === a) { - <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; - } - } - <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; - } - }; - - <span class="hljs-comment">/** - * Get the precidence and associativity of an operator. These follow the order that C/C++ use. - * See http://en.wikipedia.org/wiki/Operators_in_C_and_C++ for the table of values. - */</span> - Twig.expression.operator.lookup = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">operator, token</span>) </span>{ - <span class="hljs-keyword">switch</span> (operator) { - <span class="hljs-keyword">case</span> <span class="hljs-string">".."</span>: - <span class="hljs-keyword">case</span> <span class="hljs-string">'not in'</span>: - <span class="hljs-keyword">case</span> <span class="hljs-string">'in'</span>: - token.precidence = <span class="hljs-number">20</span>; - token.associativity = Twig.expression.operator.leftToRight; - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">','</span>: - token.precidence = <span class="hljs-number">18</span>; - token.associativity = Twig.expression.operator.leftToRight; - <span class="hljs-keyword">break</span>;</pre></div></div> - - </li> - - - <li id="section-296"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-296">¶</a> - </div> - <p>Ternary</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">'?'</span>: - <span class="hljs-keyword">case</span> <span class="hljs-string">':'</span>: - token.precidence = <span class="hljs-number">16</span>; - token.associativity = Twig.expression.operator.rightToLeft; - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'or'</span>: - token.precidence = <span class="hljs-number">14</span>; - token.associativity = Twig.expression.operator.leftToRight; - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'and'</span>: - token.precidence = <span class="hljs-number">13</span>; - token.associativity = Twig.expression.operator.leftToRight; - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'=='</span>: - <span class="hljs-keyword">case</span> <span class="hljs-string">'!='</span>: - token.precidence = <span class="hljs-number">9</span>; - token.associativity = Twig.expression.operator.leftToRight; - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'<'</span>: - <span class="hljs-keyword">case</span> <span class="hljs-string">'<='</span>: - <span class="hljs-keyword">case</span> <span class="hljs-string">'>'</span>: - <span class="hljs-keyword">case</span> <span class="hljs-string">'>='</span>: - token.precidence = <span class="hljs-number">8</span>; - token.associativity = Twig.expression.operator.leftToRight; - <span class="hljs-keyword">break</span>; - - - <span class="hljs-keyword">case</span> <span class="hljs-string">'~'</span>: <span class="hljs-comment">// String concatination</span> - <span class="hljs-keyword">case</span> <span class="hljs-string">'+'</span>: - <span class="hljs-keyword">case</span> <span class="hljs-string">'-'</span>: - token.precidence = <span class="hljs-number">6</span>; - token.associativity = Twig.expression.operator.leftToRight; - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'//'</span>: - <span class="hljs-keyword">case</span> <span class="hljs-string">'**'</span>: - <span class="hljs-keyword">case</span> <span class="hljs-string">'*'</span>: - <span class="hljs-keyword">case</span> <span class="hljs-string">'/'</span>: - <span class="hljs-keyword">case</span> <span class="hljs-string">'%'</span>: - token.precidence = <span class="hljs-number">5</span>; - token.associativity = Twig.expression.operator.leftToRight; - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'not'</span>: - token.precidence = <span class="hljs-number">3</span>; - token.associativity = Twig.expression.operator.rightToLeft; - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">default</span>: - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(operator + <span class="hljs-string">" is an unknown operator."</span>); - } - token.operator = operator; - <span class="hljs-keyword">return</span> token; - }; - - <span class="hljs-comment">/** - * Handle operations on the RPN stack. - * - * Returns the updated stack. - */</span> - Twig.expression.operator.parse = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">operator, stack</span>) </span>{ - Twig.log.trace(<span class="hljs-string">"Twig.expression.operator.parse: "</span>, <span class="hljs-string">"Handling "</span>, operator); - <span class="hljs-keyword">var</span> a, b, c; - <span class="hljs-keyword">switch</span> (operator) { - <span class="hljs-keyword">case</span> <span class="hljs-string">':'</span>:</pre></div></div> - - </li> - - - <li id="section-297"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-297">¶</a> - </div> - <p>Ignore</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'?'</span>: - c = stack.pop(); <span class="hljs-comment">// false expr</span> - b = stack.pop(); <span class="hljs-comment">// true expr</span> - a = stack.pop(); <span class="hljs-comment">// conditional</span> - <span class="hljs-keyword">if</span> (a) { - stack.push(b); - } <span class="hljs-keyword">else</span> { - stack.push(c); - } - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'+'</span>: - b = <span class="hljs-built_in">parseFloat</span>(stack.pop()); - a = <span class="hljs-built_in">parseFloat</span>(stack.pop()); - stack.push(a + b); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'-'</span>: - b = <span class="hljs-built_in">parseFloat</span>(stack.pop()); - a = <span class="hljs-built_in">parseFloat</span>(stack.pop()); - stack.push(a - b); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'*'</span>: - b = <span class="hljs-built_in">parseFloat</span>(stack.pop()); - a = <span class="hljs-built_in">parseFloat</span>(stack.pop()); - stack.push(a * b); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'/'</span>: - b = <span class="hljs-built_in">parseFloat</span>(stack.pop()); - a = <span class="hljs-built_in">parseFloat</span>(stack.pop()); - stack.push(a / b); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'//'</span>: - b = <span class="hljs-built_in">parseFloat</span>(stack.pop()); - a = <span class="hljs-built_in">parseFloat</span>(stack.pop()); - stack.push(<span class="hljs-built_in">parseInt</span>(a / b)); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'%'</span>: - b = <span class="hljs-built_in">parseFloat</span>(stack.pop()); - a = <span class="hljs-built_in">parseFloat</span>(stack.pop()); - stack.push(a % b); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'~'</span>: - b = stack.pop(); - a = stack.pop(); - stack.push( (a != <span class="hljs-literal">null</span> ? a.toString() : <span class="hljs-string">""</span>) - + (b != <span class="hljs-literal">null</span> ? b.toString() : <span class="hljs-string">""</span>) ); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'not'</span>: - <span class="hljs-keyword">case</span> <span class="hljs-string">'!'</span>: - stack.push(!stack.pop()); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'<'</span>: - b = stack.pop(); - a = stack.pop(); - stack.push(a < b); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'<='</span>: - b = stack.pop(); - a = stack.pop(); - stack.push(a <= b); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'>'</span>: - b = stack.pop(); - a = stack.pop(); - stack.push(a > b); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'>='</span>: - b = stack.pop(); - a = stack.pop(); - stack.push(a >= b); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'==='</span>: - b = stack.pop(); - a = stack.pop(); - stack.push(a === b); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'=='</span>: - b = stack.pop(); - a = stack.pop(); - stack.push(a == b); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'!=='</span>: - b = stack.pop(); - a = stack.pop(); - stack.push(a !== b); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'!='</span>: - b = stack.pop(); - a = stack.pop(); - stack.push(a != b); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'or'</span>: - b = stack.pop(); - a = stack.pop(); - stack.push(a || b); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'and'</span>: - b = stack.pop(); - a = stack.pop(); - stack.push(a && b); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'**'</span>: - b = stack.pop(); - a = stack.pop(); - stack.push(<span class="hljs-built_in">Math</span>.pow(a, b)); - <span class="hljs-keyword">break</span>; - - - <span class="hljs-keyword">case</span> <span class="hljs-string">'not in'</span>: - b = stack.pop(); - a = stack.pop(); - stack.push( !containment(a, b) ); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'in'</span>: - b = stack.pop(); - a = stack.pop(); - stack.push( containment(a, b) ); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">case</span> <span class="hljs-string">'..'</span>: - b = stack.pop(); - a = stack.pop(); - stack.push( Twig.functions.range(a, b) ); - <span class="hljs-keyword">break</span>; - - <span class="hljs-keyword">default</span>: - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(operator + <span class="hljs-string">" is an unknown operator."</span>); - } - }; - - <span class="hljs-keyword">return</span> Twig; - -})( Twig || { } );</pre></div></div> - - </li> - - - <li id="section-298"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-298">¶</a> - </div> - <pre><code>Twig.js -Available under the BSD <span class="hljs-number">2</span>-Clause License -https:<span class="hljs-comment">//github.com/justjohn/twig.js</span> -</code></pre> - </div> - - </li> - - - <li id="section-299"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-299">¶</a> - </div> - <h2 id="twig-filters-js">twig.filters.js</h2> -<p>This file handles parsing filters.</p> - - </div> - - <div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-300"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-300">¶</a> - </div> - <p>Determine object type</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">is</span>(<span class="hljs-params">type, obj</span>) </span>{ - <span class="hljs-keyword">var</span> clas = <span class="hljs-built_in">Object</span>.prototype.toString.call(obj).slice(<span class="hljs-number">8</span>, <span class="hljs-number">-1</span>); - <span class="hljs-keyword">return</span> obj !== <span class="hljs-literal">undefined</span> && obj !== <span class="hljs-literal">null</span> && clas === type; - } - - Twig.filters = {</pre></div></div> - - </li> - - - <li id="section-301"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-301">¶</a> - </div> - <p>String Filters</p> - - </div> - - <div class="content"><div class='highlight'><pre> upper: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">if</span> ( <span class="hljs-keyword">typeof</span> value !== <span class="hljs-string">"string"</span> ) { - <span class="hljs-keyword">return</span> value; - } - - <span class="hljs-keyword">return</span> value.toUpperCase(); - }, - lower: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">if</span> ( <span class="hljs-keyword">typeof</span> value !== <span class="hljs-string">"string"</span> ) { - <span class="hljs-keyword">return</span> value; - } - - <span class="hljs-keyword">return</span> value.toLowerCase(); - }, - capitalize: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">if</span> ( <span class="hljs-keyword">typeof</span> value !== <span class="hljs-string">"string"</span> ) { - <span class="hljs-keyword">return</span> value; - } - - <span class="hljs-keyword">return</span> value.substr(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>).toUpperCase() + value.toLowerCase().substr(<span class="hljs-number">1</span>); - }, - title: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">if</span> ( <span class="hljs-keyword">typeof</span> value !== <span class="hljs-string">"string"</span> ) { - <span class="hljs-keyword">return</span> value; - } - - <span class="hljs-keyword">return</span> value.toLowerCase().replace( <span class="hljs-regexp">/(^|\s)([a-z])/g</span> , <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">m, p1, p2</span>)</span>{ - <span class="hljs-keyword">return</span> p1 + p2.toUpperCase(); - }); - }, - length: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"Array"</span>, value) || <span class="hljs-keyword">typeof</span> value === <span class="hljs-string">"string"</span>) { - <span class="hljs-keyword">return</span> value.length; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"Object"</span>, value)) { - <span class="hljs-keyword">if</span> (value._keys === <span class="hljs-literal">undefined</span>) { - <span class="hljs-keyword">return</span> <span class="hljs-built_in">Object</span>.keys(value).length; - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">return</span> value._keys.length; - } - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; - } - },</pre></div></div> - - </li> - - - <li id="section-302"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-302">¶</a> - </div> - <p>Array/Object Filters</p> - - </div> - - <div class="content"><div class='highlight'><pre> reverse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"Array"</span>, value)) { - <span class="hljs-keyword">return</span> value.reverse(); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"String"</span>, value)) { - <span class="hljs-keyword">return</span> value.split(<span class="hljs-string">""</span>).reverse().join(<span class="hljs-string">""</span>); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"Object"</span>, value)) { - <span class="hljs-keyword">var</span> keys = value._keys || <span class="hljs-built_in">Object</span>.keys(value).reverse(); - value._keys = keys; - <span class="hljs-keyword">return</span> value; - } - }, - sort: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"Array"</span>, value)) { - <span class="hljs-keyword">return</span> value.sort(); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (is(<span class="hljs-string">'Object'</span>, value)) {</pre></div></div> - - </li> - - - <li id="section-303"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-303">¶</a> - </div> - <p>Sorting objects isn’t obvious since the order of -returned keys isn’t guaranteed in JavaScript. -Because of this we use a “hidden” key called _keys to -store the keys in the order we want to return them.</p> - - </div> - - <div class="content"><div class='highlight'><pre> - <span class="hljs-keyword">delete</span> value._keys; - <span class="hljs-keyword">var</span> keys = <span class="hljs-built_in">Object</span>.keys(value), - sorted_keys = keys.sort(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">a, b</span>) </span>{ - <span class="hljs-keyword">var</span> a1, a2;</pre></div></div> - - </li> - - - <li id="section-304"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-304">¶</a> - </div> - <p>if a and b are comparable, we’re fine :-)</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span>((value[a] > value[b]) == !(value[a] <= value[b])) { - <span class="hljs-keyword">return</span> value[a] > value[b] ? <span class="hljs-number">1</span> : - value[a] < value[b] ? <span class="hljs-number">-1</span> : - <span class="hljs-number">0</span>; - }</pre></div></div> - - </li> - - - <li id="section-305"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-305">¶</a> - </div> - <p>if a and b can be parsed as numbers, we can compare -their numeric value</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(!<span class="hljs-built_in">isNaN</span>(a1 = <span class="hljs-built_in">parseFloat</span>(value[a])) && - !<span class="hljs-built_in">isNaN</span>(b1 = <span class="hljs-built_in">parseFloat</span>(value[b]))) { - <span class="hljs-keyword">return</span> a1 > b1 ? <span class="hljs-number">1</span> : - a1 < b1 ? <span class="hljs-number">-1</span> : - <span class="hljs-number">0</span>; - }</pre></div></div> - - </li> - - - <li id="section-306"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-306">¶</a> - </div> - <p>if one of the values is a string, we convert the -other value to string as well</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> value[a] == <span class="hljs-string">'string'</span>) { - <span class="hljs-keyword">return</span> value[a] > value[b].toString() ? <span class="hljs-number">1</span> : - value[a] < value[b].toString() ? <span class="hljs-number">-1</span> : - <span class="hljs-number">0</span>; - } - <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> value[b] == <span class="hljs-string">'string'</span>) { - <span class="hljs-keyword">return</span> value[a].toString() > value[b] ? <span class="hljs-number">1</span> : - value[a].toString() < value[b] ? <span class="hljs-number">-1</span> : - <span class="hljs-number">0</span>; - }</pre></div></div> - - </li> - - - <li id="section-307"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-307">¶</a> - </div> - <p>everything failed - return ‘null’ as sign, that -the values are not comparable</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; - } - }); - value._keys = sorted_keys; - <span class="hljs-keyword">return</span> value; - } - }, - keys: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>){ - <span class="hljs-keyword">return</span>; - } - - <span class="hljs-keyword">var</span> keyset = value._keys || <span class="hljs-built_in">Object</span>.keys(value), - output = []; - - Twig.forEach(keyset, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{ - <span class="hljs-keyword">if</span> (key === <span class="hljs-string">"_keys"</span>) <span class="hljs-keyword">return</span>; <span class="hljs-comment">// Ignore the _keys property</span> - <span class="hljs-keyword">if</span> (value.hasOwnProperty(key)) { - output.push(key); - } - }); - <span class="hljs-keyword">return</span> output; - }, - url_encode: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>){ - <span class="hljs-keyword">return</span>; - } - - <span class="hljs-keyword">var</span> result = <span class="hljs-built_in">encodeURIComponent</span>(value); - result = result.replace(<span class="hljs-string">"'"</span>, <span class="hljs-string">"%27"</span>); - <span class="hljs-keyword">return</span> result; - }, - join: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{ - <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>){ - <span class="hljs-keyword">return</span>; - } - - <span class="hljs-keyword">var</span> join_str = <span class="hljs-string">""</span>, - output = [], - keyset = <span class="hljs-literal">null</span>; - - <span class="hljs-keyword">if</span> (params && params[<span class="hljs-number">0</span>]) { - join_str = params[<span class="hljs-number">0</span>]; - } - <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"Array"</span>, value)) { - output = value; - } <span class="hljs-keyword">else</span> { - keyset = value._keys || <span class="hljs-built_in">Object</span>.keys(value); - Twig.forEach(keyset, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{ - <span class="hljs-keyword">if</span> (key === <span class="hljs-string">"_keys"</span>) <span class="hljs-keyword">return</span>; <span class="hljs-comment">// Ignore the _keys property</span> - <span class="hljs-keyword">if</span> (value.hasOwnProperty(key)) { - output.push(value[key]); - } - }); - } - <span class="hljs-keyword">return</span> output.join(join_str); - }, - <span class="hljs-string">"default"</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{ - <span class="hljs-keyword">if</span> (params !== <span class="hljs-literal">undefined</span> && params.length > <span class="hljs-number">1</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"default filter expects one argument"</span>); - } - <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span> || value === <span class="hljs-string">''</span> ) { - <span class="hljs-keyword">if</span> (params === <span class="hljs-literal">undefined</span>) { - <span class="hljs-keyword">return</span> <span class="hljs-string">''</span>; - } - - <span class="hljs-keyword">return</span> params[<span class="hljs-number">0</span>]; - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">return</span> value; - } - }, - json_encode: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">if</span>(value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>) { - <span class="hljs-keyword">return</span> <span class="hljs-string">"null"</span>; - } - <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ((<span class="hljs-keyword">typeof</span> value == <span class="hljs-string">'object'</span>) && (is(<span class="hljs-string">"Array"</span>, value))) { - output = []; - - Twig.forEach(value, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">v</span>) </span>{ - output.push(Twig.filters.json_encode(v)); - }); - - <span class="hljs-keyword">return</span> <span class="hljs-string">"["</span> + output.join(<span class="hljs-string">","</span>) + <span class="hljs-string">"]"</span>; - } - <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> value == <span class="hljs-string">'object'</span>) { - <span class="hljs-keyword">var</span> keyset = value._keys || <span class="hljs-built_in">Object</span>.keys(value), - output = []; - - Twig.forEach(keyset, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{ - output.push(<span class="hljs-built_in">JSON</span>.stringify(key) + <span class="hljs-string">":"</span> + Twig.filters.json_encode(value[key])); - }); - - <span class="hljs-keyword">return</span> <span class="hljs-string">"{"</span> + output.join(<span class="hljs-string">","</span>) + <span class="hljs-string">"}"</span>; - } - <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">return</span> <span class="hljs-built_in">JSON</span>.stringify(value); - } - }, - merge: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{ - <span class="hljs-keyword">var</span> obj = [], - arr_index = <span class="hljs-number">0</span>, - keyset = [];</pre></div></div> - - </li> - - - <li id="section-308"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-308">¶</a> - </div> - <p>Check to see if all the objects being merged are arrays</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!is(<span class="hljs-string">"Array"</span>, value)) {</pre></div></div> - - </li> - - - <li id="section-309"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-309">¶</a> - </div> - <p>Create obj as an Object</p> - - </div> - - <div class="content"><div class='highlight'><pre> obj = { }; - } <span class="hljs-keyword">else</span> { - Twig.forEach(params, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">param</span>) </span>{ - <span class="hljs-keyword">if</span> (!is(<span class="hljs-string">"Array"</span>, param)) { - obj = { }; - } - }); - } - <span class="hljs-keyword">if</span> (!is(<span class="hljs-string">"Array"</span>, obj)) { - obj._keys = []; - } - - <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"Array"</span>, value)) { - Twig.forEach(value, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">val</span>) </span>{ - <span class="hljs-keyword">if</span> (obj._keys) obj._keys.push(arr_index); - obj[arr_index] = val; - arr_index++; - }); - } <span class="hljs-keyword">else</span> { - keyset = value._keys || <span class="hljs-built_in">Object</span>.keys(value); - Twig.forEach(keyset, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{ - obj[key] = value[key]; - obj._keys.push(key);</pre></div></div> - - </li> - - - <li id="section-310"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-310">¶</a> - </div> - <p>Handle edge case where a number index in an object is greater than - the array counter. In such a case, the array counter is increased - one past the index.</p> -<p>Example {{ [“a”, “b”]|merge({“4”:”value”}, [“c”, “d”]) -Without this, d would have an index of “4” and overwrite the value - of “value”</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> int_key = <span class="hljs-built_in">parseInt</span>(key, <span class="hljs-number">10</span>); - <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">isNaN</span>(int_key) && int_key >= arr_index) { - arr_index = int_key + <span class="hljs-number">1</span>; - } - }); - }</pre></div></div> - - </li> - - - <li id="section-311"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-311">¶</a> - </div> - <p>mixin the merge arrays</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.forEach(params, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">param</span>) </span>{ - <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"Array"</span>, param)) { - Twig.forEach(param, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">val</span>) </span>{ - <span class="hljs-keyword">if</span> (obj._keys) obj._keys.push(arr_index); - obj[arr_index] = val; - arr_index++; - }); - } <span class="hljs-keyword">else</span> { - keyset = param._keys || <span class="hljs-built_in">Object</span>.keys(param); - Twig.forEach(keyset, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{ - <span class="hljs-keyword">if</span> (!obj[key]) obj._keys.push(key); - obj[key] = param[key]; - - <span class="hljs-keyword">var</span> int_key = <span class="hljs-built_in">parseInt</span>(key, <span class="hljs-number">10</span>); - <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">isNaN</span>(int_key) && int_key >= arr_index) { - arr_index = int_key + <span class="hljs-number">1</span>; - } - }); - } - }); - <span class="hljs-keyword">if</span> (params.length === <span class="hljs-number">0</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Filter merge expects at least one parameter"</span>); - } - - <span class="hljs-keyword">return</span> obj; - }, - date: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{ - <span class="hljs-keyword">var</span> date = Twig.functions.date(value); - <span class="hljs-keyword">var</span> format = params && params.length ? params[<span class="hljs-number">0</span>] : <span class="hljs-string">'F j, Y H:i'</span>; - <span class="hljs-keyword">return</span> Twig.lib.formatDate(date, format); - }, - - date_modify: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{ - <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>) { - <span class="hljs-keyword">return</span>; - } - <span class="hljs-keyword">if</span> (params === <span class="hljs-literal">undefined</span> || params.length !== <span class="hljs-number">1</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"date_modify filter expects 1 argument"</span>); - } - - <span class="hljs-keyword">var</span> modifyText = params[<span class="hljs-number">0</span>], time; - - <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"Date"</span>, value)) { - time = Twig.lib.strtotime(modifyText, value.getTime() / <span class="hljs-number">1000</span>); - } - <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"String"</span>, value)) { - time = Twig.lib.strtotime(modifyText, Twig.lib.strtotime(value)); - } - <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"Number"</span>, value)) { - time = Twig.lib.strtotime(modifyText, value); - } - - <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(time * <span class="hljs-number">1000</span>); - }, - - replace: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{ - <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span>||value === <span class="hljs-literal">null</span>){ - <span class="hljs-keyword">return</span>; - } - - <span class="hljs-keyword">var</span> pairs = params[<span class="hljs-number">0</span>], - tag; - <span class="hljs-keyword">for</span> (tag <span class="hljs-keyword">in</span> pairs) { - <span class="hljs-keyword">if</span> (pairs.hasOwnProperty(tag) && tag !== <span class="hljs-string">"_keys"</span>) { - value = Twig.lib.replaceAll(value, tag, pairs[tag]); - } - } - <span class="hljs-keyword">return</span> value; - }, - - format: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{ - <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>){ - <span class="hljs-keyword">return</span>; - } - - <span class="hljs-keyword">return</span> Twig.lib.vsprintf(value, params); - }, - - striptags: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>){ - <span class="hljs-keyword">return</span>; - } - - <span class="hljs-keyword">return</span> Twig.lib.strip_tags(value); - }, - - <span class="hljs-built_in">escape</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{ - <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span>|| value === <span class="hljs-literal">null</span>){ - <span class="hljs-keyword">return</span>; - } - - <span class="hljs-keyword">var</span> strategy = <span class="hljs-string">"html"</span>; - <span class="hljs-keyword">if</span>(params && params.length && params[<span class="hljs-number">0</span>] !== <span class="hljs-literal">true</span>) - strategy = params[<span class="hljs-number">0</span>]; - - <span class="hljs-keyword">if</span>(strategy == <span class="hljs-string">"html"</span>) { - <span class="hljs-keyword">var</span> raw_value = value.toString().replace(<span class="hljs-regexp">/&/g</span>, <span class="hljs-string">"&amp;"</span>) - .replace(<span class="hljs-regexp">/</g</span>, <span class="hljs-string">"&lt;"</span>) - .replace(<span class="hljs-regexp">/>/g</span>, <span class="hljs-string">"&gt;"</span>) - .replace(<span class="hljs-regexp">/"/g</span>, <span class="hljs-string">"&quot;"</span>) - .replace(<span class="hljs-regexp">/'/g</span>, <span class="hljs-string">"&#039;"</span>); - <span class="hljs-keyword">return</span> Twig.Markup(raw_value, <span class="hljs-string">'html'</span>); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(strategy == <span class="hljs-string">"js"</span>) { - <span class="hljs-keyword">var</span> raw_value = value.toString(); - <span class="hljs-keyword">var</span> result = <span class="hljs-string">""</span>; - - <span class="hljs-keyword">for</span>(<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < raw_value.length; i++) { - <span class="hljs-keyword">if</span>(raw_value[i].match(<span class="hljs-regexp">/^[a-zA-Z0-9,\._]$/</span>)) - result += raw_value[i]; - <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">var</span> char_code = raw_value.charCodeAt(i); - - <span class="hljs-keyword">if</span>(char_code < <span class="hljs-number">0x80</span>) - result += <span class="hljs-string">"\\x"</span> + char_code.toString(<span class="hljs-number">16</span>).toUpperCase(); - <span class="hljs-keyword">else</span> - result += Twig.lib.sprintf(<span class="hljs-string">"\\u%04s"</span>, char_code.toString(<span class="hljs-number">16</span>).toUpperCase()); - } - } - - <span class="hljs-keyword">return</span> Twig.Markup(result, <span class="hljs-string">'js'</span>); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(strategy == <span class="hljs-string">"css"</span>) { - <span class="hljs-keyword">var</span> raw_value = value.toString(); - <span class="hljs-keyword">var</span> result = <span class="hljs-string">""</span>; - - <span class="hljs-keyword">for</span>(<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < raw_value.length; i++) { - <span class="hljs-keyword">if</span>(raw_value[i].match(<span class="hljs-regexp">/^[a-zA-Z0-9]$/</span>)) - result += raw_value[i]; - <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">var</span> char_code = raw_value.charCodeAt(i); - result += <span class="hljs-string">"\\"</span> + char_code.toString(<span class="hljs-number">16</span>).toUpperCase() + <span class="hljs-string">" "</span>; - } - } - - <span class="hljs-keyword">return</span> Twig.Markup(result, <span class="hljs-string">'css'</span>); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(strategy == <span class="hljs-string">"url"</span>) { - <span class="hljs-keyword">var</span> result = Twig.filters.url_encode(value); - <span class="hljs-keyword">return</span> Twig.Markup(result, <span class="hljs-string">'url'</span>); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(strategy == <span class="hljs-string">"html_attr"</span>) { - <span class="hljs-keyword">var</span> raw_value = value.toString(); - <span class="hljs-keyword">var</span> result = <span class="hljs-string">""</span>; - - <span class="hljs-keyword">for</span>(<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < raw_value.length; i++) { - <span class="hljs-keyword">if</span>(raw_value[i].match(<span class="hljs-regexp">/^[a-zA-Z0-9,\.\-_]$/</span>)) - result += raw_value[i]; - <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(raw_value[i].match(<span class="hljs-regexp">/^[&<>"]$/</span>)) - result += raw_value[i].replace(<span class="hljs-regexp">/&/g</span>, <span class="hljs-string">"&amp;"</span>) - .replace(<span class="hljs-regexp">/</g</span>, <span class="hljs-string">"&lt;"</span>) - .replace(<span class="hljs-regexp">/>/g</span>, <span class="hljs-string">"&gt;"</span>) - .replace(<span class="hljs-regexp">/"/g</span>, <span class="hljs-string">"&quot;"</span>); - <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">var</span> char_code = raw_value.charCodeAt(i);</pre></div></div> - - </li> - - - <li id="section-312"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-312">¶</a> - </div> - <p>The following replaces characters undefined in HTML with -the hex entity for the Unicode replacement character.</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span>(char_code <= <span class="hljs-number">0x1f</span> && char_code != <span class="hljs-number">0x09</span> && char_code != <span class="hljs-number">0x0a</span> && char_code != <span class="hljs-number">0x0d</span>) - result += <span class="hljs-string">"&#xFFFD;"</span>; - <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(char_code < <span class="hljs-number">0x80</span>) - result += Twig.lib.sprintf(<span class="hljs-string">"&#x%02s;"</span>, char_code.toString(<span class="hljs-number">16</span>).toUpperCase()); - <span class="hljs-keyword">else</span> - result += Twig.lib.sprintf(<span class="hljs-string">"&#x%04s;"</span>, char_code.toString(<span class="hljs-number">16</span>).toUpperCase()); - } - } - - <span class="hljs-keyword">return</span> Twig.Markup(result, <span class="hljs-string">'html_attr'</span>); - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"escape strategy unsupported"</span>); - } - }, - - <span class="hljs-comment">/* Alias of escape */</span> - <span class="hljs-string">"e"</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{ - <span class="hljs-keyword">return</span> Twig.filters.escape(value, params); - }, - - nl2br: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>){ - <span class="hljs-keyword">return</span>; - } - <span class="hljs-keyword">var</span> linebreak_tag = <span class="hljs-string">"BACKSLASH_n_replace"</span>, - br = <span class="hljs-string">"<br />"</span> + linebreak_tag; - - value = Twig.filters.escape(value) - .replace(<span class="hljs-regexp">/\r\n/g</span>, br) - .replace(<span class="hljs-regexp">/\r/g</span>, br) - .replace(<span class="hljs-regexp">/\n/g</span>, br); - - value = Twig.lib.replaceAll(value, linebreak_tag, <span class="hljs-string">"\n"</span>); - - <span class="hljs-keyword">return</span> Twig.Markup(value); - }, - - <span class="hljs-comment">/** - * Adapted from: http://phpjs.org/functions/number_format:481 - */</span> - number_format: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{ - <span class="hljs-keyword">var</span> number = value, - decimals = (params && params[<span class="hljs-number">0</span>]) ? params[<span class="hljs-number">0</span>] : <span class="hljs-literal">undefined</span>, - dec = (params && params[<span class="hljs-number">1</span>] !== <span class="hljs-literal">undefined</span>) ? params[<span class="hljs-number">1</span>] : <span class="hljs-string">"."</span>, - sep = (params && params[<span class="hljs-number">2</span>] !== <span class="hljs-literal">undefined</span>) ? params[<span class="hljs-number">2</span>] : <span class="hljs-string">","</span>; - - number = (number + <span class="hljs-string">''</span>).replace(<span class="hljs-regexp">/[^0-9+\-Ee.]/g</span>, <span class="hljs-string">''</span>); - <span class="hljs-keyword">var</span> n = !<span class="hljs-built_in">isFinite</span>(+number) ? <span class="hljs-number">0</span> : +number, - prec = !<span class="hljs-built_in">isFinite</span>(+decimals) ? <span class="hljs-number">0</span> : <span class="hljs-built_in">Math</span>.abs(decimals), - s = <span class="hljs-string">''</span>, - toFixedFix = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">n, prec</span>) </span>{ - <span class="hljs-keyword">var</span> k = <span class="hljs-built_in">Math</span>.pow(<span class="hljs-number">10</span>, prec); - <span class="hljs-keyword">return</span> <span class="hljs-string">''</span> + <span class="hljs-built_in">Math</span>.round(n * k) / k; - };</pre></div></div> - - </li> - - - <li id="section-313"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-313">¶</a> - </div> - <p>Fix for IE parseFloat(0.55).toFixed(0) = 0;</p> - - </div> - - <div class="content"><div class='highlight'><pre> s = (prec ? toFixedFix(n, prec) : <span class="hljs-string">''</span> + <span class="hljs-built_in">Math</span>.round(n)).split(<span class="hljs-string">'.'</span>); - <span class="hljs-keyword">if</span> (s[<span class="hljs-number">0</span>].length > <span class="hljs-number">3</span>) { - s[<span class="hljs-number">0</span>] = s[<span class="hljs-number">0</span>].replace(<span class="hljs-regexp">/\B(?=(?:\d{3})+(?!\d))/g</span>, sep); - } - <span class="hljs-keyword">if</span> ((s[<span class="hljs-number">1</span>] || <span class="hljs-string">''</span>).length < prec) { - s[<span class="hljs-number">1</span>] = s[<span class="hljs-number">1</span>] || <span class="hljs-string">''</span>; - s[<span class="hljs-number">1</span>] += <span class="hljs-keyword">new</span> <span class="hljs-built_in">Array</span>(prec - s[<span class="hljs-number">1</span>].length + <span class="hljs-number">1</span>).join(<span class="hljs-string">'0'</span>); - } - <span class="hljs-keyword">return</span> s.join(dec); - }, - - trim: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{ - <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span>|| value === <span class="hljs-literal">null</span>){ - <span class="hljs-keyword">return</span>; - } - - <span class="hljs-keyword">var</span> str = Twig.filters.escape( <span class="hljs-string">''</span> + value ), - whitespace; - <span class="hljs-keyword">if</span> ( params && params[<span class="hljs-number">0</span>] ) { - whitespace = <span class="hljs-string">''</span> + params[<span class="hljs-number">0</span>]; - } <span class="hljs-keyword">else</span> { - whitespace = <span class="hljs-string">' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000'</span>; - } - <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < str.length; i++) { - <span class="hljs-keyword">if</span> (whitespace.indexOf(str.charAt(i)) === <span class="hljs-number">-1</span>) { - str = str.substring(i); - <span class="hljs-keyword">break</span>; - } - } - <span class="hljs-keyword">for</span> (i = str.length - <span class="hljs-number">1</span>; i >= <span class="hljs-number">0</span>; i--) { - <span class="hljs-keyword">if</span> (whitespace.indexOf(str.charAt(i)) === <span class="hljs-number">-1</span>) { - str = str.substring(<span class="hljs-number">0</span>, i + <span class="hljs-number">1</span>); - <span class="hljs-keyword">break</span>; - } - } - <span class="hljs-keyword">return</span> whitespace.indexOf(str.charAt(<span class="hljs-number">0</span>)) === <span class="hljs-number">-1</span> ? str : <span class="hljs-string">''</span>; - }, - - truncate: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">value, params</span>) </span>{ - <span class="hljs-keyword">var</span> length = <span class="hljs-number">30</span>, - preserve = <span class="hljs-literal">false</span>, - separator = <span class="hljs-string">'...'</span>; - - value = value + <span class="hljs-string">''</span>; - <span class="hljs-keyword">if</span> (params) { - <span class="hljs-keyword">if</span> (params[<span class="hljs-number">0</span>]) { - length = params[<span class="hljs-number">0</span>]; - } - <span class="hljs-keyword">if</span> (params[<span class="hljs-number">1</span>]) { - preserve = params[<span class="hljs-number">1</span>]; - } - <span class="hljs-keyword">if</span> (params[<span class="hljs-number">2</span>]) { - separator = params[<span class="hljs-number">2</span>]; - } - } - - <span class="hljs-keyword">if</span> (value.length > length) { - - <span class="hljs-keyword">if</span> (preserve) { - length = value.indexOf(<span class="hljs-string">' '</span>, length); - <span class="hljs-keyword">if</span> (length === <span class="hljs-number">-1</span>) { - <span class="hljs-keyword">return</span> value; - } - } - - value = value.substr(<span class="hljs-number">0</span>, length) + separator; - } - - <span class="hljs-keyword">return</span> value; - }, - - slice: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{ - <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>) { - <span class="hljs-keyword">return</span>; - } - <span class="hljs-keyword">if</span> (params === <span class="hljs-literal">undefined</span> || params.length < <span class="hljs-number">1</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"slice filter expects at least 1 argument"</span>); - }</pre></div></div> - - </li> - - - <li id="section-314"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-314">¶</a> - </div> - <p>default to start of string</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> start = params[<span class="hljs-number">0</span>] || <span class="hljs-number">0</span>;</pre></div></div> - - </li> - - - <li id="section-315"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-315">¶</a> - </div> - <p>default to length of string</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> length = params.length > <span class="hljs-number">1</span> ? params[<span class="hljs-number">1</span>] : value.length;</pre></div></div> - - </li> - - - <li id="section-316"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-316">¶</a> - </div> - <p>handle negative start values</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> startIndex = start >= <span class="hljs-number">0</span> ? start : <span class="hljs-built_in">Math</span>.max( value.length + start, <span class="hljs-number">0</span> ); - - <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"Array"</span>, value)) { - <span class="hljs-keyword">var</span> output = []; - <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = startIndex; i < startIndex + length && i < value.length; i++) { - output.push(value[i]); - } - <span class="hljs-keyword">return</span> output; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"String"</span>, value)) { - <span class="hljs-keyword">return</span> value.substr(startIndex, length); - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"slice filter expects value to be an array or string"</span>); - } - }, - - abs: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>) { - <span class="hljs-keyword">return</span>; - } - - <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.abs(value); - }, - - first: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"Array"</span>, value)) { - <span class="hljs-keyword">return</span> value[<span class="hljs-number">0</span>]; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"Object"</span>, value)) { - <span class="hljs-keyword">if</span> (<span class="hljs-string">'_keys'</span> <span class="hljs-keyword">in</span> value) { - <span class="hljs-keyword">return</span> value[value._keys[<span class="hljs-number">0</span>]]; - } - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ( <span class="hljs-keyword">typeof</span> value === <span class="hljs-string">"string"</span> ) { - <span class="hljs-keyword">return</span> value.substr(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>); - } - - <span class="hljs-keyword">return</span>; - }, - - split: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{ - <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>) { - <span class="hljs-keyword">return</span>; - } - <span class="hljs-keyword">if</span> (params === <span class="hljs-literal">undefined</span> || params.length < <span class="hljs-number">1</span> || params.length > <span class="hljs-number">2</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"split filter expects 1 or 2 argument"</span>); - } - <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"String"</span>, value)) { - <span class="hljs-keyword">var</span> delimiter = params[<span class="hljs-number">0</span>], - limit = params[<span class="hljs-number">1</span>], - split = value.split(delimiter); - - <span class="hljs-keyword">if</span> (limit === <span class="hljs-literal">undefined</span>) { - - <span class="hljs-keyword">return</span> split; - - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (limit < <span class="hljs-number">0</span>) { - - <span class="hljs-keyword">return</span> value.split(delimiter, split.length + limit); - - } <span class="hljs-keyword">else</span> { - - <span class="hljs-keyword">var</span> limitedSplit = []; - - <span class="hljs-keyword">if</span> (delimiter == <span class="hljs-string">''</span>) {</pre></div></div> - - </li> - - - <li id="section-317"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-317">¶</a> - </div> - <p>empty delimiter -“aabbcc”|split(‘’, 2) - -> [‘aa’, ‘bb’, ‘cc’]</p> - - </div> - - <div class="content"><div class='highlight'><pre> - <span class="hljs-keyword">while</span>(split.length > <span class="hljs-number">0</span>) { - <span class="hljs-keyword">var</span> temp = <span class="hljs-string">""</span>; - <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i<limit && split.length > <span class="hljs-number">0</span>; i++) { - temp += split.shift(); - } - limitedSplit.push(temp); - } - - } <span class="hljs-keyword">else</span> {</pre></div></div> - - </li> - - - <li id="section-318"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-318">¶</a> - </div> - <p>non-empty delimiter -“one,two,three,four,five”|split(‘,’, 3) - -> [‘one’, ‘two’, ‘three,four,five’]</p> - - </div> - - <div class="content"><div class='highlight'><pre> - <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i<limit<span class="hljs-number">-1</span> && split.length > <span class="hljs-number">0</span>; i++) { - limitedSplit.push(split.shift()); - } - - <span class="hljs-keyword">if</span> (split.length > <span class="hljs-number">0</span>) { - limitedSplit.push(split.join(delimiter)); - } - } - - <span class="hljs-keyword">return</span> limitedSplit; - } - - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"split filter expects value to be a string"</span>); - } - }, - last: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">'Object'</span>, value)) { - <span class="hljs-keyword">var</span> keys; - - <span class="hljs-keyword">if</span> (value._keys === <span class="hljs-literal">undefined</span>) { - keys = <span class="hljs-built_in">Object</span>.keys(value); - } <span class="hljs-keyword">else</span> { - keys = value._keys; - } - - <span class="hljs-keyword">return</span> value[keys[keys.length - <span class="hljs-number">1</span>]]; - }</pre></div></div> - - </li> - - - <li id="section-319"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-319">¶</a> - </div> - <p>string|array</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> value[value.length - <span class="hljs-number">1</span>]; - }, - raw: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">return</span> Twig.Markup(value); - }, - batch: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">items, params</span>) </span>{ - <span class="hljs-keyword">var</span> size = params.shift(), - fill = params.shift(), - result, - last, - missing; - - <span class="hljs-keyword">if</span> (!Twig.lib.is(<span class="hljs-string">"Array"</span>, items)) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"batch filter expects items to be an array"</span>); - } - - <span class="hljs-keyword">if</span> (!Twig.lib.is(<span class="hljs-string">"Number"</span>, size)) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"batch filter expects size to be a number"</span>); - } - - size = <span class="hljs-built_in">Math</span>.ceil(size); - - result = Twig.lib.chunkArray(items, size); - - <span class="hljs-keyword">if</span> (fill && items.length % size != <span class="hljs-number">0</span>) { - last = result.pop(); - missing = size - last.length; - - <span class="hljs-keyword">while</span> (missing--) { - last.push(fill); - } - - result.push(last); - } - - <span class="hljs-keyword">return</span> result; - }, - round: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{ - params = params || []; - - <span class="hljs-keyword">var</span> precision = params.length > <span class="hljs-number">0</span> ? params[<span class="hljs-number">0</span>] : <span class="hljs-number">0</span>, - method = params.length > <span class="hljs-number">1</span> ? params[<span class="hljs-number">1</span>] : <span class="hljs-string">"common"</span>; - - value = <span class="hljs-built_in">parseFloat</span>(value); - - <span class="hljs-keyword">if</span>(precision && !Twig.lib.is(<span class="hljs-string">"Number"</span>, precision)) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"round filter expects precision to be a number"</span>); - } - - <span class="hljs-keyword">if</span> (method === <span class="hljs-string">"common"</span>) { - <span class="hljs-keyword">return</span> Twig.lib.round(value, precision); - } - - <span class="hljs-keyword">if</span>(!Twig.lib.is(<span class="hljs-string">"Function"</span>, <span class="hljs-built_in">Math</span>[method])) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"round filter expects method to be 'floor', 'ceil', or 'common'"</span>); - } - - <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>[method](value * <span class="hljs-built_in">Math</span>.pow(<span class="hljs-number">10</span>, precision)) / <span class="hljs-built_in">Math</span>.pow(<span class="hljs-number">10</span>, precision); - } - }; - - Twig.filter = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">filter, value, params</span>) </span>{ - <span class="hljs-keyword">if</span> (!Twig.filters[filter]) { - <span class="hljs-keyword">throw</span> <span class="hljs-string">"Unable to find filter "</span> + filter; - } - <span class="hljs-keyword">return</span> Twig.filters[filter].apply(<span class="hljs-keyword">this</span>, [value, params]); - }; - - Twig.filter.extend = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">filter, definition</span>) </span>{ - Twig.filters[filter] = definition; - }; - - <span class="hljs-keyword">return</span> Twig; - -})(Twig || { });</pre></div></div> - - </li> - - - <li id="section-320"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-320">¶</a> - </div> - <pre><code>Twig.js - <span class="hljs-number">2012</span> Hadrien Lanneau -Available under the BSD <span class="hljs-number">2</span>-Clause License -https:<span class="hljs-comment">//github.com/justjohn/twig.js</span> -</code></pre> - </div> - - </li> - - - <li id="section-321"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-321">¶</a> - </div> - <h2 id="twig-functions-js">twig.functions.js</h2> -<p>This file handles parsing filters.</p> - - </div> - - <div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{ - <span class="hljs-comment">/** - * @constant - * @type {string} - */</span> - <span class="hljs-keyword">var</span> TEMPLATE_NOT_FOUND_MESSAGE = <span class="hljs-string">'Template "{name}" is not defined.'</span>;</pre></div></div> - - </li> - - - <li id="section-322"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-322">¶</a> - </div> - <p>Determine object type</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">is</span>(<span class="hljs-params">type, obj</span>) </span>{ - <span class="hljs-keyword">var</span> clas = <span class="hljs-built_in">Object</span>.prototype.toString.call(obj).slice(<span class="hljs-number">8</span>, <span class="hljs-number">-1</span>); - <span class="hljs-keyword">return</span> obj !== <span class="hljs-literal">undefined</span> && obj !== <span class="hljs-literal">null</span> && clas === type; - } - - Twig.functions = {</pre></div></div> - - </li> - - - <li id="section-323"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-323">¶</a> - </div> - <p> attribute, block, constant, date, dump, parent, random,.</p> - - </div> - - </li> - - - <li id="section-324"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-324">¶</a> - </div> - <p>Range function from <a href="http://phpjs.org/functions/range:499">http://phpjs.org/functions/range:499</a> -Used under an MIT License</p> - - </div> - - <div class="content"><div class='highlight'><pre> range: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">low, high, step</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-325"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-325">¶</a> - </div> - <p><a href="http://kevin.vanzonneveld.net">http://kevin.vanzonneveld.net</a></p> -<ul> -<li>original by: Waldo Malqui Silva</li> -<li>example 1: range ( 0, 12 );</li> -<li>returns 1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]</li> -<li>example 2: range( 0, 100, 10 );</li> -<li>returns 2: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]</li> -<li>example 3: range( ‘a’, ‘i’ );</li> -<li>returns 3: [‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’, ‘i’]</li> -<li>example 4: range( ‘c’, ‘a’ );</li> -<li>returns 4: [‘c’, ‘b’, ‘a’]</li> -</ul> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> matrix = []; - <span class="hljs-keyword">var</span> inival, endval, plus; - <span class="hljs-keyword">var</span> walker = step || <span class="hljs-number">1</span>; - <span class="hljs-keyword">var</span> chars = <span class="hljs-literal">false</span>; - - <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">isNaN</span>(low) && !<span class="hljs-built_in">isNaN</span>(high)) { - inival = <span class="hljs-built_in">parseInt</span>(low, <span class="hljs-number">10</span>); - endval = <span class="hljs-built_in">parseInt</span>(high, <span class="hljs-number">10</span>); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">isNaN</span>(low) && <span class="hljs-built_in">isNaN</span>(high)) { - chars = <span class="hljs-literal">true</span>; - inival = low.charCodeAt(<span class="hljs-number">0</span>); - endval = high.charCodeAt(<span class="hljs-number">0</span>); - } <span class="hljs-keyword">else</span> { - inival = (<span class="hljs-built_in">isNaN</span>(low) ? <span class="hljs-number">0</span> : low); - endval = (<span class="hljs-built_in">isNaN</span>(high) ? <span class="hljs-number">0</span> : high); - } - - plus = ((inival > endval) ? <span class="hljs-literal">false</span> : <span class="hljs-literal">true</span>); - <span class="hljs-keyword">if</span> (plus) { - <span class="hljs-keyword">while</span> (inival <= endval) { - matrix.push(((chars) ? <span class="hljs-built_in">String</span>.fromCharCode(inival) : inival)); - inival += walker; - } - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">while</span> (inival >= endval) { - matrix.push(((chars) ? <span class="hljs-built_in">String</span>.fromCharCode(inival) : inival)); - inival -= walker; - } - } - - <span class="hljs-keyword">return</span> matrix; - }, - cycle: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">arr, i</span>) </span>{ - <span class="hljs-keyword">var</span> pos = i % arr.length; - <span class="hljs-keyword">return</span> arr[pos]; - }, - dump: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ - <span class="hljs-keyword">var</span> EOL = <span class="hljs-string">'\n'</span>, - indentChar = <span class="hljs-string">' '</span>, - indentTimes = <span class="hljs-number">0</span>, - out = <span class="hljs-string">''</span>, - args = <span class="hljs-built_in">Array</span>.prototype.slice.call(<span class="hljs-built_in">arguments</span>), - indent = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">times</span>) </span>{ - <span class="hljs-keyword">var</span> ind = <span class="hljs-string">''</span>; - <span class="hljs-keyword">while</span> (times > <span class="hljs-number">0</span>) { - times--; - ind += indentChar; - } - <span class="hljs-keyword">return</span> ind; - }, - displayVar = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">variable</span>) </span>{ - out += indent(indentTimes); - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span>(variable) === <span class="hljs-string">'object'</span>) { - dumpVar(variable); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span>(variable) === <span class="hljs-string">'function'</span>) { - out += <span class="hljs-string">'function()'</span> + EOL; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span>(variable) === <span class="hljs-string">'string'</span>) { - out += <span class="hljs-string">'string('</span> + variable.length + <span class="hljs-string">') "'</span> + variable + <span class="hljs-string">'"'</span> + EOL; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span>(variable) === <span class="hljs-string">'number'</span>) { - out += <span class="hljs-string">'number('</span> + variable + <span class="hljs-string">')'</span> + EOL; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span>(variable) === <span class="hljs-string">'boolean'</span>) { - out += <span class="hljs-string">'bool('</span> + variable + <span class="hljs-string">')'</span> + EOL; - } - }, - dumpVar = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">variable</span>) </span>{ - <span class="hljs-keyword">var</span> i; - <span class="hljs-keyword">if</span> (variable === <span class="hljs-literal">null</span>) { - out += <span class="hljs-string">'NULL'</span> + EOL; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (variable === <span class="hljs-literal">undefined</span>) { - out += <span class="hljs-string">'undefined'</span> + EOL; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> variable === <span class="hljs-string">'object'</span>) { - out += indent(indentTimes) + <span class="hljs-keyword">typeof</span>(variable); - indentTimes++; - out += <span class="hljs-string">'('</span> + (<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">obj</span>) </span>{ - <span class="hljs-keyword">var</span> size = <span class="hljs-number">0</span>, key; - <span class="hljs-keyword">for</span> (key <span class="hljs-keyword">in</span> obj) { - <span class="hljs-keyword">if</span> (obj.hasOwnProperty(key)) { - size++; - } - } - <span class="hljs-keyword">return</span> size; - })(variable) + <span class="hljs-string">') {'</span> + EOL; - <span class="hljs-keyword">for</span> (i <span class="hljs-keyword">in</span> variable) { - out += indent(indentTimes) + <span class="hljs-string">'['</span> + i + <span class="hljs-string">']=> '</span> + EOL; - displayVar(variable[i]); - } - indentTimes--; - out += indent(indentTimes) + <span class="hljs-string">'}'</span> + EOL; - } <span class="hljs-keyword">else</span> { - displayVar(variable); - } - };</pre></div></div> - - </li> - - - <li id="section-326"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-326">¶</a> - </div> - <p>handle no argument case by dumping the entire render context</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (args.length == <span class="hljs-number">0</span>) args.push(<span class="hljs-keyword">this</span>.context); - - Twig.forEach(args, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">variable</span>) </span>{ - dumpVar(variable); - }); - - <span class="hljs-keyword">return</span> out; - }, - date: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">date, time</span>) </span>{ - <span class="hljs-keyword">var</span> dateObj; - <span class="hljs-keyword">if</span> (date === <span class="hljs-literal">undefined</span>) { - dateObj = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(); - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"Date"</span>, date)) { - dateObj = date; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"String"</span>, date)) { - <span class="hljs-keyword">if</span> (date.match(<span class="hljs-regexp">/^[0-9]+$/</span>)) { - dateObj = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(date * <span class="hljs-number">1000</span>); - } - <span class="hljs-keyword">else</span> { - dateObj = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(Twig.lib.strtotime(date) * <span class="hljs-number">1000</span>); - } - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"Number"</span>, date)) {</pre></div></div> - - </li> - - - <li id="section-327"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-327">¶</a> - </div> - <p>timestamp</p> - - </div> - - <div class="content"><div class='highlight'><pre> dateObj = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(date * <span class="hljs-number">1000</span>); - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to parse date "</span> + date); - } - <span class="hljs-keyword">return</span> dateObj; - }, - block: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">block</span>) </span>{ - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.originalBlockTokens[block]) { - <span class="hljs-keyword">return</span> Twig.logic.parse.apply(<span class="hljs-keyword">this</span>, [<span class="hljs-keyword">this</span>.originalBlockTokens[block], <span class="hljs-keyword">this</span>.context]).output; - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.blocks[block]; - } - }, - parent: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{</pre></div></div> - - </li> - - - <li id="section-328"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-328">¶</a> - </div> - <p>Add a placeholder</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> Twig.placeholders.parent; - }, - attribute: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">object, method, params</span>) </span>{ - <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">'Object'</span>, object)) { - <span class="hljs-keyword">if</span> (object.hasOwnProperty(method)) { - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object[method] === <span class="hljs-string">"function"</span>) { - <span class="hljs-keyword">return</span> object[method].apply(<span class="hljs-literal">undefined</span>, params); - } - <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">return</span> object[method]; - } - } - }</pre></div></div> - - </li> - - - <li id="section-329"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-329">¶</a> - </div> - <p>Array will return element 0-index</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> object[method] || <span class="hljs-literal">undefined</span>; - }, - max: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">values</span>) </span>{ - <span class="hljs-keyword">if</span>(Twig.lib.is(<span class="hljs-string">"Object"</span>, values)) { - <span class="hljs-keyword">delete</span> values[<span class="hljs-string">"_keys"</span>]; - <span class="hljs-keyword">return</span> Twig.lib.max(values); - } - - <span class="hljs-keyword">return</span> Twig.lib.max.apply(<span class="hljs-literal">null</span>, <span class="hljs-built_in">arguments</span>); - }, - min: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">values</span>) </span>{ - <span class="hljs-keyword">if</span>(Twig.lib.is(<span class="hljs-string">"Object"</span>, values)) { - <span class="hljs-keyword">delete</span> values[<span class="hljs-string">"_keys"</span>]; - <span class="hljs-keyword">return</span> Twig.lib.min(values); - } - - <span class="hljs-keyword">return</span> Twig.lib.min.apply(<span class="hljs-literal">null</span>, <span class="hljs-built_in">arguments</span>); - }, - template_from_string: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">template</span>) </span>{ - <span class="hljs-keyword">if</span> (template === <span class="hljs-literal">undefined</span>) { - template = <span class="hljs-string">''</span>; - } - <span class="hljs-keyword">return</span> Twig.Templates.parsers.twig({ - options: <span class="hljs-keyword">this</span>.options, - data: template - }); - }, - random: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">var</span> LIMIT_INT31 = <span class="hljs-number">0x80000000</span>; - - <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getRandomNumber</span>(<span class="hljs-params">n</span>) </span>{ - <span class="hljs-keyword">var</span> random = <span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * LIMIT_INT31); - <span class="hljs-keyword">var</span> limits = [<span class="hljs-number">0</span>, n]; - <span class="hljs-keyword">var</span> min = <span class="hljs-built_in">Math</span>.min.apply(<span class="hljs-literal">null</span>, limits), - max = <span class="hljs-built_in">Math</span>.max.apply(<span class="hljs-literal">null</span>, limits); - <span class="hljs-keyword">return</span> min + <span class="hljs-built_in">Math</span>.floor((max - min + <span class="hljs-number">1</span>) * random / LIMIT_INT31); - } - - <span class="hljs-keyword">if</span>(Twig.lib.is(<span class="hljs-string">"Number"</span>, value)) { - <span class="hljs-keyword">return</span> getRandomNumber(value); - } - - <span class="hljs-keyword">if</span>(Twig.lib.is(<span class="hljs-string">"String"</span>, value)) { - <span class="hljs-keyword">return</span> value.charAt(getRandomNumber(value.length<span class="hljs-number">-1</span>)); - } - - <span class="hljs-keyword">if</span>(Twig.lib.is(<span class="hljs-string">"Array"</span>, value)) { - <span class="hljs-keyword">return</span> value[getRandomNumber(value.length<span class="hljs-number">-1</span>)]; - } - - <span class="hljs-keyword">if</span>(Twig.lib.is(<span class="hljs-string">"Object"</span>, value)) { - <span class="hljs-keyword">var</span> keys = <span class="hljs-built_in">Object</span>.keys(value); - <span class="hljs-keyword">return</span> value[keys[getRandomNumber(keys.length<span class="hljs-number">-1</span>)]]; - } - - <span class="hljs-keyword">return</span> getRandomNumber(LIMIT_INT31<span class="hljs-number">-1</span>); - }, - - <span class="hljs-comment">/** - * Returns the content of a template without rendering it - * @param {string} name - * @param {boolean} [ignore_missing=false] - * @returns {string} - */</span> - source: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">name, ignore_missing</span>) </span>{ - <span class="hljs-keyword">var</span> templateSource; - <span class="hljs-keyword">var</span> templateFound = <span class="hljs-literal">false</span>; - <span class="hljs-keyword">var</span> isNodeEnvironment = <span class="hljs-keyword">typeof</span> <span class="hljs-built_in">module</span> !== <span class="hljs-string">'undefined'</span> && <span class="hljs-keyword">typeof</span> <span class="hljs-built_in">module</span>.exports !== <span class="hljs-string">'undefined'</span> && <span class="hljs-keyword">typeof</span> <span class="hljs-built_in">window</span> === <span class="hljs-string">'undefined'</span>; - <span class="hljs-keyword">var</span> loader; - <span class="hljs-keyword">var</span> path;</pre></div></div> - - </li> - - - <li id="section-330"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-330">¶</a> - </div> - <p>if we are running in a node.js environment, set the loader to ‘fs’ and ensure the -path is relative to the CWD of the running script -else, set the loader to ‘ajax’ and set the path to the value of name</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (isNodeEnvironment) { - loader = <span class="hljs-string">'fs'</span>; - path = __dirname + <span class="hljs-string">'/'</span> + name; - } <span class="hljs-keyword">else</span> { - loader = <span class="hljs-string">'ajax'</span>; - path = name; - }</pre></div></div> - - </li> - - - <li id="section-331"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-331">¶</a> - </div> - <p>build the params object</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> params = { - id: name, - path: path, - method: loader, - parser: <span class="hljs-string">'source'</span>, - <span class="hljs-keyword">async</span>: <span class="hljs-literal">false</span>, - fetchTemplateSource: <span class="hljs-literal">true</span> - };</pre></div></div> - - </li> - - - <li id="section-332"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-332">¶</a> - </div> - <p>default ignore_missing to false</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> ignore_missing === <span class="hljs-string">'undefined'</span>) { - ignore_missing = <span class="hljs-literal">false</span>; - }</pre></div></div> - - </li> - - - <li id="section-333"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-333">¶</a> - </div> - <p>try to load the remote template</p> -<p>on exception, log it</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">try</span> { - templateSource = Twig.Templates.loadRemote(name, params);</pre></div></div> - - </li> - - - <li id="section-334"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-334">¶</a> - </div> - <p>if the template is undefined or null, set the template to an empty string and do NOT flip the -boolean indicating we found the template</p> -<p>else, all is good! flip the boolean indicating we found the template</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> templateSource === <span class="hljs-string">'undefined'</span> || templateSource === <span class="hljs-literal">null</span>) { - templateSource = <span class="hljs-string">''</span>; - } <span class="hljs-keyword">else</span> { - templateFound = <span class="hljs-literal">true</span>; - } - } <span class="hljs-keyword">catch</span> (e) { - Twig.log.debug(<span class="hljs-string">'Twig.functions.source: '</span>, <span class="hljs-string">'Problem loading template '</span>, e); - }</pre></div></div> - - </li> - - - <li id="section-335"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-335">¶</a> - </div> - <p>if the template was NOT found AND we are not ignoring missing templates, return the same message -that is returned by the PHP implementation of the twig source() function</p> -<p>else, return the template source</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!templateFound && !ignore_missing) { - <span class="hljs-keyword">return</span> TEMPLATE_NOT_FOUND_MESSAGE.replace(<span class="hljs-string">'{name}'</span>, name); - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">return</span> templateSource; - } - } - }; - - Twig._function = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">_function, value, params</span>) </span>{ - <span class="hljs-keyword">if</span> (!Twig.functions[_function]) { - <span class="hljs-keyword">throw</span> <span class="hljs-string">"Unable to find function "</span> + _function; - } - <span class="hljs-keyword">return</span> Twig.functions[_function](value, params); - }; - - Twig._function.extend = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">_function, definition</span>) </span>{ - Twig.functions[_function] = definition; - }; - - <span class="hljs-keyword">return</span> Twig; - -})(Twig || { });</pre></div></div> - - </li> - - - <li id="section-336"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-336">¶</a> - </div> - <pre><code>Twig.js -Available under the BSD <span class="hljs-number">2</span>-Clause License -https:<span class="hljs-comment">//github.com/justjohn/twig.js</span> -</code></pre> - </div> - - </li> - - - <li id="section-337"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-337">¶</a> - </div> - <h2 id="twig-path-js">twig.path.js</h2> -<p>This file handles path parsing</p> - - </div> - - <div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{ -<span class="hljs-meta"> "use strict"</span>; - - <span class="hljs-comment">/** - * Namespace for path handling. - */</span> - Twig.path = {}; - - <span class="hljs-comment">/** - * Generate the canonical version of a url based on the given base path and file path and in - * the previously registered namespaces. - * - * @param {string} template The Twig Template - * @param {string} file The file path, may be relative and may contain namespaces. - * - * @return {string} The canonical version of the path - */</span> - Twig.path.parsePath = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">template, file</span>) </span>{ - <span class="hljs-keyword">var</span> namespaces = <span class="hljs-literal">null</span>, - file = file || <span class="hljs-string">""</span>; - - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> template === <span class="hljs-string">'object'</span> && <span class="hljs-keyword">typeof</span> template.options === <span class="hljs-string">'object'</span>) { - namespaces = template.options.namespaces; - } - - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> namespaces === <span class="hljs-string">'object'</span> && (file.indexOf(<span class="hljs-string">'::'</span>) > <span class="hljs-number">0</span>) || file.indexOf(<span class="hljs-string">'@'</span>) >= <span class="hljs-number">0</span>){ - <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> k <span class="hljs-keyword">in</span> namespaces){ - <span class="hljs-keyword">if</span> (namespaces.hasOwnProperty(k)) { - file = file.replace(k + <span class="hljs-string">'::'</span>, namespaces[k]); - file = file.replace(<span class="hljs-string">'@'</span> + k, namespaces[k]); - } - } - - <span class="hljs-keyword">return</span> file; - } - - <span class="hljs-keyword">return</span> Twig.path.relativePath(template, file); - }; - - <span class="hljs-comment">/** - * Generate the relative canonical version of a url based on the given base path and file path. - * - * @param {Twig.Template} template The Twig.Template. - * @param {string} file The file path, relative to the base path. - * - * @return {string} The canonical version of the path. - */</span> - Twig.path.relativePath = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">template, file</span>) </span>{ - <span class="hljs-keyword">var</span> base, - base_path, - sep_chr = <span class="hljs-string">"/"</span>, - new_path = [], - file = file || <span class="hljs-string">""</span>, - val; - - <span class="hljs-keyword">if</span> (template.url) { - <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> template.base !== <span class="hljs-string">'undefined'</span>) { - base = template.base + ((template.base.charAt(template.base.length<span class="hljs-number">-1</span>) === <span class="hljs-string">'/'</span>) ? <span class="hljs-string">''</span> : <span class="hljs-string">'/'</span>); - } <span class="hljs-keyword">else</span> { - base = template.url; - } - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (template.path) {</pre></div></div> - - </li> - - - <li id="section-338"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-338">¶</a> - </div> - <p>Get the system-specific path separator</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>), - sep = path.sep || sep_chr, - relative = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(<span class="hljs-string">"^\\.{1,2}"</span> + sep.replace(<span class="hljs-string">"\\"</span>, <span class="hljs-string">"\\\\"</span>)); - file = file.replace(<span class="hljs-regexp">/\//g</span>, sep); - - <span class="hljs-keyword">if</span> (template.base !== <span class="hljs-literal">undefined</span> && file.match(relative) == <span class="hljs-literal">null</span>) { - file = file.replace(template.base, <span class="hljs-string">''</span>); - base = template.base + sep; - } <span class="hljs-keyword">else</span> { - base = path.normalize(template.path); - } - - base = base.replace(sep+sep, sep); - sep_chr = sep; - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ((template.name || template.id) && template.method && template.method !== <span class="hljs-string">'fs'</span> && template.method !== <span class="hljs-string">'ajax'</span>) {</pre></div></div> - - </li> - - - <li id="section-339"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-339">¶</a> - </div> - <p>Custom registered loader</p> - - </div> - - <div class="content"><div class='highlight'><pre> base = template.base || template.name || template.id; - } <span class="hljs-keyword">else</span> { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Cannot extend an inline template."</span>); - } - - base_path = base.split(sep_chr);</pre></div></div> - - </li> - - - <li id="section-340"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-340">¶</a> - </div> - <p>Remove file from url</p> - - </div> - - <div class="content"><div class='highlight'><pre> base_path.pop(); - base_path = base_path.concat(file.split(sep_chr)); - - <span class="hljs-keyword">while</span> (base_path.length > <span class="hljs-number">0</span>) { - val = base_path.shift(); - <span class="hljs-keyword">if</span> (val == <span class="hljs-string">"."</span>) {</pre></div></div> - - </li> - - - <li id="section-341"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-341">¶</a> - </div> - <p>Ignore</p> - - </div> - - <div class="content"><div class='highlight'><pre> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (val == <span class="hljs-string">".."</span> && new_path.length > <span class="hljs-number">0</span> && new_path[new_path.length<span class="hljs-number">-1</span>] != <span class="hljs-string">".."</span>) { - new_path.pop(); - } <span class="hljs-keyword">else</span> { - new_path.push(val); - } - } - - <span class="hljs-keyword">return</span> new_path.join(sep_chr); - }; - - <span class="hljs-keyword">return</span> Twig; -}) (Twig || { });</pre></div></div> - - </li> - - - <li id="section-342"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-342">¶</a> - </div> - <pre><code>Twig.js -Available under the BSD <span class="hljs-number">2</span>-Clause License -https:<span class="hljs-comment">//github.com/justjohn/twig.js</span> -</code></pre> - </div> - - </li> - - - <li id="section-343"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-343">¶</a> - </div> - <h2 id="twig-tests-js">twig.tests.js</h2> -<p>This file handles expression tests. (is empty, is not defined, etc…)</p> - - </div> - - <div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{ -<span class="hljs-meta"> "use strict"</span>; - Twig.tests = { - empty: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">null</span> || value === <span class="hljs-literal">undefined</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;</pre></div></div> - - </li> - - - <li id="section-344"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-344">¶</a> - </div> - <p>Handler numbers</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> value === <span class="hljs-string">"number"</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; <span class="hljs-comment">// numbers are never "empty"</span></pre></div></div> - - </li> - - - <li id="section-345"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-345">¶</a> - </div> - <p>Handle strings and arrays</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (value.length && value.length > <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;</pre></div></div> - - </li> - - - <li id="section-346"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-346">¶</a> - </div> - <p>Handle objects</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> key <span class="hljs-keyword">in</span> value) { - <span class="hljs-keyword">if</span> (value.hasOwnProperty(key)) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; - } - <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; - }, - odd: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">return</span> value % <span class="hljs-number">2</span> === <span class="hljs-number">1</span>; - }, - even: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">return</span> value % <span class="hljs-number">2</span> === <span class="hljs-number">0</span>; - }, - divisibleby: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{ - <span class="hljs-keyword">return</span> value % params[<span class="hljs-number">0</span>] === <span class="hljs-number">0</span>; - }, - defined: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">return</span> value !== <span class="hljs-literal">undefined</span>; - }, - none: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">return</span> value === <span class="hljs-literal">null</span>; - }, - <span class="hljs-string">'null'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.none(value); <span class="hljs-comment">// Alias of none</span> - }, - sameas: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{ - <span class="hljs-keyword">return</span> value === params[<span class="hljs-number">0</span>]; - }, - iterable: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{ - <span class="hljs-keyword">return</span> value && (Twig.lib.is(<span class="hljs-string">"Array"</span>, value) || Twig.lib.is(<span class="hljs-string">"Object"</span>, value)); - } - <span class="hljs-comment">/* - constant ? - */</span> - }; - - Twig.test = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">test, value, params</span>) </span>{ - <span class="hljs-keyword">if</span> (!Twig.tests[test]) { - <span class="hljs-keyword">throw</span> <span class="hljs-string">"Test "</span> + test + <span class="hljs-string">" is not defined."</span>; - } - <span class="hljs-keyword">return</span> Twig.tests[test](value, params); - }; - - Twig.test.extend = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">test, definition</span>) </span>{ - Twig.tests[test] = definition; - }; - - <span class="hljs-keyword">return</span> Twig; -})( Twig || { } );</pre></div></div> - - </li> - - - <li id="section-347"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-347">¶</a> - </div> - <pre><code>Twig.js -Available under the BSD <span class="hljs-number">2</span>-Clause License -https:<span class="hljs-comment">//github.com/justjohn/twig.js</span> -</code></pre> - </div> - - </li> - - - <li id="section-348"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-348">¶</a> - </div> - <h2 id="twig-exports-js">twig.exports.js</h2> -<p>This file provides extension points and other hooks into the twig functionality.</p> - - </div> - - <div class="content"><div class='highlight'><pre> -<span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{ -<span class="hljs-meta"> "use strict"</span>; - Twig.exports = { - VERSION: Twig.VERSION - }; - - <span class="hljs-comment">/** - * Create and compile a twig.js template. - * - * @param {Object} param Paramteres for creating a Twig template. - * - * @return {Twig.Template} A Twig template ready for rendering. - */</span> - Twig.exports.twig = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">twig</span>(<span class="hljs-params">params</span>) </span>{ -<span class="hljs-meta"> 'use strict'</span>; - <span class="hljs-keyword">var</span> id = params.id, - options = { - strict_variables: params.strict_variables || <span class="hljs-literal">false</span>,</pre></div></div> - - </li> - - - <li id="section-349"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-349">¶</a> - </div> - <p>TODO: turn autoscape on in the next major version</p> - - </div> - - <div class="content"><div class='highlight'><pre> autoescape: params.autoescape != <span class="hljs-literal">null</span> && params.autoescape || <span class="hljs-literal">false</span>, - allowInlineIncludes: params.allowInlineIncludes || <span class="hljs-literal">false</span>, - rethrow: params.rethrow || <span class="hljs-literal">false</span>, - namespaces: params.namespaces - }; - - <span class="hljs-keyword">if</span> (Twig.cache && id) { - Twig.validateId(id); - } - - <span class="hljs-keyword">if</span> (params.debug !== <span class="hljs-literal">undefined</span>) { - Twig.debug = params.debug; - } - <span class="hljs-keyword">if</span> (params.trace !== <span class="hljs-literal">undefined</span>) { - Twig.trace = params.trace; - } - - <span class="hljs-keyword">if</span> (params.data !== <span class="hljs-literal">undefined</span>) { - <span class="hljs-keyword">return</span> Twig.Templates.parsers.twig({ - data: params.data, - path: params.hasOwnProperty(<span class="hljs-string">'path'</span>) ? params.path : <span class="hljs-literal">undefined</span>, - <span class="hljs-built_in">module</span>: params.module, - id: id, - options: options - }); - - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (params.ref !== <span class="hljs-literal">undefined</span>) { - <span class="hljs-keyword">if</span> (params.id !== <span class="hljs-literal">undefined</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Both ref and id cannot be set on a twig.js template."</span>); - } - <span class="hljs-keyword">return</span> Twig.Templates.load(params.ref); - - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (params.method !== <span class="hljs-literal">undefined</span>) { - <span class="hljs-keyword">if</span> (!Twig.Templates.isRegisteredLoader(params.method)) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">'Loader for "'</span> + params.method + <span class="hljs-string">'" is not defined.'</span>); - } - <span class="hljs-keyword">return</span> Twig.Templates.loadRemote(params.name || params.href || params.path || id || <span class="hljs-literal">undefined</span>, { - id: id, - method: params.method, - parser: params.parser || <span class="hljs-string">'twig'</span>, - base: params.base, - <span class="hljs-built_in">module</span>: params.module, - precompiled: params.precompiled, - <span class="hljs-keyword">async</span>: params.async, - options: options - - }, params.load, params.error); - - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (params.href !== <span class="hljs-literal">undefined</span>) { - <span class="hljs-keyword">return</span> Twig.Templates.loadRemote(params.href, { - id: id, - method: <span class="hljs-string">'ajax'</span>, - parser: params.parser || <span class="hljs-string">'twig'</span>, - base: params.base, - <span class="hljs-built_in">module</span>: params.module, - precompiled: params.precompiled, - <span class="hljs-keyword">async</span>: params.async, - options: options - - }, params.load, params.error); - - } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (params.path !== <span class="hljs-literal">undefined</span>) { - <span class="hljs-keyword">return</span> Twig.Templates.loadRemote(params.path, { - id: id, - method: <span class="hljs-string">'fs'</span>, - parser: params.parser || <span class="hljs-string">'twig'</span>, - base: params.base, - <span class="hljs-built_in">module</span>: params.module, - precompiled: params.precompiled, - <span class="hljs-keyword">async</span>: params.async, - options: options - - }, params.load, params.error); - } - };</pre></div></div> - - </li> - - - <li id="section-350"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-350">¶</a> - </div> - <p>Extend Twig with a new filter.</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.exports.extendFilter = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">filter, definition</span>) </span>{ - Twig.filter.extend(filter, definition); - };</pre></div></div> - - </li> - - - <li id="section-351"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-351">¶</a> - </div> - <p>Extend Twig with a new function.</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.exports.extendFunction = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">fn, definition</span>) </span>{ - Twig._function.extend(fn, definition); - };</pre></div></div> - - </li> - - - <li id="section-352"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-352">¶</a> - </div> - <p>Extend Twig with a new test.</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.exports.extendTest = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">test, definition</span>) </span>{ - Twig.test.extend(test, definition); - };</pre></div></div> - - </li> - - - <li id="section-353"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-353">¶</a> - </div> - <p>Extend Twig with a new definition.</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.exports.extendTag = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">definition</span>) </span>{ - Twig.logic.extend(definition); - };</pre></div></div> - - </li> - - - <li id="section-354"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-354">¶</a> - </div> - <p>Provide an environment for extending Twig core. -Calls fn with the internal Twig object.</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.exports.extend = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">fn</span>) </span>{ - fn(Twig); - }; - - - <span class="hljs-comment">/** - * Provide an extension for use with express 2. - * - * @param {string} markup The template markup. - * @param {array} options The express options. - * - * @return {string} The rendered template. - */</span> - Twig.exports.compile = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">markup, options</span>) </span>{ - <span class="hljs-keyword">var</span> id = options.filename, - path = options.filename, - template;</pre></div></div> - - </li> - - - <li id="section-355"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-355">¶</a> - </div> - <p>Try to load the template from the cache</p> - - </div> - - <div class="content"><div class='highlight'><pre> template = <span class="hljs-keyword">new</span> Twig.Template({ - data: markup, - path: path, - id: id, - options: options.settings[<span class="hljs-string">'twig options'</span>] - }); <span class="hljs-comment">// Twig.Templates.load(id) ||</span> - - <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">context</span>) </span>{ - <span class="hljs-keyword">return</span> template.render(context); - }; - }; - - <span class="hljs-comment">/** - * Provide an extension for use with express 3. - * - * @param {string} path The location of the template file on disk. - * @param {Object|Function} The options or callback. - * @param {Function} fn callback. - * - * @throws Twig.Error - */</span> - Twig.exports.renderFile = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">path, options, fn</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-356"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-356">¶</a> - </div> - <p>handle callback in options</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> options === <span class="hljs-string">'function'</span>) { - fn = options; - options = {}; - } - - options = options || {}; - - <span class="hljs-keyword">var</span> settings = options.settings || {}; - - <span class="hljs-keyword">var</span> params = { - path: path, - base: settings.views, - load: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">template</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-357"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-357">¶</a> - </div> - <p>render and return template</p> - - </div> - - <div class="content"><div class='highlight'><pre> fn(<span class="hljs-literal">null</span>, template.render(options)); - } - };</pre></div></div> - - </li> - - - <li id="section-358"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-358">¶</a> - </div> - <p>mixin any options provided to the express app.</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> view_options = settings[<span class="hljs-string">'twig options'</span>]; - - <span class="hljs-keyword">if</span> (view_options) { - <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> option <span class="hljs-keyword">in</span> view_options) { - <span class="hljs-keyword">if</span> (view_options.hasOwnProperty(option)) { - params[option] = view_options[option]; - } - } - } - - Twig.exports.twig(params); - };</pre></div></div> - - </li> - - - <li id="section-359"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-359">¶</a> - </div> - <p>Express 3 handler</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.exports.__express = Twig.exports.renderFile; - - <span class="hljs-comment">/** - * Shoud Twig.js cache templates. - * Disable during development to see changes to templates without - * reloading, and disable in production to improve performance. - * - * @param {boolean} cache - */</span> - Twig.exports.cache = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">cache</span>) </span>{ - Twig.cache = cache; - };</pre></div></div> - - </li> - - - <li id="section-360"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-360">¶</a> - </div> - <p>We need to export the path module so we can effectively test it</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.exports.path = Twig.path; - - <span class="hljs-keyword">return</span> Twig; -}) (Twig || { });</pre></div></div> - - </li> - - - <li id="section-361"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-361">¶</a> - </div> - <pre><code>Twig.js -Available under the BSD <span class="hljs-number">2</span>-Clause License -https:<span class="hljs-comment">//github.com/justjohn/twig.js</span> -</code></pre> - </div> - - </li> - - - <li id="section-362"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-362">¶</a> - </div> - <h2 id="twig-compiler-js">twig.compiler.js</h2> -<p>This file handles compiling templates into JS</p> - - </div> - - <div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{ - <span class="hljs-comment">/** - * Namespace for compilation. - */</span> - Twig.compiler = { - <span class="hljs-built_in">module</span>: {} - };</pre></div></div> - - </li> - - - <li id="section-363"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-363">¶</a> - </div> - <p>Compile a Twig Template to output.</p> - - </div> - - <div class="content"><div class='highlight'><pre> Twig.compiler.compile = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">template, options</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-364"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-364">¶</a> - </div> - <p>Get tokens</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> tokens = <span class="hljs-built_in">JSON</span>.stringify(template.tokens) - , id = template.id - , output; - - <span class="hljs-keyword">if</span> (options.module) { - <span class="hljs-keyword">if</span> (Twig.compiler.module[options.module] === <span class="hljs-literal">undefined</span>) { - <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to find module type "</span> + options.module); - } - output = Twig.compiler.module[options.module](id, tokens, options.twig); - } <span class="hljs-keyword">else</span> { - output = Twig.compiler.wrap(id, tokens); - } - <span class="hljs-keyword">return</span> output; - }; - - Twig.compiler.module = { - amd: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">id, tokens, pathToTwig</span>) </span>{ - <span class="hljs-keyword">return</span> <span class="hljs-string">'define(["'</span> + pathToTwig + <span class="hljs-string">'"], function (Twig) {\n\tvar twig, templates;\ntwig = Twig.twig;\ntemplates = '</span> + Twig.compiler.wrap(id, tokens) + <span class="hljs-string">'\n\treturn templates;\n});'</span>; - } - , node: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">id, tokens</span>) </span>{ - <span class="hljs-keyword">return</span> <span class="hljs-string">'var twig = require("twig").twig;\n'</span> - + <span class="hljs-string">'exports.template = '</span> + Twig.compiler.wrap(id, tokens) - } - , cjs2: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">id, tokens, pathToTwig</span>) </span>{ - <span class="hljs-keyword">return</span> <span class="hljs-string">'module.declare([{ twig: "'</span> + pathToTwig + <span class="hljs-string">'" }], function (require, exports, module) {\n'</span> - + <span class="hljs-string">'\tvar twig = require("twig").twig;\n'</span> - + <span class="hljs-string">'\texports.template = '</span> + Twig.compiler.wrap(id, tokens) - + <span class="hljs-string">'\n});'</span> - } - }; - - Twig.compiler.wrap = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">id, tokens</span>) </span>{ - <span class="hljs-keyword">return</span> <span class="hljs-string">'twig({id:"'</span>+id.replace(<span class="hljs-string">'"'</span>, <span class="hljs-string">'\\"'</span>)+<span class="hljs-string">'", data:'</span>+tokens+<span class="hljs-string">', precompiled: true});\n'</span>; - }; - - <span class="hljs-keyword">return</span> Twig; -})(Twig || {});</pre></div></div> - - </li> - - - <li id="section-365"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-365">¶</a> - </div> - <pre><code>Twig.js -Available under the BSD <span class="hljs-number">2</span>-Clause License -https:<span class="hljs-comment">//github.com/justjohn/twig.js</span> -</code></pre> - </div> - - </li> - - - <li id="section-366"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-366">¶</a> - </div> - <h2 id="twig-module-js">twig.module.js</h2> -<p>Provide a CommonJS/AMD/Node module export.</p> - - </div> - - <div class="content"><div class='highlight'><pre> -<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">module</span> !== <span class="hljs-string">'undefined'</span> && <span class="hljs-built_in">module</span>.declare) {</pre></div></div> - - </li> - - - <li id="section-367"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-367">¶</a> - </div> - <p>Provide a CommonJS Modules/2.0 draft 8 module</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-built_in">module</span>.declare([], <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">require, exports, module</span>) </span>{</pre></div></div> - - </li> - - - <li id="section-368"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-368">¶</a> - </div> - <p>Add exports from the Twig exports</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (key <span class="hljs-keyword">in</span> Twig.exports) { - <span class="hljs-keyword">if</span> (Twig.exports.hasOwnProperty(key)) { - exports[key] = Twig.exports[key]; - } - } - }); -} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> define == <span class="hljs-string">'function'</span> && define.amd) { - define(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ - <span class="hljs-keyword">return</span> Twig.exports; - }); -} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">module</span> !== <span class="hljs-string">'undefined'</span> && <span class="hljs-built_in">module</span>.exports) {</pre></div></div> - - </li> - - - <li id="section-369"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-369">¶</a> - </div> - <p>Provide a CommonJS Modules/1.1 module</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-built_in">module</span>.exports = Twig.exports; -} <span class="hljs-keyword">else</span> {</pre></div></div> - - </li> - - - <li id="section-370"> - <div class="annotation"> - - <div class="pilwrap "> - <a class="pilcrow" href="#section-370">¶</a> - </div> - <p>Export for browser use</p> - - </div> - - <div class="content"><div class='highlight'><pre> <span class="hljs-built_in">window</span>.twig = Twig.exports.twig; - <span class="hljs-built_in">window</span>.Twig = Twig.exports; -}</pre></div></div> - - </li> - - </ul> - </div> -</body> -</html> |