Upgrade to ExtJS 3.0.0 - Released 07/06/2009
[extjs.git] / src / core / DomHelper-more.js
1 /*!
2  * Ext JS Library 3.0.0
3  * Copyright(c) 2006-2009 Ext JS, LLC
4  * licensing@extjs.com
5  * http://www.extjs.com/license
6  */
7 /**\r
8  * @class Ext.DomHelper\r
9  */\r
10 Ext.apply(Ext.DomHelper,\r
11 function(){\r
12         var pub,\r
13                 afterbegin = 'afterbegin',\r
14         afterend = 'afterend',\r
15         beforebegin = 'beforebegin',\r
16         beforeend = 'beforeend';\r
17 \r
18         // private\r
19     function doInsert(el, o, returnElement, pos, sibling, append){\r
20         el = Ext.getDom(el);\r
21         var newNode;\r
22         if (pub.useDom) {\r
23             newNode = createDom(o, null);\r
24             if (append) {\r
25                     el.appendChild(newNode);\r
26             } else {\r
27                         (sibling == 'firstChild' ? el : el.parentNode).insertBefore(newNode, el[sibling] || el);\r
28             }\r
29         } else {\r
30             newNode = Ext.DomHelper.insertHtml(pos, el, Ext.DomHelper.createHtml(o));\r
31         }\r
32         return returnElement ? Ext.get(newNode, true) : newNode;\r
33     }\r
34 \r
35         // build as dom\r
36     /** @ignore */\r
37     function createDom(o, parentNode){\r
38         var el,\r
39                 doc = document,\r
40                 useSet,\r
41                 attr,\r
42                 val,\r
43                 cn;\r
44 \r
45         if (Ext.isArray(o)) {                       // Allow Arrays of siblings to be inserted\r
46             el = doc.createDocumentFragment(); // in one shot using a DocumentFragment\r
47                 Ext.each(o, function(v) {\r
48                 createDom(v, el);\r
49             });\r
50         } else if (Ext.isString(o)) {         // Allow a string as a child spec.\r
51             el = doc.createTextNode(o);\r
52         } else {\r
53             el = doc.createElement( o.tag || 'div' );\r
54             useSet = !!el.setAttribute; // In IE some elements don't have setAttribute\r
55             Ext.iterate(o, function(attr, val){\r
56                 if(!/tag|children|cn|html|style/.test(attr)){\r
57                         if(attr == 'cls'){\r
58                             el.className = val;\r
59                         }else{\r
60                         if(useSet){\r
61                             el.setAttribute(attr, val);\r
62                         }else{\r
63                             el[attr] = val;\r
64                         }\r
65                         }\r
66                 }\r
67             });\r
68             pub.applyStyles(el, o.style);\r
69 \r
70             if ((cn = o.children || o.cn)) {\r
71                 createDom(cn, el);\r
72             } else if (o.html) {\r
73                 el.innerHTML = o.html;\r
74             }\r
75         }\r
76         if(parentNode){\r
77            parentNode.appendChild(el);\r
78         }\r
79         return el;\r
80     }\r
81 \r
82         pub = {\r
83                 /**\r
84              * Creates a new Ext.Template from the DOM object spec.\r
85              * @param {Object} o The DOM object spec (and children)\r
86              * @return {Ext.Template} The new template\r
87              */\r
88             createTemplate : function(o){\r
89                 var html = Ext.DomHelper.createHtml(o);\r
90                 return new Ext.Template(html);\r
91             },\r
92 \r
93                 /** True to force the use of DOM instead of html fragments @type Boolean */\r
94             useDom : false,\r
95 \r
96             /**\r
97              * Applies a style specification to an element.\r
98              * @param {String/HTMLElement} el The element to apply styles to\r
99              * @param {String/Object/Function} styles A style specification string e.g. 'width:100px', or object in the form {width:'100px'}, or\r
100              * a function which returns such a specification.\r
101              */\r
102             applyStyles : function(el, styles){\r
103                     if(styles){\r
104                                 var i = 0,\r
105                                 len,\r
106                                 style;\r
107 \r
108                         el = Ext.fly(el);\r
109                                 if(Ext.isFunction(styles)){\r
110                                         styles = styles.call();\r
111                                 }\r
112                                 if(Ext.isString(styles)){\r
113                                         styles = styles.trim().split(/\s*(?::|;)\s*/);\r
114                                         for(len = styles.length; i < len;){\r
115                                                 el.setStyle(styles[i++], styles[i++]);\r
116                                         }\r
117                                 }else if (Ext.isObject(styles)){\r
118                                         el.setStyle(styles);\r
119                                 }\r
120                         }\r
121             },\r
122 \r
123             /**\r
124              * Creates new DOM element(s) and inserts them before el.\r
125              * @param {Mixed} el The context element\r
126              * @param {Object/String} o The DOM object spec (and children) or raw HTML blob\r
127              * @param {Boolean} returnElement (optional) true to return a Ext.Element\r
128              * @return {HTMLElement/Ext.Element} The new node\r
129          * @hide (repeat)\r
130              */\r
131             insertBefore : function(el, o, returnElement){\r
132                 return doInsert(el, o, returnElement, beforebegin);\r
133             },\r
134 \r
135             /**\r
136              * Creates new DOM element(s) and inserts them after el.\r
137              * @param {Mixed} el The context element\r
138              * @param {Object} o The DOM object spec (and children)\r
139              * @param {Boolean} returnElement (optional) true to return a Ext.Element\r
140              * @return {HTMLElement/Ext.Element} The new node\r
141          * @hide (repeat)\r
142              */\r
143             insertAfter : function(el, o, returnElement){\r
144                 return doInsert(el, o, returnElement, afterend, 'nextSibling');\r
145             },\r
146 \r
147             /**\r
148              * Creates new DOM element(s) and inserts them as the first child of el.\r
149              * @param {Mixed} el The context element\r
150              * @param {Object/String} o The DOM object spec (and children) or raw HTML blob\r
151              * @param {Boolean} returnElement (optional) true to return a Ext.Element\r
152              * @return {HTMLElement/Ext.Element} The new node\r
153          * @hide (repeat)\r
154              */\r
155             insertFirst : function(el, o, returnElement){\r
156                 return doInsert(el, o, returnElement, afterbegin, 'firstChild');\r
157             },\r
158 \r
159             /**\r
160              * Creates new DOM element(s) and appends them to el.\r
161              * @param {Mixed} el The context element\r
162              * @param {Object/String} o The DOM object spec (and children) or raw HTML blob\r
163              * @param {Boolean} returnElement (optional) true to return a Ext.Element\r
164              * @return {HTMLElement/Ext.Element} The new node\r
165          * @hide (repeat)\r
166              */\r
167             append: function(el, o, returnElement){\r
168             return doInsert(el, o, returnElement, beforeend, '', true);\r
169         },\r
170 \r
171             /**\r
172              * Creates new DOM element(s) without inserting them to the document.\r
173              * @param {Object/String} o The DOM object spec (and children) or raw HTML blob\r
174              * @return {HTMLElement} The new uninserted node\r
175              */\r
176         createDom: createDom\r
177         };\r
178         return pub;\r
179 }());