diff --git a/src/browser/Frame.zig b/src/browser/Frame.zig index e6b25894d..80957de4f 100644 --- a/src/browser/Frame.zig +++ b/src/browser/Frame.zig @@ -145,6 +145,7 @@ _element_computed_styles: Element.ComputedStyleLookup = .empty, _element_datasets: Element.DatasetLookup = .empty, _element_class_lists: Element.ClassListLookup = .empty, _element_rel_lists: Element.RelListLookup = .empty, +_element_part_lists: Element.PartListLookup = .empty, _element_token_lists: Element.TokenListLookup = .empty, _element_shadow_roots: Element.ShadowRootLookup = .empty, _node_owner_documents: Node.OwnerDocumentLookup = .empty, diff --git a/src/browser/tests/custom_elements/registry.html b/src/browser/tests/custom_elements/registry.html index 2d0f5dc0c..7bc89a551 100644 --- a/src/browser/tests/custom_elements/registry.html +++ b/src/browser/tests/custom_elements/registry.html @@ -149,3 +149,12 @@ testing.expectEqual(1, constructorCalled); } + + diff --git a/src/browser/tests/element/part.html b/src/browser/tests/element/part.html new file mode 100644 index 000000000..262540c2c --- /dev/null +++ b/src/browser/tests/element/part.html @@ -0,0 +1,24 @@ + + + +
+ + + diff --git a/src/browser/tests/net/headers.html b/src/browser/tests/net/headers.html index 057ec603e..37279c349 100644 --- a/src/browser/tests/net/headers.html +++ b/src/browser/tests/net/headers.html @@ -364,3 +364,19 @@ testing.expectEqual(1, authEntries.length); } + + diff --git a/src/browser/webapi/CustomElementRegistry.zig b/src/browser/webapi/CustomElementRegistry.zig index 36ab863e0..b963cf04a 100644 --- a/src/browser/webapi/CustomElementRegistry.zig +++ b/src/browser/webapi/CustomElementRegistry.zig @@ -137,6 +137,16 @@ pub fn get(self: *CustomElementRegistry, name: []const u8) ?js.Function.Global { return definition.constructor; } +pub fn getName(self: *CustomElementRegistry, constructor: js.Function) ?[]const u8 { + var it = self._definitions.iterator(); + while (it.next()) |entry| { + if (entry.value_ptr.*.constructor.isEqual(constructor)) { + return entry.key_ptr.*; + } + } + return null; +} + pub fn upgrade(self: *CustomElementRegistry, root: *Node, frame: *Frame) !void { try upgradeNode(self, root, frame); } @@ -319,6 +329,7 @@ pub const JsApi = struct { pub const define = bridge.function(CustomElementRegistry.define, .{ .ce_reactions = true }); pub const get = bridge.function(CustomElementRegistry.get, .{ .null_as_undefined = true }); + pub const getName = bridge.function(CustomElementRegistry.getName, .{}); pub const upgrade = bridge.function(CustomElementRegistry.upgrade, .{ .ce_reactions = true }); pub const whenDefined = bridge.function(CustomElementRegistry.whenDefined, .{}); }; diff --git a/src/browser/webapi/Element.zig b/src/browser/webapi/Element.zig index 50a1ad790..2fd4424c5 100644 --- a/src/browser/webapi/Element.zig +++ b/src/browser/webapi/Element.zig @@ -79,6 +79,7 @@ pub const PseudoElement = enum { pub const ClassListLookup = std.AutoHashMapUnmanaged(*Element, *collections.DOMTokenList); pub const RelListLookup = std.AutoHashMapUnmanaged(*Element, *collections.DOMTokenList); +pub const PartListLookup = std.AutoHashMapUnmanaged(*Element, *collections.DOMTokenList); pub const ShadowRootLookup = std.AutoHashMapUnmanaged(*Element, *ShadowRoot); pub const NamespaceUriLookup = std.AutoHashMapUnmanaged(*Element, []const u8); @@ -1026,6 +1027,17 @@ pub fn setClassList(self: *Element, value: String, frame: *Frame) !void { try class_list.setValue(value, frame); } +pub fn getPartList(self: *Element, frame: *Frame) !*collections.DOMTokenList { + const gop = try frame._element_part_lists.getOrPut(frame.arena, self); + if (!gop.found_existing) { + gop.value_ptr.* = try frame._factory.create(collections.DOMTokenList{ + ._element = self, + ._attribute_name = comptime .wrap("part"), + }); + } + return gop.value_ptr.*; +} + pub fn getRelList(self: *Element, frame: *Frame) !*collections.DOMTokenList { const gop = try frame._element_rel_lists.getOrPut(frame.arena, self); if (!gop.found_existing) { @@ -2431,6 +2443,7 @@ pub const JsApi = struct { pub const dir = bridge.accessor(Element.getDir, Element.setDir, .{ .ce_reactions = true }); pub const className = bridge.accessor(Element.getClassName, Element.setClassName, .{ .ce_reactions = true }); pub const classList = bridge.accessor(Element.getClassList, Element.setClassList, .{ .ce_reactions = true }); + pub const part = bridge.accessor(Element.getPartList, null, .{}); pub const dataset = bridge.accessor(Element.getDataset, null, .{}); pub const style = bridge.accessor(Element.getOrCreateStyle, Element.setStyle, .{}); pub const attributes = bridge.accessor(Element.getAttributeNamedNodeMap, null, .{}); diff --git a/src/browser/webapi/net/Headers.zig b/src/browser/webapi/net/Headers.zig index dd293c99a..d628e96e5 100644 --- a/src/browser/webapi/net/Headers.zig +++ b/src/browser/webapi/net/Headers.zig @@ -65,6 +65,10 @@ pub fn get(self: *const Headers, name: []const u8, exec: *const Execution) !?[]c return try std.mem.join(exec.local_arena, ", ", all_values); } +pub fn getSetCookie(self: *const Headers, exec: *const Execution) ![]const []const u8 { + return self._list.getAll(exec.local_arena, "set-cookie"); +} + pub fn has(self: *const Headers, name: []const u8, exec: *const Execution) bool { const normalized_name = normalizeHeaderName(name, exec.buf); return self._list.has(normalized_name, null); @@ -143,6 +147,7 @@ pub const JsApi = struct { pub const append = bridge.function(Headers.append, .{}); pub const delete = bridge.function(Headers.delete, .{}); pub const get = bridge.function(Headers.get, .{}); + pub const getSetCookie = bridge.function(Headers.getSetCookie, .{}); pub const has = bridge.function(Headers.has, .{}); pub const set = bridge.function(Headers.set, .{}); pub const keys = bridge.function(Headers.keys, .{});