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

2

7

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.

Elwell answered 19/2, 2013 at 16:21 Comment(4)
JQuery should work just fine in CefSharp, since ExecuteScript just runs everything you give it in the global scope. Can you be more specific about what you mean by "thrown out"? You might want to write some test code using plain old JS like getElementById and confirm that that's working, before you try to use jQuery, just to reduce the number of things that could be going wrong.Plenary
yes of course its a good idea to do that and indeed I got plain old JS working fine, however when tryin gto do jquery selectors etc..I get an error on the console saying things like $ is not recognized... so what I was looking for was the syntax of what I should do to include jquery and call it... i may be getting closer but I am not there yetElwell
@julianguppy Has this been solved?Fraenum
Well I was under such time pressure that I ended using executescript and evaluatescript methods to achieve what I wanted it would have been easier to use jquery but I got it working withoutElwell
M
6

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();
            }
        }
    }
}
Malanie answered 19/2, 2013 at 20:25 Comment(4)
I have indeed made sure that the browser is loaded and I have the PropertyChanged event etc... and I may be being daft here But I cant see from this how I can add jquery to the dom of a loaded page and then make a call to reference an item in the dom using the jquery selectors... or is the piece of code inside webViewInitialised() which you invoke? or is it the registerJSObject? Could you elaborate just a little more? thanksElwell
Hi @julianguppy - sorry, I didn't realise you needed help loading it in. there is a line which reads "LoadHtml(reader.ReadToEnd())", in that reader is a full HTML page, which contains the minified version of jQuery (see this file: github.com/intninety/yaircc/blob/master/yaircc/UI/default.htm). You can ignore the call to registerJSObject, that isn't needed to use jQuery, it's just something I use to call back into the assembly from the web page itself.Malanie
My Situation is that I have a page that has already been loaded - say from tesco.com and I want to analyse elements on that page. Tesco.com does not have jquery I wanted to find out can i add JQeury to the dom and then start using it to select elements in the page? thus making it about a million times easier to analyze the page with nice jquery selectors? although your answer kind of says yes its possible I need to know can you add it after the fact and then use it? thanks for your responses so far they have been usefulElwell
In that case, you'd need to load jQuery yourself into the page via the ExecuteScript method, running a piece of JavaScript similar to this: https://mcmap.net/q/118623/-how-to-append-lt-script-gt-lt-script-gt-in-javascript-duplicate if however the page you are on already has jQuery included you may run into some issues.Malanie
G
1

You made it more clear in the comments that what you want to do is load jQuery into a page that doesn't already have it. int0x90's suggestion about running ExecuteScript on a local copy of the jQuery source might work for you. I want to caution you though, many pages won't be compatible with all the extra JS that their authors never put there. Two big examples are Google and Facebook. Both of those define a $ operator that is not the jQuery $, so stomping on that will almost certainly break them.

The underlying CEF library exposes a lot of methods for directly manipulating DOM elements from C++, which CefSharp hasn't exposed because there hasn't been much demand for them yet. It sounds like that's really what you'd want to be using here, though. It might not be too much work to expose them, if you took a look at the CefSharp source, but I haven't tried myself. If you want to try it, you can also post questions to https://groups.google.com/forum/#!forum/cefsharp

Galleon answered 21/2, 2013 at 19:41 Comment(1)
jQuery.noconflict should make it compatible on pages which already defined $Raab

© 2022 - 2024 — McMap. All rights reserved.