jquery and mootools

Jan 26, 2011 at 5:54 AM

good project,

can i also compile jquery and mootools javascript functions?




Jan 26, 2011 at 8:01 AM

No, sorry!

Both of those frameworks rely on the existance of a browser DOM.  By default, Jurassic can only run "pure javascript" like the CoffeeScript compiler (http://jashkenas.github.com/coffee-script/).

Basically if a script does not reference "document" or "window" it will probably work.

- Paul

Jan 28, 2014 at 8:07 AM
Any plans on implementing a DOM so that jurassic can run jquery?
Jan 28, 2014 at 10:09 AM
Edited Jan 28, 2014 at 10:09 AM
No, to implement the DOM you pretty much have to implement an entire web browser. While implementing a web browser in .NET does sound fun, there would be little practical value for such a beast. Not to mention it would probably take a couple decades for me to create anything approaching a modern browser :-)
Feb 14, 2014 at 8:30 AM
Edited Feb 14, 2014 at 6:38 PM
I have recently come up against this issue. I was trying to use ClearScript.


During my research I came across a library called jsdom which implements a javascript version of the dom. In the end I decided it was not going to be worth the effort since jsdom has some dependencies on Node.js


One of the issues raised on the github repository may lead to an implementation that may help solve this problem.


Might be worth looking into?
Mar 24, 2014 at 11:04 PM
I tweaked Jurrassic a bit to use it in a DOM context. I haven't got to the point where I can try and include jQuery, but that's the direction I am headed. I basically modified the GlobalObject to allow subclassing and modified ScriptEngine constructor to allow passing the type of the replacement global object.

public class WindowObject : GlobalObject {
   public WindowObject(ObjectInstance prototype) : base(prototype) { }

   public object window {
      get { return this; }
      set { }

   public document
   ... etc ...

ScriptEngine engine = new ScriptEngine(typeof(WindowObject));
I'm pretty sure it voids the warranty but it is behaving like I would like
Mar 26, 2014 at 3:27 AM
You can modify the global object without modifying the source:
public class WindowObject : ObjectInstance {
   public WindowObject(ObjectInstance prototype) : base(prototype)

      // Populate global properties.
      this.Engine.Global["document"] = this["document"];

   public object window {
      get { return this; }
      set { }

   public document
   ... etc ...

A bit round-about maybe, but at least you still got that sweet sweet warranty ;-)
Mar 28, 2014 at 5:30 AM
I'll have to try it. How do you initialize window? I want to ensure that code cannot overwrite the value of window or document (e.g. document = 42) in the global context. I also want to make sure that unqualified window methods resolves (like 'alert()').
Mar 28, 2014 at 9:43 PM
Ultimately there are two ways to extend an object in javascript:
  1. Add additional properties to the object.
  2. Use the prototype system.
Method 2 is an inconvenient way of extending the global object in Jurassic because (as you have noted) you can't set the global object instance without modifying the source code.

Method 1 should do what you need. The simple way to add properties (in c#) is like this:
// Equivalent to test = 5 in javascript.
engine.Global["test"] = 5;
However, you can't make properties read-only using this technique. Instead, you should use DefineProperty:
// Equivalent to Object.defineProperty(this, "test", { enumerable: true, value: 5 }); in javascript.
engine.Global.DefineProperty("test", new PropertyDescriptor(5, PropertyAttributes.Enumerable), true);
The difficulty is defining methods, since Jurassic does not make it easy to convert an arbitrary .NET method to a FunctionInstance (which represents a javascript function). In the code that I included in my previous post, I am abusing PopulateFunctions to work around this problem. PopulateFunctions essentially looks at properties with [JsProperty] and methods with [JsFunction] and converts them into FunctionInstance values, then it calls DefineProperty to set those values. Those values can then be read out of the object and utilized for other things.