@@ -277,14 +277,30 @@ pub const Node = struct {
277277 return try Node .toInterface (res );
278278 }
279279
280+ // Check if the hierarchy node tree constraints are respected.
281+ // For now, it checks only if new nodes are not self.
282+ // TODO implements the others contraints.
283+ // see https://dom.spec.whatwg.org/#concept-node-tree
284+ pub fn hierarchy (self : * parser.Node , nodes : ? Variadic (* parser.Node )) ! bool {
285+ if (nodes == null ) return true ;
286+ if (nodes .? .slice .len == 0 ) return true ;
287+
288+ for (nodes .? .slice ) | node | if (self == node ) return false ;
289+
290+ return true ;
291+ }
292+
280293 // TODO according with https://dom.spec.whatwg.org/#parentnode, the
281294 // function must accept either node or string.
282295 // blocked by https://github.com/lightpanda-io/jsruntime-lib/issues/114
283296 pub fn prepend (self : * parser.Node , nodes : ? Variadic (* parser.Node )) ! void {
284297 if (nodes == null ) return ;
285298 if (nodes .? .slice .len == 0 ) return ;
286- const first = try parser .nodeFirstChild (self );
287299
300+ // check hierarchy
301+ if (! try hierarchy (self , nodes )) return parser .DOMError .HierarchyRequest ;
302+
303+ const first = try parser .nodeFirstChild (self );
288304 if (first == null ) {
289305 for (nodes .? .slice ) | node | {
290306 _ = try parser .nodeAppendChild (self , node );
@@ -303,6 +319,10 @@ pub const Node = struct {
303319 pub fn append (self : * parser.Node , nodes : ? Variadic (* parser.Node )) ! void {
304320 if (nodes == null ) return ;
305321 if (nodes .? .slice .len == 0 ) return ;
322+
323+ // check hierarchy
324+ if (! try hierarchy (self , nodes )) return parser .DOMError .HierarchyRequest ;
325+
306326 for (nodes .? .slice ) | node | {
307327 _ = try parser .nodeAppendChild (self , node );
308328 }
@@ -312,12 +332,15 @@ pub const Node = struct {
312332 // function must accept either node or string.
313333 // blocked by https://github.com/lightpanda-io/jsruntime-lib/issues/114
314334 pub fn replaceChildren (self : * parser.Node , nodes : ? Variadic (* parser.Node )) ! void {
315- // remove existing children
316- try removeChildren (self );
317-
318335 if (nodes == null ) return ;
319336 if (nodes .? .slice .len == 0 ) return ;
320337
338+ // check hierarchy
339+ if (! try hierarchy (self , nodes )) return parser .DOMError .HierarchyRequest ;
340+
341+ // remove existing children
342+ try removeChildren (self );
343+
321344 // add new children
322345 for (nodes .? .slice ) | node | {
323346 _ = try parser .nodeAppendChild (self , node );
0 commit comments