Example #1
0
 // used by InitializeProjectionForType
 private JavaScriptObject CreateObjectFor(JavaScriptEngine engine, JavaScriptProjection baseTypeProjection)
 {
     if (baseTypeProjection != null)
     {
         // todo: revisit to see if there is a better way to do this
         // Can probably get
         // ((engine.GlobalObject.GetPropertyByName("Object") as JavaScriptObject).GetPropertyByName("create") as JavaScriptFunction).Invoke(baseTypeProjection.Prototype)
         // but this is so much clearer
         dynamic          global = engine.GlobalObject;
         JavaScriptObject result = global.Object.create(baseTypeProjection.Prototype);
         return(result);
     }
     else
     {
         return(engine.CreateObject());
     }
 }
        private void ProjectProperties(string owningTypeName, JavaScriptObject target, JavaScriptEngine engine, IEnumerable<PropertyInfo> properties)
        {
            foreach (var prop in properties)
            {
                if (prop.GetIndexParameters().Length > 0)
                    throw new NotSupportedException("Index properties not supported for projecting CLR to JavaScript objects.");

                JavaScriptFunction jsGet = null, jsSet = null;
                if (prop.GetMethod != null)
                {
                    jsGet = engine.CreateFunction((eng, ctor, thisObj, args) =>
                    {
                        var @this = thisObj as JavaScriptObject;
                        if (@this == null)
                        {
                            eng.SetException(eng.CreateTypeError("Could not retrieve property '" + prop.Name + "' because there was an invalid 'this' context."));
                            return eng.UndefinedValue;
                        }

                        try
                        {
                            return FromObject(prop.GetValue(@this.ExternalObject));
                        }
                        catch (Exception ex)
                        {
                            eng.SetException(FromObject(ex));
                            return eng.UndefinedValue;
                        }
                    }, owningTypeName + "." + prop.Name + ".get");
                }
                if (prop.SetMethod != null)
                {
                    jsSet = engine.CreateFunction((eng, ctor, thisObj, args) =>
                    {
                        var @this = thisObj as JavaScriptObject;
                        if (@this == null)
                        {
                            eng.SetException(eng.CreateTypeError("Could not retrieve property '" + prop.Name + "' because there was an invalid 'this' context."));
                            return eng.UndefinedValue;
                        }

                        try
                        {
                            var val = ToObject(args.First());
                            if (prop.PropertyType == typeof(int))
                            {
                                val = (int)(double)val;
                            }
                            prop.SetValue(@this.ExternalObject, val);
                            return eng.UndefinedValue;
                        }
                        catch (Exception ex)
                        {
                            eng.SetException(FromObject(ex));
                            return eng.UndefinedValue;
                        }
                    }, owningTypeName + "." + prop.Name + ".set");
                }

                var descriptor = engine.CreateObject();
                if (jsGet != null)
                    descriptor.SetPropertyByName("get", jsGet);
                if (jsSet != null)
                    descriptor.SetPropertyByName("set", jsSet);
                descriptor.SetPropertyByName("enumerable", engine.TrueValue);
                target.DefineProperty(prop.Name, descriptor);
            }
        }
 // used by InitializeProjectionForType
 private JavaScriptObject CreateObjectFor(JavaScriptEngine engine, JavaScriptProjection baseTypeProjection)
 {
     if (baseTypeProjection != null)
     {
         // todo: revisit to see if there is a better way to do this
         // Can probably get 
         // ((engine.GlobalObject.GetPropertyByName("Object") as JavaScriptObject).GetPropertyByName("create") as JavaScriptFunction).Invoke(baseTypeProjection.Prototype) 
         // but this is so much clearer
         dynamic global = engine.GlobalObject;
         JavaScriptObject result = global.Object.create(baseTypeProjection.Prototype);
         return result;
     }
     else
     {
         return engine.CreateObject();
     }
 }
Example #4
0
        private void ProjectProperties(string owningTypeName, JavaScriptObject target, JavaScriptEngine engine, IEnumerable <PropertyInfo> properties)
        {
            foreach (var prop in properties)
            {
                if (prop.GetIndexParameters().Length > 0)
                {
                    throw new NotSupportedException("Index properties not supported for projecting CLR to JavaScript objects.");
                }

                JavaScriptFunction jsGet = null, jsSet = null;
                if (prop.GetMethod != null)
                {
                    jsGet = engine.CreateFunction((eng, ctor, thisObj, args) =>
                    {
                        var @this = thisObj as JavaScriptObject;
                        if (@this == null)
                        {
                            eng.SetException(eng.CreateTypeError("Could not retrieve property '" + prop.Name + "' because there was an invalid 'this' context."));
                            return(eng.UndefinedValue);
                        }


                        object external = null;
                        if (!prop.GetMethod.IsStatic)
                        {
                            external = @this.ExternalObject;
                            if (external == null)
                            {
                                external = @this.Prototype.ExternalObject;
                            }
                            if (external == null)
                            {
                                throw new Exception("this object not found for method invocation. Perhaps it has been garbage collected.");
                            }
                        }
                        try
                        {
                            return(FromObject(prop.GetValue(external)));
                        }
                        catch (Exception ex)
                        {
                            eng.SetException(FromObject(ex), ex);
                            return(eng.UndefinedValue);
                        }
                    }, owningTypeName + "." + prop.Name + ".get");
                }
                if (prop.SetMethod != null)
                {
                    jsSet = engine.CreateFunction((eng, ctor, thisObj, args) =>
                    {
                        var @this = thisObj as JavaScriptObject;
                        if (@this == null)
                        {
                            eng.SetException(eng.CreateTypeError("Could not retrieve property '" + prop.Name + "' because there was an invalid 'this' context."));
                            return(eng.UndefinedValue);
                        }

                        try
                        {
                            var val = ToObject(args.First());
                            if (prop.PropertyType == typeof(int))
                            {
                                val = (int)(double)val;
                            }
                            var obj = @this.ExternalObject;
                            if (obj == null && @this.Prototype.ExternalObject == engine.GlobalObject.Prototype.ExternalObject)
                            {
                                obj = @this.Prototype.ExternalObject;
                            }
                            prop.SetValue(obj, val);
                            return(eng.UndefinedValue);
                        }
                        catch (Exception ex)
                        {
                            eng.SetException(FromObject(ex), ex);
                            return(eng.UndefinedValue);
                        }
                    }, owningTypeName + "." + prop.Name + ".set");
                }

                var descriptor = engine.CreateObject();
                if (jsGet != null)
                {
                    descriptor.SetPropertyByName("get", jsGet);
                }
                if (jsSet != null)
                {
                    descriptor.SetPropertyByName("set", jsSet);
                }
                descriptor.SetPropertyByName("enumerable", engine.TrueValue);
                target.DefineProperty(prop.Name, descriptor);
            }
        }