mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-23 05:04:42 +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 {
|
pub fn after(self: *CData, nodes: []const Node.NodeOrText, page: *Page) !void {
|
||||||
const node = self.asNode();
|
const node = self.asNode();
|
||||||
const parent = node.parentNode() orelse return;
|
const parent = node.parentNode() orelse return;
|
||||||
const next = node.nextSibling();
|
const viable_next = Node.NodeOrText.viableNextSibling(node, nodes);
|
||||||
|
|
||||||
for (nodes) |node_or_text| {
|
for (nodes) |node_or_text| {
|
||||||
const child = try node_or_text.toNode(page);
|
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 {
|
pub fn replaceWith(self: *CData, nodes: []const Node.NodeOrText, page: *Page) !void {
|
||||||
const node = self.asNode();
|
const ref_node = self.asNode();
|
||||||
const parent = node.parentNode() orelse return;
|
const parent = ref_node.parentNode() orelse return;
|
||||||
const next = node.nextSibling();
|
|
||||||
|
|
||||||
_ = try parent.removeChild(node, page);
|
|
||||||
|
|
||||||
|
var rm_ref_node = true;
|
||||||
for (nodes) |node_or_text| {
|
for (nodes) |node_or_text| {
|
||||||
const child = try node_or_text.toNode(page);
|
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 {
|
pub fn after(self: *Element, nodes: []const Node.NodeOrText, page: *Page) !void {
|
||||||
const node = self.asNode();
|
const node = self.asNode();
|
||||||
const parent = node.parentNode() orelse return;
|
const parent = node.parentNode() orelse return;
|
||||||
const next = node.nextSibling();
|
const viable_next = Node.NodeOrText.viableNextSibling(node, nodes);
|
||||||
|
|
||||||
for (nodes) |node_or_text| {
|
for (nodes) |node_or_text| {
|
||||||
const child = try node_or_text.toNode(page);
|
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),
|
.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");
|
const testing = @import("../../testing.zig");
|
||||||
|
|||||||
Reference in New Issue
Block a user