Using a WebBrowser in .NET, can a mutation observer be used to watch for DIV changes?

Viewed 233

I'm using vb.NET but I incorporated a C# example from here using addEventListener and DOMSubtreeModified to watch the entire DOM document:

    Dim script As HtmlElement = Me.Browser.Document.CreateElement("script")
    script.InnerHtml = "function listenToDOM() { document.addEventListener('DOMSubtreeModified', function(e) { window.external.DOMUpdate() }); }"
    Me.Browser.Document.GetElementsByTagName("body")(0).AppendChild(script)
    Me.Browser.Document.InvokeScript("listenToDOM")

...however, I'm trying to sort it out to more specific DIVs. I haven't succeeded on that front yet but the more I read the more it seems I should be using a MutationObserver which I know nothing about, and I especially don't know how to incorporate with a WebBrowser control.

Has anyone managed to do this?

Note: Yes this is WinForms WB and I did already set my BrowserEmulation to IE11 so that shouldn't be a problem.

Update: I attempted an implementation but it's not triggering:

    Dim scriptEl As HtmlElement = Me.Browser.Document.CreateElement("script")
    scriptEl.InnerHtml = "var targetNode = document.querySelector('.div-content');
        
        var Config = {
            attributes: true, 
            childList: true, 
            characterData: true,
            subtree: true
        };

        function (as Observer = new MutationObserver(function (MutationRecords, MutationObserver) { window.external.DivUpdated(); }); 
    
        Observer.observe(targetNode, Config);"

    Me.Browser.Document.GetElementsByTagName("body")(0).AppendChild(scriptEl)
1 Answers

Here's what I came up with. Granted I will develop it more regarding the specific changes that are being caught...

Private Sub AddScript(Code As String)

    Dim script As HtmlElement = Me.Browser.Document.CreateElement("script")
    script.InnerHtml = Code
    Me.Browser.Document.GetElementsByTagName("body")(0).AppendChild(script)

End Sub

Public Sub CreateObserver(theQuery As String)

    Dim ScriptEl As String = "var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            window.external.DIVUpdated(mutation.type);
        });    
    });

    //everything
    var observerConfig = {
        attributes: true,
        subtree: true,
        childList: true, 
        characterData: true 
    };

    var targetNode = document.querySelector('" & theQuery & "');
    observer.observe(targetNode, observerConfig);"

    AddScript(ScriptEl)

End Sub

I have multiple scripts so I made a separate sub for adding each one. And because the DIV isn't loaded right away, I had to append it later (instead of in the DOC loaded event).

So, from my form I run the CreateObserver('QueryForMyDIVClassOrOtherIdentifier') and the observer triggers my .NET function DIVUpdated() with a mutation.type. In my case I'm looking for characterData changes to the contained text.

I still should add an observer.disconnect() but honestly it's not really important since in my case I'm looking to watch it for the life of the session. But I'm thinking if I return the observer object with the CreateObserver function, I could hold the variable with my .net as an Object and then use that when I do want to disconnect().

Related