예제 #1
0
파일: JsBinding.cs 프로젝트: enklu/orchid
 /// <summary>
 /// Creates a new <see cref="JsBinding"/> instance.
 /// </summary>
 public JsBinding(JsContextScope scope, JsBinder binder, JsInterop interop, JavaScriptValue value)
 {
     _scope   = scope;
     _binder  = binder;
     _interop = interop;
     _value   = value;
 }
예제 #2
0
        /// <summary>
        /// Determine if the <see cref="Type"/> provided is suitable to be passed the provided JS value.
        /// </summary>
        public static bool IsAssignable(JavaScriptValue value, JsBinder bindingData, Type toType)
        {
            switch (value.ValueType)
            {
            case JavaScriptValueType.Undefined: return(true);

            case JavaScriptValueType.Null: return(true);

            case JavaScriptValueType.Boolean: return(IsBoolType(toType));

            case JavaScriptValueType.String: return(IsStringType(toType));

            case JavaScriptValueType.Number: return(IsNumberType(toType));

            case JavaScriptValueType.Function: return(IsFunctionType(toType));

            case JavaScriptValueType.Array: return(IsArrayType(value, bindingData, toType));

            case JavaScriptValueType.TypedArray: return(IsArrayType(value, bindingData, toType));

            case JavaScriptValueType.Object: return(IsObjectAssignable(value, bindingData, toType));

            default:
            {
                Log.Warning(null, "IsAssignable doesn't support the JS Value Type: {0}", value.ValueType);
                return(false);
            }
            }
        }
예제 #3
0
        /// <summary>
        /// This method should be used to perform type checking when the <see cref="JavaScriptValue"/> is of
        /// value type <see cref="JavaScriptValueType.Object"/>. It will use the live binding data to reverse
        /// lookup types bound to JS objects.
        /// </summary>
        private static bool IsObjectAssignable(JavaScriptValue value, JsBinder bindingData, Type toType)
        {
            // Naive Case
            if (typeof(object) == toType)
            {
                return(true);
            }

            // Attempt to locate the type from live binding data, determine if assignable
            if (TryGetJsObjectType(value, bindingData, out var objectType))
            {
                return(toType.IsAssignableFrom(objectType));
            }

            return(false);
        }
예제 #4
0
        /// <summary>
        /// Attempts to get the <see cref="Type"/> bound to  the JS value as long as the JS value has
        /// a the value type of <see cref="JavaScriptValueType.Object"/>
        /// </summary>
        private static bool TryGetJsObjectType(JavaScriptValue value, JsBinder bindingData, out Type type)
        {
            if (!value.IsValid || value.ValueType != JavaScriptValueType.Object)
            {
                type = typeof(void);
                return(false);
            }

            var boundObject = bindingData.ObjectLinkedTo(value);

            if (null == boundObject)
            {
                type = typeof(void);
                return(false);
            }

            type = boundObject.GetType();
            return(true);
        }
예제 #5
0
        /// <summary>
        /// Determines whether or not the <see cref="Type"/> is a valid JS type for array conversions.
        /// </summary>
        private static bool IsArrayType(JavaScriptValue value, JsBinder bindingData, Type type)
        {
            if (!type.IsArray)
            {
                return(false);
            }

            // Check length, if empty, we can assume it matches any of the array types
            var length = value.GetProperty(JavaScriptPropertyId.FromString("length")).ToInt32();

            if (length <= 0)
            {
                return(true);
            }

            // Look at the first element, type check against the host array element type
            var firstElement = value.GetIndexedProperty(JavaScriptValue.FromInt32(0));
            var elementType  = type.GetElementType();

            return(IsAssignable(firstElement, bindingData, elementType));
        }
예제 #6
0
 /// <summary>
 /// Creates a new <see cref="JsInterop"/> instance.
 /// </summary>
 /// <param name="scope"></param>
 public JsInterop(JsExecutionContext context, JsContextScope scope, JsBinder binder)
 {
     _context = context;
     _scope   = scope;
     _binder  = binder;
 }
예제 #7
0
 /// <summary>
 /// Creates a new <see cref="JsBindingBuilder"/> instance.
 /// </summary>
 public JsBindingBuilder(JsContextScope scope, JsBinder binder, JsInterop interop)
 {
     _scope   = scope;
     _binder  = binder;
     _interop = interop;
 }