@@ -127,18 +127,18 @@ pub const Element = struct {
127127 }
128128
129129 pub fn get_innerHTML (self : * parser.Element , page : * Page ) ! []const u8 {
130- var buf = std .ArrayList (u8 ).init (page .arena );
130+ var buf = std .ArrayList (u8 ).init (page .call_arena );
131131 try dump .writeChildren (parser .elementToNode (self ), .{}, buf .writer ());
132132 return buf .items ;
133133 }
134134
135135 pub fn get_outerHTML (self : * parser.Element , page : * Page ) ! []const u8 {
136- var buf = std .ArrayList (u8 ).init (page .arena );
136+ var buf = std .ArrayList (u8 ).init (page .call_arena );
137137 try dump .writeNode (parser .elementToNode (self ), .{}, buf .writer ());
138138 return buf .items ;
139139 }
140140
141- pub fn set_innerHTML (self : * parser.Element , str : []const u8 ) ! void {
141+ pub fn set_innerHTML (self : * parser.Element , str : []const u8 , page : * Page ) ! void {
142142 const node = parser .elementToNode (self );
143143 const doc = try parser .nodeOwnerDocument (node ) orelse return parser .DOMError .WrongDocument ;
144144 // parse the fragment
@@ -147,6 +147,8 @@ pub const Element = struct {
147147 // remove existing children
148148 try Node .removeChildren (node );
149149
150+ const fragment_node = parser .documentFragmentToNode (fragment );
151+
150152 // I'm not sure what the exact behavior is supposed to be. Initially,
151153 // we were only copying the body of the document fragment. But it seems
152154 // like head elements should be copied too. Specifically, some sites
@@ -156,9 +158,32 @@ pub const Element = struct {
156158 // or an actual document. In a blank page, something like:
157159 // x.innerHTML = '<script></script>';
158160 // does _not_ create an empty script, but in a real page, it does. Weird.
159- const fragment_node = parser .documentFragmentToNode (fragment );
160161 const html = try parser .nodeFirstChild (fragment_node ) orelse return ;
161162 const head = try parser .nodeFirstChild (html ) orelse return ;
163+ const body = try parser .nodeNextSibling (head ) orelse return ;
164+
165+ if (try parser .elementTag (self ) == .template ) {
166+ // HTMLElementTemplate is special. We don't append these as children
167+ // of the template, but instead set its content as the body of the
168+ // fragment. Simpler to do this by copying the body children into
169+ // a new fragment
170+ const clean = try parser .documentCreateDocumentFragment (doc );
171+ const children = try parser .nodeGetChildNodes (body );
172+ const ln = try parser .nodeListLength (children );
173+ for (0.. ln ) | _ | {
174+ // always index 0, because nodeAppendChild moves the node out of
175+ // the nodeList and into the new tree
176+ const child = try parser .nodeListItem (children , 0 ) orelse continue ;
177+ _ = try parser .nodeAppendChild (@alignCast (@ptrCast (clean )), child );
178+ }
179+
180+ const state = try page .getOrCreateNodeState (node );
181+ state .template_content = clean ;
182+ return ;
183+ }
184+
185+ // For any node other than a template, we copy the head and body elements
186+ // as child nodes of the element
162187 {
163188 // First, copy some of the head element
164189 const children = try parser .nodeGetChildNodes (head );
@@ -172,7 +197,6 @@ pub const Element = struct {
172197 }
173198
174199 {
175- const body = try parser .nodeNextSibling (head ) orelse return ;
176200 const children = try parser .nodeGetChildNodes (body );
177201 const ln = try parser .nodeListLength (children );
178202 for (0.. ln ) | _ | {
0 commit comments