diff --git a/src/browser/polyfill/polyfill.zig b/src/browser/polyfill/polyfill.zig
index c14c75a2..bf6f9227 100644
--- a/src/browser/polyfill/polyfill.zig
+++ b/src/browser/polyfill/polyfill.zig
@@ -61,8 +61,11 @@ pub const Loader = struct {
.{ "litNonce", {} },
.{ "litHtmlVersions", {} },
+ .{ "litElementVersions", {} },
.{ "litHtmlPolyfillSupport", {} },
.{ "litElementHydrateSupport", {} },
+ .{ "litElementPolyfillSupport", {} },
+ .{ "reactiveElementVersions", {} },
.{ "recaptcha", {} },
.{ "grecaptcha", {} },
diff --git a/src/browser/tests/custom_elements/registry.html b/src/browser/tests/custom_elements/registry.html
index 8ead6ae2..064aa9f9 100644
--- a/src/browser/tests/custom_elements/registry.html
+++ b/src/browser/tests/custom_elements/registry.html
@@ -81,3 +81,41 @@
testing.expectEqual('NO-HYPHEN-INVALID', el.tagName);
}
+
+
+
+
+
+
+
diff --git a/src/browser/webapi/CustomElementRegistry.zig b/src/browser/webapi/CustomElementRegistry.zig
index 2f8a912c..727e74ed 100644
--- a/src/browser/webapi/CustomElementRegistry.zig
+++ b/src/browser/webapi/CustomElementRegistry.zig
@@ -30,6 +30,7 @@ const CustomElementDefinition = @import("CustomElementDefinition.zig");
const CustomElementRegistry = @This();
_definitions: std.StringHashMapUnmanaged(*CustomElementDefinition) = .{},
+_when_defined: std.StringHashMapUnmanaged(js.PersistentPromiseResolver) = .{},
const DefineOptions = struct {
extends: ?[]const u8 = null,
@@ -103,6 +104,10 @@ pub fn define(self: *CustomElementRegistry, name: []const u8, constructor: js.Fu
_ = page._undefined_custom_elements.swapRemove(idx);
}
+
+ if (self._when_defined.fetchRemove(name)) |entry| {
+ try entry.value.resolve(constructor);
+ }
}
pub fn get(self: *CustomElementRegistry, name: []const u8) ?js.Function {
@@ -114,6 +119,25 @@ pub fn upgrade(self: *CustomElementRegistry, root: *Node, page: *Page) !void {
try upgradeNode(self, root, page);
}
+pub fn whenDefined(self: *CustomElementRegistry, name: []const u8, page: *Page) !js.Promise {
+ if (self._definitions.get(name)) |definition| {
+ return page.js.resolvePromise(definition.constructor);
+ }
+
+ const gop = try self._when_defined.getOrPut(page.arena, name);
+ if (gop.found_existing) {
+ return gop.value_ptr.promise();
+ }
+ errdefer _ = self._when_defined.remove(name);
+ const owned_name = try page.dupeString(name);
+
+ const resolver = try page.js.createPromiseResolver(.page);
+ gop.key_ptr.* = owned_name;
+ gop.value_ptr.* = resolver;
+
+ return resolver.promise();
+}
+
fn upgradeNode(self: *CustomElementRegistry, node: *Node, page: *Page) !void {
if (node.is(Element)) |element| {
try upgradeElement(self, element, page);
@@ -222,6 +246,7 @@ pub const JsApi = struct {
pub const define = bridge.function(CustomElementRegistry.define, .{ .dom_exception = true });
pub const get = bridge.function(CustomElementRegistry.get, .{ .null_as_undefined = true });
pub const upgrade = bridge.function(CustomElementRegistry.upgrade, .{});
+ pub const whenDefined = bridge.function(CustomElementRegistry.whenDefined, .{});
};
const testing = @import("../../testing.zig");