Logo
My Account |  Site Map | Contact Us  
Welcome Guest Search | Active Topics | Sign In | Register

Return Result From QueueScriptCall Inside RegisterJSExtensionFunction Options
AndrewS
Posted: Saturday, November 7, 2020 8:06:54 PM
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
     }));


eo_support
Posted: Sunday, November 8, 2020 11:16:34 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 22,618
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.
AndrewS
Posted: Monday, November 9, 2020 11:21:14 AM
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.
eo_support
Posted: Monday, November 9, 2020 4:21:27 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 22,618
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!
AndrewS
Posted: Monday, November 9, 2020 5:32:04 PM
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.
eo_support
Posted: Monday, November 9, 2020 7:33:35 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 22,618
You are very welcome. Please feel free to let us know if there is anything else.
Scarabyte3
Posted: Wednesday, November 25, 2020 12:20:11 AM
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


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.