event-target-shim.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871
  1. /**
  2. * @author Toru Nagashima <https://github.com/mysticatea>
  3. * @copyright 2015 Toru Nagashima. All rights reserved.
  4. * See LICENSE file in root directory for full license.
  5. */
  6. 'use strict';
  7. Object.defineProperty(exports, '__esModule', { value: true });
  8. /**
  9. * @typedef {object} PrivateData
  10. * @property {EventTarget} eventTarget The event target.
  11. * @property {{type:string}} event The original event object.
  12. * @property {number} eventPhase The current event phase.
  13. * @property {EventTarget|null} currentTarget The current event target.
  14. * @property {boolean} canceled The flag to prevent default.
  15. * @property {boolean} stopped The flag to stop propagation.
  16. * @property {boolean} immediateStopped The flag to stop propagation immediately.
  17. * @property {Function|null} passiveListener The listener if the current listener is passive. Otherwise this is null.
  18. * @property {number} timeStamp The unix time.
  19. * @private
  20. */
  21. /**
  22. * Private data for event wrappers.
  23. * @type {WeakMap<Event, PrivateData>}
  24. * @private
  25. */
  26. const privateData = new WeakMap();
  27. /**
  28. * Cache for wrapper classes.
  29. * @type {WeakMap<Object, Function>}
  30. * @private
  31. */
  32. const wrappers = new WeakMap();
  33. /**
  34. * Get private data.
  35. * @param {Event} event The event object to get private data.
  36. * @returns {PrivateData} The private data of the event.
  37. * @private
  38. */
  39. function pd(event) {
  40. const retv = privateData.get(event);
  41. console.assert(
  42. retv != null,
  43. "'this' is expected an Event object, but got",
  44. event
  45. );
  46. return retv
  47. }
  48. /**
  49. * https://dom.spec.whatwg.org/#set-the-canceled-flag
  50. * @param data {PrivateData} private data.
  51. */
  52. function setCancelFlag(data) {
  53. if (data.passiveListener != null) {
  54. if (
  55. typeof console !== "undefined" &&
  56. typeof console.error === "function"
  57. ) {
  58. console.error(
  59. "Unable to preventDefault inside passive event listener invocation.",
  60. data.passiveListener
  61. );
  62. }
  63. return
  64. }
  65. if (!data.event.cancelable) {
  66. return
  67. }
  68. data.canceled = true;
  69. if (typeof data.event.preventDefault === "function") {
  70. data.event.preventDefault();
  71. }
  72. }
  73. /**
  74. * @see https://dom.spec.whatwg.org/#interface-event
  75. * @private
  76. */
  77. /**
  78. * The event wrapper.
  79. * @constructor
  80. * @param {EventTarget} eventTarget The event target of this dispatching.
  81. * @param {Event|{type:string}} event The original event to wrap.
  82. */
  83. function Event(eventTarget, event) {
  84. privateData.set(this, {
  85. eventTarget,
  86. event,
  87. eventPhase: 2,
  88. currentTarget: eventTarget,
  89. canceled: false,
  90. stopped: false,
  91. immediateStopped: false,
  92. passiveListener: null,
  93. timeStamp: event.timeStamp || Date.now(),
  94. });
  95. // https://heycam.github.io/webidl/#Unforgeable
  96. Object.defineProperty(this, "isTrusted", { value: false, enumerable: true });
  97. // Define accessors
  98. const keys = Object.keys(event);
  99. for (let i = 0; i < keys.length; ++i) {
  100. const key = keys[i];
  101. if (!(key in this)) {
  102. Object.defineProperty(this, key, defineRedirectDescriptor(key));
  103. }
  104. }
  105. }
  106. // Should be enumerable, but class methods are not enumerable.
  107. Event.prototype = {
  108. /**
  109. * The type of this event.
  110. * @type {string}
  111. */
  112. get type() {
  113. return pd(this).event.type
  114. },
  115. /**
  116. * The target of this event.
  117. * @type {EventTarget}
  118. */
  119. get target() {
  120. return pd(this).eventTarget
  121. },
  122. /**
  123. * The target of this event.
  124. * @type {EventTarget}
  125. */
  126. get currentTarget() {
  127. return pd(this).currentTarget
  128. },
  129. /**
  130. * @returns {EventTarget[]} The composed path of this event.
  131. */
  132. composedPath() {
  133. const currentTarget = pd(this).currentTarget;
  134. if (currentTarget == null) {
  135. return []
  136. }
  137. return [currentTarget]
  138. },
  139. /**
  140. * Constant of NONE.
  141. * @type {number}
  142. */
  143. get NONE() {
  144. return 0
  145. },
  146. /**
  147. * Constant of CAPTURING_PHASE.
  148. * @type {number}
  149. */
  150. get CAPTURING_PHASE() {
  151. return 1
  152. },
  153. /**
  154. * Constant of AT_TARGET.
  155. * @type {number}
  156. */
  157. get AT_TARGET() {
  158. return 2
  159. },
  160. /**
  161. * Constant of BUBBLING_PHASE.
  162. * @type {number}
  163. */
  164. get BUBBLING_PHASE() {
  165. return 3
  166. },
  167. /**
  168. * The target of this event.
  169. * @type {number}
  170. */
  171. get eventPhase() {
  172. return pd(this).eventPhase
  173. },
  174. /**
  175. * Stop event bubbling.
  176. * @returns {void}
  177. */
  178. stopPropagation() {
  179. const data = pd(this);
  180. data.stopped = true;
  181. if (typeof data.event.stopPropagation === "function") {
  182. data.event.stopPropagation();
  183. }
  184. },
  185. /**
  186. * Stop event bubbling.
  187. * @returns {void}
  188. */
  189. stopImmediatePropagation() {
  190. const data = pd(this);
  191. data.stopped = true;
  192. data.immediateStopped = true;
  193. if (typeof data.event.stopImmediatePropagation === "function") {
  194. data.event.stopImmediatePropagation();
  195. }
  196. },
  197. /**
  198. * The flag to be bubbling.
  199. * @type {boolean}
  200. */
  201. get bubbles() {
  202. return Boolean(pd(this).event.bubbles)
  203. },
  204. /**
  205. * The flag to be cancelable.
  206. * @type {boolean}
  207. */
  208. get cancelable() {
  209. return Boolean(pd(this).event.cancelable)
  210. },
  211. /**
  212. * Cancel this event.
  213. * @returns {void}
  214. */
  215. preventDefault() {
  216. setCancelFlag(pd(this));
  217. },
  218. /**
  219. * The flag to indicate cancellation state.
  220. * @type {boolean}
  221. */
  222. get defaultPrevented() {
  223. return pd(this).canceled
  224. },
  225. /**
  226. * The flag to be composed.
  227. * @type {boolean}
  228. */
  229. get composed() {
  230. return Boolean(pd(this).event.composed)
  231. },
  232. /**
  233. * The unix time of this event.
  234. * @type {number}
  235. */
  236. get timeStamp() {
  237. return pd(this).timeStamp
  238. },
  239. /**
  240. * The target of this event.
  241. * @type {EventTarget}
  242. * @deprecated
  243. */
  244. get srcElement() {
  245. return pd(this).eventTarget
  246. },
  247. /**
  248. * The flag to stop event bubbling.
  249. * @type {boolean}
  250. * @deprecated
  251. */
  252. get cancelBubble() {
  253. return pd(this).stopped
  254. },
  255. set cancelBubble(value) {
  256. if (!value) {
  257. return
  258. }
  259. const data = pd(this);
  260. data.stopped = true;
  261. if (typeof data.event.cancelBubble === "boolean") {
  262. data.event.cancelBubble = true;
  263. }
  264. },
  265. /**
  266. * The flag to indicate cancellation state.
  267. * @type {boolean}
  268. * @deprecated
  269. */
  270. get returnValue() {
  271. return !pd(this).canceled
  272. },
  273. set returnValue(value) {
  274. if (!value) {
  275. setCancelFlag(pd(this));
  276. }
  277. },
  278. /**
  279. * Initialize this event object. But do nothing under event dispatching.
  280. * @param {string} type The event type.
  281. * @param {boolean} [bubbles=false] The flag to be possible to bubble up.
  282. * @param {boolean} [cancelable=false] The flag to be possible to cancel.
  283. * @deprecated
  284. */
  285. initEvent() {
  286. // Do nothing.
  287. },
  288. };
  289. // `constructor` is not enumerable.
  290. Object.defineProperty(Event.prototype, "constructor", {
  291. value: Event,
  292. configurable: true,
  293. writable: true,
  294. });
  295. // Ensure `event instanceof window.Event` is `true`.
  296. if (typeof window !== "undefined" && typeof window.Event !== "undefined") {
  297. Object.setPrototypeOf(Event.prototype, window.Event.prototype);
  298. // Make association for wrappers.
  299. wrappers.set(window.Event.prototype, Event);
  300. }
  301. /**
  302. * Get the property descriptor to redirect a given property.
  303. * @param {string} key Property name to define property descriptor.
  304. * @returns {PropertyDescriptor} The property descriptor to redirect the property.
  305. * @private
  306. */
  307. function defineRedirectDescriptor(key) {
  308. return {
  309. get() {
  310. return pd(this).event[key]
  311. },
  312. set(value) {
  313. pd(this).event[key] = value;
  314. },
  315. configurable: true,
  316. enumerable: true,
  317. }
  318. }
  319. /**
  320. * Get the property descriptor to call a given method property.
  321. * @param {string} key Property name to define property descriptor.
  322. * @returns {PropertyDescriptor} The property descriptor to call the method property.
  323. * @private
  324. */
  325. function defineCallDescriptor(key) {
  326. return {
  327. value() {
  328. const event = pd(this).event;
  329. return event[key].apply(event, arguments)
  330. },
  331. configurable: true,
  332. enumerable: true,
  333. }
  334. }
  335. /**
  336. * Define new wrapper class.
  337. * @param {Function} BaseEvent The base wrapper class.
  338. * @param {Object} proto The prototype of the original event.
  339. * @returns {Function} The defined wrapper class.
  340. * @private
  341. */
  342. function defineWrapper(BaseEvent, proto) {
  343. const keys = Object.keys(proto);
  344. if (keys.length === 0) {
  345. return BaseEvent
  346. }
  347. /** CustomEvent */
  348. function CustomEvent(eventTarget, event) {
  349. BaseEvent.call(this, eventTarget, event);
  350. }
  351. CustomEvent.prototype = Object.create(BaseEvent.prototype, {
  352. constructor: { value: CustomEvent, configurable: true, writable: true },
  353. });
  354. // Define accessors.
  355. for (let i = 0; i < keys.length; ++i) {
  356. const key = keys[i];
  357. if (!(key in BaseEvent.prototype)) {
  358. const descriptor = Object.getOwnPropertyDescriptor(proto, key);
  359. const isFunc = typeof descriptor.value === "function";
  360. Object.defineProperty(
  361. CustomEvent.prototype,
  362. key,
  363. isFunc
  364. ? defineCallDescriptor(key)
  365. : defineRedirectDescriptor(key)
  366. );
  367. }
  368. }
  369. return CustomEvent
  370. }
  371. /**
  372. * Get the wrapper class of a given prototype.
  373. * @param {Object} proto The prototype of the original event to get its wrapper.
  374. * @returns {Function} The wrapper class.
  375. * @private
  376. */
  377. function getWrapper(proto) {
  378. if (proto == null || proto === Object.prototype) {
  379. return Event
  380. }
  381. let wrapper = wrappers.get(proto);
  382. if (wrapper == null) {
  383. wrapper = defineWrapper(getWrapper(Object.getPrototypeOf(proto)), proto);
  384. wrappers.set(proto, wrapper);
  385. }
  386. return wrapper
  387. }
  388. /**
  389. * Wrap a given event to management a dispatching.
  390. * @param {EventTarget} eventTarget The event target of this dispatching.
  391. * @param {Object} event The event to wrap.
  392. * @returns {Event} The wrapper instance.
  393. * @private
  394. */
  395. function wrapEvent(eventTarget, event) {
  396. const Wrapper = getWrapper(Object.getPrototypeOf(event));
  397. return new Wrapper(eventTarget, event)
  398. }
  399. /**
  400. * Get the immediateStopped flag of a given event.
  401. * @param {Event} event The event to get.
  402. * @returns {boolean} The flag to stop propagation immediately.
  403. * @private
  404. */
  405. function isStopped(event) {
  406. return pd(event).immediateStopped
  407. }
  408. /**
  409. * Set the current event phase of a given event.
  410. * @param {Event} event The event to set current target.
  411. * @param {number} eventPhase New event phase.
  412. * @returns {void}
  413. * @private
  414. */
  415. function setEventPhase(event, eventPhase) {
  416. pd(event).eventPhase = eventPhase;
  417. }
  418. /**
  419. * Set the current target of a given event.
  420. * @param {Event} event The event to set current target.
  421. * @param {EventTarget|null} currentTarget New current target.
  422. * @returns {void}
  423. * @private
  424. */
  425. function setCurrentTarget(event, currentTarget) {
  426. pd(event).currentTarget = currentTarget;
  427. }
  428. /**
  429. * Set a passive listener of a given event.
  430. * @param {Event} event The event to set current target.
  431. * @param {Function|null} passiveListener New passive listener.
  432. * @returns {void}
  433. * @private
  434. */
  435. function setPassiveListener(event, passiveListener) {
  436. pd(event).passiveListener = passiveListener;
  437. }
  438. /**
  439. * @typedef {object} ListenerNode
  440. * @property {Function} listener
  441. * @property {1|2|3} listenerType
  442. * @property {boolean} passive
  443. * @property {boolean} once
  444. * @property {ListenerNode|null} next
  445. * @private
  446. */
  447. /**
  448. * @type {WeakMap<object, Map<string, ListenerNode>>}
  449. * @private
  450. */
  451. const listenersMap = new WeakMap();
  452. // Listener types
  453. const CAPTURE = 1;
  454. const BUBBLE = 2;
  455. const ATTRIBUTE = 3;
  456. /**
  457. * Check whether a given value is an object or not.
  458. * @param {any} x The value to check.
  459. * @returns {boolean} `true` if the value is an object.
  460. */
  461. function isObject(x) {
  462. return x !== null && typeof x === "object" //eslint-disable-line no-restricted-syntax
  463. }
  464. /**
  465. * Get listeners.
  466. * @param {EventTarget} eventTarget The event target to get.
  467. * @returns {Map<string, ListenerNode>} The listeners.
  468. * @private
  469. */
  470. function getListeners(eventTarget) {
  471. const listeners = listenersMap.get(eventTarget);
  472. if (listeners == null) {
  473. throw new TypeError(
  474. "'this' is expected an EventTarget object, but got another value."
  475. )
  476. }
  477. return listeners
  478. }
  479. /**
  480. * Get the property descriptor for the event attribute of a given event.
  481. * @param {string} eventName The event name to get property descriptor.
  482. * @returns {PropertyDescriptor} The property descriptor.
  483. * @private
  484. */
  485. function defineEventAttributeDescriptor(eventName) {
  486. return {
  487. get() {
  488. const listeners = getListeners(this);
  489. let node = listeners.get(eventName);
  490. while (node != null) {
  491. if (node.listenerType === ATTRIBUTE) {
  492. return node.listener
  493. }
  494. node = node.next;
  495. }
  496. return null
  497. },
  498. set(listener) {
  499. if (typeof listener !== "function" && !isObject(listener)) {
  500. listener = null; // eslint-disable-line no-param-reassign
  501. }
  502. const listeners = getListeners(this);
  503. // Traverse to the tail while removing old value.
  504. let prev = null;
  505. let node = listeners.get(eventName);
  506. while (node != null) {
  507. if (node.listenerType === ATTRIBUTE) {
  508. // Remove old value.
  509. if (prev !== null) {
  510. prev.next = node.next;
  511. } else if (node.next !== null) {
  512. listeners.set(eventName, node.next);
  513. } else {
  514. listeners.delete(eventName);
  515. }
  516. } else {
  517. prev = node;
  518. }
  519. node = node.next;
  520. }
  521. // Add new value.
  522. if (listener !== null) {
  523. const newNode = {
  524. listener,
  525. listenerType: ATTRIBUTE,
  526. passive: false,
  527. once: false,
  528. next: null,
  529. };
  530. if (prev === null) {
  531. listeners.set(eventName, newNode);
  532. } else {
  533. prev.next = newNode;
  534. }
  535. }
  536. },
  537. configurable: true,
  538. enumerable: true,
  539. }
  540. }
  541. /**
  542. * Define an event attribute (e.g. `eventTarget.onclick`).
  543. * @param {Object} eventTargetPrototype The event target prototype to define an event attrbite.
  544. * @param {string} eventName The event name to define.
  545. * @returns {void}
  546. */
  547. function defineEventAttribute(eventTargetPrototype, eventName) {
  548. Object.defineProperty(
  549. eventTargetPrototype,
  550. `on${eventName}`,
  551. defineEventAttributeDescriptor(eventName)
  552. );
  553. }
  554. /**
  555. * Define a custom EventTarget with event attributes.
  556. * @param {string[]} eventNames Event names for event attributes.
  557. * @returns {EventTarget} The custom EventTarget.
  558. * @private
  559. */
  560. function defineCustomEventTarget(eventNames) {
  561. /** CustomEventTarget */
  562. function CustomEventTarget() {
  563. EventTarget.call(this);
  564. }
  565. CustomEventTarget.prototype = Object.create(EventTarget.prototype, {
  566. constructor: {
  567. value: CustomEventTarget,
  568. configurable: true,
  569. writable: true,
  570. },
  571. });
  572. for (let i = 0; i < eventNames.length; ++i) {
  573. defineEventAttribute(CustomEventTarget.prototype, eventNames[i]);
  574. }
  575. return CustomEventTarget
  576. }
  577. /**
  578. * EventTarget.
  579. *
  580. * - This is constructor if no arguments.
  581. * - This is a function which returns a CustomEventTarget constructor if there are arguments.
  582. *
  583. * For example:
  584. *
  585. * class A extends EventTarget {}
  586. * class B extends EventTarget("message") {}
  587. * class C extends EventTarget("message", "error") {}
  588. * class D extends EventTarget(["message", "error"]) {}
  589. */
  590. function EventTarget() {
  591. /*eslint-disable consistent-return */
  592. if (this instanceof EventTarget) {
  593. listenersMap.set(this, new Map());
  594. return
  595. }
  596. if (arguments.length === 1 && Array.isArray(arguments[0])) {
  597. return defineCustomEventTarget(arguments[0])
  598. }
  599. if (arguments.length > 0) {
  600. const types = new Array(arguments.length);
  601. for (let i = 0; i < arguments.length; ++i) {
  602. types[i] = arguments[i];
  603. }
  604. return defineCustomEventTarget(types)
  605. }
  606. throw new TypeError("Cannot call a class as a function")
  607. /*eslint-enable consistent-return */
  608. }
  609. // Should be enumerable, but class methods are not enumerable.
  610. EventTarget.prototype = {
  611. /**
  612. * Add a given listener to this event target.
  613. * @param {string} eventName The event name to add.
  614. * @param {Function} listener The listener to add.
  615. * @param {boolean|{capture?:boolean,passive?:boolean,once?:boolean}} [options] The options for this listener.
  616. * @returns {void}
  617. */
  618. addEventListener(eventName, listener, options) {
  619. if (listener == null) {
  620. return
  621. }
  622. if (typeof listener !== "function" && !isObject(listener)) {
  623. throw new TypeError("'listener' should be a function or an object.")
  624. }
  625. const listeners = getListeners(this);
  626. const optionsIsObj = isObject(options);
  627. const capture = optionsIsObj
  628. ? Boolean(options.capture)
  629. : Boolean(options);
  630. const listenerType = capture ? CAPTURE : BUBBLE;
  631. const newNode = {
  632. listener,
  633. listenerType,
  634. passive: optionsIsObj && Boolean(options.passive),
  635. once: optionsIsObj && Boolean(options.once),
  636. next: null,
  637. };
  638. // Set it as the first node if the first node is null.
  639. let node = listeners.get(eventName);
  640. if (node === undefined) {
  641. listeners.set(eventName, newNode);
  642. return
  643. }
  644. // Traverse to the tail while checking duplication..
  645. let prev = null;
  646. while (node != null) {
  647. if (
  648. node.listener === listener &&
  649. node.listenerType === listenerType
  650. ) {
  651. // Should ignore duplication.
  652. return
  653. }
  654. prev = node;
  655. node = node.next;
  656. }
  657. // Add it.
  658. prev.next = newNode;
  659. },
  660. /**
  661. * Remove a given listener from this event target.
  662. * @param {string} eventName The event name to remove.
  663. * @param {Function} listener The listener to remove.
  664. * @param {boolean|{capture?:boolean,passive?:boolean,once?:boolean}} [options] The options for this listener.
  665. * @returns {void}
  666. */
  667. removeEventListener(eventName, listener, options) {
  668. if (listener == null) {
  669. return
  670. }
  671. const listeners = getListeners(this);
  672. const capture = isObject(options)
  673. ? Boolean(options.capture)
  674. : Boolean(options);
  675. const listenerType = capture ? CAPTURE : BUBBLE;
  676. let prev = null;
  677. let node = listeners.get(eventName);
  678. while (node != null) {
  679. if (
  680. node.listener === listener &&
  681. node.listenerType === listenerType
  682. ) {
  683. if (prev !== null) {
  684. prev.next = node.next;
  685. } else if (node.next !== null) {
  686. listeners.set(eventName, node.next);
  687. } else {
  688. listeners.delete(eventName);
  689. }
  690. return
  691. }
  692. prev = node;
  693. node = node.next;
  694. }
  695. },
  696. /**
  697. * Dispatch a given event.
  698. * @param {Event|{type:string}} event The event to dispatch.
  699. * @returns {boolean} `false` if canceled.
  700. */
  701. dispatchEvent(event) {
  702. if (event == null || typeof event.type !== "string") {
  703. throw new TypeError('"event.type" should be a string.')
  704. }
  705. // If listeners aren't registered, terminate.
  706. const listeners = getListeners(this);
  707. const eventName = event.type;
  708. let node = listeners.get(eventName);
  709. if (node == null) {
  710. return true
  711. }
  712. // Since we cannot rewrite several properties, so wrap object.
  713. const wrappedEvent = wrapEvent(this, event);
  714. // This doesn't process capturing phase and bubbling phase.
  715. // This isn't participating in a tree.
  716. let prev = null;
  717. while (node != null) {
  718. // Remove this listener if it's once
  719. if (node.once) {
  720. if (prev !== null) {
  721. prev.next = node.next;
  722. } else if (node.next !== null) {
  723. listeners.set(eventName, node.next);
  724. } else {
  725. listeners.delete(eventName);
  726. }
  727. } else {
  728. prev = node;
  729. }
  730. // Call this listener
  731. setPassiveListener(
  732. wrappedEvent,
  733. node.passive ? node.listener : null
  734. );
  735. if (typeof node.listener === "function") {
  736. try {
  737. node.listener.call(this, wrappedEvent);
  738. } catch (err) {
  739. if (
  740. typeof console !== "undefined" &&
  741. typeof console.error === "function"
  742. ) {
  743. console.error(err);
  744. }
  745. }
  746. } else if (
  747. node.listenerType !== ATTRIBUTE &&
  748. typeof node.listener.handleEvent === "function"
  749. ) {
  750. node.listener.handleEvent(wrappedEvent);
  751. }
  752. // Break if `event.stopImmediatePropagation` was called.
  753. if (isStopped(wrappedEvent)) {
  754. break
  755. }
  756. node = node.next;
  757. }
  758. setPassiveListener(wrappedEvent, null);
  759. setEventPhase(wrappedEvent, 0);
  760. setCurrentTarget(wrappedEvent, null);
  761. return !wrappedEvent.defaultPrevented
  762. },
  763. };
  764. // `constructor` is not enumerable.
  765. Object.defineProperty(EventTarget.prototype, "constructor", {
  766. value: EventTarget,
  767. configurable: true,
  768. writable: true,
  769. });
  770. // Ensure `eventTarget instanceof window.EventTarget` is `true`.
  771. if (
  772. typeof window !== "undefined" &&
  773. typeof window.EventTarget !== "undefined"
  774. ) {
  775. Object.setPrototypeOf(EventTarget.prototype, window.EventTarget.prototype);
  776. }
  777. exports.defineEventAttribute = defineEventAttribute;
  778. exports.EventTarget = EventTarget;
  779. exports.default = EventTarget;
  780. module.exports = EventTarget
  781. module.exports.EventTarget = module.exports["default"] = EventTarget
  782. module.exports.defineEventAttribute = defineEventAttribute
  783. //# sourceMappingURL=event-target-shim.js.map