jsem
jsem

Reputation: 181

how to return javascript function value from webbrowser c#

hi Awesomium browser provide JavaScript execute with result method to return values like this :

private const String JS_FAVICON = "(function(){links = document.getElementsByTagName('link'); wHref=window.location.protocol + '//' + window.location.hostname + '/favicon.ico'; for(i=0; i<links.length; i++){s=links[i].rel; if(s.indexOf('icon') != -1){ wHref = links[i].href }; }; return wHref; })();";
string val = webControl.ExecuteJavascriptWithResult(JS_FAVICON); 

however i need to perform this with c# builtin browser how to do it, i think there is method "webBrowser1.Document.InvokeScript" not sure how to use it..

edited... this how Awesomium browser return the value:

private void Awesomium_Windows_Forms_WebControl_DocumentReady(object  sender, UrlEventArgs e)
    {
        // DOM is ready. We can start looking for a favicon.
        //UpdateFavicon();
    }


 private void UpdateFavicon()
    {
        // Execute some simple javascript that will search for a favicon.
        string val = webControl.ExecuteJavascriptWithResult(JS_FAVICON);

        // Check for any errors.
        if (webControl.GetLastError() != Error.None)
            return;

        // Check if we got a valid response.
        if (String.IsNullOrEmpty(val) || !Uri.IsWellFormedUriString(val, UriKind.Absolute))
            return;

        // We do not need to perform the download of the favicon synchronously.
        // May be a full icon set (thus big).
        Task.Factory.StartNew<Icon>(GetFavicon, val).ContinueWith(t =>
        {
            // If the download completed successfully, set the new favicon.
            // This post-completion procedure is executed synchronously.

            if (t.Exception != null)
                return;

            if (t.Result != null)
                this.Icon = t.Result;

            if (this.DockPanel != null)
                this.DockPanel.Refresh();
        },
        TaskScheduler.FromCurrentSynchronizationContext());
    }

    private static Icon GetFavicon(Object href)
    {
        using (WebClient client = new WebClient())
        {
            Byte[] data = client.DownloadData(href.ToString());

            if ((data == null) || (data.Length <= 0))
                return null;

            using (MemoryStream ms = new MemoryStream(data))
            {
                try
                {
                    return new Icon(ms, 16, 16);
                }
                catch (ArgumentException)
                {
                    // May not be an icon file.
                    using (Bitmap b = new Bitmap(ms))
                        return Icon.FromHandle(b.GetHicon());
                }
            }
        }
    }

and this is how i did it with WinForm browser:

 private void webBrowser1_DocumentCompleted(object sender,   WebBrowserDocumentCompletedEventArgs e)
 {
        UpdateFavicon();
 }
 private void UpdateFavicon()
 {
   var obj = webBrowser1.Document.InvokeScript("_X_");
   string val = webBrowser1.DocumentText = "<script> function _X_(){return " + JS_FAVICON + ";} </script>"; 
 }

Upvotes: 0

Views: 3056

Answers (1)

Eser
Eser

Reputation: 12546

it is not imposible as @JohnSmith says

With a simple trick you can get the return value from javascript

string JS_FAVICON = "(function(){links = document.getElementsByTagName('link'); wHref=window.location.protocol + '//' + window.location.hostname + '/favicon.ico'; for(i=0; i<links.length; i++){s=links[i].rel; if(s.indexOf('icon') != -1){ wHref = links[i].href }; }; return wHref; })();";

webBrowser1.DocumentCompleted += (s, e) =>
{
    var obj = webBrowser1.Document.InvokeScript("_X_");
    //obj will be about:///favicon.ico
    //write your code that handles the return value here
};

string val = webBrowser1.DocumentText = "<script> function _X_(){return " + JS_FAVICON + ";} </script>";

But since we can get the value in DocumentCompleted handler, you can not return it from calling method directly. If you can continue your work, in that method, then no problem. If not, then it needs some more tricks to get it done. Let me know...

UPDATE

Here is full working code, Just invoke TestJavascript somewhere in your form.

async void TestJavascript()
{
    string JS_FAVICON = "(function(){links = document.getElementsByTagName('link'); wHref=window.location.protocol + '//' + window.location.hostname + '/favicon.ico'; for(i=0; i<links.length; i++){s=links[i].rel; if(s.indexOf('icon') != -1){ wHref = links[i].href }; }; return wHref; })();";

    var retval = await Execute(webBrowser1, JS_FAVICON);
    MessageBox.Show(retval.ToString());
}

Task<object> Execute(WebBrowser wb,  string anonJsFunc)
{
    var tcs = new TaskCompletionSource<object>();
    WebBrowserDocumentCompletedEventHandler documentCompleted = null;
    documentCompleted = (s, e) =>
    {
        var obj = wb.Document.InvokeScript("_X_");
        tcs.TrySetResult(obj);
        wb.DocumentCompleted -= documentCompleted; //detach
    };

    wb.DocumentCompleted += documentCompleted; //attach
    string val = wb.DocumentText = "<script> function _X_(){return " +
                                    anonJsFunc +
                                    ";} </script>";

    return tcs.Task;
}

Upvotes: 1

Related Questions