From 568a4428baac8681cb6edea089cceafa38774c17 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Tue, 2 Dec 2025 22:19:58 +0800 Subject: [PATCH] custom element registry 'whenDefine' function --- src/browser/polyfill/polyfill.zig | 3 ++ .../tests/custom_elements/registry.html | 38 +++++++++++++++++++ src/browser/webapi/CustomElementRegistry.zig | 25 ++++++++++++ 3 files changed, 66 insertions(+) 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");