mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
Merge pull request #1612 from egrs/fix-childnode-sibling-ordering
fix ChildNode after() and replaceWith() sibling ordering
This commit is contained in:
@@ -301,24 +301,30 @@ pub fn before(self: *CData, nodes: []const Node.NodeOrText, page: *Page) !void {
|
||||
pub fn after(self: *CData, nodes: []const Node.NodeOrText, page: *Page) !void {
|
||||
const node = self.asNode();
|
||||
const parent = node.parentNode() orelse return;
|
||||
const next = node.nextSibling();
|
||||
const viable_next = Node.NodeOrText.viableNextSibling(node, nodes);
|
||||
|
||||
for (nodes) |node_or_text| {
|
||||
const child = try node_or_text.toNode(page);
|
||||
_ = try parent.insertBefore(child, next, page);
|
||||
_ = try parent.insertBefore(child, viable_next, page);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replaceWith(self: *CData, nodes: []const Node.NodeOrText, page: *Page) !void {
|
||||
const node = self.asNode();
|
||||
const parent = node.parentNode() orelse return;
|
||||
const next = node.nextSibling();
|
||||
|
||||
_ = try parent.removeChild(node, page);
|
||||
const ref_node = self.asNode();
|
||||
const parent = ref_node.parentNode() orelse return;
|
||||
|
||||
var rm_ref_node = true;
|
||||
for (nodes) |node_or_text| {
|
||||
const child = try node_or_text.toNode(page);
|
||||
_ = try parent.insertBefore(child, next, page);
|
||||
if (child == ref_node) {
|
||||
rm_ref_node = false;
|
||||
continue;
|
||||
}
|
||||
_ = try parent.insertBefore(child, ref_node, page);
|
||||
}
|
||||
|
||||
if (rm_ref_node) {
|
||||
_ = try parent.removeChild(ref_node, page);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -876,11 +876,11 @@ pub fn before(self: *Element, nodes: []const Node.NodeOrText, page: *Page) !void
|
||||
pub fn after(self: *Element, nodes: []const Node.NodeOrText, page: *Page) !void {
|
||||
const node = self.asNode();
|
||||
const parent = node.parentNode() orelse return;
|
||||
const next = node.nextSibling();
|
||||
const viable_next = Node.NodeOrText.viableNextSibling(node, nodes);
|
||||
|
||||
for (nodes) |node_or_text| {
|
||||
const child = try node_or_text.toNode(page);
|
||||
_ = try parent.insertBefore(child, next, page);
|
||||
_ = try parent.insertBefore(child, viable_next, page);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1074,6 +1074,25 @@ pub const NodeOrText = union(enum) {
|
||||
.text => |txt| page.createTextNode(txt),
|
||||
};
|
||||
}
|
||||
|
||||
/// DOM spec: first following sibling of `node` that is not in `nodes`.
|
||||
pub fn viableNextSibling(node: *Node, nodes: []const NodeOrText) ?*Node {
|
||||
var sibling = node.nextSibling() orelse return null;
|
||||
blk: while (true) {
|
||||
for (nodes) |n| {
|
||||
switch (n) {
|
||||
.node => |nn| if (sibling == nn) {
|
||||
sibling = sibling.nextSibling() orelse return null;
|
||||
continue :blk;
|
||||
},
|
||||
.text => {},
|
||||
}
|
||||
} else {
|
||||
return sibling;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const testing = @import("../../testing.zig");
|
||||
|
||||
Reference in New Issue
Block a user