From f8e9e71b08690741b0c78c3d5901e89a6730f408 Mon Sep 17 00:00:00 2001 From: gh-fixes Date: Fri, 30 Oct 2026 11:20:41 +0000 Subject: [PATCH] fix: report actual parent as MutationObserver childList target (#300) --- cjs/interface/mutation-observer.js | 2 +- esm/interface/mutation-observer.js | 2 +- test/interface/mutation-observer.js | 51 +++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/cjs/interface/mutation-observer.js b/cjs/interface/mutation-observer.js index 1bd79217..7977a091 100644 --- a/cjs/interface/mutation-observer.js +++ b/cjs/interface/mutation-observer.js @@ -91,7 +91,7 @@ const moCallback = (element, parentNode) => { ) { const {callback, records, scheduled} = observer; records.push(createRecord( - 'childList', target, element, + 'childList', parentNode || element.parentNode, element, parentNode ? [] : [element], parentNode ? [element] : [] )); if (!scheduled) { diff --git a/esm/interface/mutation-observer.js b/esm/interface/mutation-observer.js index 1549f35e..969ea790 100644 --- a/esm/interface/mutation-observer.js +++ b/esm/interface/mutation-observer.js @@ -89,7 +89,7 @@ export const moCallback = (element, parentNode) => { ) { const {callback, records, scheduled} = observer; records.push(createRecord( - 'childList', target, element, + 'childList', parentNode || element.parentNode, element, parentNode ? [] : [element], parentNode ? [element] : [] )); if (!scheduled) { diff --git a/test/interface/mutation-observer.js b/test/interface/mutation-observer.js index 49914ad6..625f78e2 100644 --- a/test/interface/mutation-observer.js +++ b/test/interface/mutation-observer.js @@ -233,4 +233,55 @@ let {document: newDoc} = parseHTML(''); true, 'MutationObserver addedNodes on html' ); + args = null; + observer.disconnect(); + const bodyTarget = newDoc.body; + observer.observe(newDoc, { + childList: true, + subtree: true + }); + bodyTarget.appendChild(newDoc.createTextNode('')); + await milliseconds(10); + + assert( + checkRecord( + {target: bodyTarget, type: "childList", addedNodes: [bodyTarget.lastChild]}, + args[0] + ), + true, + 'MutationObserver target is the parent of an inserted text node' + ); + args = null; + const nestedDiv = newDoc.createElement('div'); + bodyTarget.appendChild(nestedDiv); + await milliseconds(10); + args = null; + const spanChild = newDoc.createElement('span'); + nestedDiv.appendChild(spanChild); + await milliseconds(10); + + assert( + checkRecord( + {target: nestedDiv, type: "childList", addedNodes: [spanChild]}, + args[0] + ), + true, + 'MutationObserver target is the parent of an inserted element' + ); + args = null; + const removedChild = newDoc.createElement('b'); + bodyTarget.appendChild(removedChild); + await milliseconds(10); + args = null; + bodyTarget.removeChild(removedChild); + await milliseconds(10); + + assert( + checkRecord( + {target: bodyTarget, type: "childList", removedNodes: [removedChild]}, + args[0] + ), + true, + 'MutationObserver target is the old parent of a removed child' + ); })();