mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 15:13:28 +00:00
correct element insertation in insertAdjacentHTML
* also DRY since the loop is repeated multiple times.
This commit is contained in:
@@ -242,57 +242,56 @@ pub const Element = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Parse the fragment.
|
// Parse the fragment.
|
||||||
|
// Should return error.Syntax on fail?
|
||||||
const fragment = try parser.documentParseFragmentFromStr(doc, input);
|
const fragment = try parser.documentParseFragmentFromStr(doc, input);
|
||||||
const fragment_node = parser.documentFragmentToNode(fragment);
|
const fragment_node = parser.documentFragmentToNode(fragment);
|
||||||
|
|
||||||
// We always get it wrapped like so:
|
// We always get it wrapped like so:
|
||||||
// <html><head></head><body>{ ... }</body></html>
|
// <html><head></head><body>{ ... }</body></html>
|
||||||
const html = parser.nodeFirstChild(fragment_node) orelse return;
|
// None of the following can be null.
|
||||||
const head = parser.nodeFirstChild(html) orelse return;
|
const html = parser.nodeFirstChild(fragment_node).?;
|
||||||
const body = parser.nodeNextSibling(head) orelse return;
|
const body = parser.nodeLastChild(html).?;
|
||||||
|
|
||||||
const children = try parser.nodeGetChildNodes(body);
|
const children = try parser.nodeGetChildNodes(body);
|
||||||
const len = parser.nodeListLength(children);
|
|
||||||
|
|
||||||
|
// * `target_node` is `*Node` (where we actually insert),
|
||||||
|
// * `prev_node` is `?*Node`.
|
||||||
|
const target_node, const prev_node = blk: {
|
||||||
|
// Prefer case-sensitive match.
|
||||||
|
// "beforeend" was the most common case in my tests; we might adjust the order
|
||||||
|
// depending on which ones websites prefer most.
|
||||||
if (std.mem.eql(u8, position, "beforeend")) {
|
if (std.mem.eql(u8, position, "beforeend")) {
|
||||||
for (0..len) |_| {
|
break :blk .{ self_node, null };
|
||||||
const child = parser.nodeListItem(children, 0) orelse continue;
|
|
||||||
_ = try parser.nodeInsertBefore(self_node, child, null);
|
|
||||||
}
|
}
|
||||||
} else if (std.mem.eql(u8, position, "afterbegin")) {
|
|
||||||
const target = parser.nodeFirstChild(self_node) orelse self_node;
|
if (std.mem.eql(u8, position, "afterbegin")) {
|
||||||
for (0..len) |_| {
|
// Get the first child; null indicates there are no children.
|
||||||
const child = parser.nodeListItem(children, 0) orelse continue;
|
const first_child = parser.nodeFirstChild(self_node);
|
||||||
_ = try parser.nodeInsertBefore(target, child, null);
|
break :blk .{ self_node, first_child };
|
||||||
}
|
}
|
||||||
} else if (std.mem.eql(u8, position, "beforebegin")) {
|
|
||||||
const parent = parser.nodeParentNode(self_node) orelse {
|
if (std.mem.eql(u8, position, "beforebegin")) {
|
||||||
return error.NoModificationAllowed;
|
// The node must have a parent node in order to use this variant.
|
||||||
|
const parent = parser.nodeParentNode(self_node) orelse return error.NoModificationAllowed;
|
||||||
|
break :blk .{ parent, self_node };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, position, "afterend")) {
|
||||||
|
// The node must have a parent node in order to use this variant.
|
||||||
|
const parent = parser.nodeParentNode(self_node) orelse return error.NoModificationAllowed;
|
||||||
|
// Get the next sibling or null; null indicates our node is the only one.
|
||||||
|
const sibling = parser.nodeNextSibling(self_node);
|
||||||
|
break :blk .{ parent, sibling };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thrown if:
|
||||||
|
// * position is not one of the four listed values.
|
||||||
|
// * The input is XML that is not well-formed.
|
||||||
|
return error.Syntax;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Make sure parent is not Document.
|
while (parser.nodeListItem(children, 0)) |child| {
|
||||||
// Should also check for document_fragment and document_type?
|
_ = try parser.nodeInsertBefore(target_node, child, prev_node);
|
||||||
if (parser.nodeType(parent) == .document) {
|
|
||||||
return error.NoModificationAllowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (0..len) |_| {
|
|
||||||
const child = parser.nodeListItem(children, 0) orelse continue;
|
|
||||||
_ = try parser.nodeInsertBefore(parent, child, self_node);
|
|
||||||
}
|
|
||||||
} else if (std.mem.eql(u8, position, "afterend")) {
|
|
||||||
const parent = parser.nodeParentNode(self_node) orelse {
|
|
||||||
return error.NoModificationAllowed;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (parser.nodeType(parent) == .document) {
|
|
||||||
return error.NoModificationAllowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (0..len) |_| {
|
|
||||||
const child = parser.nodeListItem(children, 0) orelse continue;
|
|
||||||
_ = try parser.nodeInsertBefore(parent, child, null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user