Skip to content

Commit d6ace3f

Browse files
authored
Merge pull request #863 from lightpanda-io/innerHTML_head
Setting innerHTML now captures head elements
2 parents dd04759 + e82240a commit d6ace3f

File tree

2 files changed

+39
-22
lines changed

2 files changed

+39
-22
lines changed

src/browser/dom/element.zig

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -127,16 +127,40 @@ pub const Element = struct {
127127
// remove existing children
128128
try Node.removeChildren(node);
129129

130-
// get fragment body children
131-
const children = try parser.documentFragmentBodyChildren(fragment) orelse return;
132-
133-
// append children to the node
134-
const ln = try parser.nodeListLength(children);
135-
for (0..ln) |_| {
136-
// always index 0, because ndoeAppendChild moves the node out of
137-
// the nodeList and into the new tree
138-
const child = try parser.nodeListItem(children, 0) orelse continue;
139-
_ = try parser.nodeAppendChild(node, child);
130+
// I'm not sure what the exact behavior is supposed to be. Initially,
131+
// we were only copying the body of the document fragment. But it seems
132+
// like head elements should be copied too. Specifically, some sites
133+
// create script tags via innerHTML, which we need to capture.
134+
// If you play with this in a browser, you should notice that the
135+
// behavior is different depending on whether you're in a blank page
136+
// or an actual document. In a blank page, something like:
137+
// x.innerHTML = '<script></script>';
138+
// does _not_ create an empty script, but in a real page, it does. Weird.
139+
const fragment_node = parser.documentFragmentToNode(fragment);
140+
const html = try parser.nodeFirstChild(fragment_node) orelse return;
141+
const head = try parser.nodeFirstChild(html) orelse return;
142+
{
143+
// First, copy some of the head element
144+
const children = try parser.nodeGetChildNodes(head);
145+
const ln = try parser.nodeListLength(children);
146+
for (0..ln) |_| {
147+
// always index 0, because nodeAppendChild moves the node out of
148+
// the nodeList and into the new tree
149+
const child = try parser.nodeListItem(children, 0) orelse continue;
150+
_ = try parser.nodeAppendChild(node, child);
151+
}
152+
}
153+
154+
{
155+
const body = try parser.nodeNextSibling(head) orelse return;
156+
const children = try parser.nodeGetChildNodes(body);
157+
const ln = try parser.nodeListLength(children);
158+
for (0..ln) |_| {
159+
// always index 0, because nodeAppendChild moves the node out of
160+
// the nodeList and into the new tree
161+
const child = try parser.nodeListItem(children, 0) orelse continue;
162+
_ = try parser.nodeAppendChild(node, child);
163+
}
140164
}
141165
}
142166

@@ -688,5 +712,10 @@ test "Browser.DOM.Element" {
688712

689713
try runner.testCases(&.{
690714
.{ "document.createElement('a').hasAttributes()", "false" },
715+
.{ "var fc; (fc = document.createElement('div')).innerHTML = '<script><\\/script>'", null },
716+
.{ "fc.outerHTML", "<div><script></script></div>" },
717+
718+
.{ "fc; (fc = document.createElement('div')).innerHTML = '<script><\\/script><p>hello</p>'", null },
719+
.{ "fc.outerHTML", "<div><script></script><p>hello</p></div>" },
691720
}, .{});
692721
}

src/browser/netsurf.zig

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,18 +1925,6 @@ pub inline fn documentFragmentToNode(doc: *DocumentFragment) *Node {
19251925
return @as(*Node, @alignCast(@ptrCast(doc)));
19261926
}
19271927

1928-
pub fn documentFragmentBodyChildren(doc: *DocumentFragment) !?*NodeList {
1929-
const node = documentFragmentToNode(doc);
1930-
const html = try nodeFirstChild(node) orelse return null;
1931-
// TODO unref
1932-
const head = try nodeFirstChild(html) orelse return null;
1933-
// TODO unref
1934-
const body = try nodeNextSibling(head) orelse return null;
1935-
// TODO unref
1936-
1937-
return try nodeGetChildNodes(body);
1938-
}
1939-
19401928
// Document Position
19411929

19421930
pub const DocumentPosition = enum(u32) {

0 commit comments

Comments
 (0)