@@ -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}
0 commit comments