UNPKG

event-target-shim

Version:

An implementation of WHATWG EventTarget interface.

1,609 lines (1,317 loc) 44 kB
import _toConsumableArray from '@babel/runtime/helpers/esm/toConsumableArray'; import _set from '@babel/runtime/helpers/esm/set'; import _get from '@babel/runtime/helpers/esm/get'; import _assertThisInitialized from '@babel/runtime/helpers/esm/assertThisInitialized'; import _inherits from '@babel/runtime/helpers/esm/inherits'; import _possibleConstructorReturn from '@babel/runtime/helpers/esm/possibleConstructorReturn'; import _getPrototypeOf from '@babel/runtime/helpers/esm/getPrototypeOf'; import _wrapNativeSuper from '@babel/runtime/helpers/esm/wrapNativeSuper'; import _defineProperty from '@babel/runtime/helpers/esm/defineProperty'; import _classCallCheck from '@babel/runtime/helpers/esm/classCallCheck'; import _createClass from '@babel/runtime/helpers/esm/createClass'; import _typeof from '@babel/runtime/helpers/esm/typeof'; function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } /** * Assert a condition. * @param condition The condition that it should satisfy. * @param message The error message. * @param args The arguments for replacing placeholders in the message. */ function assertType(condition, message) { if (!condition) { for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { args[_key - 2] = arguments[_key]; } throw new TypeError(format(message, args)); } } /** * Convert a text and arguments to one string. * @param message The formating text * @param args The arguments. */ function format(message, args) { var i = 0; return message.replace(/%[os]/g, function () { return anyToString(args[i++]); }); } /** * Convert a value to a string representation. * @param x The value to get the string representation. */ function anyToString(x) { if (_typeof(x) !== "object" || x === null) { return String(x); } return Object.prototype.toString.call(x); } var currentErrorHandler; /** * Set the error handler. * @param value The error handler to set. */ function setErrorHandler(value) { assertType(typeof value === "function" || value === undefined, "The error handler must be a function or undefined, but got %o.", value); currentErrorHandler = value; } /** * Print a error message. * @param maybeError The error object. */ function reportError(maybeError) { try { var error = maybeError instanceof Error ? maybeError : new Error(anyToString(maybeError)); // Call the user-defined error handler if exists. if (currentErrorHandler) { currentErrorHandler(error); return; } // Dispatch an `error` event if this is on a browser. if (typeof dispatchEvent === "function" && typeof ErrorEvent === "function") { dispatchEvent(new ErrorEvent("error", { error: error, message: error.message })); } // Emit an `uncaughtException` event if this is on Node.js. //istanbul ignore else else if (typeof process !== "undefined" && typeof process.emit === "function") { process.emit("uncaughtException", error); return; } // Otherwise, print the error. console.error(error); } catch (_a) {// ignore. } } /** * The global object. */ //istanbul ignore next var Global = typeof window !== "undefined" ? window : typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : typeof globalThis !== "undefined" ? globalThis : undefined; var currentWarnHandler; /** * Set the warning handler. * @param value The warning handler to set. */ function setWarningHandler(value) { assertType(typeof value === "function" || value === undefined, "The warning handler must be a function or undefined, but got %o.", value); currentWarnHandler = value; } /** * The warning information. */ var Warning = /*#__PURE__*/function () { function Warning(code, message) { _classCallCheck(this, Warning); this.code = code; this.message = message; } /** * Report this warning. * @param args The arguments of the warning. */ _createClass(Warning, [{ key: "warn", value: function warn() { var _a; try { var _console; for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } // Call the user-defined warning handler if exists. if (currentWarnHandler) { currentWarnHandler(_objectSpread(_objectSpread({}, this), {}, { args: args })); return; } // Otherwise, print the warning. var stack = ((_a = new Error().stack) !== null && _a !== void 0 ? _a : "").replace(/^(?:(?:[\0-\t\x0B\f\x0E-\u2027\u202A-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+?\n){2}/g, "\n"); (_console = console).warn.apply(_console, [this.message].concat(args, [stack])); } catch (_b) {// Ignore. } } }]); return Warning; }(); var InitEventWasCalledWhileDispatching = new Warning("W01", "Unable to initialize event under dispatching."); var FalsyWasAssignedToCancelBubble = new Warning("W02", "Assigning any falsy value to 'cancelBubble' property has no effect."); var TruthyWasAssignedToReturnValue = new Warning("W03", "Assigning any truthy value to 'returnValue' property has no effect."); var NonCancelableEventWasCanceled = new Warning("W04", "Unable to preventDefault on non-cancelable events."); var CanceledInPassiveListener = new Warning("W05", "Unable to preventDefault inside passive event listener invocation."); var EventListenerWasDuplicated = new Warning("W06", "An event listener wasn't added because it has been added already: %o, %o"); var OptionWasIgnored = new Warning("W07", "The %o option value was abandoned because the event listener wasn't added as duplicated."); var InvalidEventListener = new Warning("W08", "The 'callback' argument must be a function or an object that has 'handleEvent' method: %o"); var InvalidAttributeHandler = new Warning("W09", "Event attribute handler must be a function: %o"); /*eslint-disable class-methods-use-this */ /** * An implementation of `Event` interface, that wraps a given event object. * `EventTarget` shim can control the internal state of this `Event` objects. * @see https://dom.spec.whatwg.org/#event */ var Event = /*#__PURE__*/function () { _createClass(Event, null, [{ key: "NONE", /** * @see https://dom.spec.whatwg.org/#dom-event-none */ get: function get() { return NONE; } /** * @see https://dom.spec.whatwg.org/#dom-event-capturing_phase */ }, { key: "CAPTURING_PHASE", get: function get() { return CAPTURING_PHASE; } /** * @see https://dom.spec.whatwg.org/#dom-event-at_target */ }, { key: "AT_TARGET", get: function get() { return AT_TARGET; } /** * @see https://dom.spec.whatwg.org/#dom-event-bubbling_phase */ }, { key: "BUBBLING_PHASE", get: function get() { return BUBBLING_PHASE; } /** * Initialize this event instance. * @param type The type of this event. * @param eventInitDict Options to initialize. * @see https://dom.spec.whatwg.org/#dom-event-event */ }]); function Event(type, eventInitDict) { _classCallCheck(this, Event); Object.defineProperty(this, "isTrusted", { value: false, enumerable: true }); var opts = eventInitDict !== null && eventInitDict !== void 0 ? eventInitDict : {}; internalDataMap.set(this, { type: String(type), bubbles: Boolean(opts.bubbles), cancelable: Boolean(opts.cancelable), composed: Boolean(opts.composed), target: null, currentTarget: null, stopPropagationFlag: false, stopImmediatePropagationFlag: false, canceledFlag: false, inPassiveListenerFlag: false, dispatchFlag: false, timeStamp: Date.now() }); } /** * The type of this event. * @see https://dom.spec.whatwg.org/#dom-event-type */ _createClass(Event, [{ key: "composedPath", /** * The event target of the current dispatching. * This doesn't support node tree. * @see https://dom.spec.whatwg.org/#dom-event-composedpath */ value: function composedPath() { var currentTarget = $(this).currentTarget; if (currentTarget) { return [currentTarget]; } return []; } /** * @see https://dom.spec.whatwg.org/#dom-event-none */ }, { key: "stopPropagation", /** * Stop event bubbling. * Because this shim doesn't support node tree, this merely changes the `cancelBubble` property value. * @see https://dom.spec.whatwg.org/#dom-event-stoppropagation */ value: function stopPropagation() { $(this).stopPropagationFlag = true; } /** * `true` if event bubbling was stopped. * @deprecated * @see https://dom.spec.whatwg.org/#dom-event-cancelbubble */ }, { key: "stopImmediatePropagation", /** * Stop event bubbling and subsequent event listener callings. * @see https://dom.spec.whatwg.org/#dom-event-stopimmediatepropagation */ value: function stopImmediatePropagation() { var data = $(this); data.stopPropagationFlag = data.stopImmediatePropagationFlag = true; } /** * `true` if this event will bubble. * @see https://dom.spec.whatwg.org/#dom-event-bubbles */ }, { key: "preventDefault", /** * Cancel the default behavior. * @see https://dom.spec.whatwg.org/#dom-event-preventdefault */ value: function preventDefault() { setCancelFlag($(this)); } /** * `true` if the default behavior was canceled. * @see https://dom.spec.whatwg.org/#dom-event-defaultprevented */ }, { key: "initEvent", /** * @deprecated Don't use this method. The constructor did initialization. */ value: function initEvent(type) { var bubbles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var cancelable = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var data = $(this); if (data.dispatchFlag) { InitEventWasCalledWhileDispatching.warn(); return; } internalDataMap.set(this, _objectSpread(_objectSpread({}, data), {}, { type: String(type), bubbles: Boolean(bubbles), cancelable: Boolean(cancelable), target: null, currentTarget: null, stopPropagationFlag: false, stopImmediatePropagationFlag: false, canceledFlag: false })); } }, { key: "type", get: function get() { return $(this).type; } /** * The event target of the current dispatching. * @see https://dom.spec.whatwg.org/#dom-event-target */ }, { key: "target", get: function get() { return $(this).target; } /** * The event target of the current dispatching. * @deprecated Use the `target` property instead. * @see https://dom.spec.whatwg.org/#dom-event-srcelement */ }, { key: "srcElement", get: function get() { return $(this).target; } /** * The event target of the current dispatching. * @see https://dom.spec.whatwg.org/#dom-event-currenttarget */ }, { key: "currentTarget", get: function get() { return $(this).currentTarget; } }, { key: "NONE", get: function get() { return NONE; } /** * @see https://dom.spec.whatwg.org/#dom-event-capturing_phase */ }, { key: "CAPTURING_PHASE", get: function get() { return CAPTURING_PHASE; } /** * @see https://dom.spec.whatwg.org/#dom-event-at_target */ }, { key: "AT_TARGET", get: function get() { return AT_TARGET; } /** * @see https://dom.spec.whatwg.org/#dom-event-bubbling_phase */ }, { key: "BUBBLING_PHASE", get: function get() { return BUBBLING_PHASE; } /** * The current event phase. * @see https://dom.spec.whatwg.org/#dom-event-eventphase */ }, { key: "eventPhase", get: function get() { return $(this).dispatchFlag ? 2 : 0; } }, { key: "cancelBubble", get: function get() { return $(this).stopPropagationFlag; } /** * Stop event bubbling if `true` is set. * @deprecated Use the `stopPropagation()` method instead. * @see https://dom.spec.whatwg.org/#dom-event-cancelbubble */ , set: function set(value) { if (value) { $(this).stopPropagationFlag = true; } else { FalsyWasAssignedToCancelBubble.warn(); } } }, { key: "bubbles", get: function get() { return $(this).bubbles; } /** * `true` if this event can be canceled by the `preventDefault()` method. * @see https://dom.spec.whatwg.org/#dom-event-cancelable */ }, { key: "cancelable", get: function get() { return $(this).cancelable; } /** * `true` if the default behavior will act. * @deprecated Use the `defaultPrevented` proeprty instead. * @see https://dom.spec.whatwg.org/#dom-event-returnvalue */ }, { key: "returnValue", get: function get() { return !$(this).canceledFlag; } /** * Cancel the default behavior if `false` is set. * @deprecated Use the `preventDefault()` method instead. * @see https://dom.spec.whatwg.org/#dom-event-returnvalue */ , set: function set(value) { if (!value) { setCancelFlag($(this)); } else { TruthyWasAssignedToReturnValue.warn(); } } }, { key: "defaultPrevented", get: function get() { return $(this).canceledFlag; } /** * @see https://dom.spec.whatwg.org/#dom-event-composed */ }, { key: "composed", get: function get() { return $(this).composed; } /** * @see https://dom.spec.whatwg.org/#dom-event-istrusted */ //istanbul ignore next }, { key: "isTrusted", get: function get() { return false; } /** * @see https://dom.spec.whatwg.org/#dom-event-timestamp */ }, { key: "timeStamp", get: function get() { return $(this).timeStamp; } }]); return Event; }(); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var NONE = 0; var CAPTURING_PHASE = 1; var AT_TARGET = 2; var BUBBLING_PHASE = 3; /** * Private data for event wrappers. */ var internalDataMap = new WeakMap(); /** * Get private data. * @param event The event object to get private data. * @param name The variable name to report. * @returns The private data of the event. */ function $(event) { var name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "this"; var retv = internalDataMap.get(event); assertType(retv != null, "'%s' must be an object that Event constructor created, but got another one: %o", name, event); return retv; } /** * https://dom.spec.whatwg.org/#set-the-canceled-flag * @param data private data. */ function setCancelFlag(data) { if (data.inPassiveListenerFlag) { CanceledInPassiveListener.warn(); return; } if (!data.cancelable) { NonCancelableEventWasCanceled.warn(); return; } data.canceledFlag = true; } // Set enumerable Object.defineProperty(Event, "NONE", { enumerable: true }); Object.defineProperty(Event, "CAPTURING_PHASE", { enumerable: true }); Object.defineProperty(Event, "AT_TARGET", { enumerable: true }); Object.defineProperty(Event, "BUBBLING_PHASE", { enumerable: true }); var keys = Object.getOwnPropertyNames(Event.prototype); for (var i = 0; i < keys.length; ++i) { if (keys[i] === "constructor") { continue; } Object.defineProperty(Event.prototype, keys[i], { enumerable: true }); } // Ensure `event instanceof window.Event` is `true`. if (typeof Global !== "undefined" && typeof Global.Event !== "undefined") { Object.setPrototypeOf(Event.prototype, Global.Event.prototype); } /** * Create a new InvalidStateError instance. * @param message The error message. */ function createInvalidStateError(message) { if (Global.DOMException) { return new Global.DOMException(message, "InvalidStateError"); } if (DOMException == null) { DOMException = /*#__PURE__*/function (_Error) { _inherits(DOMException, _Error); var _super = _createSuper(DOMException); function DOMException(msg) { var _this; _classCallCheck(this, DOMException); _this = _super.call(this, msg); if (Error.captureStackTrace) { Error.captureStackTrace(_assertThisInitialized(_this), DOMException); } return _this; } // eslint-disable-next-line class-methods-use-this _createClass(DOMException, [{ key: "code", get: function get() { return 11; } // eslint-disable-next-line class-methods-use-this }, { key: "name", get: function get() { return "InvalidStateError"; } }]); return DOMException; }( /*#__PURE__*/_wrapNativeSuper(Error)); Object.defineProperties(DOMException.prototype, { code: { enumerable: true }, name: { enumerable: true } }); defineErrorCodeProperties(DOMException); defineErrorCodeProperties(DOMException.prototype); } return new DOMException(message); } //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var DOMException; var ErrorCodeMap = { INDEX_SIZE_ERR: 1, DOMSTRING_SIZE_ERR: 2, HIERARCHY_REQUEST_ERR: 3, WRONG_DOCUMENT_ERR: 4, INVALID_CHARACTER_ERR: 5, NO_DATA_ALLOWED_ERR: 6, NO_MODIFICATION_ALLOWED_ERR: 7, NOT_FOUND_ERR: 8, NOT_SUPPORTED_ERR: 9, INUSE_ATTRIBUTE_ERR: 10, INVALID_STATE_ERR: 11, SYNTAX_ERR: 12, INVALID_MODIFICATION_ERR: 13, NAMESPACE_ERR: 14, INVALID_ACCESS_ERR: 15, VALIDATION_ERR: 16, TYPE_MISMATCH_ERR: 17, SECURITY_ERR: 18, NETWORK_ERR: 19, ABORT_ERR: 20, URL_MISMATCH_ERR: 21, QUOTA_EXCEEDED_ERR: 22, TIMEOUT_ERR: 23, INVALID_NODE_TYPE_ERR: 24, DATA_CLONE_ERR: 25 }; function defineErrorCodeProperties(obj) { var keys = Object.keys(ErrorCodeMap); var _loop = function _loop(_i) { var key = keys[_i]; var value = ErrorCodeMap[key]; Object.defineProperty(obj, key, { get: function get() { return value; }, configurable: true, enumerable: true }); }; for (var _i = 0; _i < keys.length; ++_i) { _loop(_i); } } /** * An implementation of `Event` interface, that wraps a given event object. * This class controls the internal state of `Event`. * @see https://dom.spec.whatwg.org/#interface-event */ var EventWrapper = /*#__PURE__*/function (_Event) { _inherits(EventWrapper, _Event); var _super2 = _createSuper(EventWrapper); _createClass(EventWrapper, null, [{ key: "wrap", /** * Wrap a given event object to control states. * @param event The event-like object to wrap. */ value: function wrap(event) { return new (getWrapperClassOf(event))(event); } }]); function EventWrapper(event) { var _thisSuper, _thisSuper2, _this2; _classCallCheck(this, EventWrapper); _this2 = _super2.call(this, event.type, { bubbles: event.bubbles, cancelable: event.cancelable, composed: event.composed }); if (event.cancelBubble) { _get((_thisSuper = _assertThisInitialized(_this2), _getPrototypeOf(EventWrapper.prototype)), "stopPropagation", _thisSuper).call(_thisSuper); } if (event.defaultPrevented) { _get((_thisSuper2 = _assertThisInitialized(_this2), _getPrototypeOf(EventWrapper.prototype)), "preventDefault", _thisSuper2).call(_thisSuper2); } internalDataMap$1.set(_assertThisInitialized(_this2), { original: event }); // Define accessors var keys = Object.keys(event); for (var _i2 = 0; _i2 < keys.length; ++_i2) { var key = keys[_i2]; if (!(key in _assertThisInitialized(_this2))) { Object.defineProperty(_assertThisInitialized(_this2), key, defineRedirectDescriptor(event, key)); } } return _this2; } _createClass(EventWrapper, [{ key: "stopPropagation", value: function stopPropagation() { _get(_getPrototypeOf(EventWrapper.prototype), "stopPropagation", this).call(this); var _$$ = $$1(this), original = _$$.original; if ("stopPropagation" in original) { original.stopPropagation(); } } }, { key: "stopImmediatePropagation", value: function stopImmediatePropagation() { _get(_getPrototypeOf(EventWrapper.prototype), "stopImmediatePropagation", this).call(this); var _$$2 = $$1(this), original = _$$2.original; if ("stopImmediatePropagation" in original) { original.stopImmediatePropagation(); } } }, { key: "preventDefault", value: function preventDefault() { _get(_getPrototypeOf(EventWrapper.prototype), "preventDefault", this).call(this); var _$$3 = $$1(this), original = _$$3.original; if ("preventDefault" in original) { original.preventDefault(); } } }, { key: "cancelBubble", get: function get() { return _get(_getPrototypeOf(EventWrapper.prototype), "cancelBubble", this); }, set: function set(value) { _set(_getPrototypeOf(EventWrapper.prototype), "cancelBubble", value, this, true); var _$$4 = $$1(this), original = _$$4.original; if ("cancelBubble" in original) { original.cancelBubble = value; } } }, { key: "returnValue", get: function get() { return _get(_getPrototypeOf(EventWrapper.prototype), "returnValue", this); }, set: function set(value) { _set(_getPrototypeOf(EventWrapper.prototype), "returnValue", value, this, true); var _$$5 = $$1(this), original = _$$5.original; if ("returnValue" in original) { original.returnValue = value; } } }, { key: "timeStamp", get: function get() { var _$$6 = $$1(this), original = _$$6.original; if ("timeStamp" in original) { return original.timeStamp; } return _get(_getPrototypeOf(EventWrapper.prototype), "timeStamp", this); } }]); return EventWrapper; }(Event); /** * Private data for event wrappers. */ var internalDataMap$1 = new WeakMap(); /** * Get private data. * @param event The event object to get private data. * @returns The private data of the event. */ function $$1(event) { var retv = internalDataMap$1.get(event); assertType(retv != null, "'this' is expected an Event object, but got", event); return retv; } /** * Cache for wrapper classes. * @type {WeakMap<Object, Function>} * @private */ var wrapperClassCache = new WeakMap(); // Make association for wrappers. wrapperClassCache.set(Object.prototype, EventWrapper); if (typeof Global !== "undefined" && typeof Global.Event !== "undefined") { wrapperClassCache.set(Global.Event.prototype, EventWrapper); } /** * Get the wrapper class of a given prototype. * @param originalEvent The event object to wrap. */ function getWrapperClassOf(originalEvent) { var prototype = Object.getPrototypeOf(originalEvent); if (prototype == null) { return EventWrapper; } var wrapper = wrapperClassCache.get(prototype); if (wrapper == null) { wrapper = defineWrapper(getWrapperClassOf(prototype), prototype); wrapperClassCache.set(prototype, wrapper); } return wrapper; } /** * Define new wrapper class. * @param BaseEventWrapper The base wrapper class. * @param originalPrototype The prototype of the original event. */ function defineWrapper(BaseEventWrapper, originalPrototype) { var CustomEventWrapper = /*#__PURE__*/function (_BaseEventWrapper) { _inherits(CustomEventWrapper, _BaseEventWrapper); var _super3 = _createSuper(CustomEventWrapper); function CustomEventWrapper() { _classCallCheck(this, CustomEventWrapper); return _super3.apply(this, arguments); } return CustomEventWrapper; }(BaseEventWrapper); var keys = Object.keys(originalPrototype); for (var _i3 = 0; _i3 < keys.length; ++_i3) { Object.defineProperty(CustomEventWrapper.prototype, keys[_i3], defineRedirectDescriptor(originalPrototype, keys[_i3])); } return CustomEventWrapper; } /** * Get the property descriptor to redirect a given property. */ function defineRedirectDescriptor(obj, key) { var d = Object.getOwnPropertyDescriptor(obj, key); return { get: function get() { var original = $$1(this).original; var value = original[key]; if (typeof value === "function") { return value.bind(original); } return value; }, set: function set(value) { var original = $$1(this).original; original[key] = value; }, configurable: d.configurable, enumerable: d.enumerable }; } /** * Create a new listener. * @param callback The callback function. * @param capture The capture flag. * @param passive The passive flag. * @param once The once flag. * @param signal The abort signal. * @param signalListener The abort event listener for the abort signal. */ function createListener(callback, capture, passive, once, signal, signalListener) { return { callback: callback, flags: (capture ? 1 /* Capture */ : 0) | (passive ? 2 /* Passive */ : 0) | (once ? 4 /* Once */ : 0), signal: signal, signalListener: signalListener }; } /** * Set the `removed` flag to the given listener. * @param listener The listener to check. */ function setRemoved(listener) { listener.flags |= 8 /* Removed */ ; } /** * Check if the given listener has the `capture` flag or not. * @param listener The listener to check. */ function isCapture(listener) { return (listener.flags & 1 /* Capture */ ) === 1 /* Capture */ ; } /** * Check if the given listener has the `passive` flag or not. * @param listener The listener to check. */ function isPassive(listener) { return (listener.flags & 2 /* Passive */ ) === 2 /* Passive */ ; } /** * Check if the given listener has the `once` flag or not. * @param listener The listener to check. */ function isOnce(listener) { return (listener.flags & 4 /* Once */ ) === 4 /* Once */ ; } /** * Check if the given listener has the `removed` flag or not. * @param listener The listener to check. */ function isRemoved(listener) { return (listener.flags & 8 /* Removed */ ) === 8 /* Removed */ ; } /** * Call an event listener. * @param listener The listener to call. * @param target The event target object for `thisArg`. * @param event The event object for the first argument. * @param attribute `true` if this callback is an event attribute handler. */ function invokeCallback(_ref, target, event) { var callback = _ref.callback; try { if (typeof callback === "function") { callback.call(target, event); } else if (typeof callback.handleEvent === "function") { callback.handleEvent(event); } } catch (thrownError) { reportError(thrownError); } } /** * Find the index of given listener. * This returns `-1` if not found. * @param list The listener list. * @param callback The callback function to find. * @param capture The capture flag to find. */ function findIndexOfListener(_ref2, callback, capture) { var listeners = _ref2.listeners; for (var _i4 = 0; _i4 < listeners.length; ++_i4) { if (listeners[_i4].callback === callback && isCapture(listeners[_i4]) === capture) { return _i4; } } return -1; } /** * Add the given listener. * Does copy-on-write if needed. * @param list The listener list. * @param callback The callback function. * @param capture The capture flag. * @param passive The passive flag. * @param once The once flag. * @param signal The abort signal. */ function addListener(list, callback, capture, passive, once, signal) { var signalListener; if (signal) { signalListener = removeListener.bind(null, list, callback, capture); signal.addEventListener("abort", signalListener); } var listener = createListener(callback, capture, passive, once, signal, signalListener); if (list.cow) { list.cow = false; list.listeners = [].concat(_toConsumableArray(list.listeners), [listener]); } else { list.listeners.push(listener); } return listener; } /** * Remove a listener. * @param list The listener list. * @param callback The callback function to find. * @param capture The capture flag to find. * @returns `true` if it mutated the list directly. */ function removeListener(list, callback, capture) { var index = findIndexOfListener(list, callback, capture); if (index !== -1) { return removeListenerAt(list, index); } return false; } /** * Remove a listener. * @param list The listener list. * @param index The index of the target listener. * @param disableCow Disable copy-on-write if true. * @returns `true` if it mutated the `listeners` array directly. */ function removeListenerAt(list, index) { var disableCow = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var listener = list.listeners[index]; // Set the removed flag. setRemoved(listener); // Dispose the abort signal listener if exists. if (listener.signal) { listener.signal.removeEventListener("abort", listener.signalListener); } // Remove it from the array. if (list.cow && !disableCow) { list.cow = false; list.listeners = list.listeners.filter(function (_, i) { return i !== index; }); return false; } list.listeners.splice(index, 1); return true; } /** * Create a new `ListenerListMap` object. */ function createListenerListMap() { return Object.create(null); } /** * Get the listener list of the given type. * If the listener list has not been initialized, initialize and return it. * @param listenerMap The listener list map. * @param type The event type to get. */ function ensureListenerList(listenerMap, type) { var _a; return (_a = listenerMap[type]) !== null && _a !== void 0 ? _a : listenerMap[type] = { attrCallback: undefined, attrListener: undefined, cow: false, listeners: [] }; } /** * An implementation of the `EventTarget` interface. * @see https://dom.spec.whatwg.org/#eventtarget */ var EventTarget = /*#__PURE__*/function () { /** * Initialize this instance. */ function EventTarget() { _classCallCheck(this, EventTarget); internalDataMap$2.set(this, createListenerListMap()); } // Implementation _createClass(EventTarget, [{ key: "addEventListener", value: function addEventListener(type0, callback0, options0) { var listenerMap = $$2(this); var _normalizeAddOptions = normalizeAddOptions(type0, callback0, options0), callback = _normalizeAddOptions.callback, capture = _normalizeAddOptions.capture, once = _normalizeAddOptions.once, passive = _normalizeAddOptions.passive, signal = _normalizeAddOptions.signal, type = _normalizeAddOptions.type; if (callback == null || (signal === null || signal === void 0 ? void 0 : signal.aborted)) { return; } var list = ensureListenerList(listenerMap, type); // Find existing listener. var i = findIndexOfListener(list, callback, capture); if (i !== -1) { warnDuplicate(list.listeners[i], passive, once, signal); return; } // Add the new listener. addListener(list, callback, capture, passive, once, signal); } // Implementation }, { key: "removeEventListener", value: function removeEventListener(type0, callback0, options0) { var listenerMap = $$2(this); var _normalizeOptions = normalizeOptions(type0, callback0, options0), callback = _normalizeOptions.callback, capture = _normalizeOptions.capture, type = _normalizeOptions.type; var list = listenerMap[type]; if (callback != null && list) { removeListener(list, callback, capture); } } // Implementation }, { key: "dispatchEvent", value: function dispatchEvent(e) { var list = $$2(this)[String(e.type)]; if (list == null) { return true; } var event = e instanceof Event ? e : EventWrapper.wrap(e); var eventData = $(event, "event"); if (eventData.dispatchFlag) { throw createInvalidStateError("This event has been in dispatching."); } eventData.dispatchFlag = true; eventData.target = eventData.currentTarget = this; if (!eventData.stopPropagationFlag) { var cow = list.cow, listeners = list.listeners; // Set copy-on-write flag. list.cow = true; // Call listeners. for (var _i5 = 0; _i5 < listeners.length; ++_i5) { var listener = listeners[_i5]; // Skip if removed. if (isRemoved(listener)) { continue; } // Remove this listener if has the `once` flag. if (isOnce(listener) && removeListenerAt(list, _i5, !cow)) { // Because this listener was removed, the next index is the // same as the current value. _i5 -= 1; } // Call this listener with the `passive` flag. eventData.inPassiveListenerFlag = isPassive(listener); invokeCallback(listener, this, event); eventData.inPassiveListenerFlag = false; // Stop if the `event.stopImmediatePropagation()` method was called. if (eventData.stopImmediatePropagationFlag) { break; } } // Restore copy-on-write flag. if (!cow) { list.cow = false; } } eventData.target = null; eventData.currentTarget = null; eventData.stopImmediatePropagationFlag = false; eventData.stopPropagationFlag = false; eventData.dispatchFlag = false; return !eventData.canceledFlag; } }]); return EventTarget; }(); /** * Internal data. */ var internalDataMap$2 = new WeakMap(); /** * Get private data. * @param target The event target object to get private data. * @param name The variable name to report. * @returns The private data of the event. */ function $$2(target) { var name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "this"; var retv = internalDataMap$2.get(target); assertType(retv != null, "'%s' must be an object that EventTarget constructor created, but got another one: %o", name, target); return retv; } /** * Normalize options. * @param options The options to normalize. */ function normalizeAddOptions(type, callback, options) { var _a; assertCallback(callback); if (_typeof(options) === "object" && options !== null) { return { type: String(type), callback: callback !== null && callback !== void 0 ? callback : undefined, capture: Boolean(options.capture), passive: Boolean(options.passive), once: Boolean(options.once), signal: (_a = options.signal) !== null && _a !== void 0 ? _a : undefined }; } return { type: String(type), callback: callback !== null && callback !== void 0 ? callback : undefined, capture: Boolean(options), passive: false, once: false, signal: undefined }; } /** * Normalize options. * @param options The options to normalize. */ function normalizeOptions(type, callback, options) { assertCallback(callback); if (_typeof(options) === "object" && options !== null) { return { type: String(type), callback: callback !== null && callback !== void 0 ? callback : undefined, capture: Boolean(options.capture) }; } return { type: String(type), callback: callback !== null && callback !== void 0 ? callback : undefined, capture: Boolean(options) }; } /** * Assert the type of 'callback' argument. * @param callback The callback to check. */ function assertCallback(callback) { if (typeof callback === "function" || _typeof(callback) === "object" && callback !== null && typeof callback.handleEvent === "function") { return; } if (callback == null || _typeof(callback) === "object") { InvalidEventListener.warn(callback); return; } throw new TypeError(format(InvalidEventListener.message, [callback])); } /** * Print warning for duplicated. * @param listener The current listener that is duplicated. * @param passive The passive flag of the new duplicated listener. * @param once The once flag of the new duplicated listener. * @param signal The signal object of the new duplicated listener. */ function warnDuplicate(listener, passive, once, signal) { EventListenerWasDuplicated.warn(isCapture(listener) ? "capture" : "bubble", listener.callback); if (isPassive(listener) !== passive) { OptionWasIgnored.warn("passive"); } if (isOnce(listener) !== once) { OptionWasIgnored.warn("once"); } if (listener.signal !== signal) { OptionWasIgnored.warn("signal"); } } // Set enumerable var keys$1 = Object.getOwnPropertyNames(EventTarget.prototype); for (var _i6 = 0; _i6 < keys$1.length; ++_i6) { if (keys$1[_i6] === "constructor") { continue; } Object.defineProperty(EventTarget.prototype, keys$1[_i6], { enumerable: true }); } // Ensure `eventTarget instanceof window.EventTarget` is `true`. if (typeof Global !== "undefined" && typeof Global.EventTarget !== "undefined") { Object.setPrototypeOf(EventTarget.prototype, Global.EventTarget.prototype); } /** * Get the current value of a given event attribute. * @param target The `EventTarget` object to get. * @param type The event type. */ function getEventAttributeValue(target, type) { var _a, _b; var listMap = $$2(target, "target"); return (_b = (_a = listMap[type]) === null || _a === void 0 ? void 0 : _a.attrCallback) !== null && _b !== void 0 ? _b : null; } /** * Set an event listener to a given event attribute. * @param target The `EventTarget` object to set. * @param type The event type. * @param callback The event listener. */ function setEventAttributeValue(target, type, callback) { if (callback != null && typeof callback !== "function") { InvalidAttributeHandler.warn(callback); } if (typeof callback === "function" || _typeof(callback) === "object" && callback !== null) { upsertEventAttributeListener(target, type, callback); } else { removeEventAttributeListener(target, type); } } //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Update or insert the given event attribute handler. * @param target The `EventTarget` object to set. * @param type The event type. * @param callback The event listener. */ function upsertEventAttributeListener(target, type, callback) { var list = ensureListenerList($$2(target, "target"), String(type)); list.attrCallback = callback; if (list.attrListener == null) { list.attrListener = addListener(list, defineEventAttributeCallback(list), false, false, false, undefined); } } /** * Remove the given event attribute handler. * @param target The `EventTarget` object to remove. * @param type The event type. * @param callback The event listener. */ function removeEventAttributeListener(target, type) { var listMap = $$2(target, "target"); var list = listMap[String(type)]; if (list && list.attrListener) { removeListener(list, list.attrListener.callback, false); list.attrCallback = list.attrListener = undefined; } } /** * Define the callback function for the given listener list object. * It calls `attrCallback` property if the property value is a function. * @param list The `ListenerList` object. */ function defineEventAttributeCallback(list) { return function (event) { var callback = list.attrCallback; if (typeof callback === "function") { callback.call(this, event); } }; } /** * Define an `EventTarget` class that has event attibutes. * @param types The types to define event attributes. * @deprecated Use `getEventAttributeValue`/`setEventAttributeValue` pair on your derived class instead because of static analysis friendly. */ function defineCustomEventTarget() { var CustomEventTarget = /*#__PURE__*/function (_EventTarget) { _inherits(CustomEventTarget, _EventTarget); var _super4 = _createSuper(CustomEventTarget); function CustomEventTarget() { _classCallCheck(this, CustomEventTarget); return _super4.apply(this, arguments); } return CustomEventTarget; }(EventTarget); for (var _i7 = 0; _i7 < arguments.length; ++_i7) { defineEventAttribute(CustomEventTarget.prototype, _i7 < 0 || arguments.length <= _i7 ? undefined : arguments[_i7]); } return CustomEventTarget; } /** * Define an event attribute. * @param target The `EventTarget` object to define an event attribute. * @param type The event type to define. * @param _eventClass Unused, but to infer `Event` class type. * @deprecated Use `getEventAttributeValue`/`setEventAttributeValue` pair on your derived class instead because of static analysis friendly. */ function defineEventAttribute(target, type, _eventClass) { Object.defineProperty(target, "on".concat(type), { get: function get() { return getEventAttributeValue(this, type); }, set: function set(value) { setEventAttributeValue(this, type, value); }, configurable: true, enumerable: true }); } export default EventTarget; export { Event, EventTarget, defineCustomEventTarget, defineEventAttribute, getEventAttributeValue, setErrorHandler, setEventAttributeValue, setWarningHandler };