diff --git a/src/browser/Page.zig b/src/browser/Page.zig
index bd8e859c..597860e5 100644
--- a/src/browser/Page.zig
+++ b/src/browser/Page.zig
@@ -1993,10 +1993,10 @@ pub fn createElementNS(self: *Page, namespace: Element.Namespace, name: []const
.{ ._proto = undefined, ._tag_name = String.init(undefined, "article", .{}) catch unreachable, ._tag = .article },
),
asUint("details") => return self.createHtmlElementT(
- Element.Html.Generic,
+ Element.Html.Details,
namespace,
attribute_iterator,
- .{ ._proto = undefined, ._tag_name = String.init(undefined, "details", .{}) catch unreachable, ._tag = .details },
+ .{ ._proto = undefined },
),
asUint("summary") => return self.createHtmlElementT(
Element.Html.Generic,
diff --git a/src/browser/js/bridge.zig b/src/browser/js/bridge.zig
index 8d1daba2..af4df968 100644
--- a/src/browser/js/bridge.zig
+++ b/src/browser/js/bridge.zig
@@ -767,6 +767,7 @@ pub const JsApis = flattenTypes(&.{
@import("../webapi/element/html/Custom.zig"),
@import("../webapi/element/html/Data.zig"),
@import("../webapi/element/html/DataList.zig"),
+ @import("../webapi/element/html/Details.zig"),
@import("../webapi/element/html/Dialog.zig"),
@import("../webapi/element/html/Directory.zig"),
@import("../webapi/element/html/DList.zig"),
diff --git a/src/browser/tests/element/html/details.html b/src/browser/tests/element/html/details.html
new file mode 100644
index 00000000..09d82cea
--- /dev/null
+++ b/src/browser/tests/element/html/details.html
@@ -0,0 +1,63 @@
+
+
+
+
+
+ Summary
+ Content
+
+
+ Open Summary
+ Content
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/browser/webapi/Element.zig b/src/browser/webapi/Element.zig
index 9424e355..b922eb4c 100644
--- a/src/browser/webapi/Element.zig
+++ b/src/browser/webapi/Element.zig
@@ -209,6 +209,7 @@ pub fn getTagNameLower(self: *const Element) []const u8 {
.custom => |e| e._tag_name.str(),
.data => "data",
.datalist => "datalist",
+ .details => "details",
.dialog => "dialog",
.directory => "dir",
.div => "div",
@@ -287,6 +288,7 @@ pub fn getTagNameSpec(self: *const Element, buf: []u8) []const u8 {
.custom => |e| upperTagName(&e._tag_name, buf),
.data => "DATA",
.datalist => "DATALIST",
+ .details => "DETAILS",
.dialog => "DIALOG",
.directory => "DIR",
.div => "DIV",
@@ -1385,6 +1387,7 @@ pub fn getTag(self: *const Element) Tag {
.custom => .custom,
.data => .data,
.datalist => .datalist,
+ .details => .details,
.dialog => .dialog,
.directory => .directory,
.iframe => .iframe,
diff --git a/src/browser/webapi/css/CSSStyleDeclaration.zig b/src/browser/webapi/css/CSSStyleDeclaration.zig
index 5f61c607..a8eb92e4 100644
--- a/src/browser/webapi/css/CSSStyleDeclaration.zig
+++ b/src/browser/webapi/css/CSSStyleDeclaration.zig
@@ -255,7 +255,7 @@ fn getDefaultDisplay(element: *const Element) []const u8 {
.html => |html| {
return switch (html._type) {
.anchor, .br, .span, .label, .time, .font, .mod, .quote => "inline",
- .body, .div, .dl, .p, .heading, .form, .button, .canvas, .dialog, .embed, .head, .html, .hr, .iframe, .img, .input, .li, .link, .meta, .ol, .option, .script, .select, .slot, .style, .template, .textarea, .title, .ul, .media, .area, .base, .datalist, .directory, .fieldset, .legend, .map, .meter, .object, .optgroup, .output, .param, .picture, .pre, .progress, .source, .table, .table_caption, .table_cell, .table_col, .table_row, .table_section, .track => "block",
+ .body, .div, .dl, .p, .heading, .form, .button, .canvas, .details, .dialog, .embed, .head, .html, .hr, .iframe, .img, .input, .li, .link, .meta, .ol, .option, .script, .select, .slot, .style, .template, .textarea, .title, .ul, .media, .area, .base, .datalist, .directory, .fieldset, .legend, .map, .meter, .object, .optgroup, .output, .param, .picture, .pre, .progress, .source, .table, .table_caption, .table_cell, .table_col, .table_row, .table_section, .track => "block",
.generic, .custom, .unknown, .data => blk: {
const tag = element.getTagNameLower();
if (isInlineTag(tag)) break :blk "inline";
diff --git a/src/browser/webapi/element/Html.zig b/src/browser/webapi/element/Html.zig
index a4e6484d..ea962c9e 100644
--- a/src/browser/webapi/element/Html.zig
+++ b/src/browser/webapi/element/Html.zig
@@ -39,6 +39,7 @@ pub const Canvas = @import("html/Canvas.zig");
pub const Custom = @import("html/Custom.zig");
pub const Data = @import("html/Data.zig");
pub const DataList = @import("html/DataList.zig");
+pub const Details = @import("html/Details.zig");
pub const Dialog = @import("html/Dialog.zig");
pub const Directory = @import("html/Directory.zig");
pub const Div = @import("html/Div.zig");
@@ -119,6 +120,7 @@ pub const Type = union(enum) {
custom: *Custom,
data: *Data,
datalist: *DataList,
+ details: *Details,
dialog: *Dialog,
directory: *Directory,
div: *Div,
diff --git a/src/browser/webapi/element/html/Details.zig b/src/browser/webapi/element/html/Details.zig
new file mode 100644
index 00000000..1cc00ae7
--- /dev/null
+++ b/src/browser/webapi/element/html/Details.zig
@@ -0,0 +1,58 @@
+const js = @import("../../../js/js.zig");
+const Page = @import("../../../Page.zig");
+
+const Node = @import("../../Node.zig");
+const Element = @import("../../Element.zig");
+const HtmlElement = @import("../Html.zig");
+
+const Details = @This();
+
+_proto: *HtmlElement,
+
+pub fn asElement(self: *Details) *Element {
+ return self._proto._proto;
+}
+pub fn asConstElement(self: *const Details) *const Element {
+ return self._proto._proto;
+}
+pub fn asNode(self: *Details) *Node {
+ return self.asElement().asNode();
+}
+
+pub fn getOpen(self: *const Details) bool {
+ return self.asConstElement().getAttributeSafe(comptime .wrap("open")) != null;
+}
+
+pub fn setOpen(self: *Details, open: bool, page: *Page) !void {
+ if (open) {
+ try self.asElement().setAttributeSafe(comptime .wrap("open"), .wrap(""), page);
+ } else {
+ try self.asElement().removeAttribute(comptime .wrap("open"), page);
+ }
+}
+
+pub fn getName(self: *const Details) []const u8 {
+ return self.asConstElement().getAttributeSafe(comptime .wrap("name")) orelse "";
+}
+
+pub fn setName(self: *Details, value: []const u8, page: *Page) !void {
+ try self.asElement().setAttributeSafe(comptime .wrap("name"), .wrap(value), page);
+}
+
+pub const JsApi = struct {
+ pub const bridge = js.Bridge(Details);
+
+ pub const Meta = struct {
+ pub const name = "HTMLDetailsElement";
+ pub const prototype_chain = bridge.prototypeChain();
+ pub var class_id: bridge.ClassId = undefined;
+ };
+
+ pub const open = bridge.accessor(Details.getOpen, Details.setOpen, .{});
+ pub const name = bridge.accessor(Details.getName, Details.setName, .{});
+};
+
+const testing = @import("../../../../testing.zig");
+test "WebApi: HTML.Details" {
+ try testing.htmlRunner("element/html/details.html", .{});
+}