aboutsummaryrefslogtreecommitdiff
path: root/packages/idb-bridge/src/util/FakeEventTarget.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/idb-bridge/src/util/FakeEventTarget.ts')
-rw-r--r--packages/idb-bridge/src/util/FakeEventTarget.ts262
1 files changed, 135 insertions, 127 deletions
diff --git a/packages/idb-bridge/src/util/FakeEventTarget.ts b/packages/idb-bridge/src/util/FakeEventTarget.ts
index 3c7eaf468..f20432df0 100644
--- a/packages/idb-bridge/src/util/FakeEventTarget.ts
+++ b/packages/idb-bridge/src/util/FakeEventTarget.ts
@@ -14,164 +14,172 @@
permissions and limitations under the License.
*/
-
import { InvalidStateError } from "./errors";
import FakeEvent from "./FakeEvent";
import { EventCallback, EventType } from "./types";
type EventTypeProp =
- | "onabort"
- | "onblocked"
- | "oncomplete"
- | "onerror"
- | "onsuccess"
- | "onupgradeneeded"
- | "onversionchange";
+ | "onabort"
+ | "onblocked"
+ | "oncomplete"
+ | "onerror"
+ | "onsuccess"
+ | "onupgradeneeded"
+ | "onversionchange";
interface Listener {
- callback: EventCallback;
- capture: boolean;
- type: EventType;
+ callback: EventCallback;
+ capture: boolean;
+ type: EventType;
}
const stopped = (event: FakeEvent, listener: Listener) => {
- return (
- event.immediatePropagationStopped ||
- (event.eventPhase === event.CAPTURING_PHASE &&
- listener.capture === false) ||
- (event.eventPhase === event.BUBBLING_PHASE && listener.capture === true)
- );
+ return (
+ event.immediatePropagationStopped ||
+ (event.eventPhase === event.CAPTURING_PHASE &&
+ listener.capture === false) ||
+ (event.eventPhase === event.BUBBLING_PHASE && listener.capture === true)
+ );
};
// http://www.w3.org/TR/dom/#concept-event-listener-invoke
const invokeEventListeners = (event: FakeEvent, obj: FakeEventTarget) => {
- event.currentTarget = obj;
-
- // The callback might cause obj.listeners to mutate as we traverse it.
- // Take a copy of the array so that nothing sneaks in and we don't lose
- // our place.
- for (const listener of obj.listeners.slice()) {
- if (event.type !== listener.type || stopped(event, listener)) {
- continue;
- }
-
- // @ts-ignore
- listener.callback.call(event.currentTarget, event);
+ event.currentTarget = obj;
+
+ // The callback might cause obj.listeners to mutate as we traverse it.
+ // Take a copy of the array so that nothing sneaks in and we don't lose
+ // our place.
+ for (const listener of obj.listeners.slice()) {
+ if (event.type !== listener.type || stopped(event, listener)) {
+ continue;
}
- const typeToProp: { [key in EventType]: EventTypeProp } = {
- abort: "onabort",
- blocked: "onblocked",
- complete: "oncomplete",
- error: "onerror",
- success: "onsuccess",
- upgradeneeded: "onupgradeneeded",
- versionchange: "onversionchange",
+ console.log(`invoking ${event.type} event listener`, listener);
+ // @ts-ignore
+ listener.callback.call(event.currentTarget, event);
+ }
+
+ const typeToProp: { [key in EventType]: EventTypeProp } = {
+ abort: "onabort",
+ blocked: "onblocked",
+ complete: "oncomplete",
+ error: "onerror",
+ success: "onsuccess",
+ upgradeneeded: "onupgradeneeded",
+ versionchange: "onversionchange",
+ };
+ const prop = typeToProp[event.type];
+ if (prop === undefined) {
+ throw new Error(`Unknown event type: "${event.type}"`);
+ }
+
+ const callback = event.currentTarget[prop];
+ if (callback) {
+ const listener = {
+ callback,
+ capture: false,
+ type: event.type,
};
- const prop = typeToProp[event.type];
- if (prop === undefined) {
- throw new Error(`Unknown event type: "${event.type}"`);
- }
-
- const callback = event.currentTarget[prop];
- if (callback) {
- const listener = {
- callback,
- capture: false,
- type: event.type,
- };
- if (!stopped(event, listener)) {
- // @ts-ignore
- listener.callback.call(event.currentTarget, event);
- }
+ if (!stopped(event, listener)) {
+ console.log(`invoking on${event.type} event listener`, listener);
+ // @ts-ignore
+ listener.callback.call(event.currentTarget, event);
}
+ }
};
abstract class FakeEventTarget {
- public readonly listeners: Listener[] = [];
-
- // These will be overridden in individual subclasses and made not readonly
- public readonly onabort: EventCallback | null | undefined;
- public readonly onblocked: EventCallback | null | undefined;
- public readonly oncomplete: EventCallback | null | undefined;
- public readonly onerror: EventCallback | null | undefined;
- public readonly onsuccess: EventCallback | null | undefined;
- public readonly onupgradeneeded: EventCallback | null | undefined;
- public readonly onversionchange: EventCallback | null | undefined;
-
- public addEventListener(
- type: EventType,
- callback: EventCallback,
- capture = false,
- ) {
- this.listeners.push({
- callback,
- capture,
- type,
- });
- }
-
- public removeEventListener(
- type: EventType,
- callback: EventCallback,
- capture = false,
- ) {
- const i = this.listeners.findIndex(listener => {
- return (
- listener.type === type &&
- listener.callback === callback &&
- listener.capture === capture
- );
- });
-
- this.listeners.splice(i, 1);
+ public readonly listeners: Listener[] = [];
+
+ // These will be overridden in individual subclasses and made not readonly
+ public readonly onabort: EventCallback | null | undefined;
+ public readonly onblocked: EventCallback | null | undefined;
+ public readonly oncomplete: EventCallback | null | undefined;
+ public readonly onerror: EventCallback | null | undefined;
+ public readonly onsuccess: EventCallback | null | undefined;
+ public readonly onupgradeneeded: EventCallback | null | undefined;
+ public readonly onversionchange: EventCallback | null | undefined;
+
+ static enableTracing: boolean = true;
+
+ public addEventListener(
+ type: EventType,
+ callback: EventCallback,
+ capture = false,
+ ) {
+ this.listeners.push({
+ callback,
+ capture,
+ type,
+ });
+ }
+
+ public removeEventListener(
+ type: EventType,
+ callback: EventCallback,
+ capture = false,
+ ) {
+ const i = this.listeners.findIndex(listener => {
+ return (
+ listener.type === type &&
+ listener.callback === callback &&
+ listener.capture === capture
+ );
+ });
+
+ this.listeners.splice(i, 1);
+ }
+
+ // http://www.w3.org/TR/dom/#dispatching-events
+ public dispatchEvent(event: FakeEvent) {
+ if (event.dispatched || !event.initialized) {
+ throw new InvalidStateError("The object is in an invalid state.");
}
+ event.isTrusted = false;
- // http://www.w3.org/TR/dom/#dispatching-events
- public dispatchEvent(event: FakeEvent) {
- if (event.dispatched || !event.initialized) {
- throw new InvalidStateError("The object is in an invalid state.");
- }
- event.isTrusted = false;
+ event.dispatched = true;
+ event.target = this;
+ // NOT SURE WHEN THIS SHOULD BE SET event.eventPath = [];
- event.dispatched = true;
- event.target = this;
- // NOT SURE WHEN THIS SHOULD BE SET event.eventPath = [];
+ event.eventPhase = event.CAPTURING_PHASE;
+ if (FakeEventTarget.enableTracing) {
+ console.log(
+ `dispatching '${event.type}' event along path with ${event.eventPath.length} elements`,
+ );
+ }
+ for (const obj of event.eventPath) {
+ if (!event.propagationStopped) {
+ invokeEventListeners(event, obj);
+ }
+ }
- event.eventPhase = event.CAPTURING_PHASE;
- for (const obj of event.eventPath) {
- if (!event.propagationStopped) {
- invokeEventListeners(event, obj);
- }
- }
+ event.eventPhase = event.AT_TARGET;
+ if (!event.propagationStopped) {
+ invokeEventListeners(event, event.target);
+ }
- event.eventPhase = event.AT_TARGET;
+ if (event.bubbles) {
+ event.eventPath.reverse();
+ event.eventPhase = event.BUBBLING_PHASE;
+ if (event.eventPath.length === 0 && event.type === "error") {
+ console.error("Unhandled error event: ", event.target);
+ }
+ for (const obj of event.eventPath) {
if (!event.propagationStopped) {
- invokeEventListeners(event, event.target);
- }
-
- if (event.bubbles) {
- event.eventPath.reverse();
- event.eventPhase = event.BUBBLING_PHASE;
- if (event.eventPath.length === 0 && event.type === "error") {
- console.error("Unhandled error event: ", event.target);
- }
- for (const obj of event.eventPath) {
- if (!event.propagationStopped) {
- invokeEventListeners(event, obj);
- }
- }
+ invokeEventListeners(event, obj);
}
+ }
+ }
- event.dispatched = false;
- event.eventPhase = event.NONE;
- event.currentTarget = null;
+ event.dispatched = false;
+ event.eventPhase = event.NONE;
+ event.currentTarget = null;
- if (event.canceled) {
- return false;
- }
- return true;
+ if (event.canceled) {
+ return false;
}
+ return true;
+ }
}
export default FakeEventTarget;