3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
19 Ext.Element.addMethods((function(){
20 var focusRe = /button|input|textarea|select|object/;
23 * Monitors this Element for the mouse leaving. Calls the function after the specified delay only if
24 * the mouse was not moved back into the Element within the delay. If the mouse <i>was</i> moved
25 * back in, the function is not called.
26 * @param {Number} delay The delay <b>in milliseconds</b> to wait for possible mouse re-entry before calling the handler function.
27 * @param {Function} handler The function to call if the mouse remains outside of this Element for the specified time.
28 * @param {Object} scope The scope (<code>this</code> reference) in which the handler function executes. Defaults to this Element.
29 * @return {Object} The listeners object which was added to this element so that monitoring can be stopped. Example usage:<pre><code>
30 // Hide the menu if the mouse moves out for 250ms or more
31 this.mouseLeaveMonitor = this.menuEl.monitorMouseLeave(250, this.hideMenu, this);
34 // Remove mouseleave monitor on menu destroy
35 this.menuEl.un(this.mouseLeaveMonitor);
38 monitorMouseLeave: function(delay, handler, scope) {
42 mouseleave: function(e) {
43 timer = setTimeout(Ext.Function.bind(handler, scope||me, [e]), delay);
45 mouseenter: function() {
56 * Stops the specified event(s) from bubbling and optionally prevents the default action
57 * @param {String/String[]} eventName an event / array of events to stop from bubbling
58 * @param {Boolean} preventDefault (optional) true to prevent the default action too
59 * @return {Ext.Element} this
61 swallowEvent : function(eventName, preventDefault) {
70 if (Ext.isArray(eventName)) {
71 Ext.each(eventName, function(e) {
81 * Create an event handler on this element such that when the event fires and is handled by this element,
82 * it will be relayed to another object (i.e., fired again as if it originated from that object instead).
83 * @param {String} eventName The type of event to relay
84 * @param {Object} object Any object that extends {@link Ext.util.Observable} that will provide the context
85 * for firing the relayed event
87 relayEvent : function(eventName, observable) {
88 this.on(eventName, function(e) {
89 observable.fireEvent(eventName, e);
94 * Removes Empty, or whitespace filled text nodes. Combines adjacent text nodes.
95 * @param {Boolean} forceReclean (optional) By default the element
96 * keeps track if it has been cleaned already so
97 * you can call this over and over. However, if you update the element and
98 * need to force a reclean, you can pass true.
100 clean : function(forceReclean) {
107 if (Ext.Element.data(dom, 'isCleaned') && forceReclean !== true) {
113 if (n.nodeType == 3) {
114 // Remove empty/whitespace text nodes
115 if (!(/\S/.test(n.nodeValue))) {
117 // Combine adjacent text nodes
118 } else if (nx && nx.nodeType == 3) {
119 n.appendData(Ext.String.trim(nx.data));
132 Ext.Element.data(dom, 'isCleaned', true);
137 * Direct access to the Ext.ElementLoader {@link Ext.ElementLoader#load} method. The method takes the same object
138 * parameter as {@link Ext.ElementLoader#load}
139 * @return {Ext.Element} this
141 load : function(options) {
142 this.getLoader().load(options);
147 * Gets this element's {@link Ext.ElementLoader ElementLoader}
148 * @return {Ext.ElementLoader} The loader
150 getLoader : function() {
152 data = Ext.Element.data,
153 loader = data(dom, 'loader');
156 loader = Ext.create('Ext.ElementLoader', {
159 data(dom, 'loader', loader);
165 * Update the innerHTML of this element, optionally searching for and processing scripts
166 * @param {String} html The new HTML
167 * @param {Boolean} [loadScripts=false] True to look for and process scripts
168 * @param {Function} [callback] For async script loading you can be notified when the update completes
169 * @return {Ext.Element} this
171 update : function(html, loadScripts, callback) {
183 if (loadScripts !== true) {
184 dom.innerHTML = html;
185 Ext.callback(callback, me);
190 html += '<span id="' + id + '"></span>';
192 interval = setInterval(function(){
193 if (!document.getElementById(id)) {
196 clearInterval(interval);
198 hd = DOC.getElementsByTagName("head")[0],
199 re = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,
200 srcRe = /\ssrc=([\'\"])(.*?)\1/i,
201 typeRe = /\stype=([\'\"])(.*?)\1/i,
209 while ((match = re.exec(html))) {
211 srcMatch = attrs ? attrs.match(srcRe) : false;
212 if (srcMatch && srcMatch[2]) {
213 s = DOC.createElement("script");
215 typeMatch = attrs.match(typeRe);
216 if (typeMatch && typeMatch[2]) {
217 s.type = typeMatch[2];
220 } else if (match[2] && match[2].length > 0) {
221 if (window.execScript) {
222 window.execScript(match[2]);
224 window.eval(match[2]);
229 el = DOC.getElementById(id);
233 Ext.callback(callback, me);
235 dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, '');
239 // inherit docs, overridden so we can add removeAnchor
240 removeAllListeners : function() {
242 Ext.EventManager.removeAll(this.dom);
247 * Gets the parent node of the current element taking into account Ext.scopeResetCSS
249 * @return {HTMLElement} The parent element
251 getScopeParent: function(){
252 var parent = this.dom.parentNode;
253 return Ext.scopeResetCSS ? parent.parentNode : parent;
257 * Creates a proxy element of this element
258 * @param {String/Object} config The class name of the proxy element or a DomHelper config object
259 * @param {String/HTMLElement} [renderTo] The element or element id to render the proxy to (defaults to document.body)
260 * @param {Boolean} [matchBox=false] True to align and size the proxy to this element now.
261 * @return {Ext.Element} The new proxy element
263 createProxy : function(config, renderTo, matchBox) {
264 config = (typeof config == 'object') ? config : {tag : "div", cls: config};
267 proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) :
268 Ext.DomHelper.insertBefore(me.dom, config, true);
270 proxy.setVisibilityMode(Ext.Element.DISPLAY);
272 if (matchBox && me.setBox && me.getBox) { // check to make sure Element.position.js is loaded
273 proxy.setBox(me.getBox());
279 * Checks whether this element can be focused.
280 * @return {Boolean} True if the element is focusable
282 focusable: function(){
284 nodeName = dom.nodeName.toLowerCase(),
286 hasTabIndex = !isNaN(dom.tabIndex);
289 if (focusRe.test(nodeName)) {
292 canFocus = nodeName == 'a' ? dom.href || hasTabIndex : hasTabIndex;
295 return canFocus && this.isVisible(true);
299 Ext.Element.prototype.clearListeners = Ext.Element.prototype.removeAllListeners;