eventfix.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. Ext.EventManager = function(){
  2. var docReadyEvent, docReadyProcId, docReadyState = false;
  3. var resizeEvent, resizeTask, textEvent, textSize;
  4. var E = Ext.lib.Event;
  5. var D = Ext.lib.Dom;
  6. // fix parser confusion
  7. var xname = 'Ex' + 't';
  8. var elHash = {};
  9. var addListener = function(el, ename, fn, wrap, scope){
  10. var id = Ext.id(el);
  11. if(!elHash[id]){
  12. elHash[id] = {};
  13. }
  14. var es = elHash[id];
  15. if(!es[ename]){
  16. es[ename] = [];
  17. }
  18. var ls = es[ename];
  19. ls.push({
  20. id: id,
  21. ename: ename,
  22. fn: fn,
  23. wrap: wrap,
  24. scope: scope
  25. });
  26. E.on(el, ename, wrap);
  27. if(ename == "mousewheel" && el.addEventListener){ // workaround for jQuery
  28. el.addEventListener("DOMMouseScroll", wrap, false);
  29. E.on(window, 'unload', function(){
  30. el.removeEventListener("DOMMouseScroll", wrap, false);
  31. });
  32. }
  33. if(ename == "mousedown" && el == document){ // fix stopped mousedowns on the document
  34. Ext.EventManager.stoppedMouseDownEvent.addListener(wrap);
  35. }
  36. };
  37. var removeListener = function(el, ename, fn, scope){
  38. el = Ext.getDom(el);
  39. var id = Ext.id(el), es = elHash[id], wrap;
  40. if(es){
  41. var ls = es[ename], l;
  42. if(ls){
  43. for(var i = 0, len = ls.length; i < len; i++){
  44. l = ls[i];
  45. if(l.fn == fn && (!scope || l.scope == scope)){
  46. wrap = l.wrap;
  47. E.un(el, ename, wrap);
  48. ls.splice(i, 1);
  49. break;
  50. }
  51. }
  52. }
  53. }
  54. if(ename == "mousewheel" && el.addEventListener && wrap){
  55. el.removeEventListener("DOMMouseScroll", wrap, false);
  56. }
  57. if(ename == "mousedown" && el == document && wrap){ // fix stopped mousedowns on the document
  58. Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
  59. }
  60. };
  61. var removeAll = function(el){
  62. el = Ext.getDom(el);
  63. var id = Ext.id(el), es = elHash[id], ls;
  64. if(es){
  65. for(var ename in es){
  66. if(es.hasOwnProperty(ename)){
  67. ls = es[ename];
  68. for(var i = 0, len = ls.length; i < len; i++){
  69. E.un(el, ename, ls[i].wrap);
  70. ls[i] = null;
  71. }
  72. }
  73. es[ename] = null;
  74. }
  75. delete elHash[id];
  76. }
  77. };
  78. var fireDocReady = function(){
  79. if(!docReadyState){
  80. docReadyState = true;
  81. Ext.isReady = true;
  82. if(docReadyProcId){
  83. clearInterval(docReadyProcId);
  84. }
  85. if(Ext.isGecko || Ext.isOpera) {
  86. document.removeEventListener("DOMContentLoaded", fireDocReady, false);
  87. }
  88. if(Ext.isIE){
  89. var defer = document.getElementById("ie-deferred-loader");
  90. if(defer){
  91. defer.onreadystatechange = null;
  92. defer.parentNode.removeChild(defer);
  93. }
  94. }
  95. if(docReadyEvent){
  96. docReadyEvent.fire();
  97. docReadyEvent.clearListeners();
  98. }
  99. }
  100. };
  101. var initDocReady = function(){
  102. docReadyEvent = new Ext.util.Event();
  103. if(Ext.isGecko || Ext.isOpera) {
  104. document.addEventListener("DOMContentLoaded", fireDocReady, false);
  105. }else if(Ext.isIE){
  106. document.write("<s"+'cript id="ie-deferred-loader" defer="defer" src="/'+'/:"></s'+"cript>");
  107. var defer = document.getElementById("ie-deferred-loader");
  108. defer.onreadystatechange = function(){
  109. if(this.readyState == "complete"){
  110. fireDocReady();
  111. }
  112. };
  113. }else if(Ext.isSafari){
  114. docReadyProcId = setInterval(function(){
  115. var rs = document.readyState;
  116. if(rs == "complete") {
  117. fireDocReady();
  118. }
  119. }, 10);
  120. }
  121. E.on(window, "load", fireDocReady);
  122. };
  123. var createBuffered = function(h, o){
  124. var task = new Ext.util.DelayedTask(h);
  125. return function(e){
  126. e = new Ext.EventObjectImpl(e);
  127. task.delay(o.buffer, h, null, [e]);
  128. };
  129. };
  130. var createSingle = function(h, el, ename, fn){
  131. return function(e){
  132. Ext.EventManager.removeListener(el, ename, fn);
  133. h(e);
  134. };
  135. };
  136. var createDelayed = function(h, o){
  137. return function(e){
  138. e = new Ext.EventObjectImpl(e);
  139. setTimeout(function(){
  140. h(e);
  141. }, o.delay || 10);
  142. };
  143. };
  144. var listen = function(element, ename, opt, fn, scope){
  145. var o = (!opt || typeof opt == "boolean") ? {} : opt;
  146. fn = fn || o.fn; scope = scope || o.scope;
  147. var el = Ext.getDom(element);
  148. if(!el){
  149. throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';
  150. }
  151. var h = function(e){
  152. e = Ext.EventObject.setEvent(e);
  153. var t;
  154. if(o.delegate){
  155. t = e.getTarget(o.delegate, el);
  156. if(!t){
  157. return;
  158. }
  159. }else{
  160. t = e.target;
  161. }
  162. if(o.stopEvent === true){
  163. e.stopEvent();
  164. }
  165. if(o.preventDefault === true){
  166. e.preventDefault();
  167. }
  168. if(o.stopPropagation === true){
  169. e.stopPropagation();
  170. }
  171. if(o.normalized === false){
  172. e = e.browserEvent;
  173. }
  174. fn.call(scope || el, e, t, o);
  175. };
  176. if(o.delay){
  177. h = createDelayed(h, o);
  178. }
  179. if(o.single){
  180. h = createSingle(h, el, ename, fn);
  181. }
  182. if(o.buffer){
  183. h = createBuffered(h, o);
  184. }
  185. fn._handlers = fn._handlers || [];
  186. fn._handlers.push([Ext.id(el), ename, h]);
  187. E.on(el, ename, h);
  188. if(ename == "mousewheel" && el.addEventListener){
  189. el.addEventListener("DOMMouseScroll", h, false);
  190. E.on(window, 'unload', function(){
  191. el.removeEventListener("DOMMouseScroll", h, false);
  192. });
  193. }
  194. if(ename == "mousedown" && el == document){
  195. Ext.EventManager.stoppedMouseDownEvent.addListener(h);
  196. }
  197. return h;
  198. };
  199. var stopListening = function(el, ename, fn){
  200. var id = Ext.id(el), hds = fn._handlers, hd = fn;
  201. if(hds){
  202. for(var i = 0, len = hds.length; i < len; i++){
  203. var h = hds[i];
  204. if(h[0] == id && h[1] == ename){
  205. hd = h[2];
  206. hds.splice(i, 1);
  207. break;
  208. }
  209. }
  210. }
  211. E.un(el, ename, hd);
  212. el = Ext.getDom(el);
  213. if(ename == "mousewheel" && el.addEventListener){
  214. el.removeEventListener("DOMMouseScroll", hd, false);
  215. }
  216. if(ename == "mousedown" && el == document){
  217. Ext.EventManager.stoppedMouseDownEvent.removeListener(hd);
  218. }
  219. };
  220. var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
  221. var pub = {
  222. addListener : function(element, eventName, fn, scope, options){
  223. if(typeof eventName == "object"){
  224. var o = eventName;
  225. for(var e in o){
  226. if(propRe.test(e)){
  227. continue;
  228. }
  229. if(typeof o[e] == "function"){
  230. listen(element, e, o, o[e], o.scope);
  231. }else{
  232. listen(element, e, o[e]);
  233. }
  234. }
  235. return;
  236. }
  237. return listen(element, eventName, options, fn, scope);
  238. },
  239. removeListener : function(element, eventName, fn){
  240. return stopListening(element, eventName, fn);
  241. },
  242. removeAll : function(element){
  243. return removeAll(element);
  244. },
  245. onDocumentReady : function(fn, scope, options){
  246. if(docReadyState){
  247. docReadyEvent.addListener(fn, scope, options);
  248. docReadyEvent.fire();
  249. docReadyEvent.clearListeners();
  250. return;
  251. }
  252. if(!docReadyEvent){
  253. initDocReady();
  254. }
  255. options = options || {};
  256. if(!options.delay) {
  257. options.delay = 1;
  258. }
  259. docReadyEvent.addListener(fn, scope, options);
  260. },
  261. onWindowResize : function(fn, scope, options){
  262. if(!resizeEvent){
  263. resizeEvent = new Ext.util.Event();
  264. resizeTask = new Ext.util.DelayedTask(function(){
  265. resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
  266. });
  267. E.on(window, "resize", this.fireWindowResize, this);
  268. }
  269. resizeEvent.addListener(fn, scope, options);
  270. },
  271. fireWindowResize : function(){
  272. if(resizeEvent){
  273. if((Ext.isIE||Ext.isAir) && resizeTask){
  274. resizeTask.delay(50);
  275. }else{
  276. resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
  277. }
  278. }
  279. },
  280. onTextResize : function(fn, scope, options){
  281. if(!textEvent){
  282. textEvent = new Ext.util.Event();
  283. var textEl = new Ext.Element(document.createElement('div'));
  284. textEl.dom.className = 'x-text-resize';
  285. textEl.dom.innerHTML = 'X';
  286. textEl.appendTo(document.body);
  287. textSize = textEl.dom.offsetHeight;
  288. setInterval(function(){
  289. if(textEl.dom.offsetHeight != textSize){
  290. textEvent.fire(textSize, textSize = textEl.dom.offsetHeight);
  291. }
  292. }, this.textResizeInterval);
  293. }
  294. textEvent.addListener(fn, scope, options);
  295. },
  296. removeResizeListener : function(fn, scope){
  297. if(resizeEvent){
  298. resizeEvent.removeListener(fn, scope);
  299. }
  300. },
  301. fireResize : function(){
  302. if(resizeEvent){
  303. resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
  304. }
  305. },
  306. ieDeferSrc : false,
  307. textResizeInterval : 50
  308. };
  309. pub.on = pub.addListener;
  310. pub.un = pub.removeListener;
  311. pub.stoppedMouseDownEvent = new Ext.util.Event();
  312. return pub;
  313. }();
  314. Ext.onReady = Ext.EventManager.onDocumentReady;
  315. Ext.onReady(function(){
  316. var bd = Ext.getBody();
  317. if(!bd){ return; }
  318. var cls = [
  319. Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : 'ext-ie7')
  320. : Ext.isGecko ? "ext-gecko"
  321. : Ext.isOpera ? "ext-opera"
  322. : Ext.isSafari ? "ext-safari" : ""];
  323. if(Ext.isMac){
  324. cls.push("ext-mac");
  325. }
  326. if(Ext.isLinux){
  327. cls.push("ext-linux");
  328. }
  329. if(Ext.isBorderBox){
  330. cls.push('ext-border-box');
  331. }
  332. if(Ext.isStrict){
  333. var p = bd.dom.parentNode;
  334. if(p){
  335. p.className += ' ext-strict';
  336. }
  337. }
  338. bd.addClass(cls.join(' '));
  339. });