diff --git a/src/dom/document.zig b/src/dom/document.zig index 58845359..2524be9b 100644 --- a/src/dom/document.zig +++ b/src/dom/document.zig @@ -54,6 +54,11 @@ pub const Document = struct { const root = parser.documentGetDocumentElement(self); return collection.HTMLCollectionByTagName(parser.elementToNode(root), tag_name); } + + pub fn _getElementsByClassName(self: *parser.Document, classNames: []const u8) !collection.HTMLCollection { + const root = parser.documentGetDocumentElement(self); + return collection.HTMLCollectionByClassName(parser.elementToNode(root), classNames); + } }; // Tests diff --git a/src/dom/html_collection.zig b/src/dom/html_collection.zig index 7b2e8605..5e486807 100644 --- a/src/dom/html_collection.zig +++ b/src/dom/html_collection.zig @@ -13,6 +13,7 @@ const Union = @import("element.zig").Union; const Match = union(enum) { matchByTagName: MatchByTagName, + matchByClassName: MatchByClassName, pub fn match(self: Match, node: *parser.Node) bool { switch (self) { @@ -55,6 +56,37 @@ pub fn HTMLCollectionByTagName(root: *parser.Node, tag_name: []const u8) !HTMLCo }; } +pub const MatchByClassName = struct { + classNames: []const u8, + + fn init(classNames: []const u8) !MatchByClassName { + return MatchByClassName{ + .classNames = classNames, + }; + } + + pub fn match(self: MatchByClassName, node: *parser.Node) bool { + var it = std.mem.splitAny(u8, self.classNames, " "); + const e = parser.nodeToElement(node); + while (it.next()) |c| { + if (!parser.elementHasClass(e, c)) { + return false; + } + } + + return true; + } +}; + +pub fn HTMLCollectionByClassName(root: *parser.Node, classNames: []const u8) !HTMLCollection { + return HTMLCollection{ + .root = root, + .match = Match{ + .matchByClassName = try MatchByClassName.init(classNames), + }, + }; +} + // WEB IDL https://dom.spec.whatwg.org/#htmlcollection // HTMLCollection is re implemented in zig here because libdom // dom_html_collection expects a comparison function callback as arguement. diff --git a/src/netsurf.zig b/src/netsurf.zig index 7052a0ac..c0f9bd5b 100644 --- a/src/netsurf.zig +++ b/src/netsurf.zig @@ -522,6 +522,11 @@ pub fn nodeReplaceChild(node: *Node, new_child: *Node, old_child: *Node) *Node { return res.?; } +// nodeToElement is an helper to convert a node to an element. +pub inline fn nodeToElement(node: *Node) *Element { + return @as(*Element, @ptrCast(node)); +} + // CharacterData pub const CharacterData = c.dom_characterdata; @@ -621,6 +626,12 @@ pub fn elementGetAttribute(elem: *Element, name: []const u8) ?[]const u8 { return stringToData(s.?); } +pub fn elementHasClass(elem: *Element, class: []const u8) bool { + var res: bool = undefined; + _ = elementVtable(elem).dom_element_has_class.?(elem, stringFromData(class), &res); + return res; +} + // elementToNode is an helper to convert an element to a node. pub inline fn elementToNode(e: *Element) *Node { return @as(*Node, @ptrCast(e));