UI for Zipcoin Blue

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. /**
  2. * @license
  3. * Copyright Google Inc. All Rights Reserved.
  4. *
  5. * Use of this source code is governed by an MIT-style license that can be
  6. * found in the LICENSE file at https://angular.io/license
  7. */
  8. /**
  9. * @fileoverview
  10. * @suppress {missingRequire}
  11. */
  12. import {ADD_EVENT_LISTENER_STR, attachOriginToPatched, FALSE_STR, ObjectGetPrototypeOf, REMOVE_EVENT_LISTENER_STR, TRUE_STR, ZONE_SYMBOL_PREFIX, zoneSymbol} from './utils';
  13. /** @internal **/
  14. interface EventTaskData extends TaskData {
  15. // use global callback or not
  16. readonly useG?: boolean;
  17. }
  18. // an identifier to tell ZoneTask do not create a new invoke closure
  19. const OPTIMIZED_ZONE_EVENT_TASK_DATA: EventTaskData = {
  20. useG: true
  21. };
  22. export const zoneSymbolEventNames: any = {};
  23. export const globalSources: any = {};
  24. const EVENT_NAME_SYMBOL_REGX = /^__zone_symbol__(\w+)(true|false)$/;
  25. const IMMEDIATE_PROPAGATION_SYMBOL = ('__zone_symbol__propagationStopped');
  26. export interface PatchEventTargetOptions {
  27. // validateHandler
  28. vh?: (nativeDelegate: any, delegate: any, target: any, args: any) => boolean;
  29. // addEventListener function name
  30. add?: string;
  31. // removeEventListener function name
  32. rm?: string;
  33. // prependEventListener function name
  34. prepend?: string;
  35. // listeners function name
  36. listeners?: string;
  37. // removeAllListeners function name
  38. rmAll?: string;
  39. // useGlobalCallback flag
  40. useG?: boolean;
  41. // check duplicate flag when addEventListener
  42. chkDup?: boolean;
  43. // return target flag when addEventListener
  44. rt?: boolean;
  45. // event compare handler
  46. diff?: (task: any, delegate: any) => boolean;
  47. }
  48. export function patchEventTarget(
  49. _global: any, apis: any[], patchOptions?: PatchEventTargetOptions) {
  50. const ADD_EVENT_LISTENER = (patchOptions && patchOptions.add) || ADD_EVENT_LISTENER_STR;
  51. const REMOVE_EVENT_LISTENER = (patchOptions && patchOptions.rm) || REMOVE_EVENT_LISTENER_STR;
  52. const LISTENERS_EVENT_LISTENER = (patchOptions && patchOptions.listeners) || 'eventListeners';
  53. const REMOVE_ALL_LISTENERS_EVENT_LISTENER =
  54. (patchOptions && patchOptions.rmAll) || 'removeAllListeners';
  55. const zoneSymbolAddEventListener = zoneSymbol(ADD_EVENT_LISTENER);
  56. const ADD_EVENT_LISTENER_SOURCE = '.' + ADD_EVENT_LISTENER + ':';
  57. const PREPEND_EVENT_LISTENER = 'prependListener';
  58. const PREPEND_EVENT_LISTENER_SOURCE = '.' + PREPEND_EVENT_LISTENER + ':';
  59. const invokeTask = function(task: any, target: any, event: Event) {
  60. // for better performance, check isRemoved which is set
  61. // by removeEventListener
  62. if (task.isRemoved) {
  63. return;
  64. }
  65. const delegate = task.callback;
  66. if (typeof delegate === 'object' && delegate.handleEvent) {
  67. // create the bind version of handleEvent when invoke
  68. task.callback = (event: Event) => delegate.handleEvent(event);
  69. task.originalDelegate = delegate;
  70. }
  71. // invoke static task.invoke
  72. task.invoke(task, target, [event]);
  73. const options = task.options;
  74. if (options && typeof options === 'object' && options.once) {
  75. // if options.once is true, after invoke once remove listener here
  76. // only browser need to do this, nodejs eventEmitter will cal removeListener
  77. // inside EventEmitter.once
  78. const delegate = task.originalDelegate ? task.originalDelegate : task.callback;
  79. target[REMOVE_EVENT_LISTENER].call(target, event.type, delegate, options);
  80. }
  81. };
  82. // global shared zoneAwareCallback to handle all event callback with capture = false
  83. const globalZoneAwareCallback = function(event: Event) {
  84. // https://github.com/angular/zone.js/issues/911, in IE, sometimes
  85. // event will be undefined, so we need to use window.event
  86. event = event || _global.event;
  87. if (!event) {
  88. return;
  89. }
  90. // event.target is needed for Samsung TV and SourceBuffer
  91. // || global is needed https://github.com/angular/zone.js/issues/190
  92. const target: any = this || event.target || _global;
  93. const tasks = target[zoneSymbolEventNames[event.type][FALSE_STR]];
  94. if (tasks) {
  95. // invoke all tasks which attached to current target with given event.type and capture = false
  96. // for performance concern, if task.length === 1, just invoke
  97. if (tasks.length === 1) {
  98. invokeTask(tasks[0], target, event);
  99. } else {
  100. // https://github.com/angular/zone.js/issues/836
  101. // copy the tasks array before invoke, to avoid
  102. // the callback will remove itself or other listener
  103. const copyTasks = tasks.slice();
  104. for (let i = 0; i < copyTasks.length; i++) {
  105. if (event && (event as any)[IMMEDIATE_PROPAGATION_SYMBOL] === true) {
  106. break;
  107. }
  108. invokeTask(copyTasks[i], target, event);
  109. }
  110. }
  111. }
  112. };
  113. // global shared zoneAwareCallback to handle all event callback with capture = true
  114. const globalZoneAwareCaptureCallback = function(event: Event) {
  115. // https://github.com/angular/zone.js/issues/911, in IE, sometimes
  116. // event will be undefined, so we need to use window.event
  117. event = event || _global.event;
  118. if (!event) {
  119. return;
  120. }
  121. // event.target is needed for Samsung TV and SourceBuffer
  122. // || global is needed https://github.com/angular/zone.js/issues/190
  123. const target: any = this || event.target || _global;
  124. const tasks = target[zoneSymbolEventNames[event.type][TRUE_STR]];
  125. if (tasks) {
  126. // invoke all tasks which attached to current target with given event.type and capture = false
  127. // for performance concern, if task.length === 1, just invoke
  128. if (tasks.length === 1) {
  129. invokeTask(tasks[0], target, event);
  130. } else {
  131. // https://github.com/angular/zone.js/issues/836
  132. // copy the tasks array before invoke, to avoid
  133. // the callback will remove itself or other listener
  134. const copyTasks = tasks.slice();
  135. for (let i = 0; i < copyTasks.length; i++) {
  136. if (event && (event as any)[IMMEDIATE_PROPAGATION_SYMBOL] === true) {
  137. break;
  138. }
  139. invokeTask(copyTasks[i], target, event);
  140. }
  141. }
  142. }
  143. };
  144. function patchEventTargetMethods(obj: any, patchOptions?: PatchEventTargetOptions) {
  145. if (!obj) {
  146. return false;
  147. }
  148. let useGlobalCallback = true;
  149. if (patchOptions && patchOptions.useG !== undefined) {
  150. useGlobalCallback = patchOptions.useG;
  151. }
  152. const validateHandler = patchOptions && patchOptions.vh;
  153. let checkDuplicate = true;
  154. if (patchOptions && patchOptions.chkDup !== undefined) {
  155. checkDuplicate = patchOptions.chkDup;
  156. }
  157. let returnTarget = false;
  158. if (patchOptions && patchOptions.rt !== undefined) {
  159. returnTarget = patchOptions.rt;
  160. }
  161. let proto = obj;
  162. while (proto && !proto.hasOwnProperty(ADD_EVENT_LISTENER)) {
  163. proto = ObjectGetPrototypeOf(proto);
  164. }
  165. if (!proto && obj[ADD_EVENT_LISTENER]) {
  166. // somehow we did not find it, but we can see it. This happens on IE for Window properties.
  167. proto = obj;
  168. }
  169. if (!proto) {
  170. return false;
  171. }
  172. if (proto[zoneSymbolAddEventListener]) {
  173. return false;
  174. }
  175. // a shared global taskData to pass data for scheduleEventTask
  176. // so we do not need to create a new object just for pass some data
  177. const taskData: any = {};
  178. const nativeAddEventListener = proto[zoneSymbolAddEventListener] = proto[ADD_EVENT_LISTENER];
  179. const nativeRemoveEventListener = proto[zoneSymbol(REMOVE_EVENT_LISTENER)] =
  180. proto[REMOVE_EVENT_LISTENER];
  181. const nativeListeners = proto[zoneSymbol(LISTENERS_EVENT_LISTENER)] =
  182. proto[LISTENERS_EVENT_LISTENER];
  183. const nativeRemoveAllListeners = proto[zoneSymbol(REMOVE_ALL_LISTENERS_EVENT_LISTENER)] =
  184. proto[REMOVE_ALL_LISTENERS_EVENT_LISTENER];
  185. let nativePrependEventListener: any;
  186. if (patchOptions && patchOptions.prepend) {
  187. nativePrependEventListener = proto[zoneSymbol(patchOptions.prepend)] =
  188. proto[patchOptions.prepend];
  189. }
  190. const customScheduleGlobal = function() {
  191. // if there is already a task for the eventName + capture,
  192. // just return, because we use the shared globalZoneAwareCallback here.
  193. if (taskData.isExisting) {
  194. return;
  195. }
  196. return nativeAddEventListener.call(
  197. taskData.target, taskData.eventName,
  198. taskData.capture ? globalZoneAwareCaptureCallback : globalZoneAwareCallback,
  199. taskData.options);
  200. };
  201. const customCancelGlobal = function(task: any) {
  202. // if task is not marked as isRemoved, this call is directly
  203. // from Zone.prototype.cancelTask, we should remove the task
  204. // from tasksList of target first
  205. if (!task.isRemoved) {
  206. const symbolEventNames = zoneSymbolEventNames[task.eventName];
  207. let symbolEventName;
  208. if (symbolEventNames) {
  209. symbolEventName = symbolEventNames[task.capture ? TRUE_STR : FALSE_STR];
  210. }
  211. const existingTasks = symbolEventName && task.target[symbolEventName];
  212. if (existingTasks) {
  213. for (let i = 0; i < existingTasks.length; i++) {
  214. const existingTask = existingTasks[i];
  215. if (existingTask === task) {
  216. existingTasks.splice(i, 1);
  217. // set isRemoved to data for faster invokeTask check
  218. task.isRemoved = true;
  219. if (existingTasks.length === 0) {
  220. // all tasks for the eventName + capture have gone,
  221. // remove globalZoneAwareCallback and remove the task cache from target
  222. task.allRemoved = true;
  223. task.target[symbolEventName] = null;
  224. }
  225. break;
  226. }
  227. }
  228. }
  229. }
  230. // if all tasks for the eventName + capture have gone,
  231. // we will really remove the global event callback,
  232. // if not, return
  233. if (!task.allRemoved) {
  234. return;
  235. }
  236. return nativeRemoveEventListener.call(
  237. task.target, task.eventName,
  238. task.capture ? globalZoneAwareCaptureCallback : globalZoneAwareCallback, task.options);
  239. };
  240. const customScheduleNonGlobal = function(task: Task) {
  241. return nativeAddEventListener.call(
  242. taskData.target, taskData.eventName, task.invoke, taskData.options);
  243. };
  244. const customSchedulePrepend = function(task: Task) {
  245. return nativePrependEventListener.call(
  246. taskData.target, taskData.eventName, task.invoke, taskData.options);
  247. };
  248. const customCancelNonGlobal = function(task: any) {
  249. return nativeRemoveEventListener.call(task.target, task.eventName, task.invoke, task.options);
  250. };
  251. const customSchedule = useGlobalCallback ? customScheduleGlobal : customScheduleNonGlobal;
  252. const customCancel = useGlobalCallback ? customCancelGlobal : customCancelNonGlobal;
  253. const compareTaskCallbackVsDelegate = function(task: any, delegate: any) {
  254. const typeOfDelegate = typeof delegate;
  255. return (typeOfDelegate === 'function' && task.callback === delegate) ||
  256. (typeOfDelegate === 'object' && task.originalDelegate === delegate);
  257. };
  258. const compare =
  259. (patchOptions && patchOptions.diff) ? patchOptions.diff : compareTaskCallbackVsDelegate;
  260. const blackListedEvents: string[] = (Zone as any)[Zone.__symbol__('BLACK_LISTED_EVENTS')];
  261. const makeAddListener = function(
  262. nativeListener: any, addSource: string, customScheduleFn: any, customCancelFn: any,
  263. returnTarget = false, prepend = false) {
  264. return function() {
  265. const target = this || _global;
  266. let delegate = arguments[1];
  267. if (!delegate) {
  268. return nativeListener.apply(this, arguments);
  269. }
  270. // don't create the bind delegate function for handleEvent
  271. // case here to improve addEventListener performance
  272. // we will create the bind delegate when invoke
  273. let isHandleEvent = false;
  274. if (typeof delegate !== 'function') {
  275. if (!delegate.handleEvent) {
  276. return nativeListener.apply(this, arguments);
  277. }
  278. isHandleEvent = true;
  279. }
  280. if (validateHandler && !validateHandler(nativeListener, delegate, target, arguments)) {
  281. return;
  282. }
  283. const eventName = arguments[0];
  284. const options = arguments[2];
  285. if (blackListedEvents) {
  286. // check black list
  287. for (let i = 0; i < blackListedEvents.length; i++) {
  288. if (eventName === blackListedEvents[i]) {
  289. return nativeListener.apply(this, arguments);
  290. }
  291. }
  292. }
  293. let capture;
  294. let once = false;
  295. if (options === undefined) {
  296. capture = false;
  297. } else if (options === true) {
  298. capture = true;
  299. } else if (options === false) {
  300. capture = false;
  301. } else {
  302. capture = options ? !!options.capture : false;
  303. once = options ? !!options.once : false;
  304. }
  305. const zone = Zone.current;
  306. const symbolEventNames = zoneSymbolEventNames[eventName];
  307. let symbolEventName;
  308. if (!symbolEventNames) {
  309. // the code is duplicate, but I just want to get some better performance
  310. const falseEventName = eventName + FALSE_STR;
  311. const trueEventName = eventName + TRUE_STR;
  312. const symbol = ZONE_SYMBOL_PREFIX + falseEventName;
  313. const symbolCapture = ZONE_SYMBOL_PREFIX + trueEventName;
  314. zoneSymbolEventNames[eventName] = {};
  315. zoneSymbolEventNames[eventName][FALSE_STR] = symbol;
  316. zoneSymbolEventNames[eventName][TRUE_STR] = symbolCapture;
  317. symbolEventName = capture ? symbolCapture : symbol;
  318. } else {
  319. symbolEventName = symbolEventNames[capture ? TRUE_STR : FALSE_STR];
  320. }
  321. let existingTasks = target[symbolEventName];
  322. let isExisting = false;
  323. if (existingTasks) {
  324. // already have task registered
  325. isExisting = true;
  326. if (checkDuplicate) {
  327. for (let i = 0; i < existingTasks.length; i++) {
  328. if (compare(existingTasks[i], delegate)) {
  329. // same callback, same capture, same event name, just return
  330. return;
  331. }
  332. }
  333. }
  334. } else {
  335. existingTasks = target[symbolEventName] = [];
  336. }
  337. let source;
  338. const constructorName = target.constructor['name'];
  339. const targetSource = globalSources[constructorName];
  340. if (targetSource) {
  341. source = targetSource[eventName];
  342. }
  343. if (!source) {
  344. source = constructorName + addSource + eventName;
  345. }
  346. // do not create a new object as task.data to pass those things
  347. // just use the global shared one
  348. taskData.options = options;
  349. if (once) {
  350. // if addEventListener with once options, we don't pass it to
  351. // native addEventListener, instead we keep the once setting
  352. // and handle ourselves.
  353. taskData.options.once = false;
  354. }
  355. taskData.target = target;
  356. taskData.capture = capture;
  357. taskData.eventName = eventName;
  358. taskData.isExisting = isExisting;
  359. const data = useGlobalCallback ? OPTIMIZED_ZONE_EVENT_TASK_DATA : null;
  360. // keep taskData into data to allow onScheduleEventTask to access the task information
  361. if (data) {
  362. (data as any).taskData = taskData;
  363. }
  364. const task: any =
  365. zone.scheduleEventTask(source, delegate, data, customScheduleFn, customCancelFn);
  366. // should clear taskData.target to avoid memory leak
  367. // issue, https://github.com/angular/angular/issues/20442
  368. taskData.target = null;
  369. // need to clear up taskData because it is a global object
  370. if (data) {
  371. (data as any).taskData = null;
  372. }
  373. // have to save those information to task in case
  374. // application may call task.zone.cancelTask() directly
  375. if (once) {
  376. options.once = true;
  377. }
  378. task.options = options;
  379. task.target = target;
  380. task.capture = capture;
  381. task.eventName = eventName;
  382. if (isHandleEvent) {
  383. // save original delegate for compare to check duplicate
  384. (task as any).originalDelegate = delegate;
  385. }
  386. if (!prepend) {
  387. existingTasks.push(task);
  388. } else {
  389. existingTasks.unshift(task);
  390. }
  391. if (returnTarget) {
  392. return target;
  393. }
  394. };
  395. };
  396. proto[ADD_EVENT_LISTENER] = makeAddListener(
  397. nativeAddEventListener, ADD_EVENT_LISTENER_SOURCE, customSchedule, customCancel,
  398. returnTarget);
  399. if (nativePrependEventListener) {
  400. proto[PREPEND_EVENT_LISTENER] = makeAddListener(
  401. nativePrependEventListener, PREPEND_EVENT_LISTENER_SOURCE, customSchedulePrepend,
  402. customCancel, returnTarget, true);
  403. }
  404. proto[REMOVE_EVENT_LISTENER] = function() {
  405. const target = this || _global;
  406. const eventName = arguments[0];
  407. const options = arguments[2];
  408. let capture;
  409. if (options === undefined) {
  410. capture = false;
  411. } else if (options === true) {
  412. capture = true;
  413. } else if (options === false) {
  414. capture = false;
  415. } else {
  416. capture = options ? !!options.capture : false;
  417. }
  418. const delegate = arguments[1];
  419. if (!delegate) {
  420. return nativeRemoveEventListener.apply(this, arguments);
  421. }
  422. if (validateHandler &&
  423. !validateHandler(nativeRemoveEventListener, delegate, target, arguments)) {
  424. return;
  425. }
  426. const symbolEventNames = zoneSymbolEventNames[eventName];
  427. let symbolEventName;
  428. if (symbolEventNames) {
  429. symbolEventName = symbolEventNames[capture ? TRUE_STR : FALSE_STR];
  430. }
  431. const existingTasks = symbolEventName && target[symbolEventName];
  432. if (existingTasks) {
  433. for (let i = 0; i < existingTasks.length; i++) {
  434. const existingTask = existingTasks[i];
  435. if (compare(existingTask, delegate)) {
  436. existingTasks.splice(i, 1);
  437. // set isRemoved to data for faster invokeTask check
  438. (existingTask as any).isRemoved = true;
  439. if (existingTasks.length === 0) {
  440. // all tasks for the eventName + capture have gone,
  441. // remove globalZoneAwareCallback and remove the task cache from target
  442. (existingTask as any).allRemoved = true;
  443. target[symbolEventName] = null;
  444. }
  445. existingTask.zone.cancelTask(existingTask);
  446. if (returnTarget) {
  447. return target;
  448. }
  449. return;
  450. }
  451. }
  452. }
  453. // issue 930, didn't find the event name or callback
  454. // from zone kept existingTasks, the callback maybe
  455. // added outside of zone, we need to call native removeEventListener
  456. // to try to remove it.
  457. return nativeRemoveEventListener.apply(this, arguments);
  458. };
  459. proto[LISTENERS_EVENT_LISTENER] = function() {
  460. const target = this || _global;
  461. const eventName = arguments[0];
  462. const listeners: any[] = [];
  463. const tasks = findEventTasks(target, eventName);
  464. for (let i = 0; i < tasks.length; i++) {
  465. const task: any = tasks[i];
  466. let delegate = task.originalDelegate ? task.originalDelegate : task.callback;
  467. listeners.push(delegate);
  468. }
  469. return listeners;
  470. };
  471. proto[REMOVE_ALL_LISTENERS_EVENT_LISTENER] = function() {
  472. const target = this || _global;
  473. const eventName = arguments[0];
  474. if (!eventName) {
  475. const keys = Object.keys(target);
  476. for (let i = 0; i < keys.length; i++) {
  477. const prop = keys[i];
  478. const match = EVENT_NAME_SYMBOL_REGX.exec(prop);
  479. let evtName = match && match[1];
  480. // in nodejs EventEmitter, removeListener event is
  481. // used for monitoring the removeListener call,
  482. // so just keep removeListener eventListener until
  483. // all other eventListeners are removed
  484. if (evtName && evtName !== 'removeListener') {
  485. this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].call(this, evtName);
  486. }
  487. }
  488. // remove removeListener listener finally
  489. this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].call(this, 'removeListener');
  490. } else {
  491. const symbolEventNames = zoneSymbolEventNames[eventName];
  492. if (symbolEventNames) {
  493. const symbolEventName = symbolEventNames[FALSE_STR];
  494. const symbolCaptureEventName = symbolEventNames[TRUE_STR];
  495. const tasks = target[symbolEventName];
  496. const captureTasks = target[symbolCaptureEventName];
  497. if (tasks) {
  498. const removeTasks = tasks.slice();
  499. for (let i = 0; i < removeTasks.length; i++) {
  500. const task = removeTasks[i];
  501. let delegate = task.originalDelegate ? task.originalDelegate : task.callback;
  502. this[REMOVE_EVENT_LISTENER].call(this, eventName, delegate, task.options);
  503. }
  504. }
  505. if (captureTasks) {
  506. const removeTasks = captureTasks.slice();
  507. for (let i = 0; i < removeTasks.length; i++) {
  508. const task = removeTasks[i];
  509. let delegate = task.originalDelegate ? task.originalDelegate : task.callback;
  510. this[REMOVE_EVENT_LISTENER].call(this, eventName, delegate, task.options);
  511. }
  512. }
  513. }
  514. }
  515. if (returnTarget) {
  516. return this;
  517. }
  518. };
  519. // for native toString patch
  520. attachOriginToPatched(proto[ADD_EVENT_LISTENER], nativeAddEventListener);
  521. attachOriginToPatched(proto[REMOVE_EVENT_LISTENER], nativeRemoveEventListener);
  522. if (nativeRemoveAllListeners) {
  523. attachOriginToPatched(proto[REMOVE_ALL_LISTENERS_EVENT_LISTENER], nativeRemoveAllListeners);
  524. }
  525. if (nativeListeners) {
  526. attachOriginToPatched(proto[LISTENERS_EVENT_LISTENER], nativeListeners);
  527. }
  528. return true;
  529. }
  530. let results: any[] = [];
  531. for (let i = 0; i < apis.length; i++) {
  532. results[i] = patchEventTargetMethods(apis[i], patchOptions);
  533. }
  534. return results;
  535. }
  536. export function findEventTasks(target: any, eventName: string): Task[] {
  537. const foundTasks: any[] = [];
  538. for (let prop in target) {
  539. const match = EVENT_NAME_SYMBOL_REGX.exec(prop);
  540. let evtName = match && match[1];
  541. if (evtName && (!eventName || evtName === eventName)) {
  542. const tasks: any = target[prop];
  543. if (tasks) {
  544. for (let i = 0; i < tasks.length; i++) {
  545. foundTasks.push(tasks[i]);
  546. }
  547. }
  548. }
  549. }
  550. return foundTasks;
  551. }
  552. export function patchEventPrototype(global: any, api: _ZonePrivate) {
  553. const Event = global['Event'];
  554. if (Event && Event.prototype) {
  555. api.patchMethod(
  556. Event.prototype, 'stopImmediatePropagation',
  557. (delegate: Function) => function(self: any, args: any[]) {
  558. self[IMMEDIATE_PROPAGATION_SYMBOL] = true;
  559. // we need to call the native stopImmediatePropagation
  560. // in case in some hybrid application, some part of
  561. // application will be controlled by zone, some are not
  562. delegate && delegate.apply(self, args);
  563. });
  564. }
  565. }