123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- "use strict";
- function flattenOptions(options) {
- if (options !== Object(options)) {
- return {
- capture: Boolean(options),
- once: false,
- passive: false
- };
- }
- return {
- capture: Boolean(options.capture),
- once: Boolean(options.once),
- passive: Boolean(options.passive)
- };
- }
- function not(fn) {
- return function () {
- return !fn.apply(this, arguments);
- };
- }
- function hasListenerFilter(listener, capture) {
- return function (listenerSpec) {
- return listenerSpec.capture === capture
- && listenerSpec.listener === listener;
- };
- }
- var EventTarget = {
- // https://dom.spec.whatwg.org/#dom-eventtarget-addeventlistener
- addEventListener: function addEventListener(event, listener, providedOptions) {
- // 3. Let capture, passive, and once be the result of flattening more options.
- // Flatten property before executing step 2,
- // feture detection is usually based on registering handler with options object,
- // that has getter defined
- // addEventListener("load", () => {}, {
- // get once() { supportsOnce = true; }
- // });
- var options = flattenOptions(providedOptions);
- // 2. If callback is null, then return.
- if (listener == null) {
- return;
- }
- this.eventListeners = this.eventListeners || {};
- this.eventListeners[event] = this.eventListeners[event] || [];
- // 4. If context object’s associated list of event listener
- // does not contain an event listener whose type is type,
- // callback is callback, and capture is capture, then append
- // a new event listener to it, whose type is type, callback is
- // callback, capture is capture, passive is passive, and once is once.
- if (!this.eventListeners[event].some(hasListenerFilter(listener, options.capture))) {
- this.eventListeners[event].push({
- listener: listener,
- capture: options.capture,
- once: options.once
- });
- }
- },
- // https://dom.spec.whatwg.org/#dom-eventtarget-removeeventlistener
- removeEventListener: function removeEventListener(event, listener, providedOptions) {
- if (!this.eventListeners || !this.eventListeners[event]) {
- return;
- }
- // 2. Let capture be the result of flattening options.
- var options = flattenOptions(providedOptions);
- // 3. If there is an event listener in the associated list of
- // event listeners whose type is type, callback is callback,
- // and capture is capture, then set that event listener’s
- // removed to true and remove it from the associated list of event listeners.
- this.eventListeners[event] = this.eventListeners[event]
- .filter(not(hasListenerFilter(listener, options.capture)));
- },
- dispatchEvent: function dispatchEvent(event) {
- if (!this.eventListeners || !this.eventListeners[event.type]) {
- return Boolean(event.defaultPrevented);
- }
- var self = this;
- var type = event.type;
- var listeners = self.eventListeners[type];
- // Remove listeners, that should be dispatched once
- // before running dispatch loop to avoid nested dispatch issues
- self.eventListeners[type] = listeners.filter(function (listenerSpec) {
- return !listenerSpec.once;
- });
- listeners.forEach(function (listenerSpec) {
- var listener = listenerSpec.listener;
- if (typeof listener === "function") {
- listener.call(self, event);
- } else {
- listener.handleEvent(event);
- }
- });
- return Boolean(event.defaultPrevented);
- }
- };
- module.exports = EventTarget;
|