242 lines
9.3 KiB
JavaScript
242 lines
9.3 KiB
JavaScript
|
|
/*
|
||
|
|
* Ext JS Library 2.3.0
|
||
|
|
* Copyright(c) 2006-2009, Ext JS, LLC.
|
||
|
|
* licensing@extjs.com
|
||
|
|
*
|
||
|
|
* http://extjs.com/license
|
||
|
|
*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @class Ext.Template
|
||
|
|
* Represents an HTML fragment template. Templates can be precompiled for greater performance.
|
||
|
|
* For a list of available format functions, see {@link Ext.util.Format}.<br />
|
||
|
|
* Usage:
|
||
|
|
<pre><code>
|
||
|
|
var t = new Ext.Template(
|
||
|
|
'<div name="{id}">',
|
||
|
|
'<span class="{cls}">{name:trim} {value:ellipsis(10)}</span>',
|
||
|
|
'</div>'
|
||
|
|
);
|
||
|
|
t.append('some-element', {id: 'myid', cls: 'myclass', name: 'foo', value: 'bar'});
|
||
|
|
</code></pre>
|
||
|
|
* @constructor
|
||
|
|
* @param {String/Array} html The HTML fragment or an array of fragments to join("") or multiple arguments to join("")
|
||
|
|
*/
|
||
|
|
Ext.Template = function(html){
|
||
|
|
var a = arguments;
|
||
|
|
if(Ext.isArray(html)){
|
||
|
|
html = html.join("");
|
||
|
|
}else if(a.length > 1){
|
||
|
|
var buf = [];
|
||
|
|
for(var i = 0, len = a.length; i < len; i++){
|
||
|
|
if(typeof a[i] == 'object'){
|
||
|
|
Ext.apply(this, a[i]);
|
||
|
|
}else{
|
||
|
|
buf[buf.length] = a[i];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
html = buf.join('');
|
||
|
|
}
|
||
|
|
/**@private*/
|
||
|
|
this.html = html;
|
||
|
|
if(this.compiled){
|
||
|
|
this.compile();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
Ext.Template.prototype = {
|
||
|
|
/**
|
||
|
|
* Returns an HTML fragment of this template with the specified values applied.
|
||
|
|
* @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'})
|
||
|
|
* @return {String} The HTML fragment
|
||
|
|
*/
|
||
|
|
applyTemplate : function(values){
|
||
|
|
if(this.compiled){
|
||
|
|
return this.compiled(values);
|
||
|
|
}
|
||
|
|
var useF = this.disableFormats !== true;
|
||
|
|
var fm = Ext.util.Format, tpl = this;
|
||
|
|
var fn = function(m, name, format, args){
|
||
|
|
if(format && useF){
|
||
|
|
if(format.substr(0, 5) == "this."){
|
||
|
|
return tpl.call(format.substr(5), values[name], values);
|
||
|
|
}else{
|
||
|
|
if(args){
|
||
|
|
// quoted values are required for strings in compiled templates,
|
||
|
|
// but for non compiled we need to strip them
|
||
|
|
// quoted reversed for jsmin
|
||
|
|
var re = /^\s*['"](.*)["']\s*$/;
|
||
|
|
args = args.split(',');
|
||
|
|
for(var i = 0, len = args.length; i < len; i++){
|
||
|
|
args[i] = args[i].replace(re, "$1");
|
||
|
|
}
|
||
|
|
args = [values[name]].concat(args);
|
||
|
|
}else{
|
||
|
|
args = [values[name]];
|
||
|
|
}
|
||
|
|
return fm[format].apply(fm, args);
|
||
|
|
}
|
||
|
|
}else{
|
||
|
|
return values[name] !== undefined ? values[name] : "";
|
||
|
|
}
|
||
|
|
};
|
||
|
|
return this.html.replace(this.re, fn);
|
||
|
|
},
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sets the HTML used as the template and optionally compiles it.
|
||
|
|
* @param {String} html
|
||
|
|
* @param {Boolean} compile (optional) True to compile the template (defaults to undefined)
|
||
|
|
* @return {Ext.Template} this
|
||
|
|
*/
|
||
|
|
set : function(html, compile){
|
||
|
|
this.html = html;
|
||
|
|
this.compiled = null;
|
||
|
|
if(compile){
|
||
|
|
this.compile();
|
||
|
|
}
|
||
|
|
return this;
|
||
|
|
},
|
||
|
|
|
||
|
|
/**
|
||
|
|
* True to disable format functions (defaults to false)
|
||
|
|
* @type Boolean
|
||
|
|
*/
|
||
|
|
disableFormats : false,
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The regular expression used to match template variables
|
||
|
|
* @type RegExp
|
||
|
|
* @property
|
||
|
|
*/
|
||
|
|
re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Compiles the template into an internal function, eliminating the RegEx overhead.
|
||
|
|
* @return {Ext.Template} this
|
||
|
|
*/
|
||
|
|
compile : function(){
|
||
|
|
var fm = Ext.util.Format;
|
||
|
|
var useF = this.disableFormats !== true;
|
||
|
|
var sep = Ext.isGecko ? "+" : ",";
|
||
|
|
var fn = function(m, name, format, args){
|
||
|
|
if(format && useF){
|
||
|
|
args = args ? ',' + args : "";
|
||
|
|
if(format.substr(0, 5) != "this."){
|
||
|
|
format = "fm." + format + '(';
|
||
|
|
}else{
|
||
|
|
format = 'this.call("'+ format.substr(5) + '", ';
|
||
|
|
args = ", values";
|
||
|
|
}
|
||
|
|
}else{
|
||
|
|
args= ''; format = "(values['" + name + "'] == undefined ? '' : ";
|
||
|
|
}
|
||
|
|
return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'";
|
||
|
|
};
|
||
|
|
var body;
|
||
|
|
// branched to use + in gecko and [].join() in others
|
||
|
|
if(Ext.isGecko){
|
||
|
|
body = "this.compiled = function(values){ return '" +
|
||
|
|
this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
|
||
|
|
"';};";
|
||
|
|
}else{
|
||
|
|
body = ["this.compiled = function(values){ return ['"];
|
||
|
|
body.push(this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn));
|
||
|
|
body.push("'].join('');};");
|
||
|
|
body = body.join('');
|
||
|
|
}
|
||
|
|
eval(body);
|
||
|
|
return this;
|
||
|
|
},
|
||
|
|
|
||
|
|
// private function used to call members
|
||
|
|
call : function(fnName, value, allValues){
|
||
|
|
return this[fnName](value, allValues);
|
||
|
|
},
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Applies the supplied values to the template and inserts the new node(s) as the first child of el.
|
||
|
|
* @param {Mixed} el The context element
|
||
|
|
* @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'})
|
||
|
|
* @param {Boolean} returnElement (optional) true to return a Ext.Element (defaults to undefined)
|
||
|
|
* @return {HTMLElement/Ext.Element} The new node or Element
|
||
|
|
*/
|
||
|
|
insertFirst: function(el, values, returnElement){
|
||
|
|
return this.doInsert('afterBegin', el, values, returnElement);
|
||
|
|
},
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Applies the supplied values to the template and inserts the new node(s) before el.
|
||
|
|
* @param {Mixed} el The context element
|
||
|
|
* @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'})
|
||
|
|
* @param {Boolean} returnElement (optional) true to return a Ext.Element (defaults to undefined)
|
||
|
|
* @return {HTMLElement/Ext.Element} The new node or Element
|
||
|
|
*/
|
||
|
|
insertBefore: function(el, values, returnElement){
|
||
|
|
return this.doInsert('beforeBegin', el, values, returnElement);
|
||
|
|
},
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Applies the supplied values to the template and inserts the new node(s) after el.
|
||
|
|
* @param {Mixed} el The context element
|
||
|
|
* @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'})
|
||
|
|
* @param {Boolean} returnElement (optional) true to return a Ext.Element (defaults to undefined)
|
||
|
|
* @return {HTMLElement/Ext.Element} The new node or Element
|
||
|
|
*/
|
||
|
|
insertAfter : function(el, values, returnElement){
|
||
|
|
return this.doInsert('afterEnd', el, values, returnElement);
|
||
|
|
},
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Applies the supplied values to the template and appends the new node(s) to el.
|
||
|
|
* @param {Mixed} el The context element
|
||
|
|
* @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'})
|
||
|
|
* @param {Boolean} returnElement (optional) true to return a Ext.Element (defaults to undefined)
|
||
|
|
* @return {HTMLElement/Ext.Element} The new node or Element
|
||
|
|
*/
|
||
|
|
append : function(el, values, returnElement){
|
||
|
|
return this.doInsert('beforeEnd', el, values, returnElement);
|
||
|
|
},
|
||
|
|
|
||
|
|
doInsert : function(where, el, values, returnEl){
|
||
|
|
el = Ext.getDom(el);
|
||
|
|
var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values));
|
||
|
|
return returnEl ? Ext.get(newNode, true) : newNode;
|
||
|
|
},
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Applies the supplied values to the template and overwrites the content of el with the new node(s).
|
||
|
|
* @param {Mixed} el The context element
|
||
|
|
* @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'})
|
||
|
|
* @param {Boolean} returnElement (optional) true to return a Ext.Element (defaults to undefined)
|
||
|
|
* @return {HTMLElement/Ext.Element} The new node or Element
|
||
|
|
*/
|
||
|
|
overwrite : function(el, values, returnElement){
|
||
|
|
el = Ext.getDom(el);
|
||
|
|
el.innerHTML = this.applyTemplate(values);
|
||
|
|
return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
/**
|
||
|
|
* Alias for {@link #applyTemplate}
|
||
|
|
* Returns an HTML fragment of this template with the specified values applied.
|
||
|
|
* @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'})
|
||
|
|
* @return {String} The HTML fragment
|
||
|
|
* @member Ext.Template
|
||
|
|
* @method apply
|
||
|
|
*/
|
||
|
|
Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
|
||
|
|
|
||
|
|
// backwards compat
|
||
|
|
Ext.DomHelper.Template = Ext.Template;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates a template from the passed element's value (<i>display:none</i> textarea, preferred) or innerHTML.
|
||
|
|
* @param {String/HTMLElement} el A DOM element or its id
|
||
|
|
* @param {Object} config A configuration object
|
||
|
|
* @return {Ext.Template} The created template
|
||
|
|
* @static
|
||
|
|
*/
|
||
|
|
Ext.Template.from = function(el, config){
|
||
|
|
el = Ext.getDom(el);
|
||
|
|
return new Ext.Template(el.value || el.innerHTML, config || '');
|
||
|
|
};
|