1

I am trying to insert my own javascript to present HTML(index.html - present in IsolatedStorage) at runtime. To get call from javascript to c# webBrowser_ScriptNotify. How I will achieve this, here is my attempts to achieve this.

string script = " <script type=\"text/javascript\"> function scriptNotify() { window.external.notify(\"runtime\");}</script>";
byte[] param = GetBytes(script);

webBrowser.Navigate(new Uri("/index.html", UriKind.Relative), param,"Content-Type: application/x-www-form-urlencoded");


private void webBrowser_ScriptNotify(object sender, NotifyEventArgs e)
{            
   if (e.Value.ToString().Equals("runtime"))
   {
       Debug.WriteLine("Call from dynamic javascript");
   }
}   

static byte[] GetBytes(string str)
{
    byte[] bytes = new byte[str.Length * sizeof(char)];
    System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
    return bytes;
}

Update

Here my new try to inject script tag in currently opened HTML page.

var scriptString = "var script=document.createElement('script');"
                                   + "script.type=\"text/javascript\";"
                                   + "script.InnerHTML=\"function callMe(){window.external.notify(\"runtime\")};\""
                                    + "document.getElementsByTagName('head')[0].appendChild(script);";

webBrowser.InvokeScript("eval", scriptString);

its failed with some system error.

System.SystemException was unhandled
Message: An unhandled exception of type 'System.SystemException' occurred in Microsoft.Phone.Interop.ni.dll
Additional information: An unknown error has occurred. Error: 80020101.

StackTrace:

at Microsoft.Phone.Controls.NativeMethods.ValidateHResult(Int32 hr)
   at Microsoft.Phone.Controls.WebBrowserInterop.InvokeScript(String scriptName, String[] args)
   at Microsoft.Phone.Controls.WebBrowser.InvokeScript(String scriptName, String[] args)
   at WebBrowserJSTest.MainPage.webBrowser_LoadCompleted(Object sender, NavigationEventArgs e)

Thanks in advance.

gofor.net
  • 4,218
  • 10
  • 43
  • 65

3 Answers3

1

Note that eval is known to work when there's already at least one <script> tag on the page.

The following solution uses webBrowser.InvokeScript("setTimeout", ...) to execute some JavaScript (and thus enable eval). I tested this approach with a Windows Store app and it works there. I expect it to work with Windows Phone too, hopefully you'd be able to confirm it.

async Task ExecScriptNotify()
{
    // load a blank page
    var tcsLoad = new TaskCompletionSource<object>();
    this.webBrowser.NavigationCompleted += (s, eArgs) =>
        tcsLoad.TrySetResult(Type.Missing);
    this.webBrowser.NavigateToString("<body></body>");
    await tcsLoad.Task;

    // first add a script via "setTimeout", JavaScript gets initialized
    var tcsInit = new TaskCompletionSource<object>();
    this.webBrowser.ScriptNotify += (s, eArgs) =>
    {
        if (eArgs.Value == "initialized")
            tcsInit.TrySetResult(Type.Missing);
    };
    this.webBrowser.InvokeScript("setTimeout", 
        new string[] { "window.external.notify('initialized')", "0" });
    await tcsInit.Task;

    // then use "eval"
    this.webBrowser.InvokeScript("eval", 
        new string[] { "document.body.style.backgroundColor = 'yellow'" });
}
noseratio
  • 59,932
  • 34
  • 208
  • 486
  • 1
    thanks for suggestion, I have tried your code and its working fine. But the last line `document.body.style.backgroundColor = 'yellow'` instead I replace it with my code `var scriptString = "var script=document.createElement('script');" + "script.type=\"text/javascript\";" + "script.src='/rtemaster.js'" + "this.document.getElementsByTagName('head')[0].appendChild(script);"; webBrowser.InvokeScript("eval", scriptString);` – gofor.net Aug 22 '14 at 05:37
  • @gofor.net, good to know it works under Windows Phone. I'm a bit surprised `script.src='/rtemaster.js` works too. Or does it not? – noseratio Aug 22 '14 at 06:02
0

WebBrowser.InvokeScript Method

Narek
  • 459
  • 2
  • 13
  • thanks for reply Narek, but I don't want to call present javascript function from c#. I want to append new javascript function to HTML file which is currently open in WebBrowser control. – gofor.net Aug 21 '14 at 10:03
0

try something like this:

string script = "//Your JS method "; string elementInnerText = (string)WebBrowser1.InvokeScript("eval", script);

Rajesh KP
  • 17
  • 8
  • In Windows Phone 8 `webBrowser1.Document` is not supported. Can you please suggest some other workaround for the solution. – gofor.net Aug 21 '14 at 12:22
  • for windows phone, use something like this: string script = "function() { return document.getElementById('ElementID').innerText; }"; string elementInnerText = (string)WebBrowser1.InvokeScript("eval", script); – Rajesh KP Aug 21 '14 at 12:47
  • thanks for quick reply, but if I want to append new script tag with javascript into present HTML then how I will achieve this? – gofor.net Aug 21 '14 at 13:00