@@ -297,12 +297,29 @@ pub const Node = struct {
297297 }
298298 }
299299
300+ // Check if the hierarchy node tree constraints are respected.
301+ // For now, it checks only if new nodes are not self.
302+ // TODO implements the others contraints.
303+ // see https://dom.spec.whatwg.org/#concept-node-tree
304+ pub fn hierarchy (self : * parser.Node , nodes : ? Variadic (* parser.Node )) ! bool {
305+ if (nodes == null ) return true ;
306+ if (nodes .? .slice .len == 0 ) return true ;
307+
308+ for (nodes .? .slice ) | node | if (self == node ) return false ;
309+
310+ return true ;
311+ }
312+
300313 // TODO according with https://dom.spec.whatwg.org/#parentnode, the
301314 // function must accept either node or string.
302315 // blocked by https://github.com/lightpanda-io/jsruntime-lib/issues/114
303316 pub fn append (self : * parser.Node , nodes : ? Variadic (* parser.Node )) ! void {
304317 if (nodes == null ) return ;
305318 if (nodes .? .slice .len == 0 ) return ;
319+
320+ // check hierarchy
321+ if (! try hierarchy (self , nodes )) return parser .DOMError .HierarchyRequest ;
322+
306323 for (nodes .? .slice ) | node | {
307324 _ = try parser .nodeAppendChild (self , node );
308325 }
@@ -312,12 +329,15 @@ pub const Node = struct {
312329 // function must accept either node or string.
313330 // blocked by https://github.com/lightpanda-io/jsruntime-lib/issues/114
314331 pub fn replaceChildren (self : * parser.Node , nodes : ? Variadic (* parser.Node )) ! void {
315- // remove existing children
316- try removeChildren (self );
317-
318332 if (nodes == null ) return ;
319333 if (nodes .? .slice .len == 0 ) return ;
320334
335+ // check hierarchy
336+ if (! try hierarchy (self , nodes )) return parser .DOMError .HierarchyRequest ;
337+
338+ // remove existing children
339+ try removeChildren (self );
340+
321341 // add new children
322342 for (nodes .? .slice ) | node | {
323343 _ = try parser .nodeAppendChild (self , node );
0 commit comments