mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 07:03:29 +00:00
Element closest
This commit is contained in:
@@ -135,6 +135,30 @@ pub const Element = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The closest() method of the Element interface traverses the element and its parents (heading toward the document root) until it finds a node that matches the specified CSS selector.
|
||||||
|
// Returns the closest ancestor Element or itself, which matches the selectors. If there are no such element, null.
|
||||||
|
pub fn _closest(self: *parser.Element, selector: []const u8, state: *SessionState) !?*parser.Element {
|
||||||
|
const cssParse = @import("../css/css.zig").parse;
|
||||||
|
const CssNodeWrap = @import("../css/libdom.zig").Node;
|
||||||
|
const select = try cssParse(state.call_arena, selector, .{});
|
||||||
|
|
||||||
|
var current: CssNodeWrap = .{ .node = parser.elementToNode(self) };
|
||||||
|
while (true) {
|
||||||
|
if (try select.match(current)) {
|
||||||
|
if (!current.isElement()) {
|
||||||
|
std.debug.print("closest: is not an element: {s}\n", .{try current.tag()});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return parser.nodeToElement(current.node);
|
||||||
|
}
|
||||||
|
if (try current.parent()) |parent| {
|
||||||
|
current = parent;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn _hasAttributes(self: *parser.Element) !bool {
|
pub fn _hasAttributes(self: *parser.Element) !bool {
|
||||||
return try parser.nodeHasAttributes(parser.elementToNode(self));
|
return try parser.nodeHasAttributes(parser.elementToNode(self));
|
||||||
}
|
}
|
||||||
@@ -401,6 +425,20 @@ test "Browser.DOM.Element" {
|
|||||||
.{ "cl.length", "2" },
|
.{ "cl.length", "2" },
|
||||||
}, .{});
|
}, .{});
|
||||||
|
|
||||||
|
try runner.testCases(&.{
|
||||||
|
.{ "const el2 = document.createElement('div');", "undefined" },
|
||||||
|
.{ "el2.id = 'closest'; el2.className = 'ok';", "ok" },
|
||||||
|
.{ "el2.closest('#closest')", "[object HTMLDivElement]" },
|
||||||
|
.{ "el2.closest('.ok')", "[object HTMLDivElement]" },
|
||||||
|
.{ "el2.closest('#9000')", "null" },
|
||||||
|
.{ "el2.closest('.notok')", "null" },
|
||||||
|
|
||||||
|
.{ "const sp = document.createElement('span');", "undefined" },
|
||||||
|
.{ "el2.appendChild(sp);", "[object HTMLSpanElement]" },
|
||||||
|
.{ "sp.closest('#closest')", "[object HTMLDivElement]" },
|
||||||
|
.{ "sp.closest('#9000')", "null" },
|
||||||
|
}, .{});
|
||||||
|
|
||||||
try runner.testCases(&.{
|
try runner.testCases(&.{
|
||||||
.{ "let a = document.getElementById('content')", "undefined" },
|
.{ "let a = document.getElementById('content')", "undefined" },
|
||||||
.{ "a.hasAttributes()", "true" },
|
.{ "a.hasAttributes()", "true" },
|
||||||
|
|||||||
Reference in New Issue
Block a user