3 <title>The source code</title>
4 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
5 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
7 <body onload="prettyPrint();">
8 <pre class="prettyprint lang-js">/*!
10 * Copyright(c) 2006-2009 Ext JS, LLC
12 * http://www.extjs.com/license
14 Ext.lib.Event = function() {
\r
15 var loadComplete = false,
\r
17 unloadListeners = [],
\r
34 SCROLLLEFT = 'scrollLeft',
\r
35 SCROLLTOP = 'scrollTop',
\r
37 MOUSEOVER = 'mouseover',
\r
38 MOUSEOUT = 'mouseout',
\r
40 doAdd = function() {
\r
42 if (win.addEventListener) {
\r
43 ret = function(el, eventName, fn, capture) {
\r
44 if (eventName == 'mouseenter') {
\r
45 fn = fn.createInterceptor(checkRelatedTarget);
\r
46 el.addEventListener(MOUSEOVER, fn, (capture));
\r
47 } else if (eventName == 'mouseleave') {
\r
48 fn = fn.createInterceptor(checkRelatedTarget);
\r
49 el.addEventListener(MOUSEOUT, fn, (capture));
\r
51 el.addEventListener(eventName, fn, (capture));
\r
55 } else if (win.attachEvent) {
\r
56 ret = function(el, eventName, fn, capture) {
\r
57 el.attachEvent("on" + eventName, fn);
\r
66 doRemove = function(){
\r
68 if (win.removeEventListener) {
\r
69 ret = function (el, eventName, fn, capture) {
\r
70 if (eventName == 'mouseenter') {
\r
71 eventName = MOUSEOVER;
\r
72 } else if (eventName == 'mouseleave') {
\r
73 eventName = MOUSEOUT;
\r
75 el.removeEventListener(eventName, fn, (capture));
\r
77 } else if (win.detachEvent) {
\r
78 ret = function (el, eventName, fn) {
\r
79 el.detachEvent("on" + eventName, fn);
\r
87 function checkRelatedTarget(e) {
\r
88 return !elContains(e.currentTarget, pub.getRelatedTarget(e));
\r
91 function elContains(parent, child) {
\r
92 if(parent && parent.firstChild){
\r
94 if(child === parent) {
\r
97 child = child.parentNode;
\r
98 if(child && (child.nodeType != 1)) {
\r
108 function _getCacheIndex(el, eventName, fn) {
\r
109 for(var v, index = -1, len = listeners.length, i = len - 1; i >= 0; --i){
\r
111 if (v && v[FN] == fn && v[EL] == el && v[TYPE] == eventName) {
\r
120 function _tryPreloadAttach() {
\r
124 tryAgain = !loadComplete || (retryCount > 0);
\r
129 Ext.each(onAvailStack, function (v,i,a){
\r
130 if(v && (element = doc.getElementById(v.id))){
\r
131 if(!v.checkReady || loadComplete || element.nextSibling || (doc && doc.body)) {
\r
132 element = v.override ? (v.override === true ? v.obj : v.override) : element;
\r
133 v.fn.call(element, v.obj);
\r
134 onAvailStack[i] = null;
\r
141 retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;
\r
146 clearInterval(_interval);
\r
150 ret = !(locked = false);
\r
156 function startInterval() {
\r
158 var callback = function() {
\r
159 _tryPreloadAttach();
\r
161 _interval = setInterval(callback, POLL_INTERVAL);
\r
166 function getScroll() {
\r
167 var dd = doc.documentElement,
\r
169 if(dd && (dd[SCROLLTOP] || dd[SCROLLLEFT])){
\r
170 return [dd[SCROLLLEFT], dd[SCROLLTOP]];
\r
172 return [db[SCROLLLEFT], db[SCROLLTOP]];
\r
179 function getPageCoord (ev, xy) {
\r
180 ev = ev.browserEvent || ev;
\r
181 var coord = ev['page' + xy];
\r
182 if (!coord && coord !== 0) {
\r
183 coord = ev['client' + xy] || 0;
\r
186 coord += getScroll()[xy == "X" ? 0 : 1];
\r
194 onAvailable : function(p_id, p_fn, p_obj, p_override) {
\r
195 onAvailStack.push({
\r
199 override: p_override,
\r
200 checkReady: false });
\r
202 retryCount = POLL_RETRYS;
\r
207 addListener: function(el, eventName, fn) {
\r
209 el = Ext.getDom(el);
\r
211 if (UNLOAD == eventName) {
\r
212 ret = !!(unloadListeners[unloadListeners.length] = [el, eventName, fn]);
\r
214 listeners.push([el, eventName, fn, ret = doAdd(el, eventName, fn, false)]);
\r
220 removeListener: function(el, eventName, fn) {
\r
225 el = Ext.getDom(el);
\r
228 ret = this.purgeElement(el, false, eventName);
\r
229 } else if (UNLOAD == eventName) {
\r
230 Ext.each(unloadListeners, function(v, i, a) {
\r
231 if( v && v[0] == el && v[1] == eventName && v[2] == fn) {
\r
232 unloadListeners.splice(i, 1);
\r
237 index = arguments[3] || _getCacheIndex(el, eventName, fn);
\r
238 cacheItem = listeners[index];
\r
240 if (el && cacheItem) {
\r
241 doRemove(el, eventName, cacheItem[WFN], false);
\r
242 cacheItem[WFN] = cacheItem[FN] = null;
\r
243 listeners.splice(index, 1);
\r
250 getTarget : function(ev) {
\r
251 ev = ev.browserEvent || ev;
\r
252 return this.resolveTextNode(ev.target || ev.srcElement);
\r
255 resolveTextNode : Ext.isGecko ? function(node){
\r
259 // work around firefox bug, https://bugzilla.mozilla.org/show_bug.cgi?id=101197
\r
260 var s = HTMLElement.prototype.toString.call(node);
\r
261 if(s == '[xpconnect wrapped native prototype]' || s == '[object XULElement]'){
\r
264 return node.nodeType == 3 ? node.parentNode : node;
\r
265 } : function(node){
\r
266 return node && node.nodeType == 3 ? node.parentNode : node;
\r
269 getRelatedTarget : function(ev) {
\r
270 ev = ev.browserEvent || ev;
\r
271 return this.resolveTextNode(ev.relatedTarget ||
\r
272 (ev.type == MOUSEOUT ? ev.toElement :
\r
273 ev.type == MOUSEOVER ? ev.fromElement : null));
\r
276 getPageX : function(ev) {
\r
277 return getPageCoord(ev, "X");
\r
280 getPageY : function(ev) {
\r
281 return getPageCoord(ev, "Y");
\r
285 getXY : function(ev) {
\r
286 return [this.getPageX(ev), this.getPageY(ev)];
\r
289 // Is this useful? Removing to save space unless use case exists.
\r
290 // getTime: function(ev) {
\r
291 // ev = ev.browserEvent || ev;
\r
293 // var t = new Date().getTime();
\r
304 stopEvent : function(ev) {
\r
305 this.stopPropagation(ev);
\r
306 this.preventDefault(ev);
\r
309 stopPropagation : function(ev) {
\r
310 ev = ev.browserEvent || ev;
\r
311 if (ev.stopPropagation) {
\r
312 ev.stopPropagation();
\r
314 ev.cancelBubble = true;
\r
318 preventDefault : function(ev) {
\r
319 ev = ev.browserEvent || ev;
\r
320 if (ev.preventDefault) {
\r
321 ev.preventDefault();
\r
323 ev.returnValue = false;
\r
327 getEvent : function(e) {
\r
328 e = e || win.event;
\r
330 var c = this.getEvent.caller;
\r
332 e = c.arguments[0];
\r
333 if (e && Event == e.constructor) {
\r
342 getCharCode : function(ev) {
\r
343 ev = ev.browserEvent || ev;
\r
344 return ev.charCode || ev.keyCode || 0;
\r
347 //clearCache: function() {},
\r
349 _load : function(e) {
\r
350 loadComplete = true;
\r
351 var EU = Ext.lib.Event;
\r
352 if (Ext.isIE && e !== true) {
\r
353 // IE8 complains that _load is null or not an object
\r
354 // so lets remove self via arguments.callee
\r
355 doRemove(win, "load", arguments.callee);
\r
359 purgeElement : function(el, recurse, eventName) {
\r
361 Ext.each( me.getListeners(el, eventName), function(v){
\r
363 me.removeListener(el, v.type, v.fn, v.index);
\r
367 if (recurse && el && el.childNodes) {
\r
368 Ext.each(el.childNodes, function(v){
\r
369 me.purgeElement(v, recurse, eventName);
\r
374 getListeners : function(el, eventName) {
\r
380 searchLists = eventName == UNLOAD ? unloadListeners : listeners;
\r
382 searchLists = listeners.concat(unloadListeners);
\r
385 Ext.each(searchLists, function(v, i){
\r
386 if (v && v[EL] == el && (!eventName || eventName == v[TYPE])) {
\r
391 adjust: v[ADJ_SCOPE],
\r
397 return results.length ? results : null;
\r
400 _unload : function(e) {
\r
401 var EU = Ext.lib.Event,
\r
410 Ext.each(unloadListeners, function(v) {
\r
413 scope = v[ADJ_SCOPE] ? (v[ADJ_SCOPE] === true ? v[OBJ] : v[ADJ_SCOPE]) : win;
\r
414 v[FN].call(scope, EU.getEvent(e), v[OBJ]);
\r
419 unloadListeners = null;
\r
421 if(listeners && (j = listeners.length)){
\r
423 if((l = listeners[index = --j])){
\r
424 EU.removeListener(l[EL], l[TYPE], l[FN], index);
\r
430 doRemove(win, UNLOAD, EU._unload);
\r
434 // Initialize stuff.
\r
435 pub.on = pub.addListener;
\r
436 pub.un = pub.removeListener;
\r
437 if (doc && doc.body) {
\r
440 doAdd(win, "load", pub._load);
\r
442 doAdd(win, UNLOAD, pub._unload);
\r
443 _tryPreloadAttach();
\r