I have successfully embedded CefSharp into a .NET 4.0 application. Is it possible to get jQuery calls working on the DOM?

julian guppy picture julian guppy · Feb 19, 2013 · Viewed 17k times · Source

I am trying to find out if this is possible. I have been through the GitHub example https://github.com/chillitom/CefSharp which gave me the source code for the classes (although I could not build CefSharp itself from this GITHUB.

I did however then try the binaries download from this link https://github.com/downloads/ataranto/CefSharp/CefSharp-1.19.0.7z and then I built my C# win32 app by referencing these examples, this went reasonably smoothly and after 8 hours or so I have got a working embedded browser, yipeee. However, I am now at the point where I want to manipulate the DOM - I have read that you can only do this with webView.EvaluateScript("some script"); and webView.ExecuteScript("some script"); as direct DOM access is not available through cefsharp

So what I am trying to find out is. Can I call jQuery methods? If the page I have loaded already has jQuery loaded, can I do the following in c#?

webView.ExecuteScript("$(\"input#some_id\").val(\"[email protected]\")"));

Currently this throws an exception. I am trying to find out; should I even be trying to use jQuery from the cefsharp DLL, or do I have to stick to standard old school JavaScript that will take me 5 times as long to write...?

I am hoping a stacker will have an answer. I have tried the wikis and forums for cefsharp but they do not offer much in the way of leads; and the only examples I have found are of old school JavaScript.

Answer

user1243584 picture user1243584 · Feb 19, 2013

Yes, you can use jQuery, however you can only use it after the DOM has been fully loaded. To do this you need to use the PropertyChanged event of the WebView to check when the IsLoading property has been changed to false and the IsBrowserInitialized property is set to true.

See below a snippet of how I do it in one of my projects. As you can see, once the IsLoading property changes, I then call some methods which will setup the content in the WebView, and this is done by calling jQuery via ExecuteScript as you are doing.

/// <summary>
/// Initialise the WebView control
/// </summary>
private void InitialiseWebView()
{
    // Disable caching.
    BrowserSettings settings = new BrowserSettings();
    settings.ApplicationCacheDisabled = true;
    settings.PageCacheDisabled = true;

    // Initialise the WebView.
    this.webView = new WebView(string.Empty, settings);
    this.WebView.Name = string.Format("{0}WebBrowser", this.Name);
    this.WebView.Dock = DockStyle.Fill;

    // Setup and regsiter the marshal for the WebView.
    this.chromiumMarshal = new ChromiumMarshal(new Action(() => { this.FlushQueuedMessages(); this.initialising = false; }));
    this.WebView.RegisterJsObject("marshal", this.chromiumMarshal);

    // Setup the event handlers for the WebView.
    this.WebView.PropertyChanged += this.WebView_PropertyChanged;
    this.WebView.PreviewKeyDown += new PreviewKeyDownEventHandler(this.WebView_PreviewKeyDown);

    this.Controls.Add(this.WebView);
}

/// <summary>
/// Handles the PropertyChanged event of CefSharp.WinForms.WebView.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The event arguments.</param>
private void WebView_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
    // Once the browser is initialised, load the HTML for the tab.
    if (!this.webViewIsReady)
    {
        if (e.PropertyName.Equals("IsBrowserInitialized", StringComparison.OrdinalIgnoreCase))
        {
            this.webViewIsReady = this.WebView.IsBrowserInitialized;
            if (this.webViewIsReady)
            {
                string resourceName = "Yaircc.UI.default.htm";
                using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
                {
                    using (StreamReader reader = new StreamReader(stream))
                    {
                        this.WebView.LoadHtml(reader.ReadToEnd());
                    }
                }
            }
        }
    }

    // Once the HTML has finished loading, begin loading the initial content.
    if (e.PropertyName.Equals("IsLoading", StringComparison.OrdinalIgnoreCase))
    {
        if (!this.WebView.IsLoading)
        {
            this.SetSplashText();
            if (this.type == IRCTabType.Console)
            {
                this.SetupConsoleContent();
            }

            GlobalSettings settings = GlobalSettings.Instance;
            this.LoadTheme(settings.ThemeFileName);

            if (this.webViewInitialised != null)
            {
                this.webViewInitialised.Invoke();
            }
        }
    }
}