3 <title>The source code</title>
\r
4 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
\r
5 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
\r
7 <body onload="prettyPrint();">
\r
8 <pre class="prettyprint lang-js">Ext.lib.Event = function() {
\r
9 var loadComplete = false,
\r
11 unloadListeners = [],
\r
28 SCROLLLEFT = 'scrollLeft',
\r
29 SCROLLTOP = 'scrollTop',
\r
31 MOUSEOVER = 'mouseover',
\r
32 MOUSEOUT = 'mouseout',
\r
34 doAdd = function() {
\r
36 if (win.addEventListener) {
\r
37 ret = function(el, eventName, fn, capture) {
\r
38 if (eventName == 'mouseenter') {
\r
39 fn = fn.createInterceptor(checkRelatedTarget);
\r
40 el.addEventListener(MOUSEOVER, fn, (capture));
\r
41 } else if (eventName == 'mouseleave') {
\r
42 fn = fn.createInterceptor(checkRelatedTarget);
\r
43 el.addEventListener(MOUSEOUT, fn, (capture));
\r
45 el.addEventListener(eventName, fn, (capture));
\r
49 } else if (win.attachEvent) {
\r
50 ret = function(el, eventName, fn, capture) {
\r
51 el.attachEvent("on" + eventName, fn);
\r
60 doRemove = function(){
\r
62 if (win.removeEventListener) {
\r
63 ret = function (el, eventName, fn, capture) {
\r
64 if (eventName == 'mouseenter') {
\r
65 eventName = MOUSEOVER;
\r
66 } else if (eventName == 'mouseleave') {
\r
67 eventName = MOUSEOUT;
\r
69 el.removeEventListener(eventName, fn, (capture));
\r
71 } else if (win.detachEvent) {
\r
72 ret = function (el, eventName, fn) {
\r
73 el.detachEvent("on" + eventName, fn);
\r
81 var isXUL = Ext.isGecko ? function(node){
\r
82 return Object.prototype.toString.call(node) == '[object XULElement]';
\r
85 var isTextNode = Ext.isGecko ? function(node){
\r
87 return node.nodeType == 3;
\r
93 return node.nodeType == 3;
\r
96 function checkRelatedTarget(e) {
\r
97 var related = pub.getRelatedTarget(e);
\r
98 return !(isXUL(related) || elContains(e.currentTarget,related));
\r
101 function elContains(parent, child) {
\r
102 if(parent && parent.firstChild){
\r
104 if(child === parent) {
\r
108 child = child.parentNode;
\r
110 // In FF if you mouseout an text input element
\r
111 // thats inside a div sometimes it randomly throws
\r
112 // Permission denied to get property HTMLDivElement.parentNode
\r
113 // See https://bugzilla.mozilla.org/show_bug.cgi?id=208427
\r
117 if(child && (child.nodeType != 1)) {
\r
127 function _getCacheIndex(el, eventName, fn) {
\r
129 Ext.each(listeners, function (v,i) {
\r
130 if(v && v[FN] == fn && v[EL] == el && v[TYPE] == eventName) {
\r
138 function _tryPreloadAttach() {
\r
142 tryAgain = !loadComplete || (retryCount > 0);
\r
147 Ext.each(onAvailStack, function (v,i,a){
\r
148 if(v && (element = doc.getElementById(v.id))){
\r
149 if(!v.checkReady || loadComplete || element.nextSibling || (doc && doc.body)) {
\r
150 element = v.override ? (v.override === true ? v.obj : v.override) : element;
\r
151 v.fn.call(element, v.obj);
\r
152 onAvailStack[i] = null;
\r
159 retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;
\r
164 clearInterval(_interval);
\r
168 ret = !(locked = false);
\r
174 function startInterval() {
\r
176 var callback = function() {
\r
177 _tryPreloadAttach();
\r
179 _interval = setInterval(callback, POLL_INTERVAL);
\r
184 function getScroll() {
\r
185 var dd = doc.documentElement,
\r
187 if(dd && (dd[SCROLLTOP] || dd[SCROLLLEFT])){
\r
188 return [dd[SCROLLLEFT], dd[SCROLLTOP]];
\r
190 return [db[SCROLLLEFT], db[SCROLLTOP]];
\r
197 function getPageCoord (ev, xy) {
\r
198 ev = ev.browserEvent || ev;
\r
199 var coord = ev['page' + xy];
\r
200 if (!coord && coord !== 0) {
\r
201 coord = ev['client' + xy] || 0;
\r
204 coord += getScroll()[xy == "X" ? 0 : 1];
\r
212 onAvailable : function(p_id, p_fn, p_obj, p_override) {
\r
213 onAvailStack.push({
\r
217 override: p_override,
\r
218 checkReady: false });
\r
220 retryCount = POLL_RETRYS;
\r
225 addListener: function(el, eventName, fn) {
\r
227 el = Ext.getDom(el);
\r
229 if (UNLOAD == eventName) {
\r
230 ret = !!(unloadListeners[unloadListeners.length] = [el, eventName, fn]);
\r
232 listeners.push([el, eventName, fn, ret = doAdd(el, eventName, fn, false)]);
\r
238 removeListener: function(el, eventName, fn) {
\r
243 el = Ext.getDom(el);
\r
246 ret = this.purgeElement(el, false, eventName);
\r
247 } else if (UNLOAD == eventName) {
\r
248 Ext.each(unloadListeners, function(v, i, a) {
\r
249 if( v && v[0] == el && v[1] == eventName && v[2] == fn) {
\r
250 unloadListeners.splice(i, 1);
\r
255 index = arguments[3] || _getCacheIndex(el, eventName, fn);
\r
256 cacheItem = listeners[index];
\r
258 if (el && cacheItem) {
\r
259 doRemove(el, eventName, cacheItem[WFN], false);
\r
260 cacheItem[WFN] = cacheItem[FN] = null;
\r
261 listeners.splice(index, 1);
\r
268 getTarget : function(ev) {
\r
269 ev = ev.browserEvent || ev;
\r
270 return this.resolveTextNode(ev.target || ev.srcElement);
\r
273 resolveTextNode : function(node) {
\r
274 return node && !isXUL(node) && isTextNode(node) ? node.parentNode : node;
\r
277 getRelatedTarget : function(ev) {
\r
278 ev = ev.browserEvent || ev;
\r
279 return this.resolveTextNode(ev.relatedTarget ||
\r
280 (ev.type == MOUSEOUT ? ev.toElement :
\r
281 ev.type == MOUSEOVER ? ev.fromElement : null));
\r
284 getPageX : function(ev) {
\r
285 return getPageCoord(ev, "X");
\r
288 getPageY : function(ev) {
\r
289 return getPageCoord(ev, "Y");
\r
293 getXY : function(ev) {
\r
294 return [this.getPageX(ev), this.getPageY(ev)];
\r
297 // Is this useful? Removing to save space unless use case exists.
\r
298 // getTime: function(ev) {
\r
299 // ev = ev.browserEvent || ev;
\r
301 // var t = new Date().getTime();
\r
312 stopEvent : function(ev) {
\r
313 this.stopPropagation(ev);
\r
314 this.preventDefault(ev);
\r
317 stopPropagation : function(ev) {
\r
318 ev = ev.browserEvent || ev;
\r
319 if (ev.stopPropagation) {
\r
320 ev.stopPropagation();
\r
322 ev.cancelBubble = true;
\r
326 preventDefault : function(ev) {
\r
327 ev = ev.browserEvent || ev;
\r
328 if (ev.preventDefault) {
\r
329 ev.preventDefault();
\r
331 ev.returnValue = false;
\r
335 getEvent : function(e) {
\r
336 e = e || win.event;
\r
338 var c = this.getEvent.caller;
\r
340 e = c.arguments[0];
\r
341 if (e && Event == e.constructor) {
\r
350 getCharCode : function(ev) {
\r
351 ev = ev.browserEvent || ev;
\r
352 return ev.charCode || ev.keyCode || 0;
\r
355 //clearCache: function() {},
\r
357 _load : function(e) {
\r
358 loadComplete = true;
\r
359 var EU = Ext.lib.Event;
\r
360 if (Ext.isIE && e !== true) {
\r
361 // IE8 complains that _load is null or not an object
\r
362 // so lets remove self via arguments.callee
\r
363 doRemove(win, "load", arguments.callee);
\r
367 purgeElement : function(el, recurse, eventName) {
\r
369 Ext.each( me.getListeners(el, eventName), function(v){
\r
371 me.removeListener(el, v.type, v.fn);
\r
375 if (recurse && el && el.childNodes) {
\r
376 Ext.each(el.childNodes, function(v){
\r
377 me.purgeElement(v, recurse, eventName);
\r
382 getListeners : function(el, eventName) {
\r
388 searchLists = eventName == UNLOAD ? unloadListeners : listeners;
\r
390 searchLists = listeners.concat(unloadListeners);
\r
393 Ext.each(searchLists, function(v, i){
\r
394 if (v && v[EL] == el && (!eventName || eventName == v[TYPE])) {
\r
399 adjust: v[ADJ_SCOPE],
\r
405 return results.length ? results : null;
\r
408 _unload : function(e) {
\r
409 var EU = Ext.lib.Event,
\r
418 Ext.each(unloadListeners, function(v) {
\r
421 scope = v[ADJ_SCOPE] ? (v[ADJ_SCOPE] === true ? v[OBJ] : v[ADJ_SCOPE]) : win;
\r
422 v[FN].call(scope, EU.getEvent(e), v[OBJ]);
\r
427 unloadListeners = null;
\r
429 if(listeners && (j = listeners.length)){
\r
431 if((l = listeners[index = --j])){
\r
432 EU.removeListener(l[EL], l[TYPE], l[FN], index);
\r
438 doRemove(win, UNLOAD, EU._unload);
\r
442 // Initialize stuff.
\r
443 pub.on = pub.addListener;
\r
444 pub.un = pub.removeListener;
\r
445 if (doc && doc.body) {
\r
448 doAdd(win, "load", pub._load);
\r
450 doAdd(win, UNLOAD, pub._unload);
\r
451 _tryPreloadAttach();
\r