mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-15 15:58:57 +00:00
axtree: fix skip children for head
This commit is contained in:
@@ -49,7 +49,10 @@ pub const Writer = struct {
|
|||||||
|
|
||||||
fn toJSON(self: *const Writer, node: *const Node, w: anytype) !void {
|
fn toJSON(self: *const Writer, node: *const Node, w: anytype) !void {
|
||||||
try w.beginArray();
|
try w.beginArray();
|
||||||
try self.writeNode(node, w);
|
if (try self.writeNode(node, w)) {
|
||||||
|
try w.endArray();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const walker = Walker{};
|
const walker = Walker{};
|
||||||
var next: ?*parser.Node = null;
|
var next: ?*parser.Node = null;
|
||||||
@@ -63,13 +66,7 @@ pub const Writer = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const n = try self.registry.register(next.?);
|
const n = try self.registry.register(next.?);
|
||||||
try self.writeNode(n, w);
|
skip_children = try self.writeNode(n, w);
|
||||||
|
|
||||||
const tag = try parser.elementTag(@ptrCast(next.?));
|
|
||||||
skip_children = switch (tag) {
|
|
||||||
.head => true,
|
|
||||||
else => false,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try w.endArray();
|
try w.endArray();
|
||||||
@@ -194,13 +191,16 @@ pub const Writer = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// write a node. returns true if children must be skipped.
|
// write a node. returns true if children must be skipped.
|
||||||
fn writeNode(self: *const Writer, node: *const Node, w: anytype) !void {
|
fn writeNode(self: *const Writer, node: *const Node, w: anytype) !bool {
|
||||||
try w.beginObject();
|
try w.beginObject();
|
||||||
|
|
||||||
const axn = try AXNode.fromNode(node._node);
|
const axn = try AXNode.fromNode(node._node);
|
||||||
try w.objectField("nodeId");
|
try w.objectField("nodeId");
|
||||||
try w.write(node.id);
|
try w.write(node.id);
|
||||||
|
|
||||||
|
try w.objectField("backendDOMNodeId");
|
||||||
|
try w.write(node.id);
|
||||||
|
|
||||||
try w.objectField("role");
|
try w.objectField("role");
|
||||||
try self.writeAXValue(.{ .type = .role, .value = .{ .string = try axn.getRole() } }, w);
|
try self.writeAXValue(.{ .type = .role, .value = .{ .string = try axn.getRole() } }, w);
|
||||||
|
|
||||||
@@ -249,28 +249,34 @@ pub const Writer = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Children
|
// Children
|
||||||
|
const skip_children = try axn.ignoreChildren();
|
||||||
|
|
||||||
try w.objectField("childIds");
|
try w.objectField("childIds");
|
||||||
var registry = self.registry;
|
|
||||||
const child_nodes = try parser.nodeGetChildNodes(n);
|
|
||||||
const child_count = parser.nodeListLength(child_nodes);
|
|
||||||
|
|
||||||
var i: usize = 0;
|
|
||||||
try w.beginArray();
|
try w.beginArray();
|
||||||
for (0..child_count) |_| {
|
if (!skip_children) {
|
||||||
defer i += 1;
|
var registry = self.registry;
|
||||||
const child = (parser.nodeListItem(child_nodes, @intCast(i))) orelse break;
|
const child_nodes = try parser.nodeGetChildNodes(n);
|
||||||
|
const child_count = parser.nodeListLength(child_nodes);
|
||||||
|
|
||||||
// ignore non-elements
|
var i: usize = 0;
|
||||||
if (parser.nodeType(child) != .element) {
|
for (0..child_count) |_| {
|
||||||
continue;
|
defer i += 1;
|
||||||
|
const child = (parser.nodeListItem(child_nodes, @intCast(i))) orelse break;
|
||||||
|
|
||||||
|
// ignore non-elements
|
||||||
|
if (parser.nodeType(child) != .element) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const child_node = try registry.register(child);
|
||||||
|
try w.write(child_node.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const child_node = try registry.register(child);
|
|
||||||
try w.write(child_node.id);
|
|
||||||
}
|
}
|
||||||
try w.endArray();
|
try w.endArray();
|
||||||
|
|
||||||
try w.endObject();
|
try w.endObject();
|
||||||
|
|
||||||
|
return skip_children;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -328,11 +334,11 @@ pub const AXRole = enum(u8) {
|
|||||||
term,
|
term,
|
||||||
textbox,
|
textbox,
|
||||||
time,
|
time,
|
||||||
WebRootArea,
|
RootWebArea,
|
||||||
|
|
||||||
fn fromNode(node: *parser.Node) !AXRole {
|
fn fromNode(node: *parser.Node) !AXRole {
|
||||||
switch (parser.nodeType(node)) {
|
switch (parser.nodeType(node)) {
|
||||||
.document => return .WebRootArea, // Chrome specific.
|
.document => return .RootWebArea, // Chrome specific.
|
||||||
.element => {},
|
.element => {},
|
||||||
else => {
|
else => {
|
||||||
log.debug(.cdp, "invalid tag", .{ .node_type = parser.nodeType(node) });
|
log.debug(.cdp, "invalid tag", .{ .node_type = parser.nodeType(node) });
|
||||||
@@ -660,6 +666,22 @@ fn isHidden(elt: *parser.Element) !bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn ignoreChildren(self: AXNode) !bool {
|
||||||
|
const node = self._node;
|
||||||
|
if (parser.nodeType(node) == .document) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.assert(parser.nodeType(node) == .element);
|
||||||
|
|
||||||
|
const elt: *parser.Element = @ptrCast(node);
|
||||||
|
const tag = try parser.elementTag(elt);
|
||||||
|
return switch (tag) {
|
||||||
|
.head => true,
|
||||||
|
else => false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn isIgnore(self: AXNode) !bool {
|
fn isIgnore(self: AXNode) !bool {
|
||||||
const node = self._node;
|
const node = self._node;
|
||||||
const role_attr = self.role_attr;
|
const role_attr = self.role_attr;
|
||||||
|
|||||||
Reference in New Issue
Block a user