jsdom / jsdom

A JavaScript implementation of various web standards, for use with Node.js

Repository from Github https://github.comjsdom/jsdomRepository from Github https://github.comjsdom/jsdom

Inconsitent appendChild behavior from Web implementation

sukima opened this issue · comments

Basic info:

  • Node.js version: 22.12.0
  • jsdom version: 25.0.1

Minimal reproduction case

Given a document with the following XML:

<bar>
  <bar id="theBar"><child-bars/></bar>
  <child-bars/>
</bar>

using appendChild to move #theBar into the parent child-bars element will generate the error [DOMException [HierarchyRequestError]: The operation would yield an incorrect node tree.].

const { JSDOM } = require('jsdom');
const xml = `
  <bar>
    <bar id="theBar"><child-bars/></bar>
    <child-bars/>
  </bar>
`.trim();
const { document } = new JSDOM(xml, { contentType: 'text/xml' }).window;
for (const bar of [...document.querySelectorAll('bar')]) {
  if (!bar.parentElement) continue;
  bar.parentElement.querySelector(':scope > child-bars').appendChild(bar);
}

How does similar code behave in browsers?

Comparatively running the same in FireFox works as expected.

const xml = `
  <bar>
    <bar id="theBar"><child-bars/></bar>
    <child-bars/>
  </bar>
`.trim();
const doc = new DOMParser().parseFromString(xml, 'text/xml');
for (const bar of [...doc.querySelectorAll('bar')]) {
  if (!bar.parentElement) continue;
  bar.parentElement.querySelector(':scope > child-bars').appendChild(bar);
}

JSFiddle Link

Hmm, can you test without using :scope? Our support for that selector has historically not been great, so I wonder if the problem might be there, instead of in appendChild().