diff --git a/src/browser/tests/element/html/select-optgroup.html b/src/browser/tests/element/html/select-optgroup.html
new file mode 100644
index 000000000..3fcfe0f2f
--- /dev/null
+++ b/src/browser/tests/element/html/select-optgroup.html
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/browser/webapi/collections/HTMLCollection.zig b/src/browser/webapi/collections/HTMLCollection.zig
index 4311623d2..57969c406 100644
--- a/src/browser/webapi/collections/HTMLCollection.zig
+++ b/src/browser/webapi/collections/HTMLCollection.zig
@@ -36,6 +36,7 @@ const Mode = enum {
child_elements,
child_tag,
cells,
+ select_options,
selected_options,
links,
anchors,
@@ -54,6 +55,7 @@ _data: union(Mode) {
child_elements: NodeLive(.child_elements),
child_tag: NodeLive(.child_tag),
cells: NodeLive(.cells),
+ select_options: NodeLive(.select_options),
selected_options: NodeLive(.selected_options),
links: NodeLive(.links),
anchors: NodeLive(.anchors),
@@ -111,6 +113,7 @@ pub fn iterator(self: *HTMLCollection, exec: *const Execution) !*Iterator {
.child_elements => |*impl| .{ .child_elements = impl._tw.clone() },
.child_tag => |*impl| .{ .child_tag = impl._tw.clone() },
.cells => |*impl| .{ .cells = impl._tw.clone() },
+ .select_options => |*impl| .{ .select_options = impl._tw.clone() },
.selected_options => |*impl| .{ .selected_options = impl._tw.clone() },
.links => |*impl| .{ .links = impl._tw.clone() },
.anchors => |*impl| .{ .anchors = impl._tw.clone() },
@@ -132,7 +135,8 @@ pub const Iterator = GenericIterator(struct {
child_elements: TreeWalker.Children,
child_tag: TreeWalker.Children,
cells: TreeWalker.Children,
- selected_options: TreeWalker.Children,
+ select_options: TreeWalker.FullExcludeSelf,
+ selected_options: TreeWalker.FullExcludeSelf,
links: TreeWalker.FullExcludeSelf,
anchors: TreeWalker.FullExcludeSelf,
form: TreeWalker.FullExcludeSelf,
@@ -157,6 +161,7 @@ pub const Iterator = GenericIterator(struct {
.child_elements => |*impl| impl.nextTw(&self.tw.child_elements),
.child_tag => |*impl| impl.nextTw(&self.tw.child_tag),
.cells => |*impl| impl.nextTw(&self.tw.cells),
+ .select_options => |*impl| impl.nextTw(&self.tw.select_options),
.selected_options => |*impl| impl.nextTw(&self.tw.selected_options),
.links => |*impl| impl.nextTw(&self.tw.links),
.anchors => |*impl| impl.nextTw(&self.tw.anchors),
diff --git a/src/browser/webapi/collections/node_live.zig b/src/browser/webapi/collections/node_live.zig
index 221075eb6..36c919732 100644
--- a/src/browser/webapi/collections/node_live.zig
+++ b/src/browser/webapi/collections/node_live.zig
@@ -40,6 +40,7 @@ const Mode = enum {
child_elements,
child_tag,
cells,
+ select_options,
selected_options,
links,
anchors,
@@ -68,6 +69,7 @@ const Filters = union(Mode) {
child_elements,
child_tag: Element.Tag,
cells,
+ select_options,
selected_options,
links,
anchors,
@@ -100,7 +102,10 @@ pub fn NodeLive(comptime mode: Mode) type {
const Filter = Filters.TypeOf(mode);
const TW = switch (mode) {
.tag, .tag_name, .tag_name_ns, .class_name, .name, .all_elements, .links, .anchors, .form => TreeWalker.FullExcludeSelf,
- .child_elements, .child_tag, .cells, .selected_options => TreeWalker.Children,
+ .child_elements, .child_tag, .cells => TreeWalker.Children,
+ // A select's options can sit one level down, inside an