From f0fbd49a2d1f506f2e59a089b32cbfe960a999fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Sun, 4 Jul 2021 16:43:21 +0200 Subject: [PATCH] refactor: use primordials in extensions/web/02_event.js (#11264) --- extensions/web/02_event.js | 144 ++++++++++++++++++++++++------------- 1 file changed, 93 insertions(+), 51 deletions(-) diff --git a/extensions/web/02_event.js b/extensions/web/02_event.js index 3fed3127ec..4ae8b50f2a 100644 --- a/extensions/web/02_event.js +++ b/extensions/web/02_event.js @@ -9,6 +9,36 @@ ((window) => { const webidl = window.__bootstrap.webidl; const { DOMException } = window.__bootstrap.domException; + const { + ArrayPrototypeFilter, + ArrayPrototypeIncludes, + ArrayPrototypeIndexOf, + ArrayPrototypeMap, + ArrayPrototypePush, + ArrayPrototypeSlice, + ArrayPrototypeSplice, + ArrayPrototypeUnshift, + Boolean, + DateNow, + Error, + FunctionPrototypeCall, + Map, + MapPrototypeGet, + MapPrototypeSet, + ObjectCreate, + ObjectDefineProperty, + ObjectGetOwnPropertyDescriptor, + Proxy, + ReflectDefineProperty, + ReflectGet, + ReflectGetOwnPropertyDescriptor, + Symbol, + SymbolFor, + SymbolToStringTag, + WeakMap, + WeakMapPrototypeGet, + WeakMapPrototypeSet, + } = window.__bootstrap.primordials; // accessors for non runtime visible data @@ -77,7 +107,7 @@ return "relatedTarget" in event; } - const isTrusted = Object.getOwnPropertyDescriptor({ + const isTrusted = ObjectGetOwnPropertyDescriptor({ get isTrusted() { return this[_isTrusted]; }, @@ -136,15 +166,15 @@ currentTarget: null, eventPhase: Event.NONE, target: null, - timeStamp: Date.now(), + timeStamp: DateNow(), }; - Reflect.defineProperty(this, "isTrusted", { + ReflectDefineProperty(this, "isTrusted", { enumerable: true, get: isTrusted, }); } - [Symbol.for("Deno.privateCustomInspect")](inspect) { + [SymbolFor("Deno.privateCustomInspect")](inspect) { return inspect(buildFilteredPropertyInspectObject(this, EVENT_PROPS)); } @@ -220,7 +250,7 @@ } if (currentHiddenLevel <= maxHiddenLevel) { - composedPath.unshift({ + ArrayPrototypeUnshift(composedPath, { item, itemInShadowTree: false, relatedTarget: null, @@ -251,7 +281,7 @@ } if (currentHiddenLevel <= maxHiddenLevel) { - composedPath.push({ + ArrayPrototypePush(composedPath, { item, itemInShadowTree: false, relatedTarget: null, @@ -270,7 +300,7 @@ } } } - return composedPath.map((p) => p.item); + return ArrayPrototypeMap(composedPath, (p) => p.item); } get NONE() { @@ -373,22 +403,22 @@ // in the inspect code return new Proxy({}, { get(_target, key) { - if (key === Symbol.toStringTag) { + if (key === SymbolToStringTag) { return object.constructor?.name; - } else if (keys.includes(key)) { - return Reflect.get(object, key); + } else if (ArrayPrototypeIncludes(keys, key)) { + return ReflectGet(object, key); } else { return undefined; } }, getOwnPropertyDescriptor(_target, key) { - if (!keys.includes(key)) { + if (!ArrayPrototypeIncludes(keys, key)) { return undefined; } - return Reflect.getOwnPropertyDescriptor(object, key) ?? + return ReflectGetOwnPropertyDescriptor(object, key) ?? (object.prototype && - Reflect.getOwnPropertyDescriptor(object.prototype, key)) ?? + ReflectGetOwnPropertyDescriptor(object.prototype, key)) ?? { configurable: true, enumerable: true, @@ -396,7 +426,7 @@ }; }, has(_target, key) { - return keys.includes(key); + return ArrayPrototypeIncludes(keys, key); }, ownKeys() { return keys; @@ -409,7 +439,7 @@ props, ) { for (const prop of props) { - Reflect.defineProperty(Ctor.prototype, prop, { enumerable: true }); + ReflectDefineProperty(Ctor.prototype, prop, { enumerable: true }); } } @@ -508,7 +538,7 @@ const rootOfClosedTree = isShadowRoot(target) && getMode(target) === "closed"; - getPath(eventImpl).push({ + ArrayPrototypePush(getPath(eventImpl), { item: target, itemInShadowTree, target: targetOverride, @@ -705,7 +735,7 @@ } // Copy event listeners before iterating since the list can be modified during the iteration. - const handlers = targetListeners[type].slice(); + const handlers = ArrayPrototypeSlice(targetListeners[type]); for (let i = 0; i < handlers.length; i++) { const listener = handlers[i]; @@ -722,7 +752,7 @@ } // Check if the event listener has been removed since the listeners has been cloned. - if (!targetListeners[type].includes(listener)) { + if (!ArrayPrototypeIncludes(targetListeners[type], listener)) { continue; } @@ -736,8 +766,9 @@ } if (once) { - targetListeners[type].splice( - targetListeners[type].indexOf(listener), + ArrayPrototypeSplice( + targetListeners[type], + ArrayPrototypeIndexOf(targetListeners[type], listener), 1, ); } @@ -751,7 +782,11 @@ listener.callback.handleEvent(eventImpl); } } else { - listener.callback.call(eventImpl.currentTarget, eventImpl); + FunctionPrototypeCall( + listener.callback, + eventImpl.currentTarget, + eventImpl, + ); } setInPassiveListener(eventImpl, false); @@ -769,7 +804,7 @@ * Ref: https://dom.spec.whatwg.org/#concept-event-listener-invoke */ function invokeEventListeners(tuple, eventImpl) { const path = getPath(eventImpl); - const tupleIndex = path.indexOf(tuple); + const tupleIndex = ArrayPrototypeIndexOf(path, tuple); for (let i = tupleIndex; i >= 0; i--) { const t = path[i]; if (t.target) { @@ -844,29 +879,29 @@ const eventTargetData = new WeakMap(); function setEventTargetData(value) { - eventTargetData.set(value, getDefaultTargetData()); + WeakMapPrototypeSet(eventTargetData, value, getDefaultTargetData()); } function getAssignedSlot(target) { - return Boolean(eventTargetData.get(target)?.assignedSlot); + return Boolean(WeakMapPrototypeGet(eventTargetData, target)?.assignedSlot); } function getHasActivationBehavior(target) { return Boolean( - eventTargetData.get(target)?.hasActivationBehavior, + WeakMapPrototypeGet(eventTargetData, target)?.hasActivationBehavior, ); } function getHost(target) { - return eventTargetData.get(target)?.host ?? null; + return WeakMapPrototypeGet(eventTargetData, target)?.host ?? null; } function getListeners(target) { - return eventTargetData.get(target)?.listeners ?? {}; + return WeakMapPrototypeGet(eventTargetData, target)?.listeners ?? {}; } function getMode(target) { - return eventTargetData.get(target)?.mode ?? null; + return WeakMapPrototypeGet(eventTargetData, target)?.mode ?? null; } function getDefaultTargetData() { @@ -874,14 +909,14 @@ assignedSlot: false, hasActivationBehavior: false, host: null, - listeners: Object.create(null), + listeners: ObjectCreate(null), mode: "", }; } class EventTarget { constructor() { - eventTargetData.set(this, getDefaultTargetData()); + WeakMapPrototypeSet(eventTargetData, this, getDefaultTargetData()); } addEventListener( @@ -897,7 +932,10 @@ } options = normalizeAddEventHandlerOptions(options); - const { listeners } = eventTargetData.get(this ?? globalThis); + const { listeners } = WeakMapPrototypeGet( + eventTargetData, + this ?? globalThis, + ); if (!(type in listeners)) { listeners[type] = []; @@ -927,7 +965,7 @@ }); } } - listeners[type].push({ callback, options }); + ArrayPrototypePush(listeners[type], { callback, options }); } removeEventListener( @@ -939,9 +977,11 @@ prefix: "Failed to execute 'removeEventListener' on 'EventTarget'", }); - const listeners = eventTargetData.get(this ?? globalThis).listeners; + const listeners = + WeakMapPrototypeGet(eventTargetData, this ?? globalThis).listeners; if (callback !== null && type in listeners) { - listeners[type] = listeners[type].filter( + listeners[type] = ArrayPrototypeFilter( + listeners[type], (listener) => listener.callback !== callback, ); } else if (callback === null || !listeners[type]) { @@ -959,7 +999,7 @@ listener.options.capture === options.capture)) && listener.callback === callback ) { - listeners[type].splice(i, 1); + ArrayPrototypeSplice(listeners[type], i, 1); break; } } @@ -971,7 +1011,7 @@ }); const self = this ?? globalThis; - const listeners = eventTargetData.get(self).listeners; + const listeners = WeakMapPrototypeGet(eventTargetData, self).listeners; if (!(event.type in listeners)) { setTarget(event, this); return true; @@ -988,7 +1028,7 @@ return dispatch(self, event); } - get [Symbol.toStringTag]() { + get [SymbolToStringTag]() { return "EventTarget"; } @@ -1052,11 +1092,11 @@ this.#error = error; } - get [Symbol.toStringTag]() { + get [SymbolToStringTag]() { return "ErrorEvent"; } - [Symbol.for("Deno.privateCustomInspect")](inspect) { + [SymbolFor("Deno.privateCustomInspect")](inspect) { return inspect(buildFilteredPropertyInspectObject(this, [ ...EVENT_PROPS, "message", @@ -1110,7 +1150,7 @@ this.#reason = reason; } - [Symbol.for("Deno.privateCustomInspect")](inspect) { + [SymbolFor("Deno.privateCustomInspect")](inspect) { return inspect(buildFilteredPropertyInspectObject(this, [ ...EVENT_PROPS, "wasClean", @@ -1138,7 +1178,7 @@ this.lastEventId = eventInitDict?.lastEventId ?? ""; } - [Symbol.for("Deno.privateCustomInspect")](inspect) { + [SymbolFor("Deno.privateCustomInspect")](inspect) { return inspect(buildFilteredPropertyInspectObject(this, [ ...EVENT_PROPS, "data", @@ -1164,11 +1204,11 @@ return this.#detail; } - get [Symbol.toStringTag]() { + get [SymbolToStringTag]() { return "CustomEvent"; } - [Symbol.for("Deno.privateCustomInspect")](inspect) { + [SymbolFor("Deno.privateCustomInspect")](inspect) { return inspect(buildFilteredPropertyInspectObject(this, [ ...EVENT_PROPS, "detail", @@ -1176,7 +1216,7 @@ } } - Reflect.defineProperty(CustomEvent.prototype, "detail", { + ReflectDefineProperty(CustomEvent.prototype, "detail", { enumerable: true, }); @@ -1191,7 +1231,7 @@ this.total = eventInitDict?.total ?? 0; } - [Symbol.for("Deno.privateCustomInspect")](inspect) { + [SymbolFor("Deno.privateCustomInspect")](inspect) { return inspect(buildFilteredPropertyInspectObject(this, [ ...EVENT_PROPS, "lengthComputable", @@ -1208,7 +1248,7 @@ if (typeof wrappedHandler.handler !== "function") { return; } - return wrappedHandler.handler.call(this, ...args); + return FunctionPrototypeCall(wrappedHandler.handler, this, ...args); } wrappedHandler.handler = handler; return wrappedHandler; @@ -1217,24 +1257,26 @@ // TODO(benjamingr) reuse this here and websocket where possible function defineEventHandler(emitter, name, init) { // HTML specification section 8.1.5.1 - Object.defineProperty(emitter, `on${name}`, { + ObjectDefineProperty(emitter, `on${name}`, { get() { - return this[_eventHandlers]?.get(name)?.handler; + const map = this[_eventHandlers]; + + if (!map) return undefined; + return MapPrototypeGet(map, name)?.handler; }, set(value) { if (!this[_eventHandlers]) { this[_eventHandlers] = new Map(); } - let handlerWrapper = this[_eventHandlers]?.get(name); + let handlerWrapper = MapPrototypeGet(this[_eventHandlers], name); if (handlerWrapper) { - console.log("foo"); handlerWrapper.handler = value; } else { handlerWrapper = makeWrappedHandler(value); this.addEventListener(name, handlerWrapper); init?.(this); } - this[_eventHandlers].set(name, handlerWrapper); + MapPrototypeSet(this[_eventHandlers], name, handlerWrapper); }, configurable: true, enumerable: true,