This project has moved. For the latest updates, please go here.

Global window object

Sep 1, 2014 at 6:13 PM
Is there a way to create a global "window" object. And has it been done already?
Coordinator
Sep 1, 2014 at 7:39 PM
Hi AndersBillLinden,

ClearScript lets you expose any .NET object to the script engine. Do you already have an implementation for the object you require?

Cheers!
Sep 1, 2014 at 8:35 PM
Edited Sep 1, 2014 at 8:36 PM
Yes, I was exposing the window object like this:
var engine = new V8ScriptEngine();
engine.AddHostObject("window", new Window());
Then I can have a class Window that looks like this:
using System;

namespace foo
{
    public class Window
    {
        public void alert(string msg)
        {
            Console.WriteLine("alert: " + msg);
        }
    }
}
Now a script can use window.alert("foo") can it will come out on the console. What I need is to set the global object to window, so I can call just alert("foo"); from a script
Sep 1, 2014 at 8:36 PM
Edited Sep 1, 2014 at 8:37 PM
Seems the forum translated my plus sign, however after I had written this comment, the plus sign was ok again
Sep 2, 2014 at 12:44 AM
Not sure if it is possible in ClearScript but this is what i used

var alert = window.alert;
var prompt = window.prompt;
var confirm = window.confirm;
Sep 2, 2014 at 5:38 AM
Then I could of course just create some global functions and run the corresponding functions in the window object from them. But javascript has a global object, so if clearscript is a correct implementation, it should have one as well.
Coordinator
Sep 2, 2014 at 12:34 PM
Hi AndersBillLinden,

The global object is provided by the underlying script engine, and ClearScript does not allow you to replace it.

However, ClearScript lets you expose a host object so that its members appear within the global namespace:
engine.AddHostObject("window", HostItemFlags.GlobalMembers, new Window());
engine.Execute("alert('hello')");
Good luck!
Sep 2, 2014 at 5:16 PM
Thanks for the answer!
Sep 2, 2014 at 5:19 PM
I think there should be anything about the HostItemFlags in the tutorial!
Coordinator
Sep 4, 2014 at 4:48 PM
Hi again,

Please be aware that the HostItemFlags.GlobalMembers feature is quite expensive. It requires the script engine to call back to the host for all global property access, and that's a performance killer for V8, at least in scenarios that require fast access to global properties.

Support for this feature is enabled by default in order to maintain API compatibility, but we recommend that performance-critical applications disable it by using V8ScriptEngineFlags.DisableGlobalMembers. Of course, if you do that, you'll have to use a different technique to expose host methods at the global level.

Cheers!
Sep 6, 2014 at 1:50 PM
Is there some implementation of a decent browser DOM as well?
Coordinator
Sep 7, 2014 at 2:58 PM
It may not be quite what you're looking for, but Html Agility Pack is quite popular.
Sep 7, 2014 at 2:59 PM
I meant DOM implementation that uses clearscript.
Sep 7, 2014 at 3:02 PM
Edited Sep 7, 2014 at 3:03 PM
It requires the script engine to call back to the host for all global property access, and that's a performance killer for V8, at least in scenarios that require fast access to global properties.
But that is what browsers do, I presume. How can it be more expensive than exposing host methods?
Coordinator
Sep 7, 2014 at 3:39 PM
Hi AndersBillLinden,

I meant DOM implementation that uses clearscript.

We aren't aware of one, but we would hope that any existing .NET implementation of the DOM would be easy to expose via ClearScript.

But that is what browsers do, I presume. How can it be more expensive than exposing host methods?

When support for HostItemFlags.GlobalMembers is enabled (as it is by default), V8 calls back to the host for all global property access, such as when a script reads or writes a global variable, or retrieves a JavaScript built-in such as Math, String, Function, etc.

When V8ScriptEngineFlags.DisableGlobalMembers is in effect, this doesn't happen. Global properties are read and written without the host's involvement. Obviously if the global property is a host object, then accessing its members still involves the host, but retrieving a reference to the host object itself does not.

With recent efforts to make JavaScript code more modular and less reliant on global data, the impact may be reduced, but ClearScriptBenchmarks clearly shows that disabling support for HostItemFlags.GlobalMembers makes a huge difference for SunSpider performance.

Good luck!
Dec 5, 2014 at 1:06 AM
I just wanted to say THANKS for this amazing project. I am also working on a private, .NET-based DOM implementation and was previously using another .NET engine for JavaScript and have recently migrated my code to use ClearScript. The GlobalMembers flag is a godsend!
Coordinator
Dec 5, 2014 at 12:36 PM
Thanks, krisoye!

GlobalMembers is an old Windows Script feature (see here) that ClearScript exposed early on when it supported only Windows Script engines, and then extended to V8 to achieve API parity.

The good news about GlobalMembers is that recent V8 drops have greatly reduced its performance impact, so if you're using it, stay tuned for the next ClearScript release :)

Cheers!
Dec 17, 2014 at 12:21 AM
So another question in regards to simulating the window object in a browser:

I have created a DynamicObject "window" which uses the GlobalMembers method which is great (access to location, screen, document, etc as expected). The thing I am trying to accomplish now is to allow dynamic properties set on the global host to be reflected in the window object and visa-versa.

e.g.

answer = 42;
console.log(window.answer); // 42

So one direction works:
window.answer = 42;

Evaluate("answer") = 42;

But this:
answer = 42;

Evaluate("window.answer") = undefined

I tried to override GetDynamicMemberNames() in my window object to include dynamic properties from the global context but that results in a stack overflow. Is there a way my window object can retrieve a list of properties from the global object without recursively coming back to itself?
Coordinator
Dec 17, 2014 at 11:50 AM
Hi again,

It sounds like you really want window to be the same as the global object, and that's very easy to set up:
engine.Execute("window = this");
Then you could simply expose your GlobalMembers host object under a different (dummy) name:
engine.AddHostObject("_window", HostItemFlags.GlobalMembers, new MyWindow());
With this setup, your host object's members - and any dynamic properties added by script code - are visible in both window and the global object (because they're one and the same). In fact, this way your host object might not need dynamic support at all.

Good luck!