mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
Merge pull request #1578 from lightpanda-io/detach_attached_parsed_node
Detach attached nodes on appendBeforeSibling callback
This commit is contained in:
@@ -421,7 +421,16 @@ fn appendBeforeSiblingCallback(ctx: *anyopaque, sibling_ref: *anyopaque, node_or
|
|||||||
fn _appendBeforeSiblingCallback(self: *Parser, sibling: *Node, node_or_text: h5e.NodeOrText) !void {
|
fn _appendBeforeSiblingCallback(self: *Parser, sibling: *Node, node_or_text: h5e.NodeOrText) !void {
|
||||||
const parent = sibling.parentNode() orelse return error.NoParent;
|
const parent = sibling.parentNode() orelse return error.NoParent;
|
||||||
const node: *Node = switch (node_or_text.toUnion()) {
|
const node: *Node = switch (node_or_text.toUnion()) {
|
||||||
.node => |cpn| getNode(cpn),
|
.node => |cpn| blk: {
|
||||||
|
const child = getNode(cpn);
|
||||||
|
if (child._parent) |previous_parent| {
|
||||||
|
// A custom element constructor may have inserted the node into the
|
||||||
|
// DOM before the parser officially places it (e.g. via foster
|
||||||
|
// parenting). Detach it first so insertNodeRelative's assertion holds.
|
||||||
|
self.page.removeNode(previous_parent, child, .{ .will_be_reconnected = parent.isConnected() });
|
||||||
|
}
|
||||||
|
break :blk child;
|
||||||
|
},
|
||||||
.text => |txt| try self.page.createTextNode(txt),
|
.text => |txt| try self.page.createTextNode(txt),
|
||||||
};
|
};
|
||||||
try self.page.insertNodeRelative(parent, node, .{ .before = sibling }, .{});
|
try self.page.insertNodeRelative(parent, node, .{ .before = sibling }, .{});
|
||||||
|
|||||||
@@ -119,3 +119,33 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script id="constructor_self_insert_foster_parent">
|
||||||
|
{
|
||||||
|
// Regression: custom element constructor inserting itself (via appendChild) during
|
||||||
|
// innerHTML parsing. When the element is not valid table content, the HTML5 parser
|
||||||
|
// foster-parents it before the <table> via appendBeforeSiblingCallback. That callback
|
||||||
|
// previously didn't check for an existing _parent before calling insertNodeRelative,
|
||||||
|
// causing the "Page.insertNodeRelative parent" assertion to fire.
|
||||||
|
let constructorCalled = 0;
|
||||||
|
let container;
|
||||||
|
|
||||||
|
class CtorSelfInsert extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
constructorCalled++;
|
||||||
|
// Insert self into container so _parent is set before the parser
|
||||||
|
// officially places this element via appendBeforeSiblingCallback.
|
||||||
|
if (container) container.appendChild(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('ctor-self-insert', CtorSelfInsert);
|
||||||
|
|
||||||
|
container = document.createElement('div');
|
||||||
|
// ctor-self-insert is not valid table content; the parser foster-parents it
|
||||||
|
// before the <table>, calling appendBeforeSiblingCallback(sibling=table, node=element).
|
||||||
|
// At that point the element already has _parent=container from the constructor.
|
||||||
|
container.innerHTML = '<table><ctor-self-insert></ctor-self-insert></table>';
|
||||||
|
|
||||||
|
testing.expectEqual(1, constructorCalled);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -1417,7 +1417,7 @@ pub const Transfer = struct {
|
|||||||
header_len = buf_len - 1;
|
header_len = buf_len - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const header = buffer[0 .. header_len];
|
const header = buffer[0..header_len];
|
||||||
|
|
||||||
// We need to parse the first line headers for each request b/c curl's
|
// We need to parse the first line headers for each request b/c curl's
|
||||||
// CURLINFO_RESPONSE_CODE returns the status code of the final request.
|
// CURLINFO_RESPONSE_CODE returns the status code of the final request.
|
||||||
|
|||||||
Reference in New Issue
Block a user