diff --git a/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.cpp b/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.cpp
index c5e0ea656e4..20a552439ad 100644
--- a/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.cpp
+++ b/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.cpp
@@ -326,7 +326,7 @@ JS::ThrowCompletionOr CustomElementRegistry::define(String const& name, We
}
// https://html.spec.whatwg.org/multipage/custom-elements.html#dom-customelementregistry-get
-Variant, JS::Value> CustomElementRegistry::get(String const& name) const
+Variant, Empty> CustomElementRegistry::get(String const& name) const
{
// 1. If this's custom element definition set contains an item with name name, then return that item's constructor.
auto existing_definition_iterator = m_custom_element_definitions.find_if([&name](auto const& definition) {
@@ -337,7 +337,7 @@ Variant, JS::Value> CustomElementRegistry::get(St
return GC::make_root((*existing_definition_iterator)->constructor());
// 2. Return undefined.
- return JS::js_undefined();
+ return Empty {};
}
// https://html.spec.whatwg.org/multipage/custom-elements.html#dom-customelementregistry-getname
diff --git a/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.h b/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.h
index 464229ba79d..c9ab78b35ca 100644
--- a/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.h
+++ b/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.h
@@ -25,7 +25,7 @@ public:
virtual ~CustomElementRegistry() override;
JS::ThrowCompletionOr define(String const& name, WebIDL::CallbackType* constructor, ElementDefinitionOptions options);
- Variant, JS::Value> get(String const& name) const;
+ Variant, Empty> get(String const& name) const;
Optional get_name(GC::Root const& constructor) const;
WebIDL::ExceptionOr> when_defined(String const& name);
void upgrade(GC::Ref root) const;
diff --git a/Libraries/LibWeb/HTML/Window.cpp b/Libraries/LibWeb/HTML/Window.cpp
index c5013fe60fc..850a5a8c80f 100644
--- a/Libraries/LibWeb/HTML/Window.cpp
+++ b/Libraries/LibWeb/HTML/Window.cpp
@@ -1199,12 +1199,12 @@ WebIDL::ExceptionOr Window::post_message(JS::Value message, String const&
}
// https://dom.spec.whatwg.org/#dom-window-event
-Variant, JS::Value> Window::event() const
+Variant, Empty> Window::event() const
{
// The event getter steps are to return this’s current event.
if (auto* current_event = this->current_event())
return make_root(const_cast(*current_event));
- return JS::js_undefined();
+ return Empty {};
}
// https://w3c.github.io/csswg-drafts/cssom/#dom-window-getcomputedstyle
diff --git a/Libraries/LibWeb/HTML/Window.h b/Libraries/LibWeb/HTML/Window.h
index 32d85912aa9..87f36ba038b 100644
--- a/Libraries/LibWeb/HTML/Window.h
+++ b/Libraries/LibWeb/HTML/Window.h
@@ -196,7 +196,7 @@ public:
WebIDL::ExceptionOr post_message(JS::Value message, String const&, Vector> const&);
WebIDL::ExceptionOr post_message(JS::Value message, WindowPostMessageOptions const&);
- Variant, JS::Value> event() const;
+ Variant, Empty> event() const;
[[nodiscard]] GC::Ref get_computed_style(DOM::Element&, Optional const& pseudo_element) const;
diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp
index 07332287523..d36203836cb 100644
--- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp
+++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp
@@ -231,9 +231,15 @@ CppType idl_type_name_to_cpp_type(Type const& type, Interface const& interface)
if (type.name() == "long" && !type.is_nullable())
return { .name = "WebIDL::Long", .sequence_storage_type = SequenceStorageType::Vector };
- if (type.name() == "any" || type.name() == "undefined")
+ if (type.name() == "any")
return { .name = "JS::Value", .sequence_storage_type = SequenceStorageType::RootVector };
+ // NOTE: undefined is a somewhat special case that may be used in a union to represent the javascript 'undefined' (and
+ // only ever js_undefined). Therefore, we say that the type is Empty here, so that a union of (T, undefined) is
+ // generated as Variant, which is then returned in the Variant's visit as undefined if it is Empty.
+ if (type.name() == "undefined")
+ return { .name = "Empty", .sequence_storage_type = SequenceStorageType::RootVector };
+
if (type.name() == "object")
return { .name = "GC::Root", .sequence_storage_type = SequenceStorageType::Vector };