|
Rank: Member Groups: Member
Joined: 4/28/2016 Posts: 13
|
I'm trying to figure out how to return the result back from a JavaScript function called inside RegisterJSExtensionFunction. Thank you for any guidance you can give. My C# code looks like this
Code: C#
wb.RegisterJSExtensionFunction("GetPlugin",
new JSExtInvokeHandler((s, args) =>
{
var v = wb.QueueScriptCall("window." + plugin.Value.JSFunctionName);
v.OnDone(() =>
{
args.ReturnValue = (JSObject)v.Result;
});
}));
and I'm calling it from JavaScript like this
Code: JavaScript
GetPlugin('PluginName').OnCreditChanged = CreditChangedHandler;
I also tried this, which seemed to hang at WaitOne()
Code: C#
wb.RegisterJSExtensionFunction("GetPlugin",
new JSExtInvokeHandler((s, args) =>
{
var v = wb.QueueScriptCall("window." + plugin.Value.JSFunctionName);
v.WaitOne();
args.ReturnValue = (JSObject)v.Result
}));
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,217
|
Why do you want to use a JavaScript Extension function to call JavaScript code? Why not call the JavaScript code directly? For example, you can simply define a JavaScript function like this:
Code: C#
function GetPlugin()
{
return window.plugin.value.SomeFunctionName();
}
The extension function is designed for you to call .NET code from JavaScript and the implementation of your extension function CAN NOT call back into the JavaScript because doing so would cause the JavaScript engine to be re-entered. This is not allowed. So you can not use JavaScript extension this way.
|
|
Rank: Member Groups: Member
Joined: 4/28/2016 Posts: 13
|
That's a good questions and thank you for helping me look at this from a different angle. I simplified the example to remove the C# code, but I'm actually doing some conditional logic in C# first before calling the JavaScript.
Code: C#
wb.RegisterJSExtensionFunction("GetPlugin",
new JSExtInvokeHandler((s, args) =>
{
var plugin = webKitPlugins.Where(w => w.Key == ((string)args.Arguments[0])).FirstOrDefault();
if (plugin.Value == null) args.ReturnValue = null;
else
{
var v = wb.QueueScriptCall("window." + plugin.Value.JSFunctionName);
v.WaitOne();
args.ReturnValue = (JSObject)v.Result;
}
}));
This worked in version 18.3.46.0, but after upgrading to the latest version it hangs on the call to WaitOne() so I was trying to figure out how to avoid getting locked in to the old version. Any suggestions would be greatly appreciated and thank you again for the quick reply.
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,217
|
Hi, You will have to change your code logic to either let this to be done completely on the JavaScript side, or do it asynchronously. For example, you can have a JavaScript extension function "AcquirePlugin" that starts to "acquire plugin". Then once you have everything on the C# side, you can call back into JavaScript function "PluginReady" that sends the information back to JavaScript at a later time (after your JavaScript extension function returns). The reason that calling JavaScript code inside an extension function is not allowed is because it can cause the JavaScript engine to be re-entered and causes all kind of problems. Consider the following JavaScript code:
Code: JavaScript
var i = 1;
var x = GetPlugin();
if (i != 1)
alert("How come??");
If we allow GetPlugin to run additional JavaScript code, then that code could potentially change variable i. Then you could see the "How come??" alert. This is not allowed by JavaScript language. This is just to demonstrate what could happen logically. The reality is a lot worse because JavaScript engine by the language definition itself can not be re-entered, so the engine is hard-coded and heavily optimized based on this fact. Thus re-reentering JavaScript engine can cause all kind of crashes in the engine. Our old version did allow re-entering and it does work "most of the time", however a lot of things can go wrong. The new version fixed this loophole so this can no longer happen. Thanks!
|
|
Rank: Member Groups: Member
Joined: 4/28/2016 Posts: 13
|
That makes sense and thank you for the in-depth explanation. I'm planning to take the route of going completely JavaScript.
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,217
|
You are very welcome. Please feel free to let us know if there is anything else.
|
|
Rank: Newbie Groups: Member
Joined: 11/25/2020 Posts: 1
|
The extension function is designed for you to call .NET code from JavaScript and the implementation of your extension function CAN NOT call back into the JavaScript because doing so would cause the JavaScript engine to be re-entered. This is not allowed. So you can not use JavaScript extension this way. mcdvoice
|
|