question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Mutation Observer throws when connecting to a document

See original GitHub issue

Bug Report

Prerequisites

  • [y] Can you reproduce the problem in a MWE?
  • [y] Are you running the latest version of AngleSharp?
  • [y] Did you check the FAQs to see if that helps you?
  • [y] Are you reporting to the correct repository? (there are multiple AngleSharp libraries, e.g., AngleSharp.Css for CSS support)
  • [y] Did you perform a search in the issues?

For more information, see the CONTRIBUTING guide.

Description

I’m trying to use a mutation observer to watch an entire document. Unfortunately when I try to do that I get a null reference exception.

Steps to Reproduce

var document = ... //from somewhere
var observer = new MutationObserver((mutations, observer) => {});
observer.Connect(document);

Expected behavior: no exception should be thrown

Actual behavior: a null reference exception was thrown when the connect method tries to access the document owner which is always null

Environment details: Windows .NET 5

Possible Solution

In this file: https://github.com/AngleSharp/AngleSharp/blob/devel/src/AngleSharp/Dom/MutationObserver.cs#L221 the following line in the issue

node.Owner.Mutations.Register(this);

the problem is that a document always returns null for it’s owner. I see 2 ways to fix this, the first is to change the document so returns itself as it’s owner. The other way would be to refactor this line to check if the node is a document and if it is then just use the Mutations Property directly. Something like this

if (node is Document d)
    d.Mutations.Register(this);
else
    node.Owner.Mutations.Register(this);

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
FlorianRapplcommented, Oct 6, 2021
0reactions
hahn-kevcommented, Oct 6, 2021

I’m sorry, I think my example was incorrect, instead of this: observer.Connect(document); it should have been this observer.Connect(document, true); so I wouldn’t get an error about any of those settings being false.

I did a little testing (in Firefox and Chrome) and it seems perfectly happy to observe the document without any errors. If you want to test it out copy this into your browser console and modify something in the html.

// Options for the observer (which mutations to observe)
const config = { attributes: true, childList: true, subtree: true };

// Callback function to execute when mutations are observed
const callback = function(mutationsList, observer) {
    // Use traditional 'for loops' for IE 11
    for(const mutation of mutationsList) {
        if (mutation.type === 'childList') {
            console.log('A child node has been added or removed.');
        }
        else if (mutation.type === 'attributes') {
            console.log('The ' + mutation.attributeName + ' attribute was modified.');
        }
    }
};

// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);

// Start observing the target node for configured mutations
observer.observe(document, config);

Like you said a document is a node, in AngleSharp and the browser, there’s just a minor detail in AngleSharp that seems to prevent it from working currently. As for step 3 of the algorithm I don’t see what this has to do with a document not being accepted.

Read more comments on GitHub >

github_iconTop Results From Across the Web

What could cause Mutation Observer on entire document ...
It may be related to an infinite loop where when a mutation is observed, a node is added. This causes a mutation to...
Read more >
MutationObserver: observe() method - Web APIs | MDN
The MutationObserver method observe() configures the MutationObserver callback to begin receiving notifications of changes to the DOM that ...
Read more >
Getting To Know The MutationObserver API
The first and simplest MutationObserver you can initiate is one that looks for child nodes of a specified node (usually an element) to...
Read more >
Use a MutationObserver to Handle DOM Nodes that Don't ...
All the code you see is being thrown onto the call stack and executed immediately (except, of course, setTimeout() 's callback), so by...
Read more >
JavaScript MutationObserver
The MutationObserver API allows you to monitor for changes being made to the DOM tree. When the DOM nodes change, you can invoke...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found