Upgrade to ExtJS 3.2.2 - Released 06/02/2010
[extjs.git] / src / core / Template-more.js
1 /*!
2  * Ext JS Library 3.2.2
3  * Copyright(c) 2006-2010 Ext JS, Inc.
4  * licensing@extjs.com
5  * http://www.extjs.com/license
6  */
7 /**
8  * @class Ext.Template
9  */
10 Ext.apply(Ext.Template.prototype, {
11     /**
12      * @cfg {Boolean} disableFormats Specify <tt>true</tt> to disable format
13      * functions in the template. If the template does not contain
14      * {@link Ext.util.Format format functions}, setting <code>disableFormats</code>
15      * to true will reduce <code>{@link #apply}</code> time. Defaults to <tt>false</tt>.
16      * <pre><code>
17 var t = new Ext.Template(
18     '&lt;div name="{id}"&gt;',
19         '&lt;span class="{cls}"&gt;{name} {value}&lt;/span&gt;',
20     '&lt;/div&gt;',
21     {
22         compiled: true,      // {@link #compile} immediately
23         disableFormats: true // reduce <code>{@link #apply}</code> time since no formatting
24     }
25 );
26      * </code></pre>
27      * For a list of available format functions, see {@link Ext.util.Format}.
28      */
29     disableFormats : false,
30     /**
31      * See <code>{@link #disableFormats}</code>.
32      * @type Boolean
33      * @property disableFormats
34      */
35
36     /**
37      * The regular expression used to match template variables
38      * @type RegExp
39      * @property
40      * @hide repeat doc
41      */
42     re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
43     argsRe : /^\s*['"](.*)["']\s*$/,
44     compileARe : /\\/g,
45     compileBRe : /(\r\n|\n)/g,
46     compileCRe : /'/g,
47
48     /**
49      * Returns an HTML fragment of this template with the specified values applied.
50      * @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'})
51      * @return {String} The HTML fragment
52      * @hide repeat doc
53      */
54     applyTemplate : function(values){
55         var me = this,
56             useF = me.disableFormats !== true,
57             fm = Ext.util.Format,
58             tpl = me;
59
60         if(me.compiled){
61             return me.compiled(values);
62         }
63         function fn(m, name, format, args){
64             if (format && useF) {
65                 if (format.substr(0, 5) == "this.") {
66                     return tpl.call(format.substr(5), values[name], values);
67                 } else {
68                     if (args) {
69                         // quoted values are required for strings in compiled templates,
70                         // but for non compiled we need to strip them
71                         // quoted reversed for jsmin
72                         var re = me.argsRe;
73                         args = args.split(',');
74                         for(var i = 0, len = args.length; i < len; i++){
75                             args[i] = args[i].replace(re, "$1");
76                         }
77                         args = [values[name]].concat(args);
78                     } else {
79                         args = [values[name]];
80                     }
81                     return fm[format].apply(fm, args);
82                 }
83             } else {
84                 return values[name] !== undefined ? values[name] : "";
85             }
86         }
87         return me.html.replace(me.re, fn);
88     },
89
90     /**
91      * Compiles the template into an internal function, eliminating the RegEx overhead.
92      * @return {Ext.Template} this
93      * @hide repeat doc
94      */
95     compile : function(){
96         var me = this,
97             fm = Ext.util.Format,
98             useF = me.disableFormats !== true,
99             sep = Ext.isGecko ? "+" : ",",
100             body;
101
102         function fn(m, name, format, args){
103             if(format && useF){
104                 args = args ? ',' + args : "";
105                 if(format.substr(0, 5) != "this."){
106                     format = "fm." + format + '(';
107                 }else{
108                     format = 'this.call("'+ format.substr(5) + '", ';
109                     args = ", values";
110                 }
111             }else{
112                 args= ''; format = "(values['" + name + "'] == undefined ? '' : ";
113             }
114             return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'";
115         }
116
117         // branched to use + in gecko and [].join() in others
118         if(Ext.isGecko){
119             body = "this.compiled = function(values){ return '" +
120                    me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn) +
121                     "';};";
122         }else{
123             body = ["this.compiled = function(values){ return ['"];
124             body.push(me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn));
125             body.push("'].join('');};");
126             body = body.join('');
127         }
128         eval(body);
129         return me;
130     },
131
132     // private function used to call members
133     call : function(fnName, value, allValues){
134         return this[fnName](value, allValues);
135     }
136 });
137 Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;