From 1a1bf9b500307c9ff6c924907a40808b319d5949 Mon Sep 17 00:00:00 2001 From: David Reed Date: Sat, 19 Nov 2022 19:57:18 -0500 Subject: [PATCH] npm events, expose EventEmitter via bundle --- package-lock.json | 5 +- package.json | 1 + src/client/dom/attr.js | 2 +- src/client/dom/document.js | 2 +- src/client/dom/element.js | 2 +- src/client/dom/node.js | 2 +- src/client/dom/style.js | 2 +- src/client/events.js | 522 ----------------------------- src/client/history.js | 2 +- src/client/index.js | 2 +- src/client/location.js | 2 +- src/client/message.js | 2 +- src/client/native/function.js | 2 +- src/client/native/object.js | 2 +- src/client/navigator.js | 2 +- src/client/requests/eventsource.js | 2 +- src/client/requests/fetch.js | 2 +- src/client/requests/xhr.js | 2 +- src/client/storage.js | 2 +- src/client/url.js | 2 +- src/client/worker.js | 2 +- src/rewrite/css.js | 2 +- src/rewrite/events.js | 522 ----------------------------- src/rewrite/html.js | 2 +- src/rewrite/index.js | 2 + src/rewrite/js.js | 2 +- src/uv.sw.js | 500 +-------------------------- 27 files changed, 27 insertions(+), 1567 deletions(-) delete mode 100644 src/client/events.js delete mode 100644 src/rewrite/events.js diff --git a/package-lock.json b/package-lock.json index b156310..949bb2e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "bowser": "^2.11.0", "css-tree": "^2.0.4", "esotope-hammerhead": "^0.6.1", + "events": "^3.3.0", "idb": "^7.0.0", "meriyah": "^4.2.0", "mime-db": "^1.51.0", @@ -1167,7 +1168,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, "engines": { "node": ">=0.8.x" } @@ -3580,8 +3580,7 @@ "events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" }, "fast-deep-equal": { "version": "3.1.3", diff --git a/package.json b/package.json index 0490268..24530c6 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "bowser": "^2.11.0", "css-tree": "^2.0.4", "esotope-hammerhead": "^0.6.1", + "events": "^3.3.0", "idb": "^7.0.0", "meriyah": "^4.2.0", "mime-db": "^1.51.0", diff --git a/src/client/dom/attr.js b/src/client/dom/attr.js index 3d2e1ab..db5886a 100644 --- a/src/client/dom/attr.js +++ b/src/client/dom/attr.js @@ -1,4 +1,4 @@ -import EventEmitter from '../events.js'; +import EventEmitter from 'events'; import HookEvent from '../hook.js'; class AttrApi extends EventEmitter { diff --git a/src/client/dom/document.js b/src/client/dom/document.js index 619d5a0..d9974ee 100644 --- a/src/client/dom/document.js +++ b/src/client/dom/document.js @@ -1,4 +1,4 @@ -import EventEmitter from '../events.js'; +import EventEmitter from 'events'; import HookEvent from '../hook.js'; class DocumentHook extends EventEmitter { diff --git a/src/client/dom/element.js b/src/client/dom/element.js index 8a7dcda..c33c98e 100644 --- a/src/client/dom/element.js +++ b/src/client/dom/element.js @@ -1,4 +1,4 @@ -import EventEmitter from '../events.js'; +import EventEmitter from 'events'; import HookEvent from '../hook.js'; class ElementApi extends EventEmitter { diff --git a/src/client/dom/node.js b/src/client/dom/node.js index 3957591..bdb93c5 100644 --- a/src/client/dom/node.js +++ b/src/client/dom/node.js @@ -1,4 +1,4 @@ -import EventEmitter from '../events.js'; +import EventEmitter from 'events'; import HookEvent from '../hook.js'; class NodeApi extends EventEmitter { diff --git a/src/client/dom/style.js b/src/client/dom/style.js index 01567ad..24c983d 100644 --- a/src/client/dom/style.js +++ b/src/client/dom/style.js @@ -1,4 +1,4 @@ -import EventEmitter from '../events.js'; +import EventEmitter from 'events'; import HookEvent from '../hook.js'; class StyleApi extends EventEmitter { diff --git a/src/client/events.js b/src/client/events.js deleted file mode 100644 index 196b9e4..0000000 --- a/src/client/events.js +++ /dev/null @@ -1,522 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; - -var R = typeof Reflect === 'object' ? Reflect : null; -var ReflectApply = - R && typeof R.apply === 'function' - ? R.apply - : function ReflectApply(target, receiver, args) { - return Function.prototype.apply.call(target, receiver, args); - }; - -var ReflectOwnKeys; -if (R && typeof R.ownKeys === 'function') { - ReflectOwnKeys = R.ownKeys; -} else if (Object.getOwnPropertySymbols) { - ReflectOwnKeys = function ReflectOwnKeys(target) { - return Object.getOwnPropertyNames(target).concat( - Object.getOwnPropertySymbols(target) - ); - }; -} else { - ReflectOwnKeys = function ReflectOwnKeys(target) { - return Object.getOwnPropertyNames(target); - }; -} - -function ProcessEmitWarning(warning) { - if (console && console.warn) console.warn(warning); -} - -var NumberIsNaN = - Number.isNaN || - function NumberIsNaN(value) { - return value !== value; - }; - -function EventEmitter() { - EventEmitter.init.call(this); -} - -export default EventEmitter; - -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; - -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._eventsCount = 0; -EventEmitter.prototype._maxListeners = undefined; - -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -var defaultMaxListeners = 10; - -function checkListener(listener) { - if (typeof listener !== 'function') { - throw new TypeError( - 'The "listener" argument must be of type Function. Received type ' + - typeof listener - ); - } -} - -Object.defineProperty(EventEmitter, 'defaultMaxListeners', { - enumerable: true, - get: function () { - return defaultMaxListeners; - }, - set: function (arg) { - if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) { - throw new RangeError( - 'The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + - arg + - '.' - ); - } - defaultMaxListeners = arg; - }, -}); - -EventEmitter.init = function () { - if ( - this._events === undefined || - this._events === Object.getPrototypeOf(this)._events - ) { - this._events = Object.create(null); - this._eventsCount = 0; - } - - this._maxListeners = this._maxListeners || undefined; -}; - -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { - if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) { - throw new RangeError( - 'The value of "n" is out of range. It must be a non-negative number. Received ' + - n + - '.' - ); - } - this._maxListeners = n; - return this; -}; - -function _getMaxListeners(that) { - if (that._maxListeners === undefined) - return EventEmitter.defaultMaxListeners; - return that._maxListeners; -} - -EventEmitter.prototype.getMaxListeners = function getMaxListeners() { - return _getMaxListeners(this); -}; - -EventEmitter.prototype.emit = function emit(type) { - var args = []; - for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); - var doError = type === 'error'; - - var events = this._events; - if (events !== undefined) doError = doError && events.error === undefined; - else if (!doError) return false; - - // If there is no 'error' event listener then throw. - if (doError) { - var er; - if (args.length > 0) er = args[0]; - if (er instanceof Error) { - // Note: The comments on the `throw` lines are intentional, they show - // up in Node's output if this results in an unhandled exception. - throw er; // Unhandled 'error' event - } - // At least give some kind of context to the user - var err = new Error( - 'Unhandled error.' + (er ? ' (' + er.message + ')' : '') - ); - err.context = er; - throw err; // Unhandled 'error' event - } - - var handler = events[type]; - - if (handler === undefined) return false; - - if (typeof handler === 'function') { - ReflectApply(handler, this, args); - } else { - var len = handler.length; - var listeners = arrayClone(handler, len); - for (var i = 0; i < len; ++i) ReflectApply(listeners[i], this, args); - } - - return true; -}; - -function _addListener(target, type, listener, prepend) { - var m; - var events; - var existing; - - checkListener(listener); - - events = target._events; - if (events === undefined) { - events = target._events = Object.create(null); - target._eventsCount = 0; - } else { - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (events.newListener !== undefined) { - target.emit( - 'newListener', - type, - listener.listener ? listener.listener : listener - ); - - // Re-assign `events` because a newListener handler could have caused the - // this._events to be assigned to a new object - events = target._events; - } - existing = events[type]; - } - - if (existing === undefined) { - // Optimize the case of one listener. Don't need the extra array object. - existing = events[type] = listener; - ++target._eventsCount; - } else { - if (typeof existing === 'function') { - // Adding the second element, need to change to array. - existing = events[type] = prepend - ? [listener, existing] - : [existing, listener]; - // If we've already got an array, just append. - } else if (prepend) { - existing.unshift(listener); - } else { - existing.push(listener); - } - - // Check for listener leak - m = _getMaxListeners(target); - if (m > 0 && existing.length > m && !existing.warned) { - existing.warned = true; - // No error code for this since it is a Warning - // eslint-disable-next-line no-restricted-syntax - var w = new Error( - 'Possible EventEmitter memory leak detected. ' + - existing.length + - ' ' + - String(type) + - ' listeners ' + - 'added. Use emitter.setMaxListeners() to ' + - 'increase limit' - ); - w.name = 'MaxListenersExceededWarning'; - w.emitter = target; - w.type = type; - w.count = existing.length; - ProcessEmitWarning(w); - } - } - - return target; -} - -EventEmitter.prototype.addListener = function addListener(type, listener) { - return _addListener(this, type, listener, false); -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.prependListener = function prependListener( - type, - listener -) { - return _addListener(this, type, listener, true); -}; - -function onceWrapper() { - if (!this.fired) { - this.target.removeListener(this.type, this.wrapFn); - this.fired = true; - if (arguments.length === 0) return this.listener.call(this.target); - return this.listener.apply(this.target, arguments); - } -} - -function _onceWrap(target, type, listener) { - var state = { - fired: false, - wrapFn: undefined, - target: target, - type: type, - listener: listener, - }; - var wrapped = onceWrapper.bind(state); - wrapped.listener = listener; - state.wrapFn = wrapped; - return wrapped; -} - -EventEmitter.prototype.once = function once(type, listener) { - checkListener(listener); - this.on(type, _onceWrap(this, type, listener)); - return this; -}; - -EventEmitter.prototype.prependOnceListener = function prependOnceListener( - type, - listener -) { - checkListener(listener); - this.prependListener(type, _onceWrap(this, type, listener)); - return this; -}; - -// Emits a 'removeListener' event if and only if the listener was removed. -EventEmitter.prototype.removeListener = function removeListener( - type, - listener -) { - var list, events, position, i, originalListener; - - checkListener(listener); - - events = this._events; - if (events === undefined) return this; - - list = events[type]; - if (list === undefined) return this; - - if (list === listener || list.listener === listener) { - if (--this._eventsCount === 0) this._events = Object.create(null); - else { - delete events[type]; - if (events.removeListener) - this.emit('removeListener', type, list.listener || listener); - } - } else if (typeof list !== 'function') { - position = -1; - - for (i = list.length - 1; i >= 0; i--) { - if (list[i] === listener || list[i].listener === listener) { - originalListener = list[i].listener; - position = i; - break; - } - } - - if (position < 0) return this; - - if (position === 0) list.shift(); - else { - spliceOne(list, position); - } - - if (list.length === 1) events[type] = list[0]; - - if (events.removeListener !== undefined) - this.emit('removeListener', type, originalListener || listener); - } - - return this; -}; - -EventEmitter.prototype.off = EventEmitter.prototype.removeListener; - -EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) { - var listeners, events, i; - - events = this._events; - if (events === undefined) return this; - - // not listening for removeListener, no need to emit - if (events.removeListener === undefined) { - if (arguments.length === 0) { - this._events = Object.create(null); - this._eventsCount = 0; - } else if (events[type] !== undefined) { - if (--this._eventsCount === 0) this._events = Object.create(null); - else delete events[type]; - } - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - var keys = Object.keys(events); - var key; - for (i = 0; i < keys.length; ++i) { - key = keys[i]; - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = Object.create(null); - this._eventsCount = 0; - return this; - } - - listeners = events[type]; - - if (typeof listeners === 'function') { - this.removeListener(type, listeners); - } else if (listeners !== undefined) { - // LIFO order - for (i = listeners.length - 1; i >= 0; i--) { - this.removeListener(type, listeners[i]); - } - } - - return this; -}; - -function _listeners(target, type, unwrap) { - var events = target._events; - - if (events === undefined) return []; - - var evlistener = events[type]; - if (evlistener === undefined) return []; - - if (typeof evlistener === 'function') - return unwrap ? [evlistener.listener || evlistener] : [evlistener]; - - return unwrap - ? unwrapListeners(evlistener) - : arrayClone(evlistener, evlistener.length); -} - -EventEmitter.prototype.listeners = function listeners(type) { - return _listeners(this, type, true); -}; - -EventEmitter.prototype.rawListeners = function rawListeners(type) { - return _listeners(this, type, false); -}; - -EventEmitter.listenerCount = function (emitter, type) { - if (typeof emitter.listenerCount === 'function') { - return emitter.listenerCount(type); - } else { - return listenerCount.call(emitter, type); - } -}; - -EventEmitter.prototype.listenerCount = listenerCount; -function listenerCount(type) { - var events = this._events; - - if (events !== undefined) { - var evlistener = events[type]; - - if (typeof evlistener === 'function') { - return 1; - } else if (evlistener !== undefined) { - return evlistener.length; - } - } - - return 0; -} - -EventEmitter.prototype.eventNames = function eventNames() { - return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; -}; - -function arrayClone(arr, n) { - var copy = new Array(n); - for (var i = 0; i < n; ++i) copy[i] = arr[i]; - return copy; -} - -function spliceOne(list, index) { - for (; index + 1 < list.length; index++) list[index] = list[index + 1]; - list.pop(); -} - -function unwrapListeners(arr) { - var ret = new Array(arr.length); - for (var i = 0; i < ret.length; ++i) { - ret[i] = arr[i].listener || arr[i]; - } - return ret; -} - -function once(emitter, name) { - return new Promise(function (resolve, reject) { - function errorListener(err) { - emitter.removeListener(name, resolver); - reject(err); - } - - function resolver() { - if (typeof emitter.removeListener === 'function') { - emitter.removeListener('error', errorListener); - } - resolve([].slice.call(arguments)); - } - - eventTargetAgnosticAddListener(emitter, name, resolver, { once: true }); - if (name !== 'error') { - addErrorHandlerIfEventEmitter(emitter, errorListener, { - once: true, - }); - } - }); -} - -function addErrorHandlerIfEventEmitter(emitter, handler, flags) { - if (typeof emitter.on === 'function') { - eventTargetAgnosticAddListener(emitter, 'error', handler, flags); - } -} - -function eventTargetAgnosticAddListener(emitter, name, listener, flags) { - if (typeof emitter.on === 'function') { - if (flags.once) { - emitter.once(name, listener); - } else { - emitter.on(name, listener); - } - } else if (typeof emitter.addEventListener === 'function') { - // EventTarget does not have `error` event semantics like Node - // EventEmitters, we do not listen for `error` events here. - emitter.addEventListener(name, function wrapListener(arg) { - // IE does not have builtin `{ once: true }` support so we - // have to do it manually. - if (flags.once) { - emitter.removeEventListener(name, wrapListener); - } - listener(arg); - }); - } else { - throw new TypeError( - 'The "emitter" argument must be of type EventEmitter. Received type ' + - typeof emitter - ); - } -} diff --git a/src/client/history.js b/src/client/history.js index 6e93ac5..64b258c 100644 --- a/src/client/history.js +++ b/src/client/history.js @@ -1,4 +1,4 @@ -import EventEmitter from './events.js'; +import EventEmitter from 'events'; import HookEvent from './hook.js'; class History extends EventEmitter { diff --git a/src/client/index.js b/src/client/index.js index 1cf71d1..8c26906 100644 --- a/src/client/index.js +++ b/src/client/index.js @@ -13,7 +13,7 @@ import MessageApi from './message.js'; import NavigatorApi from './navigator.js'; import Workers from './worker.js'; import URLApi from './url.js'; -import EventEmitter from './events.js'; +import EventEmitter from 'events'; import StorageApi from './storage.js'; import StyleApi from './dom/style.js'; diff --git a/src/client/location.js b/src/client/location.js index bdc10b6..d7483e3 100644 --- a/src/client/location.js +++ b/src/client/location.js @@ -1,4 +1,4 @@ -import EventEmitter from './events.js'; +import EventEmitter from 'events'; class LocationApi extends EventEmitter { constructor(ctx) { diff --git a/src/client/message.js b/src/client/message.js index 08d7243..ccba1ad 100644 --- a/src/client/message.js +++ b/src/client/message.js @@ -1,4 +1,4 @@ -import EventEmitter from './events.js'; +import EventEmitter from 'events'; import HookEvent from './hook.js'; class MessageApi extends EventEmitter { diff --git a/src/client/native/function.js b/src/client/native/function.js index 7e350bb..b090548 100644 --- a/src/client/native/function.js +++ b/src/client/native/function.js @@ -1,4 +1,4 @@ -import EventEmitter from '../events.js'; +import EventEmitter from 'events'; import HookEvent from '../hook.js'; class FunctionHook extends EventEmitter { diff --git a/src/client/native/object.js b/src/client/native/object.js index e94bd33..ad9e499 100644 --- a/src/client/native/object.js +++ b/src/client/native/object.js @@ -1,4 +1,4 @@ -import EventEmitter from '../events.js'; +import EventEmitter from 'events'; import HookEvent from '../hook.js'; class ObjectHook extends EventEmitter { diff --git a/src/client/navigator.js b/src/client/navigator.js index 77a3f1d..7dfa80e 100644 --- a/src/client/navigator.js +++ b/src/client/navigator.js @@ -1,4 +1,4 @@ -import EventEmitter from './events.js'; +import EventEmitter from 'events'; import HookEvent from './hook.js'; class NavigatorApi extends EventEmitter { diff --git a/src/client/requests/eventsource.js b/src/client/requests/eventsource.js index bf3d009..5437712 100644 --- a/src/client/requests/eventsource.js +++ b/src/client/requests/eventsource.js @@ -1,4 +1,4 @@ -import EventEmitter from '../events.js'; +import EventEmitter from 'events'; import HookEvent from '../hook.js'; class EventSourceApi extends EventEmitter { diff --git a/src/client/requests/fetch.js b/src/client/requests/fetch.js index c2b20c6..3a99fb3 100644 --- a/src/client/requests/fetch.js +++ b/src/client/requests/fetch.js @@ -1,4 +1,4 @@ -import EventEmitter from '../events.js'; +import EventEmitter from 'events'; import HookEvent from '../hook.js'; class Fetch extends EventEmitter { diff --git a/src/client/requests/xhr.js b/src/client/requests/xhr.js index 66638e0..256eaa6 100644 --- a/src/client/requests/xhr.js +++ b/src/client/requests/xhr.js @@ -1,4 +1,4 @@ -import EventEmitter from '../events.js'; +import EventEmitter from 'events'; import HookEvent from '../hook.js'; class Xhr extends EventEmitter { diff --git a/src/client/storage.js b/src/client/storage.js index feea283..05b2cda 100644 --- a/src/client/storage.js +++ b/src/client/storage.js @@ -1,4 +1,4 @@ -import EventEmitter from './events.js'; +import EventEmitter from 'events'; import HookEvent from './hook.js'; class StorageApi extends EventEmitter { diff --git a/src/client/url.js b/src/client/url.js index 16f1482..f569ee6 100644 --- a/src/client/url.js +++ b/src/client/url.js @@ -1,4 +1,4 @@ -import EventEmitter from './events.js'; +import EventEmitter from 'events'; import HookEvent from './hook.js'; class URLApi extends EventEmitter { diff --git a/src/client/worker.js b/src/client/worker.js index 340acbf..b72e236 100644 --- a/src/client/worker.js +++ b/src/client/worker.js @@ -1,4 +1,4 @@ -import EventEmitter from './events.js'; +import EventEmitter from 'events'; import HookEvent from './hook.js'; class Workers extends EventEmitter { diff --git a/src/rewrite/css.js b/src/rewrite/css.js index 3fd669d..7d0f5ee 100644 --- a/src/rewrite/css.js +++ b/src/rewrite/css.js @@ -1,5 +1,5 @@ import { parse, walk, generate } from 'css-tree'; -import EventEmitter from './events.js'; +import EventEmitter from 'events'; import parsel from './parsel.js'; class CSS extends EventEmitter { diff --git a/src/rewrite/events.js b/src/rewrite/events.js deleted file mode 100644 index 196b9e4..0000000 --- a/src/rewrite/events.js +++ /dev/null @@ -1,522 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; - -var R = typeof Reflect === 'object' ? Reflect : null; -var ReflectApply = - R && typeof R.apply === 'function' - ? R.apply - : function ReflectApply(target, receiver, args) { - return Function.prototype.apply.call(target, receiver, args); - }; - -var ReflectOwnKeys; -if (R && typeof R.ownKeys === 'function') { - ReflectOwnKeys = R.ownKeys; -} else if (Object.getOwnPropertySymbols) { - ReflectOwnKeys = function ReflectOwnKeys(target) { - return Object.getOwnPropertyNames(target).concat( - Object.getOwnPropertySymbols(target) - ); - }; -} else { - ReflectOwnKeys = function ReflectOwnKeys(target) { - return Object.getOwnPropertyNames(target); - }; -} - -function ProcessEmitWarning(warning) { - if (console && console.warn) console.warn(warning); -} - -var NumberIsNaN = - Number.isNaN || - function NumberIsNaN(value) { - return value !== value; - }; - -function EventEmitter() { - EventEmitter.init.call(this); -} - -export default EventEmitter; - -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; - -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._eventsCount = 0; -EventEmitter.prototype._maxListeners = undefined; - -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -var defaultMaxListeners = 10; - -function checkListener(listener) { - if (typeof listener !== 'function') { - throw new TypeError( - 'The "listener" argument must be of type Function. Received type ' + - typeof listener - ); - } -} - -Object.defineProperty(EventEmitter, 'defaultMaxListeners', { - enumerable: true, - get: function () { - return defaultMaxListeners; - }, - set: function (arg) { - if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) { - throw new RangeError( - 'The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + - arg + - '.' - ); - } - defaultMaxListeners = arg; - }, -}); - -EventEmitter.init = function () { - if ( - this._events === undefined || - this._events === Object.getPrototypeOf(this)._events - ) { - this._events = Object.create(null); - this._eventsCount = 0; - } - - this._maxListeners = this._maxListeners || undefined; -}; - -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { - if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) { - throw new RangeError( - 'The value of "n" is out of range. It must be a non-negative number. Received ' + - n + - '.' - ); - } - this._maxListeners = n; - return this; -}; - -function _getMaxListeners(that) { - if (that._maxListeners === undefined) - return EventEmitter.defaultMaxListeners; - return that._maxListeners; -} - -EventEmitter.prototype.getMaxListeners = function getMaxListeners() { - return _getMaxListeners(this); -}; - -EventEmitter.prototype.emit = function emit(type) { - var args = []; - for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); - var doError = type === 'error'; - - var events = this._events; - if (events !== undefined) doError = doError && events.error === undefined; - else if (!doError) return false; - - // If there is no 'error' event listener then throw. - if (doError) { - var er; - if (args.length > 0) er = args[0]; - if (er instanceof Error) { - // Note: The comments on the `throw` lines are intentional, they show - // up in Node's output if this results in an unhandled exception. - throw er; // Unhandled 'error' event - } - // At least give some kind of context to the user - var err = new Error( - 'Unhandled error.' + (er ? ' (' + er.message + ')' : '') - ); - err.context = er; - throw err; // Unhandled 'error' event - } - - var handler = events[type]; - - if (handler === undefined) return false; - - if (typeof handler === 'function') { - ReflectApply(handler, this, args); - } else { - var len = handler.length; - var listeners = arrayClone(handler, len); - for (var i = 0; i < len; ++i) ReflectApply(listeners[i], this, args); - } - - return true; -}; - -function _addListener(target, type, listener, prepend) { - var m; - var events; - var existing; - - checkListener(listener); - - events = target._events; - if (events === undefined) { - events = target._events = Object.create(null); - target._eventsCount = 0; - } else { - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (events.newListener !== undefined) { - target.emit( - 'newListener', - type, - listener.listener ? listener.listener : listener - ); - - // Re-assign `events` because a newListener handler could have caused the - // this._events to be assigned to a new object - events = target._events; - } - existing = events[type]; - } - - if (existing === undefined) { - // Optimize the case of one listener. Don't need the extra array object. - existing = events[type] = listener; - ++target._eventsCount; - } else { - if (typeof existing === 'function') { - // Adding the second element, need to change to array. - existing = events[type] = prepend - ? [listener, existing] - : [existing, listener]; - // If we've already got an array, just append. - } else if (prepend) { - existing.unshift(listener); - } else { - existing.push(listener); - } - - // Check for listener leak - m = _getMaxListeners(target); - if (m > 0 && existing.length > m && !existing.warned) { - existing.warned = true; - // No error code for this since it is a Warning - // eslint-disable-next-line no-restricted-syntax - var w = new Error( - 'Possible EventEmitter memory leak detected. ' + - existing.length + - ' ' + - String(type) + - ' listeners ' + - 'added. Use emitter.setMaxListeners() to ' + - 'increase limit' - ); - w.name = 'MaxListenersExceededWarning'; - w.emitter = target; - w.type = type; - w.count = existing.length; - ProcessEmitWarning(w); - } - } - - return target; -} - -EventEmitter.prototype.addListener = function addListener(type, listener) { - return _addListener(this, type, listener, false); -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.prependListener = function prependListener( - type, - listener -) { - return _addListener(this, type, listener, true); -}; - -function onceWrapper() { - if (!this.fired) { - this.target.removeListener(this.type, this.wrapFn); - this.fired = true; - if (arguments.length === 0) return this.listener.call(this.target); - return this.listener.apply(this.target, arguments); - } -} - -function _onceWrap(target, type, listener) { - var state = { - fired: false, - wrapFn: undefined, - target: target, - type: type, - listener: listener, - }; - var wrapped = onceWrapper.bind(state); - wrapped.listener = listener; - state.wrapFn = wrapped; - return wrapped; -} - -EventEmitter.prototype.once = function once(type, listener) { - checkListener(listener); - this.on(type, _onceWrap(this, type, listener)); - return this; -}; - -EventEmitter.prototype.prependOnceListener = function prependOnceListener( - type, - listener -) { - checkListener(listener); - this.prependListener(type, _onceWrap(this, type, listener)); - return this; -}; - -// Emits a 'removeListener' event if and only if the listener was removed. -EventEmitter.prototype.removeListener = function removeListener( - type, - listener -) { - var list, events, position, i, originalListener; - - checkListener(listener); - - events = this._events; - if (events === undefined) return this; - - list = events[type]; - if (list === undefined) return this; - - if (list === listener || list.listener === listener) { - if (--this._eventsCount === 0) this._events = Object.create(null); - else { - delete events[type]; - if (events.removeListener) - this.emit('removeListener', type, list.listener || listener); - } - } else if (typeof list !== 'function') { - position = -1; - - for (i = list.length - 1; i >= 0; i--) { - if (list[i] === listener || list[i].listener === listener) { - originalListener = list[i].listener; - position = i; - break; - } - } - - if (position < 0) return this; - - if (position === 0) list.shift(); - else { - spliceOne(list, position); - } - - if (list.length === 1) events[type] = list[0]; - - if (events.removeListener !== undefined) - this.emit('removeListener', type, originalListener || listener); - } - - return this; -}; - -EventEmitter.prototype.off = EventEmitter.prototype.removeListener; - -EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) { - var listeners, events, i; - - events = this._events; - if (events === undefined) return this; - - // not listening for removeListener, no need to emit - if (events.removeListener === undefined) { - if (arguments.length === 0) { - this._events = Object.create(null); - this._eventsCount = 0; - } else if (events[type] !== undefined) { - if (--this._eventsCount === 0) this._events = Object.create(null); - else delete events[type]; - } - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - var keys = Object.keys(events); - var key; - for (i = 0; i < keys.length; ++i) { - key = keys[i]; - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = Object.create(null); - this._eventsCount = 0; - return this; - } - - listeners = events[type]; - - if (typeof listeners === 'function') { - this.removeListener(type, listeners); - } else if (listeners !== undefined) { - // LIFO order - for (i = listeners.length - 1; i >= 0; i--) { - this.removeListener(type, listeners[i]); - } - } - - return this; -}; - -function _listeners(target, type, unwrap) { - var events = target._events; - - if (events === undefined) return []; - - var evlistener = events[type]; - if (evlistener === undefined) return []; - - if (typeof evlistener === 'function') - return unwrap ? [evlistener.listener || evlistener] : [evlistener]; - - return unwrap - ? unwrapListeners(evlistener) - : arrayClone(evlistener, evlistener.length); -} - -EventEmitter.prototype.listeners = function listeners(type) { - return _listeners(this, type, true); -}; - -EventEmitter.prototype.rawListeners = function rawListeners(type) { - return _listeners(this, type, false); -}; - -EventEmitter.listenerCount = function (emitter, type) { - if (typeof emitter.listenerCount === 'function') { - return emitter.listenerCount(type); - } else { - return listenerCount.call(emitter, type); - } -}; - -EventEmitter.prototype.listenerCount = listenerCount; -function listenerCount(type) { - var events = this._events; - - if (events !== undefined) { - var evlistener = events[type]; - - if (typeof evlistener === 'function') { - return 1; - } else if (evlistener !== undefined) { - return evlistener.length; - } - } - - return 0; -} - -EventEmitter.prototype.eventNames = function eventNames() { - return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; -}; - -function arrayClone(arr, n) { - var copy = new Array(n); - for (var i = 0; i < n; ++i) copy[i] = arr[i]; - return copy; -} - -function spliceOne(list, index) { - for (; index + 1 < list.length; index++) list[index] = list[index + 1]; - list.pop(); -} - -function unwrapListeners(arr) { - var ret = new Array(arr.length); - for (var i = 0; i < ret.length; ++i) { - ret[i] = arr[i].listener || arr[i]; - } - return ret; -} - -function once(emitter, name) { - return new Promise(function (resolve, reject) { - function errorListener(err) { - emitter.removeListener(name, resolver); - reject(err); - } - - function resolver() { - if (typeof emitter.removeListener === 'function') { - emitter.removeListener('error', errorListener); - } - resolve([].slice.call(arguments)); - } - - eventTargetAgnosticAddListener(emitter, name, resolver, { once: true }); - if (name !== 'error') { - addErrorHandlerIfEventEmitter(emitter, errorListener, { - once: true, - }); - } - }); -} - -function addErrorHandlerIfEventEmitter(emitter, handler, flags) { - if (typeof emitter.on === 'function') { - eventTargetAgnosticAddListener(emitter, 'error', handler, flags); - } -} - -function eventTargetAgnosticAddListener(emitter, name, listener, flags) { - if (typeof emitter.on === 'function') { - if (flags.once) { - emitter.once(name, listener); - } else { - emitter.on(name, listener); - } - } else if (typeof emitter.addEventListener === 'function') { - // EventTarget does not have `error` event semantics like Node - // EventEmitters, we do not listen for `error` events here. - emitter.addEventListener(name, function wrapListener(arg) { - // IE does not have builtin `{ once: true }` support so we - // have to do it manually. - if (flags.once) { - emitter.removeEventListener(name, wrapListener); - } - listener(arg); - }); - } else { - throw new TypeError( - 'The "emitter" argument must be of type EventEmitter. Received type ' + - typeof emitter - ); - } -} diff --git a/src/rewrite/html.js b/src/rewrite/html.js index 035bf80..183cf42 100644 --- a/src/rewrite/html.js +++ b/src/rewrite/html.js @@ -1,4 +1,4 @@ -import EventEmitter from './events.js'; +import EventEmitter from 'events'; import { parse, parseFragment, serialize } from 'parse5'; class HTML extends EventEmitter { diff --git a/src/rewrite/index.js b/src/rewrite/index.js index 117aca0..7d4a05e 100644 --- a/src/rewrite/index.js +++ b/src/rewrite/index.js @@ -37,6 +37,7 @@ import parsel from './parsel.js'; import UVClient from '../client/index.js'; import Bowser from 'bowser'; import BareClient from '@tomphttp/bare-client'; +import EventEmitter from 'events'; const valid_chars = "!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~"; @@ -214,6 +215,7 @@ class Ultraviolet { static openDB = openDB; static Bowser = Bowser; static BareClient = BareClient; + static EventEmitter = EventEmitter; } export default Ultraviolet; diff --git a/src/rewrite/js.js b/src/rewrite/js.js index 188ec23..2189cef 100644 --- a/src/rewrite/js.js +++ b/src/rewrite/js.js @@ -1,7 +1,7 @@ import { parseScript } from 'meriyah'; // import { parse } from 'acorn-hammerhead'; import { generate } from 'esotope-hammerhead'; -import EventEmitter from './events.js'; +import EventEmitter from 'events'; class JS extends EventEmitter { constructor() { diff --git a/src/uv.sw.js b/src/uv.sw.js index d14803d..540f2ed 100644 --- a/src/uv.sw.js +++ b/src/uv.sw.js @@ -31,7 +31,7 @@ const cspHeaders = [ const emptyMethods = ['GET', 'HEAD']; const emptyStatus = [204, 304]; -class UVServiceWorker extends EventEmitter { +class UVServiceWorker extends Ultraviolet.EventEmitter { constructor(config = __uv$config) { super(); if (!config.bare) config.bare = '/bare/'; @@ -344,501 +344,3 @@ class HookEvent { this.#intercepted = true; } } - -var R = typeof Reflect === 'object' ? Reflect : null; -var ReflectApply = - R && typeof R.apply === 'function' - ? R.apply - : function ReflectApply(target, receiver, args) { - return Function.prototype.apply.call(target, receiver, args); - }; - -var ReflectOwnKeys; -if (R && typeof R.ownKeys === 'function') { - ReflectOwnKeys = R.ownKeys; -} else if (Object.getOwnPropertySymbols) { - ReflectOwnKeys = function ReflectOwnKeys(target) { - return Object.getOwnPropertyNames(target).concat( - Object.getOwnPropertySymbols(target) - ); - }; -} else { - ReflectOwnKeys = function ReflectOwnKeys(target) { - return Object.getOwnPropertyNames(target); - }; -} - -function ProcessEmitWarning(warning) { - if (console && console.warn) console.warn(warning); -} - -var NumberIsNaN = - Number.isNaN || - function NumberIsNaN(value) { - return value !== value; - }; - -function EventEmitter() { - EventEmitter.init.call(this); -} - -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; - -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._eventsCount = 0; -EventEmitter.prototype._maxListeners = undefined; - -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -var defaultMaxListeners = 10; - -function checkListener(listener) { - if (typeof listener !== 'function') { - throw new TypeError( - 'The "listener" argument must be of type Function. Received type ' + - typeof listener - ); - } -} - -Object.defineProperty(EventEmitter, 'defaultMaxListeners', { - enumerable: true, - get: function () { - return defaultMaxListeners; - }, - set: function (arg) { - if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) { - throw new RangeError( - 'The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + - arg + - '.' - ); - } - defaultMaxListeners = arg; - }, -}); - -EventEmitter.init = function () { - if ( - this._events === undefined || - this._events === Object.getPrototypeOf(this)._events - ) { - this._events = Object.create(null); - this._eventsCount = 0; - } - - this._maxListeners = this._maxListeners || undefined; -}; - -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { - if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) { - throw new RangeError( - 'The value of "n" is out of range. It must be a non-negative number. Received ' + - n + - '.' - ); - } - this._maxListeners = n; - return this; -}; - -function _getMaxListeners(that) { - if (that._maxListeners === undefined) - return EventEmitter.defaultMaxListeners; - return that._maxListeners; -} - -EventEmitter.prototype.getMaxListeners = function getMaxListeners() { - return _getMaxListeners(this); -}; - -EventEmitter.prototype.emit = function emit(type) { - var args = []; - for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); - var doError = type === 'error'; - - var events = this._events; - if (events !== undefined) doError = doError && events.error === undefined; - else if (!doError) return false; - - // If there is no 'error' event listener then throw. - if (doError) { - var er; - if (args.length > 0) er = args[0]; - if (er instanceof Error) { - // Note: The comments on the `throw` lines are intentional, they show - // up in Node's output if this results in an unhandled exception. - throw er; // Unhandled 'error' event - } - // At least give some kind of context to the user - var err = new Error( - 'Unhandled error.' + (er ? ' (' + er.message + ')' : '') - ); - err.context = er; - throw err; // Unhandled 'error' event - } - - var handler = events[type]; - - if (handler === undefined) return false; - - if (typeof handler === 'function') { - ReflectApply(handler, this, args); - } else { - var len = handler.length; - var listeners = arrayClone(handler, len); - for (var i = 0; i < len; ++i) ReflectApply(listeners[i], this, args); - } - - return true; -}; - -function _addListener(target, type, listener, prepend) { - var m; - var events; - var existing; - - checkListener(listener); - - events = target._events; - if (events === undefined) { - events = target._events = Object.create(null); - target._eventsCount = 0; - } else { - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (events.newListener !== undefined) { - target.emit( - 'newListener', - type, - listener.listener ? listener.listener : listener - ); - - // Re-assign `events` because a newListener handler could have caused the - // this._events to be assigned to a new object - events = target._events; - } - existing = events[type]; - } - - if (existing === undefined) { - // Optimize the case of one listener. Don't need the extra array object. - existing = events[type] = listener; - ++target._eventsCount; - } else { - if (typeof existing === 'function') { - // Adding the second element, need to change to array. - existing = events[type] = prepend - ? [listener, existing] - : [existing, listener]; - // If we've already got an array, just append. - } else if (prepend) { - existing.unshift(listener); - } else { - existing.push(listener); - } - - // Check for listener leak - m = _getMaxListeners(target); - if (m > 0 && existing.length > m && !existing.warned) { - existing.warned = true; - // No error code for this since it is a Warning - // eslint-disable-next-line no-restricted-syntax - var w = new Error( - 'Possible EventEmitter memory leak detected. ' + - existing.length + - ' ' + - String(type) + - ' listeners ' + - 'added. Use emitter.setMaxListeners() to ' + - 'increase limit' - ); - w.name = 'MaxListenersExceededWarning'; - w.emitter = target; - w.type = type; - w.count = existing.length; - ProcessEmitWarning(w); - } - } - - return target; -} - -EventEmitter.prototype.addListener = function addListener(type, listener) { - return _addListener(this, type, listener, false); -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.prependListener = function prependListener( - type, - listener -) { - return _addListener(this, type, listener, true); -}; - -function onceWrapper() { - if (!this.fired) { - this.target.removeListener(this.type, this.wrapFn); - this.fired = true; - if (arguments.length === 0) return this.listener.call(this.target); - return this.listener.apply(this.target, arguments); - } -} - -function _onceWrap(target, type, listener) { - var state = { - fired: false, - wrapFn: undefined, - target: target, - type: type, - listener: listener, - }; - var wrapped = onceWrapper.bind(state); - wrapped.listener = listener; - state.wrapFn = wrapped; - return wrapped; -} - -EventEmitter.prototype.once = function once(type, listener) { - checkListener(listener); - this.on(type, _onceWrap(this, type, listener)); - return this; -}; - -EventEmitter.prototype.prependOnceListener = function prependOnceListener( - type, - listener -) { - checkListener(listener); - this.prependListener(type, _onceWrap(this, type, listener)); - return this; -}; - -// Emits a 'removeListener' event if and only if the listener was removed. -EventEmitter.prototype.removeListener = function removeListener( - type, - listener -) { - var list, events, position, i, originalListener; - - checkListener(listener); - - events = this._events; - if (events === undefined) return this; - - list = events[type]; - if (list === undefined) return this; - - if (list === listener || list.listener === listener) { - if (--this._eventsCount === 0) this._events = Object.create(null); - else { - delete events[type]; - if (events.removeListener) - this.emit('removeListener', type, list.listener || listener); - } - } else if (typeof list !== 'function') { - position = -1; - - for (i = list.length - 1; i >= 0; i--) { - if (list[i] === listener || list[i].listener === listener) { - originalListener = list[i].listener; - position = i; - break; - } - } - - if (position < 0) return this; - - if (position === 0) list.shift(); - else { - spliceOne(list, position); - } - - if (list.length === 1) events[type] = list[0]; - - if (events.removeListener !== undefined) - this.emit('removeListener', type, originalListener || listener); - } - - return this; -}; - -EventEmitter.prototype.off = EventEmitter.prototype.removeListener; - -EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) { - var listeners, events, i; - - events = this._events; - if (events === undefined) return this; - - // not listening for removeListener, no need to emit - if (events.removeListener === undefined) { - if (arguments.length === 0) { - this._events = Object.create(null); - this._eventsCount = 0; - } else if (events[type] !== undefined) { - if (--this._eventsCount === 0) this._events = Object.create(null); - else delete events[type]; - } - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - var keys = Object.keys(events); - var key; - for (i = 0; i < keys.length; ++i) { - key = keys[i]; - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = Object.create(null); - this._eventsCount = 0; - return this; - } - - listeners = events[type]; - - if (typeof listeners === 'function') { - this.removeListener(type, listeners); - } else if (listeners !== undefined) { - // LIFO order - for (i = listeners.length - 1; i >= 0; i--) { - this.removeListener(type, listeners[i]); - } - } - - return this; -}; - -function _listeners(target, type, unwrap) { - var events = target._events; - - if (events === undefined) return []; - - var evlistener = events[type]; - if (evlistener === undefined) return []; - - if (typeof evlistener === 'function') - return unwrap ? [evlistener.listener || evlistener] : [evlistener]; - - return unwrap - ? unwrapListeners(evlistener) - : arrayClone(evlistener, evlistener.length); -} - -EventEmitter.prototype.listeners = function listeners(type) { - return _listeners(this, type, true); -}; - -EventEmitter.prototype.rawListeners = function rawListeners(type) { - return _listeners(this, type, false); -}; - -EventEmitter.listenerCount = function (emitter, type) { - if (typeof emitter.listenerCount === 'function') { - return emitter.listenerCount(type); - } else { - return listenerCount.call(emitter, type); - } -}; - -EventEmitter.prototype.listenerCount = listenerCount; -function listenerCount(type) { - var events = this._events; - - if (events !== undefined) { - var evlistener = events[type]; - - if (typeof evlistener === 'function') { - return 1; - } else if (evlistener !== undefined) { - return evlistener.length; - } - } - - return 0; -} - -EventEmitter.prototype.eventNames = function eventNames() { - return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; -}; - -function arrayClone(arr, n) { - var copy = new Array(n); - for (var i = 0; i < n; ++i) copy[i] = arr[i]; - return copy; -} - -function spliceOne(list, index) { - for (; index + 1 < list.length; index++) list[index] = list[index + 1]; - list.pop(); -} - -function unwrapListeners(arr) { - var ret = new Array(arr.length); - for (var i = 0; i < ret.length; ++i) { - ret[i] = arr[i].listener || arr[i]; - } - return ret; -} - -function once(emitter, name) { - return new Promise(function (resolve, reject) { - function errorListener(err) { - emitter.removeListener(name, resolver); - reject(err); - } - - function resolver() { - if (typeof emitter.removeListener === 'function') { - emitter.removeListener('error', errorListener); - } - resolve([].slice.call(arguments)); - } - - eventTargetAgnosticAddListener(emitter, name, resolver, { once: true }); - if (name !== 'error') { - addErrorHandlerIfEventEmitter(emitter, errorListener, { - once: true, - }); - } - }); -} - -function addErrorHandlerIfEventEmitter(emitter, handler, flags) { - if (typeof emitter.on === 'function') { - eventTargetAgnosticAddListener(emitter, 'error', handler, flags); - } -} - -function eventTargetAgnosticAddListener(emitter, name, listener, flags) { - if (typeof emitter.on === 'function') { - if (flags.once) { - emitter.once(name, listener); - } else { - emitter.on(name, listener); - } - } else if (typeof emitter.addEventListener === 'function') { - // EventTarget does not have `error` event semantics like Node - // EventEmitters, we do not listen for `error` events here. - emitter.addEventListener(name, function wrapListener(arg) { - // IE does not have builtin `{ once: true }` support so we - // have to do it manually. - if (flags.once) { - emitter.removeEventListener(name, wrapListener); - } - listener(arg); - }); - } else { - throw new TypeError( - 'The "emitter" argument must be of type EventEmitter. Received type ' + - typeof emitter - ); - } -}