Search code examples
javascriptc#winformscefsharp

CefSharp get a part from a Source Code of a selected/active element


enter image description here

Hello everyone 😊 and already thanks in advance!

I need to somehow get only a part of a loaded Website Source Code (Picture point 2) by hovering (if not possible I would also be happy with a mouse click) over an element (Picture point 1). I know it sounds maybe weird because the DevTool does it already really nice with just a click (Picture point 3). But if possible I would like to only read out the inner- and outer-HTML (whichever I need in the moment) the part which is active/selected.

What I have reached is:

int counter = 0;

private async void timer1_Tick(object sender, EventArgs e)
{
        string returnValue = "";

        string script = "(function() { return document.activeElement.outerHTML; })();";

        var task = browser.GetMainFrame().EvaluateScriptAsync(script);

        await task.ContinueWith(t =>
        {
            if (!t.IsFaulted)
            {
                var response = t.Result;

                if (response.Success && response.Result != null)
                {
                    returnValue = response.Result.ToString();
                }
            }
        });

        if (returnValue != "")
        {
            richTextBox1.Invoke(new Action(() => richTextBox1.Text = returnValue));
        }
        else // Just to check if there still happens something:
        {
            counter += 1;
            richTextBox1.Invoke(new Action(() => richTextBox1.Text = counter.ToString() ));
        }
}

With this code the problem seems solved 😆. But I wonder if there is an "better" way without an timer.


Solution

  • The answer or lets say the better solution is (thanks to @amaitland) to throw that timer away and use instead (in Form_Load or whereever you setup everything):

    browser.JavascriptMessageReceived += OnBrowserJavascriptMessageReceived;
    browser.FrameLoadEnd += Browser_FrameLoadEnd;
    

    and put my code in:

    private void OnBrowserJavascriptMessageReceived(object sender, JavascriptMessageReceivedEventArgs e)
    {
        // the code
    }
    

    And also you need:

    async void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
    { // Does wait till the Website is fully loaded.
        if (e.Frame.IsMain)
        {
            //In the main frame we inject some javascript that's run on mouseUp
            //You can hook any javascript event you like.
            browser.ExecuteScriptAsync(@"
                  document.body.onmouseup = function()
                  {
                    //CefSharp.PostMessage can be used to communicate between the browser
                    //and .Net, in this case we pass a simple string,
                    //complex objects are supported, passing a reference to Javascript methods
                    //is also supported.
                    //See https://github.com/cefsharp/CefSharp/issues/2775#issuecomment-498454221 for details
                    CefSharp.PostMessage(window.getSelection().toString());
                  }
            ");
        }
    }