I have a WinForms project with the CefSharp ChromiumWebBrowser control.
I have the following JavaScript in a file
var msgTypes = Object.freeze({
MessageReceived: 0
});
var config = {
childList: true,
subtree: true
};
var callback = function(mutations, observer) {
mutations.forEach((mutation) => {
if (mutation.addedNodes.length > 0)
{
var msgs = mutation.addedNodes.querySelectorAll('.message');
if (msgs != null && msgs.length > 0)
{
for(const msg of msgs)
{
var text = msg.querySelectorAll('.message-text');
if (text != null && text.length > 0)
{
CefSharp.PostMessage({"messageType": msgTypes.MessageReceived, "data":{ "text": text[0].innerText }});
}
}
}
}
});
};
var body = document.querySelector('body');
var observer = new MutationObserver(callback);
// Create an observer instance linked to the callback function
//var observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(body, config);
The C# code below executes the JavaScript above by the CefSharp ChromiumWebBrowser web browser control in a Form in the project mentioned above.
public async Task ExecuteAsync(ScriptType type)
{
string fileName = string.Join('-', Regex.Split(type.ToString(), @"(?<!^)(?=[A-Z])")).ToLower();
string filePath = Path.Combine(Globals.AppPath, "js", $"{fileName}.js");
string jsCode = await File.ReadAllTextAsync(filePath);
browser.ExecuteScriptAsync(jsCode);
}
Where browser is the WinForms ChromiumWebBrowser control.
Below is the code that executes the JavaScript above when the main frame has finished loading for the CefSharp ChromiumWebBrowser control.
private async void WebBrowser_FrameLoadEnd(object? sender, FrameLoadEndEventArgs e)
{
if (e.Frame.IsMain && !frameLoaded)
await ExecLoadJs();
if (frameLoaded)
return;
else
frameLoaded = true;
}
Below is the code that attaches a handler to the JavaScriptMessageReceived event (which is fired when the CefSharp.PostMessage is called from the JS code above.
webBrowser.JavascriptMessageReceived += WebBrowser_JavascriptMessageReceived;
webBrowser.FrameLoadEnd += WebBrowser_FrameLoadEnd;
Below is the handler code mentioned above.
private void WebBrowser_JavascriptMessageReceived(object? sender, JavascriptMessageReceivedEventArgs e)
{
HandleMessageReceived(e);
}
The problem is that the handler above only gets fired when the is page loaded. Afterwards, when the DOM changes in real-time, the handler no longer gets fired. So it seems like the MutationObserver is not working as it should with the CefSharp ChromiumWebBrowser control. However, the same JavaScript code works correctly in a Chrome Extension (omitted from this) I created that does the same; that is, the MutationObserver in the Chrome Extension is constantly detecting real-time DOM changes. This appear a very difficult problem to solve. A solution/code sample would be much appreciated.
Attached the debugger, ran the project in debug mode with VS and was expecting the WebBrowser_JavascriptMessageReceived to fire continuously after DOM changes. However, the breakpoint only fires after the page loads.