Пример #1
0
        public static int RegisterDelegate(JavaScriptFunction callback, SynchronizationContext syncContext)
        {
            var cookie = Interlocked.Increment(ref registrationTokens);

            eventRegistrations[cookie] = Tuple.Create(callback, syncContext);
            return(cookie);
        }
Пример #2
0
 public JavaScriptArray Filter(JavaScriptFunction predicate)
 {
     if (predicate == null)
     {
         throw new ArgumentNullException(nameof(predicate));
     }
     return(GetArrayBuiltin("filter").Invoke(this, predicate) as JavaScriptArray);
 }
Пример #3
0
        public void ForEach(JavaScriptFunction callee)
        {
            if (callee == null)
            {
                throw new ArgumentNullException(nameof(callee));
            }

            GetArrayBuiltin("forEach").Invoke(this, callee);
        }
Пример #4
0
        public JavaScriptValue ReduceRight(JavaScriptFunction aggregator, JavaScriptValue initialValue)
        {
            if (aggregator == null)
            {
                throw new ArgumentNullException(nameof(aggregator));
            }

            return(GetArrayBuiltin("reduceRight").Invoke(this, aggregator, initialValue));
        }
Пример #5
0
        public bool Some(JavaScriptFunction predicate)
        {
            if (predicate == null)
            {
                throw new ArgumentNullException(nameof(predicate));
            }

            return(GetEngine().Converter.ToBoolean(GetArrayBuiltin("some").Invoke(this, predicate)));
        }
Пример #6
0
        public JavaScriptArray Map(JavaScriptFunction converter)
        {
            if (converter == null)
            {
                throw new ArgumentNullException(nameof(converter));
            }


            return(GetArrayBuiltin("map").Invoke(this, converter) as JavaScriptArray);
        }
Пример #7
0
        internal JavaScriptValue CreateValueFromHandle(JavaScriptValueSafeHandle handle)
        {
            Debug.Assert(!(handle.IsClosed || handle.IsInvalid));

            JsValueType kind;

            Errors.ThrowIfIs(api_.JsGetValueType(handle, out kind));

            JavaScriptValue result = null;

            switch (kind)
            {
            case JsValueType.JsArray:
                result = new JavaScriptArray(handle, JavaScriptValueType.Array, this);
                break;

            case JsValueType.JsFunction:
                result = new JavaScriptFunction(handle, JavaScriptValueType.Function, this);
                break;

            case JsValueType.JsObject:
            case JsValueType.JsNull:
            case JsValueType.JsError:
                result = new JavaScriptObject(handle, JavaScriptValueType.Object, this);
                break;

            case JsValueType.JsSymbol:
                result = new JavaScriptSymbol(handle, JavaScriptValueType.Symbol, this);
                break;

            case JsValueType.JsArrayBuffer:
                result = new JavaScriptArrayBuffer(handle, JavaScriptValueType.ArrayBuffer, this);
                break;

            case JsValueType.JsTypedArray:
                result = new JavaScriptTypedArray(handle, JavaScriptValueType.TypedArray, this);
                break;

            case JsValueType.JsDataView:
                result = new JavaScriptDataView(handle, JavaScriptValueType.DataView, this);
                break;

            case JsValueType.JsBoolean:
            case JsValueType.JsNumber:
            case JsValueType.JsString:
            case JsValueType.JsUndefined:
            default:
                result = new JavaScriptValue(handle, kind.ToApiValueType(), this);
                break;
            }

            return(result);
        }
Пример #8
0
        public void Sort(JavaScriptFunction compareFunction = null)
        {
            var fn = GetArrayBuiltin("sort");
            List <JavaScriptValue> args = new List <JavaScriptValue>();

            args.Add(this);
            if (compareFunction != null)
            {
                args.Add(compareFunction);
            }

            fn.Invoke(args);
        }
Пример #9
0
        public void Sort(JavaScriptFunction compareFunction = null)
        {
            var fn = GetArrayBuiltin("sort");

            if (compareFunction != null)
            {
                fn.Invoke(this, compareFunction);
            }
            else
            {
                fn.Invoke(this);
            }
        }
Пример #10
0
        public JavaScriptValue ReduceRight(JavaScriptFunction aggregator)
        {
            if (aggregator == null)
            {
                throw new ArgumentNullException(nameof(aggregator));
            }

            var args = new List <JavaScriptValue>();

            args.Add(this);
            args.Add(aggregator);

            return(GetArrayBuiltin("reduceRight").Invoke(args));
        }
Пример #11
0
        public JavaScriptArray Map(JavaScriptFunction converter)
        {
            if (converter == null)
            {
                throw new ArgumentNullException(nameof(converter));
            }

            var args = new List <JavaScriptValue>();

            args.Add(this);
            args.Add(converter);

            return(GetArrayBuiltin("map").Invoke(args) as JavaScriptArray);
        }
Пример #12
0
        public bool Some(JavaScriptFunction predicate)
        {
            if (predicate == null)
            {
                throw new ArgumentNullException(nameof(predicate));
            }

            var args = new List <JavaScriptValue>();

            args.Add(this);
            args.Add(predicate);

            return(GetEngine().Converter.ToBoolean(GetArrayBuiltin("some").Invoke(args)));
        }
Пример #13
0
        public void ForEach(JavaScriptFunction callee)
        {
            if (callee == null)
            {
                throw new ArgumentNullException(nameof(callee));
            }

            var args = new List <JavaScriptValue>();

            args.Add(this);
            args.Add(callee);

            GetArrayBuiltin("forEach").Invoke(args);
        }
Пример #14
0
        public JavaScriptArray Filter(JavaScriptFunction predicate)
        {
            if (predicate == null)
            {
                throw new ArgumentNullException(nameof(predicate));
            }

            var args = new List <JavaScriptValue>();

            args.Add(this);
            args.Add(predicate);

            return(GetArrayBuiltin("filter").Invoke(args) as JavaScriptArray);
        }
Пример #15
0
        internal JavaScriptObject CreateObjectFromHandle(JavaScriptValueSafeHandle handle)
        {
            JsValueType kind;

            Errors.ThrowIfIs(api_.JsGetValueType(handle, out kind));

            JavaScriptObject result = null;

            switch (kind)
            {
            case JsValueType.JsArray:
                result = new JavaScriptArray(handle, JavaScriptValueType.Array, this);
                break;

            case JsValueType.JsFunction:
                result = new JavaScriptFunction(handle, JavaScriptValueType.Function, this);
                break;

            case JsValueType.JsObject:
            case JsValueType.JsError:
            case JsValueType.JsNull:
                result = new JavaScriptObject(handle, JavaScriptValueType.Object, this);
                break;

            case JsValueType.JsArrayBuffer:
                result = new JavaScriptArrayBuffer(handle, JavaScriptValueType.ArrayBuffer, this);
                break;

            case JsValueType.JsTypedArray:
                result = new JavaScriptTypedArray(handle, JavaScriptValueType.TypedArray, this);
                break;

            case JsValueType.JsDataView:
                result = new JavaScriptDataView(handle, JavaScriptValueType.DataView, this);
                break;

            case JsValueType.JsBoolean:
            case JsValueType.JsNumber:
            case JsValueType.JsString:
            case JsValueType.JsUndefined:
            case JsValueType.JsSymbol:
            default:
                throw new ArgumentException();
            }

            return(result);
        }
Пример #16
0
 public static int RegisterDelegate(JavaScriptFunction callback, SynchronizationContext syncContext)
 {
     var cookie = Interlocked.Increment(ref registrationTokens);
     eventRegistrations[cookie] = Tuple.Create(callback, syncContext);
     return cookie;
 }
Пример #17
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);
            }
        }
Пример #18
0
        private void ProjectEvents(string owningTypeName, JavaScriptObject target, JavaScriptEngine engine, IEnumerable <EventInfo> events, JavaScriptProjection baseTypeProjection, bool instance)
        {
            var eventsArray  = events.ToArray();
            var eventsLookup = eventsArray.ToDictionary(ei => ei.Name.ToLower());
            // General approach here
            // if there is a base thing, invoke that
            // for each event, register a delegate that marshals it back to JavaScript
            var add = engine.CreateFunction((eng, ctor, thisObj, args) =>
            {
                bool callBase = instance && (baseTypeProjection?.HasInstanceEvents ?? false);
                var @this     = thisObj as JavaScriptObject;
                if (@this == null)
                {
                    return(eng.UndefinedValue);
                }

                if (callBase)
                {
                    var baseObj = baseTypeProjection.Prototype;
                    var baseFn  = baseObj.GetPropertyByName("addEventListener") as JavaScriptFunction;
                    if (baseFn != null)
                    {
                        baseFn.Call(@this, args);
                    }
                }

                var argsArray = args.ToArray();
                if (argsArray.Length < 2)
                {
                    return(eng.UndefinedValue);
                }

                string eventName = argsArray[0].ToString();
                JavaScriptFunction callbackFunction = argsArray[1] as JavaScriptFunction;
                if (callbackFunction == null)
                {
                    return(eng.UndefinedValue);
                }

                EventInfo curEvent;
                if (!eventsLookup.TryGetValue(eventName, out curEvent))
                {
                    return(eng.UndefinedValue);
                }

                MethodInfo targetMethod = curEvent.EventHandlerType.GetMethod("Invoke");

                var paramsExpr = targetMethod.GetParameters().Select(p => Expression.Parameter(p.ParameterType, p.Name)).ToArray();
                int cookie     = EventMarshaler.RegisterDelegate(callbackFunction, SynchronizationContext.Current);

                var marshaler = Expression.Lambda(curEvent.EventHandlerType, Expression.Block(
                                                      Expression.Call(
                                                          typeof(EventMarshaler).GetMethod(nameof(EventMarshaler.InvokeJavaScriptCallback)),
                                                          Expression.Constant(cookie),
                                                          Expression.NewArrayInit(typeof(string), targetMethod.GetParameters().Select(p => Expression.Constant(p.Name))),
                                                          Expression.NewArrayInit(typeof(object), paramsExpr))
                                                      ), paramsExpr);

                curEvent.AddMethod.Invoke(@this.ExternalObject, new object[] { marshaler.Compile() });

                return(eng.UndefinedValue);
            }, owningTypeName + ".addEventListener");

            target.SetPropertyByName("addEventListener", add);
        }