buddy

node MVC discord bot
Log | Files | Refs | README

event-target-shim.js (23692B)


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