Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions ext/fetch/27_eventsource.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const {
StringPrototypeStartsWith,
StringPrototypeToLowerCase,
SymbolFor,
ObjectDefineProperty,
SymbolToStringTag,
} = primordials;

const webidl = core.loadExtScript("ext:deno_webidl/00_webidl.js");
Expand Down Expand Up @@ -416,6 +418,13 @@ class EventSource extends EventTarget {
}

const EventSourcePrototype = EventSource.prototype;
ObjectDefineProperty(EventSourcePrototype, SymbolToStringTag, {
__proto__: null,
value: "EventSource",
writable: false,
enumerable: false,
configurable: true,
});

ObjectDefineProperties(EventSource, {
CONNECTING: {
Expand Down
9 changes: 9 additions & 0 deletions ext/web/01_broadcast_channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ const {
Symbol,
SymbolFor,
Uint8Array,
ObjectDefineProperty,
SymbolToStringTag,
} = primordials;

const webidl = core.loadExtScript("ext:deno_webidl/00_webidl.js");
Expand Down Expand Up @@ -223,6 +225,13 @@ class BroadcastChannel extends EventTarget {
defineEventHandler(BroadcastChannel.prototype, "message");
defineEventHandler(BroadcastChannel.prototype, "messageerror");
const BroadcastChannelPrototype = BroadcastChannel.prototype;
ObjectDefineProperty(BroadcastChannelPrototype, SymbolToStringTag, {
__proto__: null,
value: "BroadcastChannel",
writable: false,
enumerable: false,
configurable: true,
});

return { BroadcastChannel, refBroadcastChannel };
})();
47 changes: 42 additions & 5 deletions ext/web/02_event.js
Original file line number Diff line number Diff line change
Expand Up @@ -1223,10 +1223,16 @@ class ErrorEvent extends Event {
}

// TODO(lucacasonato): remove when this interface is spec aligned
[SymbolToStringTag] = "ErrorEvent";
}

const ErrorEventPrototype = ErrorEvent.prototype;
ObjectDefineProperty(ErrorEventPrototype, SymbolToStringTag, {
__proto__: null,
value: "ErrorEvent",
writable: false,
enumerable: false,
configurable: true,
});

defineEnumerableProps(ErrorEvent, [
"message",
Expand Down Expand Up @@ -1288,6 +1294,13 @@ class CloseEvent extends Event {
}

const CloseEventPrototype = CloseEvent.prototype;
ObjectDefineProperty(CloseEventPrototype, SymbolToStringTag, {
__proto__: null,
value: "CloseEvent",
writable: false,
enumerable: false,
configurable: true,
});

// Lazy reference to MessagePort.prototype - 13_message_port.js depends on
// this module, so the script can't be loaded at definition time without
Expand Down Expand Up @@ -1444,10 +1457,16 @@ class MessageEvent extends Event {
}

// TODO(lucacasonato): remove when this interface is spec aligned
[SymbolToStringTag] = "MessageEvent";
}

const MessageEventPrototype = MessageEvent.prototype;
ObjectDefineProperty(MessageEventPrototype, SymbolToStringTag, {
__proto__: null,
value: "MessageEvent",
writable: false,
enumerable: false,
configurable: true,
});

class CustomEvent extends Event {
#detail = null;
Expand Down Expand Up @@ -1482,10 +1501,16 @@ class CustomEvent extends Event {
}

// TODO(lucacasonato): remove when this interface is spec aligned
[SymbolToStringTag] = "CustomEvent";
}

const CustomEventPrototype = CustomEvent.prototype;
ObjectDefineProperty(CustomEventPrototype, SymbolToStringTag, {
__proto__: null,
value: "CustomEvent",
writable: false,
enumerable: false,
configurable: true,
});

ReflectDefineProperty(CustomEvent.prototype, "detail", {
__proto__: null,
Expand Down Expand Up @@ -1520,10 +1545,16 @@ class ProgressEvent extends Event {
}

// TODO(lucacasonato): remove when this interface is spec aligned
[SymbolToStringTag] = "ProgressEvent";
}

const ProgressEventPrototype = ProgressEvent.prototype;
ObjectDefineProperty(ProgressEventPrototype, SymbolToStringTag, {
__proto__: null,
value: "ProgressEvent",
writable: false,
enumerable: false,
configurable: true,
});

class PromiseRejectionEvent extends Event {
#promise = null;
Expand Down Expand Up @@ -1575,10 +1606,16 @@ class PromiseRejectionEvent extends Event {
}

// TODO(lucacasonato): remove when this interface is spec aligned
[SymbolToStringTag] = "PromiseRejectionEvent";
}

const PromiseRejectionEventPrototype = PromiseRejectionEvent.prototype;
ObjectDefineProperty(PromiseRejectionEventPrototype, SymbolToStringTag, {
__proto__: null,
value: "PromiseRejectionEvent",
writable: false,
enumerable: false,
configurable: true,
});

defineEnumerableProps(PromiseRejectionEvent, [
"promise",
Expand Down
9 changes: 8 additions & 1 deletion runtime/js/11_workers.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const {
SymbolFor,
SymbolIterator,
SymbolToStringTag,
ObjectDefineProperty,
} = primordials;

const EMPTY_OPTIONS = ObjectFreeze(ObjectSetPrototypeOf({}, null));
Expand Down Expand Up @@ -382,10 +383,16 @@ class Worker extends EventTarget {
);
}

[SymbolToStringTag] = "Worker";
}

const WorkerPrototype = Worker.prototype;
ObjectDefineProperty(WorkerPrototype, SymbolToStringTag, {
__proto__: null,
value: "Worker",
writable: false,
enumerable: false,
configurable: true,
});

defineEventHandler(Worker.prototype, "error");
defineEventHandler(Worker.prototype, "message");
Expand Down
9 changes: 9 additions & 0 deletions runtime/js/98_global_scope_window.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const {
SymbolFor,
StringPrototypeToUpperCase,
StringPrototypeSlice,
ObjectDefineProperty,
SymbolToStringTag,
} = primordials;

const location = core.loadExtScript("ext:deno_web/12_location.js");
Expand Down Expand Up @@ -203,6 +205,13 @@ ObjectDefineProperties(Navigator.prototype, {
},
});
const NavigatorPrototype = Navigator.prototype;
ObjectDefineProperty(NavigatorPrototype, SymbolToStringTag, {
__proto__: null,
value: "Navigator",
writable: false,
enumerable: false,
configurable: true,
});

const mainRuntimeGlobalProperties = {
Location: location.locationConstructorDescriptor,
Expand Down
48 changes: 48 additions & 0 deletions tests/unit/event_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,54 @@ Deno.test(function eventSubclassWithReadOnlyToStringTag() {
assertEquals(Object.hasOwn(event, Symbol.toStringTag), false);
});

Deno.test(function interfacePrototypesHaveToStringTag() {
const interfaces = [
BroadcastChannel,
CloseEvent,
CustomEvent,
ErrorEvent,
EventSource,
MessageEvent,
Navigator,
ProgressEvent,
PromiseRejectionEvent,
Worker,
];
for (const iface of interfaces) {
const descriptor = Object.getOwnPropertyDescriptor(
iface.prototype,
Symbol.toStringTag,
);
assertEquals(descriptor, {
value: iface.name,
writable: false,
enumerable: false,
configurable: true,
}, iface.name);
}

const event = new CustomEvent("test");
assertEquals(Object.hasOwn(event, Symbol.toStringTag), false);
assertEquals(
Object.prototype.toString.call(event),
"[object CustomEvent]",
);
assertEquals(
Object.prototype.toString.call(navigator),
"[object Navigator]",
);

class MyEvent extends CustomEvent<unknown> {
get [Symbol.toStringTag]() {
return "MyEvent";
}
}
assertEquals(
Object.prototype.toString.call(new MyEvent("test")),
"[object MyEvent]",
);
});

Deno.test(function eventComposedPathSuccess() {
const type = "click";
const event = new Event(type);
Expand Down