mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-15 15:58:57 +00:00
custom element registry 'whenDefine' function
This commit is contained in:
@@ -61,8 +61,11 @@ pub const Loader = struct {
|
||||
|
||||
.{ "litNonce", {} },
|
||||
.{ "litHtmlVersions", {} },
|
||||
.{ "litElementVersions", {} },
|
||||
.{ "litHtmlPolyfillSupport", {} },
|
||||
.{ "litElementHydrateSupport", {} },
|
||||
.{ "litElementPolyfillSupport", {} },
|
||||
.{ "reactiveElementVersions", {} },
|
||||
|
||||
.{ "recaptcha", {} },
|
||||
.{ "grecaptcha", {} },
|
||||
|
||||
@@ -81,3 +81,41 @@
|
||||
testing.expectEqual('NO-HYPHEN-INVALID', el.tagName);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="whenDefined_already_defined">
|
||||
{
|
||||
class AlreadyDefined extends HTMLElement {}
|
||||
customElements.define('already-defined', AlreadyDefined);
|
||||
|
||||
const promise = customElements.whenDefined('already-defined');
|
||||
testing.expectEqual('object', typeof promise);
|
||||
testing.expectEqual(true, promise instanceof Promise);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="whenDefined_not_yet_defined">
|
||||
{
|
||||
const promise = customElements.whenDefined('future-element');
|
||||
testing.expectEqual('object', typeof promise);
|
||||
testing.expectEqual(true, promise instanceof Promise);
|
||||
|
||||
// Now define it
|
||||
class FutureElement extends HTMLElement {}
|
||||
customElements.define('future-element', FutureElement);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="whenDefined_same_promise">
|
||||
{
|
||||
const promise1 = customElements.whenDefined('pending-element');
|
||||
const promise2 = customElements.whenDefined('pending-element');
|
||||
|
||||
// Should return the same promise for the same name
|
||||
testing.expectEqual(true, promise1 === promise2);
|
||||
|
||||
// Define it so cleanup happens
|
||||
class PendingElement extends HTMLElement {}
|
||||
customElements.define('pending-element', PendingElement);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user