Skip to content
3 changes: 2 additions & 1 deletion src/browser/dom/element.zig
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ pub const Element = struct {
}

pub fn get_attributes(self: *parser.Element) !*parser.NamedNodeMap {
return try parser.nodeGetAttributes(parser.elementToNode(self));
// An element must have non-nil attributes.
return try parser.nodeGetAttributes(parser.elementToNode(self)) orelse unreachable;
}

pub fn get_innerHTML(self: *parser.Element, state: *SessionState) ![]const u8 {
Expand Down
24 changes: 12 additions & 12 deletions src/browser/dump.zig
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,18 @@ pub fn writeNode(node: *parser.Node, writer: anytype) anyerror!void {
try writer.writeAll(tag);

// write the attributes
const map = try parser.nodeGetAttributes(node);
const ln = try parser.namedNodeMapGetLength(map);
var i: u32 = 0;
while (i < ln) {
const attr = try parser.namedNodeMapItem(map, i) orelse break;
try writer.writeAll(" ");
try writer.writeAll(try parser.attributeGetName(attr));
try writer.writeAll("=\"");
const attribute_value = try parser.attributeGetValue(attr) orelse "";
try writeEscapedAttributeValue(writer, attribute_value);
try writer.writeAll("\"");
i += 1;
const _map = try parser.nodeGetAttributes(node);
if (_map) |map| {
const ln = try parser.namedNodeMapGetLength(map);
for (0..ln) |i| {
const attr = try parser.namedNodeMapItem(map, @intCast(i)) orelse break;
try writer.writeAll(" ");
try writer.writeAll(try parser.attributeGetName(attr));
try writer.writeAll("=\"");
const attribute_value = try parser.attributeGetValue(attr) orelse "";
try writeEscapedAttributeValue(writer, attribute_value);
try writer.writeAll("\"");
}
}

try writer.writeAll(">");
Expand Down
4 changes: 2 additions & 2 deletions src/browser/netsurf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1338,11 +1338,11 @@ pub fn nodeHasAttributes(node: *Node) !bool {
return res;
}

pub fn nodeGetAttributes(node: *Node) !*NamedNodeMap {
pub fn nodeGetAttributes(node: *Node) !?*NamedNodeMap {
var res: ?*NamedNodeMap = undefined;
const err = nodeVtable(node).dom_node_get_attributes.?(node, &res);
try DOMErr(err);
return res.?;
return res;
}

pub fn nodeGetNamespace(node: *Node) !?[]const u8 {
Expand Down
29 changes: 23 additions & 6 deletions src/cdp/Node.zig
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ pub const Writer = struct {

fn toJSON(self: *const Writer, w: anytype) !void {
try w.beginObject();
try writeCommon(self.node, false, w);
try self.writeCommon(self.node, false, w);

{
var registry = self.registry;
Expand All @@ -232,7 +232,7 @@ pub const Writer = struct {
const child = (try parser.nodeListItem(child_nodes, @intCast(i))) orelse break;
const child_node = try registry.register(child);
try w.beginObject();
try writeCommon(child_node, true, w);
try self.writeCommon(child_node, true, w);
try w.endObject();
i += 1;
}
Expand All @@ -245,7 +245,7 @@ pub const Writer = struct {
try w.endObject();
}

fn writeCommon(node: *const Node, include_child_count: bool, w: anytype) !void {
fn writeCommon(self: *const Writer, node: *const Node, include_child_count: bool, w: anytype) !void {
try w.objectField("nodeId");
try w.write(node.id);

Expand All @@ -254,9 +254,24 @@ pub const Writer = struct {

const n = node._node;

// TODO:
// try w.objectField("parentId");
// try w.write(pid);
if (try parser.nodeParentNode(n)) |p| {
const parent_node = try self.registry.register(p);
try w.objectField("parentId");
try w.write(parent_node.id);
}

const _map = try parser.nodeGetAttributes(n);
if (_map) |map| {
const attr_count = try parser.namedNodeMapGetLength(map);
try w.objectField("attributes");
try w.beginArray();
for (0..attr_count) |i| {
const attr = try parser.namedNodeMapItem(map, @intCast(i)) orelse continue;
try w.write(try parser.attributeGetName(attr));
try w.write(try parser.attributeGetValue(attr) orelse continue);
}
try w.endArray();
}

try w.objectField("nodeType");
try w.write(@intFromEnum(try parser.nodeType(n)));
Expand Down Expand Up @@ -461,6 +476,7 @@ test "cdp Node: Writer" {
.xmlVersion = "",
.compatibilityMode = "NoQuirksMode",
.isScrollable = false,
.parentId = 1,
}, .{
.nodeId = 3,
.backendNodeId = 3,
Expand All @@ -474,6 +490,7 @@ test "cdp Node: Writer" {
.xmlVersion = "",
.compatibilityMode = "NoQuirksMode",
.isScrollable = false,
.parentId = 1,
} },
}, json);
}
Expand Down
17 changes: 17 additions & 0 deletions src/cdp/domains/dom.zig
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,23 @@ fn performSearch(cmd: anytype) !void {

const search = try bc.node_search_list.create(list.nodes.items);

// dispatch setChildNodesEvents to inform the client of the subpart of node
// tree covering the results.
for (list.nodes.items) |n| {
// retrieve the node's parent
if (try parser.nodeParentNode(n)) |p| {
// Register the parent and send the node.
const parent_node = try bc.node_registry.register(p);
const node = bc.node_registry.lookup_by_node.get(n) orelse unreachable;
// Should-we return one DOM.setChildNodes event per parentId
// containing all its children in the nodes array?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

If it's something we'll need to do often, we could expand the NodeWriter. It already takes a placeholder option, so it could be something like:

.nodes = bc.nodeWriter(parent_node, .{.mode = .child_list})},

try cmd.sendEvent("DOM.setChildNodes", .{
.parentId = parent_node.id,
.nodes = .{bc.nodeWriter(node, .{})},
}, .{});
}
}

return cmd.sendResult(.{
.searchId = search.name,
.resultCount = @as(u32, @intCast(search.node_ids.len)),
Expand Down
Loading