@@ -137,18 +137,18 @@ pub const Element = struct {
137137 }
138138
139139 pub fn get_innerHTML (self : * parser.Element , page : * Page ) ! []const u8 {
140- var buf = std .ArrayList (u8 ).init (page .arena );
140+ var buf = std .ArrayList (u8 ).init (page .call_arena );
141141 try dump .writeChildren (parser .elementToNode (self ), .{}, buf .writer ());
142142 return buf .items ;
143143 }
144144
145145 pub fn get_outerHTML (self : * parser.Element , page : * Page ) ! []const u8 {
146- var buf = std .ArrayList (u8 ).init (page .arena );
146+ var buf = std .ArrayList (u8 ).init (page .call_arena );
147147 try dump .writeNode (parser .elementToNode (self ), .{}, buf .writer ());
148148 return buf .items ;
149149 }
150150
151- pub fn set_innerHTML (self : * parser.Element , str : []const u8 ) ! void {
151+ pub fn set_innerHTML (self : * parser.Element , str : []const u8 , page : * Page ) ! void {
152152 const node = parser .elementToNode (self );
153153 const doc = try parser .nodeOwnerDocument (node ) orelse return parser .DOMError .WrongDocument ;
154154 // parse the fragment
@@ -157,6 +157,8 @@ pub const Element = struct {
157157 // remove existing children
158158 try Node .removeChildren (node );
159159
160+ const fragment_node = parser .documentFragmentToNode (fragment );
161+
160162 // I'm not sure what the exact behavior is supposed to be. Initially,
161163 // we were only copying the body of the document fragment. But it seems
162164 // like head elements should be copied too. Specifically, some sites
@@ -166,9 +168,32 @@ pub const Element = struct {
166168 // or an actual document. In a blank page, something like:
167169 // x.innerHTML = '<script></script>';
168170 // does _not_ create an empty script, but in a real page, it does. Weird.
169- const fragment_node = parser .documentFragmentToNode (fragment );
170171 const html = try parser .nodeFirstChild (fragment_node ) orelse return ;
171172 const head = try parser .nodeFirstChild (html ) orelse return ;
173+ const body = try parser .nodeNextSibling (head ) orelse return ;
174+
175+ if (try parser .elementTag (self ) == .template ) {
176+ // HTMLElementTemplate is special. We don't append these as children
177+ // of the template, but instead set its content as the body of the
178+ // fragment. Simpler to do this by copying the body children into
179+ // a new fragment
180+ const clean = try parser .documentCreateDocumentFragment (doc );
181+ const children = try parser .nodeGetChildNodes (body );
182+ const ln = try parser .nodeListLength (children );
183+ for (0.. ln ) | _ | {
184+ // always index 0, because nodeAppendChild moves the node out of
185+ // the nodeList and into the new tree
186+ const child = try parser .nodeListItem (children , 0 ) orelse continue ;
187+ _ = try parser .nodeAppendChild (@alignCast (@ptrCast (clean )), child );
188+ }
189+
190+ const state = try page .getOrCreateNodeState (node );
191+ state .template_content = clean ;
192+ return ;
193+ }
194+
195+ // For any node other than a template, we copy the head and body elements
196+ // as child nodes of the element
172197 {
173198 // First, copy some of the head element
174199 const children = try parser .nodeGetChildNodes (head );
@@ -182,7 +207,6 @@ pub const Element = struct {
182207 }
183208
184209 {
185- const body = try parser .nodeNextSibling (head ) orelse return ;
186210 const children = try parser .nodeGetChildNodes (body );
187211 const ln = try parser .nodeListLength (children );
188212 for (0.. ln ) | _ | {
0 commit comments