1 | /* |
---|
2 | * Ext JS Library 2.2.1 |
---|
3 | * Copyright(c) 2006-2009, Ext JS, LLC. |
---|
4 | * licensing@extjs.com |
---|
5 | * |
---|
6 | * http://extjs.com/license |
---|
7 | */ |
---|
8 | |
---|
9 | /** |
---|
10 | * @class Ext.Template |
---|
11 | * Represents an HTML fragment template. Templates can be precompiled for greater performance. |
---|
12 | * For a list of available format functions, see {@link Ext.util.Format}.<br /> |
---|
13 | * Usage: |
---|
14 | <pre><code> |
---|
15 | var t = new Ext.Template( |
---|
16 | '<div name="{id}">', |
---|
17 | '<span class="{cls}">{name:trim} {value:ellipsis(10)}</span>', |
---|
18 | '</div>' |
---|
19 | ); |
---|
20 | t.append('some-element', {id: 'myid', cls: 'myclass', name: 'foo', value: 'bar'}); |
---|
21 | </code></pre> |
---|
22 | * @constructor |
---|
23 | * @param {String/Array} html The HTML fragment or an array of fragments to join("") or multiple arguments to join("") |
---|
24 | */ |
---|
25 | Ext.Template = function(html){ |
---|
26 | var a = arguments; |
---|
27 | if(Ext.isArray(html)){ |
---|
28 | html = html.join(""); |
---|
29 | }else if(a.length > 1){ |
---|
30 | var buf = []; |
---|
31 | for(var i = 0, len = a.length; i < len; i++){ |
---|
32 | if(typeof a[i] == 'object'){ |
---|
33 | Ext.apply(this, a[i]); |
---|
34 | }else{ |
---|
35 | buf[buf.length] = a[i]; |
---|
36 | } |
---|
37 | } |
---|
38 | html = buf.join(''); |
---|
39 | } |
---|
40 | /**@private*/ |
---|
41 | this.html = html; |
---|
42 | if(this.compiled){ |
---|
43 | this.compile(); |
---|
44 | } |
---|
45 | }; |
---|
46 | Ext.Template.prototype = { |
---|
47 | /** |
---|
48 | * Returns an HTML fragment of this template with the specified values applied. |
---|
49 | * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'}) |
---|
50 | * @return {String} The HTML fragment |
---|
51 | */ |
---|
52 | applyTemplate : function(values){ |
---|
53 | if(this.compiled){ |
---|
54 | return this.compiled(values); |
---|
55 | } |
---|
56 | var useF = this.disableFormats !== true; |
---|
57 | var fm = Ext.util.Format, tpl = this; |
---|
58 | var fn = function(m, name, format, args){ |
---|
59 | if(format && useF){ |
---|
60 | if(format.substr(0, 5) == "this."){ |
---|
61 | return tpl.call(format.substr(5), values[name], values); |
---|
62 | }else{ |
---|
63 | if(args){ |
---|
64 | // quoted values are required for strings in compiled templates, |
---|
65 | // but for non compiled we need to strip them |
---|
66 | // quoted reversed for jsmin |
---|
67 | var re = /^\s*['"](.*)["']\s*$/; |
---|
68 | args = args.split(','); |
---|
69 | for(var i = 0, len = args.length; i < len; i++){ |
---|
70 | args[i] = args[i].replace(re, "$1"); |
---|
71 | } |
---|
72 | args = [values[name]].concat(args); |
---|
73 | }else{ |
---|
74 | args = [values[name]]; |
---|
75 | } |
---|
76 | return fm[format].apply(fm, args); |
---|
77 | } |
---|
78 | }else{ |
---|
79 | return values[name] !== undefined ? values[name] : ""; |
---|
80 | } |
---|
81 | }; |
---|
82 | return this.html.replace(this.re, fn); |
---|
83 | }, |
---|
84 | |
---|
85 | /** |
---|
86 | * Sets the HTML used as the template and optionally compiles it. |
---|
87 | * @param {String} html |
---|
88 | * @param {Boolean} compile (optional) True to compile the template (defaults to undefined) |
---|
89 | * @return {Ext.Template} this |
---|
90 | */ |
---|
91 | set : function(html, compile){ |
---|
92 | this.html = html; |
---|
93 | this.compiled = null; |
---|
94 | if(compile){ |
---|
95 | this.compile(); |
---|
96 | } |
---|
97 | return this; |
---|
98 | }, |
---|
99 | |
---|
100 | /** |
---|
101 | * True to disable format functions (defaults to false) |
---|
102 | * @type Boolean |
---|
103 | */ |
---|
104 | disableFormats : false, |
---|
105 | |
---|
106 | /** |
---|
107 | * The regular expression used to match template variables |
---|
108 | * @type RegExp |
---|
109 | * @property |
---|
110 | */ |
---|
111 | re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g, |
---|
112 | |
---|
113 | /** |
---|
114 | * Compiles the template into an internal function, eliminating the RegEx overhead. |
---|
115 | * @return {Ext.Template} this |
---|
116 | */ |
---|
117 | compile : function(){ |
---|
118 | var fm = Ext.util.Format; |
---|
119 | var useF = this.disableFormats !== true; |
---|
120 | var sep = Ext.isGecko ? "+" : ","; |
---|
121 | var fn = function(m, name, format, args){ |
---|
122 | if(format && useF){ |
---|
123 | args = args ? ',' + args : ""; |
---|
124 | if(format.substr(0, 5) != "this."){ |
---|
125 | format = "fm." + format + '('; |
---|
126 | }else{ |
---|
127 | format = 'this.call("'+ format.substr(5) + '", '; |
---|
128 | args = ", values"; |
---|
129 | } |
---|
130 | }else{ |
---|
131 | args= ''; format = "(values['" + name + "'] == undefined ? '' : "; |
---|
132 | } |
---|
133 | return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'"; |
---|
134 | }; |
---|
135 | var body; |
---|
136 | // branched to use + in gecko and [].join() in others |
---|
137 | if(Ext.isGecko){ |
---|
138 | body = "this.compiled = function(values){ return '" + |
---|
139 | this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) + |
---|
140 | "';};"; |
---|
141 | }else{ |
---|
142 | body = ["this.compiled = function(values){ return ['"]; |
---|
143 | body.push(this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn)); |
---|
144 | body.push("'].join('');};"); |
---|
145 | body = body.join(''); |
---|
146 | } |
---|
147 | eval(body); |
---|
148 | return this; |
---|
149 | }, |
---|
150 | |
---|
151 | // private function used to call members |
---|
152 | call : function(fnName, value, allValues){ |
---|
153 | return this[fnName](value, allValues); |
---|
154 | }, |
---|
155 | |
---|
156 | /** |
---|
157 | * Applies the supplied values to the template and inserts the new node(s) as the first child of el. |
---|
158 | * @param {Mixed} el The context element |
---|
159 | * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'}) |
---|
160 | * @param {Boolean} returnElement (optional) true to return a Ext.Element (defaults to undefined) |
---|
161 | * @return {HTMLElement/Ext.Element} The new node or Element |
---|
162 | */ |
---|
163 | insertFirst: function(el, values, returnElement){ |
---|
164 | return this.doInsert('afterBegin', el, values, returnElement); |
---|
165 | }, |
---|
166 | |
---|
167 | /** |
---|
168 | * Applies the supplied values to the template and inserts the new node(s) before el. |
---|
169 | * @param {Mixed} el The context element |
---|
170 | * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'}) |
---|
171 | * @param {Boolean} returnElement (optional) true to return a Ext.Element (defaults to undefined) |
---|
172 | * @return {HTMLElement/Ext.Element} The new node or Element |
---|
173 | */ |
---|
174 | insertBefore: function(el, values, returnElement){ |
---|
175 | return this.doInsert('beforeBegin', el, values, returnElement); |
---|
176 | }, |
---|
177 | |
---|
178 | /** |
---|
179 | * Applies the supplied values to the template and inserts the new node(s) after el. |
---|
180 | * @param {Mixed} el The context element |
---|
181 | * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'}) |
---|
182 | * @param {Boolean} returnElement (optional) true to return a Ext.Element (defaults to undefined) |
---|
183 | * @return {HTMLElement/Ext.Element} The new node or Element |
---|
184 | */ |
---|
185 | insertAfter : function(el, values, returnElement){ |
---|
186 | return this.doInsert('afterEnd', el, values, returnElement); |
---|
187 | }, |
---|
188 | |
---|
189 | /** |
---|
190 | * Applies the supplied values to the template and appends the new node(s) to el. |
---|
191 | * @param {Mixed} el The context element |
---|
192 | * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'}) |
---|
193 | * @param {Boolean} returnElement (optional) true to return a Ext.Element (defaults to undefined) |
---|
194 | * @return {HTMLElement/Ext.Element} The new node or Element |
---|
195 | */ |
---|
196 | append : function(el, values, returnElement){ |
---|
197 | return this.doInsert('beforeEnd', el, values, returnElement); |
---|
198 | }, |
---|
199 | |
---|
200 | doInsert : function(where, el, values, returnEl){ |
---|
201 | el = Ext.getDom(el); |
---|
202 | var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values)); |
---|
203 | return returnEl ? Ext.get(newNode, true) : newNode; |
---|
204 | }, |
---|
205 | |
---|
206 | /** |
---|
207 | * Applies the supplied values to the template and overwrites the content of el with the new node(s). |
---|
208 | * @param {Mixed} el The context element |
---|
209 | * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'}) |
---|
210 | * @param {Boolean} returnElement (optional) true to return a Ext.Element (defaults to undefined) |
---|
211 | * @return {HTMLElement/Ext.Element} The new node or Element |
---|
212 | */ |
---|
213 | overwrite : function(el, values, returnElement){ |
---|
214 | el = Ext.getDom(el); |
---|
215 | el.innerHTML = this.applyTemplate(values); |
---|
216 | return returnElement ? Ext.get(el.firstChild, true) : el.firstChild; |
---|
217 | } |
---|
218 | }; |
---|
219 | /** |
---|
220 | * Alias for {@link #applyTemplate} |
---|
221 | * Returns an HTML fragment of this template with the specified values applied. |
---|
222 | * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'}) |
---|
223 | * @return {String} The HTML fragment |
---|
224 | * @member Ext.Template |
---|
225 | * @method apply |
---|
226 | */ |
---|
227 | Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate; |
---|
228 | |
---|
229 | // backwards compat |
---|
230 | Ext.DomHelper.Template = Ext.Template; |
---|
231 | |
---|
232 | /** |
---|
233 | * Creates a template from the passed element's value (<i>display:none</i> textarea, preferred) or innerHTML. |
---|
234 | * @param {String/HTMLElement} el A DOM element or its id |
---|
235 | * @param {Object} config A configuration object |
---|
236 | * @return {Ext.Template} The created template |
---|
237 | * @static |
---|
238 | */ |
---|
239 | Ext.Template.from = function(el, config){ |
---|
240 | el = Ext.getDom(el); |
---|
241 | return new Ext.Template(el.value || el.innerHTML, config || ''); |
---|
242 | }; |
---|