public static int RegisterDelegate(JavaScriptFunction callback, SynchronizationContext syncContext) { var cookie = Interlocked.Increment(ref registrationTokens); eventRegistrations[cookie] = Tuple.Create(callback, syncContext); return(cookie); }
public JavaScriptArray Filter(JavaScriptFunction predicate) { if (predicate == null) { throw new ArgumentNullException(nameof(predicate)); } return(GetArrayBuiltin("filter").Invoke(this, predicate) as JavaScriptArray); }
public void ForEach(JavaScriptFunction callee) { if (callee == null) { throw new ArgumentNullException(nameof(callee)); } GetArrayBuiltin("forEach").Invoke(this, callee); }
public JavaScriptValue ReduceRight(JavaScriptFunction aggregator, JavaScriptValue initialValue) { if (aggregator == null) { throw new ArgumentNullException(nameof(aggregator)); } return(GetArrayBuiltin("reduceRight").Invoke(this, aggregator, initialValue)); }
public bool Some(JavaScriptFunction predicate) { if (predicate == null) { throw new ArgumentNullException(nameof(predicate)); } return(GetEngine().Converter.ToBoolean(GetArrayBuiltin("some").Invoke(this, predicate))); }
public JavaScriptArray Map(JavaScriptFunction converter) { if (converter == null) { throw new ArgumentNullException(nameof(converter)); } return(GetArrayBuiltin("map").Invoke(this, converter) as JavaScriptArray); }
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); }
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); }
public void Sort(JavaScriptFunction compareFunction = null) { var fn = GetArrayBuiltin("sort"); if (compareFunction != null) { fn.Invoke(this, compareFunction); } else { fn.Invoke(this); } }
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)); }
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); }
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))); }
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); }
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); }
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); }
public static int RegisterDelegate(JavaScriptFunction callback, SynchronizationContext syncContext) { var cookie = Interlocked.Increment(ref registrationTokens); eventRegistrations[cookie] = Tuple.Create(callback, syncContext); return cookie; }
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); } }
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); }