Exemple #1
0
        public PropertyMapper(IPropertyDescriptor descriptor, bool isDefaultIdentity)
        {
            this.Descriptor = descriptor;
            this.IsDefaultIdentity = isDefaultIdentity;

            this.TypeProcessor = this.Descriptor.GetTypeProcessor();
            if (this.TypeProcessor == null)
            {
                var type = descriptor.Property.PropertyType;
                if (type.IsEnum)
                {
                    this.TypeProcessor = new EnumProcessor(descriptor.Property);
                }
                else if (typeof(IList).IsAssignableFrom(type))
                {
                    this.TypeProcessor = new ArrayProcessor(descriptor.Property);
                }
                else
                {
                    this.TypeProcessor = new BasicProcessor();
                }
            }

            this.Accessor = new PropertyAccessor(descriptor.Property);
        }
Exemple #2
0
 public bool TryGetProperty(IPropertyDescriptor property, out IAbstractPropertySetter value)
 {
     ResolvedPropertySetter result;
     value = null;
     if (!Properties.TryGetValue((DotvvmProperty)property, out result)) return false;
     value = result;
     return true;
 }
 public bool Equals(IPropertyDescriptor other)
 {
     return Value == other.Value
         && Writable == other.Writable
         && Get == other.Get
         && Set == other.Set
         && Enumerable == other.Enumerable
         && Configurable == other.Configurable;
 }
        public override bool EnterMapping(IPropertyDescriptor key, object value)
        {
            var defaultValueAttribute = (DefaultValueAttribute)key.Property.GetCustomAttributes(typeof(DefaultValueAttribute), true).FirstOrDefault();
            var defaultValue = defaultValueAttribute != null
                ? defaultValueAttribute.Value
                : GetDefault(key.Property.PropertyType);

            return !_objectComparer.Equals(value, defaultValue)
                   && base.EnterMapping(key, value);
        }
		public override bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value)
		{
			var defaultValueAttribute = key.GetCustomAttribute<DefaultValueAttribute>();
			var defaultValue = defaultValueAttribute != null
				? defaultValueAttribute.Value
				: GetDefault(key.Type);

			return !_objectComparer.Equals(value.Value, defaultValue)
				   && base.EnterMapping(key, value);
		}
Exemple #6
0
        public virtual IPropertyDescriptor DefineOwnProperty(IPropertyDescriptor descriptor)
        {
            if (!Extensible)
            {
                throw new JsTypeException();
            }
            var existing = GetOwnProperty(descriptor.Name);
            if ((existing != null) && !existing.Configurable)
            {
                throw new JsTypeException();
            }
            if (_properties == null)
            {
                _properties = new Dictionary<string, IPropertyDescriptor>();
            }

            return _properties[descriptor.Name] = descriptor;
        }
        public override ITypeDescriptor GetChildDataContextType(ITypeDescriptor dataContext, IDataContextStack controlContextStack, IAbstractControl control, IPropertyDescriptor property = null)
        {
            IPropertyDescriptor controlProperty;
            if (!control.Metadata.TryGetProperty(PropertyName, out controlProperty))
            {
                throw new Exception($"The property '{PropertyName}' was not found on control '{control.Metadata.Type}'!");
            }

            IAbstractPropertySetter setter;
            if (control.TryGetProperty(controlProperty, out setter))
            {
                var binding = setter as IAbstractPropertyBinding;
                if (binding == null)
                {
                    return dataContext;
                }
                return binding.Binding.ResultType;
            }
            else
            {
                if (AllowMissingProperty) return dataContext;
                else throw new Exception($"Property '{PropertyName}' is required on '{control.Metadata.Type.Name}'.");
            }
        }
Exemple #8
0
 public RenamedPropertyDescriptor(IPropertyDescriptor inner, string name)
 {
     _inner = inner;
     _name  = name;
 }
 /// <summary>
 /// Gets the inner property elements and makes sure that no other content is present.
 /// </summary>
 private IEnumerable <TNode> FilterNodes <TNode>(IEnumerable <DothtmlNode> nodes, IPropertyDescriptor property) where TNode : DothtmlNode
 {
     foreach (var child in nodes)
     {
         if (child is TNode)
         {
             yield return((TNode)child);
         }
         else if (child.IsNotEmpty())
         {
             child.AddError($"Content is not allowed inside the property '{property.FullName}'! (Conflicting node: Node {child.GetType().Name})");
         }
     }
 }
Exemple #10
0
 /// <summary>
 /// Compiles the binding.
 /// </summary>
 protected abstract IAbstractBinding CompileBinding(DothtmlBindingNode node, BindingParserOptions bindingOptions, IDataContextStack context, IPropertyDescriptor property);
Exemple #11
0
 public OverridePropertyDescriptor(IPropertyDescriptor baseDescriptor, YamlAttributeOverrides overrides, Type classType)
 {
     this.baseDescriptor = baseDescriptor;
     this.overrides      = overrides;
     this.classType      = classType;
 }
Exemple #12
0
            => control.Content.All(c => !DothtmlNodeHelper.IsNotEmpty(c.DothtmlNode)); // allow only whitespace literals

        public static bool HasProperty(this IAbstractControl control, IPropertyDescriptor property)
        {
            IAbstractPropertySetter blackHole;
            return control.TryGetProperty(property, out blackHole);
        }
Exemple #13
0
 public IAbstractPropertyControlCollection BuildPropertyControlCollection(IPropertyDescriptor property, IEnumerable<IAbstractControl> controls)
 {
     return new ResolvedPropertyControlCollection((DotvvmProperty)property, controls.Cast<ResolvedControl>().ToList());
 }
Exemple #14
0
 protected abstract bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value);
 public abstract ITypeDescriptor GetChildDataContextType(ITypeDescriptor dataContext, IDataContextStack controlContextStack, IAbstractControl control, IPropertyDescriptor property = null);
Exemple #16
0
 bool IObjectGraphVisitor.EnterMapping(IPropertyDescriptor key, IObjectDescriptor value) =>
 true;
        public override ITypeDescriptor GetChildDataContextType(ITypeDescriptor dataContext, IDataContextStack controlContextStack, IAbstractControl control, IPropertyDescriptor property = null)
        {
            IPropertyDescriptor controlProperty;

            if (!control.Metadata.TryGetProperty(PropertyName, out controlProperty))
            {
                throw new Exception($"The property '{PropertyName}' was not found on control '{control.Metadata.Type}'!");
            }

            IAbstractPropertySetter setter;

            if (control.TryGetProperty(controlProperty, out setter))
            {
                var binding = setter as IAbstractPropertyBinding;
                if (binding == null)
                {
                    return(dataContext);
                }
                return(binding.Binding.ResultType);
            }
            else
            {
                if (AllowMissingProperty)
                {
                    return(dataContext);
                }
                else
                {
                    throw new Exception($"Property '{PropertyName}' is required on '{control.Metadata.Type.Name}'.");
                }
            }
        }
Exemple #18
0
 public IAbstractPropertyBinding BuildPropertyBinding(IPropertyDescriptor property, IAbstractBinding binding)
 {
     return new ResolvedPropertyBinding((DotvvmProperty)property, (ResolvedBinding)binding);
 }
Exemple #19
0
 public IAbstractPropertyValue BuildPropertyValue(IPropertyDescriptor property, object value)
 {
     return new ResolvedPropertyValue((DotvvmProperty)property, value);
 }
Exemple #20
0
 public IAbstractPropertyTemplate BuildPropertyTemplate(IPropertyDescriptor property, IEnumerable<IAbstractControl> templateControls)
 {
     return new ResolvedPropertyTemplate((DotvvmProperty)property, templateControls.Cast<ResolvedControl>().ToList());
 }
 protected virtual ITypeDescriptor GetCollectionType(IPropertyDescriptor property)
 {
     return(property.PropertyType.TryGetArrayElementOrIEnumerableType());
 }
Exemple #22
0
 bool IObjectGraphVisitor <Nothing> .EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, Nothing context)
 {
     return(EnterMapping(key, value));
 }
		public abstract IDataContextStack ChangeStackForChildren(IDataContextStack original, IAbstractControl control, IPropertyDescriptor property, Func<IDataContextStack, ITypeDescriptor, IDataContextStack> createNewFrame);
 protected override bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value)
 {
     return(true);
 }
Exemple #25
0
        public override bool DefineOwnProperty(string p, IPropertyDescriptor desc, bool @throw)
        {
            var oldLenDesc = GetOwnProperty("length");
            var oldLen = oldLenDesc.Value;

            if (p == "length")
            {
                if (desc.Value == null)
                {
                    return base.DefineOwnProperty(p, desc, @throw);
                }

                var newLenDesc = ((SPropertyDescriptor)desc).Copy();
                var newLen = desc.Value.ConvertToUInt32();

                if (desc.Value.ConvertToNumber().BaseValue != newLen.BaseValue)
                {
                    throw Environment.CreateRangeError("");
                }

                newLenDesc.Value = newLen;

                if (newLen.BaseValue >= oldLen.ConvertToNumber().BaseValue)
                {
                    return base.DefineOwnProperty(p, newLenDesc, @throw);
                }

                if (!(oldLenDesc.Writable ?? false))
                {
                    if (!@throw) return false;
                    throw Environment.CreateTypeError("");
                }

                var newWritable = true;
                if (newLenDesc.Writable != null && !newLenDesc.Writable.Value)
                {
                    newWritable = false;
                    newLenDesc.Writable = true;
                }

                var succeeded = base.DefineOwnProperty("length", newLenDesc, @throw);

                if (!succeeded)
                {
                    return false;
                }

                var nl = newLen.BaseValue;
                var ol = oldLen.ConvertToUInt32().BaseValue;

                while (nl < ol)
                {
                    --ol;

                    var cannotDelete = Delete(ol.ToString(), false);
                    if (!cannotDelete)
                    {
                        newLenDesc.Value = Environment.CreateNumber(ol + 1.0);
                        if (!newWritable)
                        {
                            newLenDesc.Writable = false;
                        }
                        base.DefineOwnProperty("length", newLenDesc, false);
                        if (!@throw) return false;
                        throw Environment.CreateTypeError("");
                    }
                }

                if (!newWritable)
                {
                    base.DefineOwnProperty("length", Environment.CreateDataDescriptor(null, false, null, null), false);
                }

                return true;
            }

            var index = Environment.CreateString(p).ConvertToUInt32();
            if (index.ConvertToString().BaseValue == p && index.BaseValue != 4294967295)
            {
                var oldLenVal = oldLen.ConvertToNumber().BaseValue;
                if (index.BaseValue >= oldLenVal && (!(oldLenDesc.Writable ?? false)))
                {
                    if (!@throw) return false;
                    throw Environment.CreateTypeError("");
                }

                var succeeded = base.DefineOwnProperty(p, desc, @throw);
                if (!succeeded)
                {
                    if (!@throw) return false;
                    throw Environment.CreateTypeError("");
                }

                if (index.BaseValue >= oldLenVal)
                {
                    oldLenDesc.Value = Environment.CreateNumber(index.BaseValue + 1.0);
                    base.DefineOwnProperty("length", oldLenDesc, false);
                }

                return true;
            }

            return base.DefineOwnProperty(p, desc, @throw);
        }
 protected ValidationRule(IPropertyDescriptor property)
 {
     _property = property;
 }
Exemple #27
0
 protected override IAbstractBinding CompileBinding(DothtmlBindingNode node, BindingParserOptions bindingOptions, IDataContextStack context, IPropertyDescriptor property)
 {
     if (context == null)
     {
         node.AddError("The DataContext couldn't be evaluated because of the errors above.");
     }
     return(treeBuilder.BuildBinding(bindingOptions, context, node, property));
 }
Exemple #28
0
        public override ITypeDescriptor GetChildDataContextType(ITypeDescriptor dataContext, IDataContextStack controlContextStack, IAbstractControl control, IPropertyDescriptor property = null)
        {
            if (!control.Metadata.TryGetProperty(PropertyName, out var controlProperty))
            {
                throw new Exception($"The property '{PropertyName}' was not found on control '{control.Metadata.Type}'!");
            }

            if (control.TryGetProperty(controlProperty, out var setter))
            {
                return(setter is IAbstractPropertyBinding binding
                    ? binding.Binding.ResultType ?? throw new Exception($"The '{controlProperty.Name}' property contains invalid data-binding")
                    : dataContext);
            }

            if (AllowMissingProperty)
            {
                return(dataContext);
            }

            throw new Exception($"Property '{PropertyName}' is required on '{control.Metadata.Type.Name}'.");
        }
Exemple #29
0
        public static (ITypeDescriptor type, List <BindingExtensionParameter> extensionParameters) ApplyContextChange(IDataContextStack dataContext, DataContextChangeAttribute[] attributes, IAbstractControl control, IPropertyDescriptor property)
        {
            var type = dataContext.DataContextType;
            var extensionParameters = new List <BindingExtensionParameter>();

            foreach (var attribute in attributes.OrderBy(a => a.Order))
            {
                if (type == null)
                {
                    break;
                }
                extensionParameters.AddRange(attribute.GetExtensionParameters(type));
                type = attribute.GetChildDataContextType(type, dataContext, control, property);
            }
            return(type, extensionParameters);
        }
Exemple #30
0
 bool IObjectGraphVisitor.EnterMapping(IPropertyDescriptor key, object value)
 {
     return(true);
 }
Exemple #31
0
 public override ITypeDescriptor GetChildDataContextType(ITypeDescriptor dataContext, IDataContextStack controlContextStack, IAbstractControl control, IPropertyDescriptor property = null)
 {
     return(TypeDescriptorUtils.GetCollectionItemType(dataContext));
 }
Exemple #32
0
 public void SetProperty(IPropertyDescriptor property, object value)
 {
     _source?.SetProperty(property, value);
 }
 /// <inheritdoc />
 public virtual IEnumerable <string> FormatPropertyDefinition(Converter converter, IPropertyDescriptor descriptor)
 {
     yield break;
 }
Exemple #34
0
 public void SetProperty <T>(IPropertyDescriptor <T> property, T value)
 {
     _source?.SetProperty(property, value);
 }
        /// <summary>
        /// Processes the element which contains property value.
        /// </summary>
        private IAbstractPropertySetter ProcessElementProperty(IAbstractControl control, IPropertyDescriptor property, IEnumerable <DothtmlNode> elementContent, DothtmlElementNode propertyWrapperElement)
        {
            // resolve data context
            var dataContext = control.DataContextTypeStack;

            dataContext = GetDataContextChange(dataContext, control, property);

            // the element is a property
            if (IsTemplateProperty(property))
            {
                // template
                return(treeBuilder.BuildPropertyTemplate(property, ProcessTemplate(control, elementContent, dataContext), propertyWrapperElement));
            }
            else if (IsCollectionProperty(property))
            {
                var collectionType = GetCollectionType(property);
                // collection of elements
                var collection =
                    FilterNodes <DothtmlElementNode>(elementContent, property)
                    .Select(childObject => ProcessObjectElement(childObject, dataContext));
                if (collectionType != null)
                {
                    collection = FilterOrError(collection,
                                               c => c.Metadata.Type.IsAssignableTo(collectionType),
                                               c => c.DothtmlNode.AddError($"Control type {c.Metadata.Type.FullName} can't be used in collection of type {collectionType.FullName}."));
                }

                return(treeBuilder.BuildPropertyControlCollection(property, collection.ToArray(), propertyWrapperElement));
            }
            else if (property.PropertyType.IsEqualTo(new ResolvedTypeDescriptor(typeof(string))))
            {
                // string property
                var strings = FilterNodes <DothtmlLiteralNode>(elementContent, property);
                var value   = string.Concat(strings.Select(s => s.Value));
                return(treeBuilder.BuildPropertyValue(property, value, propertyWrapperElement));
            }
            else if (IsControlProperty(property))
            {
                // new object
                var children = FilterNodes <DothtmlElementNode>(elementContent, property).ToList();
                if (children.Count > 1)
                {
                    foreach (var c in children.Skip(1))
                    {
                        c.AddError($"The property '{property.MarkupOptions.Name}' can have only one child element!");
                    }
                    children = children.Take(1).ToList();
                }
                if (children.Count == 1)
                {
                    return(treeBuilder.BuildPropertyControl(property, ProcessObjectElement(children[0], dataContext), propertyWrapperElement));
                }
                else
                {
                    return(treeBuilder.BuildPropertyControl(property, null, propertyWrapperElement));
                }
            }
            else
            {
                control.DothtmlNode.AddError($"The property '{property.FullName}' is not supported!");
                return(treeBuilder.BuildPropertyValue(property, null, propertyWrapperElement));
            }
        }
Exemple #36
0
 public ValidationResult(IPropertyDescriptor property, string description, ValidationResultType resultType) : this(property, description, ValidationResultSeverity.Error, resultType)
 {
 }
 protected virtual bool IsCollectionProperty(IPropertyDescriptor property)
 {
     return(property.PropertyType.IsAssignableTo(new ResolvedTypeDescriptor(typeof(ICollection))));
 }
Exemple #38
0
        /// <summary>
        /// Processes the binding node.
        /// </summary>
        public IAbstractBinding ProcessBinding(DothtmlBindingNode node, IDataContextStack context, IPropertyDescriptor property)
        {
            var bindingOptions = controlResolver.ResolveBinding(node.Name);

            if (bindingOptions == null)
            {
                node.NameNode.AddError($"Binding {node.Name} could not be resolved.");
                bindingOptions = controlResolver.ResolveBinding("value"); // just try it as with value binding
            }

            if (context != null && context.NamespaceImports.Count > 0)
            {
                bindingOptions = bindingOptions.AddImports(context.NamespaceImports);
            }

            return(CompileBinding(node, bindingOptions, context, property));
        }
Exemple #39
0
 protected override bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value)
 {
     return true;
 }
Exemple #40
0
        /// <summary>
        /// Processes the attribute node.
        /// </summary>
        private void ProcessAttribute(IPropertyDescriptor property, DothtmlAttributeNode attribute, IAbstractControl control, IDataContextStack dataContext)
        {
            if (property.IsBindingProperty || property.DataContextManipulationAttribute != null) // when DataContextManipulationAttribute is set, lets hope that author knows what is he doing.
            {
                dataContext = GetDataContextChange(dataContext, control, property);
            }

            if (!property.MarkupOptions.MappingMode.HasFlag(MappingMode.Attribute))
            {
                attribute.AddError($"The property '{property.FullName}' cannot be used as a control attribute!");
                return;
            }

            // set the property
            if (attribute.ValueNode == null)
            {
                // implicitly set boolean property
                if (property.PropertyType.IsEqualTo(new ResolvedTypeDescriptor(typeof(bool))) || property.PropertyType.IsEqualTo(new ResolvedTypeDescriptor(typeof(bool?))))
                {
                    string error;
                    if (!treeBuilder.AddProperty(control, treeBuilder.BuildPropertyValue(property, true, attribute), out error))
                    {
                        attribute.AddError(error);
                    }
                }
                else if (property.MarkupOptions.AllowAttributeWithoutValue)
                {
                    string error;
                    if (!treeBuilder.AddProperty(control, treeBuilder.BuildPropertyValue(property, (property as DotVVM.Framework.Binding.DotvvmProperty)?.DefaultValue, attribute), out error))
                    {
                        attribute.AddError(error);
                    }
                }
                else
                {
                    attribute.AddError($"The attribute '{property.Name}' on the control '{control.Metadata.Type.FullName}' must have a value!");
                }
            }
            else if (attribute.ValueNode is DothtmlValueBindingNode)
            {
                // binding
                var bindingNode = (attribute.ValueNode as DothtmlValueBindingNode).BindingNode;
                if (property.IsVirtual && !property.IsBindingProperty && property.PropertyType.FullName != "System.Object")
                {
                    attribute.ValueNode.AddError($"The property '{ property.FullName }' cannot contain bindings because it's not DotvvmProperty.");
                }
                else if (!treatBindingAsHardCodedValue.Contains(bindingNode.Name))
                {
                    if (!property.MarkupOptions.AllowBinding)
                    {
                        attribute.ValueNode.AddError($"The property '{ property.FullName }' cannot contain {bindingNode.Name} binding.");
                    }
                }
                var    binding         = ProcessBinding(bindingNode, dataContext, property);
                var    bindingProperty = treeBuilder.BuildPropertyBinding(property, binding, attribute);
                string error;
                if (!treeBuilder.AddProperty(control, bindingProperty, out error))
                {
                    attribute.AddError(error);
                }
            }
            else
            {
                // hard-coded value in markup
                if (!property.MarkupOptions.AllowHardCodedValue)
                {
                    attribute.ValueNode.AddError($"The property '{ property.FullName }' cannot contain hard coded value.");
                }

                var    textValue     = attribute.ValueNode as DothtmlValueTextNode;
                var    value         = ConvertValue(WebUtility.HtmlDecode(textValue.Text), property.PropertyType);
                var    propertyValue = treeBuilder.BuildPropertyValue(property, value, attribute);
                string error;
                if (!treeBuilder.AddProperty(control, propertyValue, out error))
                {
                    attribute.AddError(error);
                }
            }
        }
Exemple #41
0
        public IDynamic FromPropertyDescriptor(IPropertyDescriptor desc)
        {
            // 8.10.4 FromPropertyDescriptor ( Desc )

            if (desc == null) // Property descriptors use null rather than undefined to simplify interaction.
            {
                return Undefined;
            }

            var obj = ObjectConstructor.Op_Construct(EmptyArgs);

            if (desc.IsDataDescriptor)
            {
                var value = CreateDataDescriptor(desc.Value, true, true, true);
                var writable = CreateDataDescriptor(CreateBoolean(desc.Writable.Value), true, true, true);

                obj.DefineOwnProperty("value", value, false);
                obj.DefineOwnProperty("writable", writable, false);
            }
            else
            {
                Debug.Assert(desc.IsAccessorDescriptor);

                var get = CreateDataDescriptor(desc.Get, true, true, true);
                var set = CreateDataDescriptor(desc.Set, true, true, true);

                obj.DefineOwnProperty("get", get, false);
                obj.DefineOwnProperty("set", set, false);
            }

            var enumerable = CreateDataDescriptor(CreateBoolean(desc.Enumerable.Value), true, true, true);
            var configurable = CreateDataDescriptor(CreateBoolean(desc.Configurable.Value), true, true, true);

            obj.DefineOwnProperty("enumerable", enumerable, false);
            obj.DefineOwnProperty("configurable", configurable, false);

            return obj;
        }
Exemple #42
0
 public PropertyDescriptor(IPropertyDescriptor baseDescriptor)
 {
     this.baseDescriptor = baseDescriptor;
     Name = baseDescriptor.Name;
 }
Exemple #43
0
 bool IObjectGraphVisitor <IEmitter> .EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, IEmitter context)
 {
     return(true);
 }
		bool IObjectGraphVisitor.EnterMapping(IPropertyDescriptor key, IObjectDescriptor value)
		{
			return true;
		}
 public override ITypeDescriptor GetChildDataContextType(ITypeDescriptor dataContext, IDataContextStack controlContextStack, IAbstractControl control, IPropertyDescriptor property = null)
 {
     return new ResolvedTypeDescriptor(type);
 }
		public override IDataContextStack ChangeStackForChildren(IDataContextStack original, IAbstractControl control, IPropertyDescriptor property, Func<IDataContextStack, ITypeDescriptor, IDataContextStack> createNewFrame)
		{
			return original.Parent;
		}
Exemple #47
0
 public static bool HasPropertyValue(this IAbstractControl control, IPropertyDescriptor property)
 {
     IAbstractPropertySetter setter;
     return control.TryGetProperty(property, out setter) && setter is IAbstractPropertyValue;
 }
Exemple #48
0
 public override bool DefineOwnProperty(string p, IPropertyDescriptor desc, bool @throw)
 {
     return _underlying.Value.DefineOwnProperty(p, desc, @throw);
 }
Exemple #49
0
        /// <summary>
        /// Processes the element which contains property value.
        /// </summary>
        private IAbstractPropertySetter ProcessElementProperty(IAbstractControl control, IPropertyDescriptor property, IEnumerable <DothtmlNode> elementContent, DothtmlElementNode propertyWrapperElement)
        {
            IEnumerable <IAbstractControl> filterByType(ITypeDescriptor type, IEnumerable <IAbstractControl> controls) =>
            FilterOrError(controls,
                          c => c.Metadata.Type.IsAssignableTo(type),
                          c => {
                // empty nodes are only filtered, non-empty nodes cause errors
                if (c.DothtmlNode.IsNotEmpty())
                {
                    c.DothtmlNode.AddError($"Control type {c.Metadata.Type.FullName} can't be used in collection of type {type.FullName}.");
                }
            });

            // resolve data context
            var dataContext = control.DataContextTypeStack;

            dataContext = GetDataContextChange(dataContext, control, property);

            // the element is a property
            if (IsTemplateProperty(property))
            {
                // template
                return(treeBuilder.BuildPropertyTemplate(property, ProcessTemplate(control, elementContent, dataContext), propertyWrapperElement));
            }
            else if (IsCollectionProperty(property))
            {
                var collectionType = GetCollectionType(property);
                // collection of elements
                var collection = elementContent.Select(childObject => ProcessNode(control, childObject, control.Metadata, dataContext));
                if (collectionType != null)
                {
                    collection = filterByType(collectionType, collection);
                }

                return(treeBuilder.BuildPropertyControlCollection(property, collection.ToArray(), propertyWrapperElement));
            }
            else if (property.PropertyType.IsEqualTo(new ResolvedTypeDescriptor(typeof(string))))
            {
                // string property
                var strings = FilterNodes <DothtmlLiteralNode>(elementContent, property);
                var value   = string.Concat(strings.Select(s => s.Value));
                return(treeBuilder.BuildPropertyValue(property, value, propertyWrapperElement));
            }
            else if (IsControlProperty(property))
            {
                var children = filterByType(property.PropertyType, elementContent.Select(childObject => ProcessNode(control, childObject, control.Metadata, dataContext))).ToArray();
                if (children.Length > 1)
                {
                    // try with the empty nodes are excluded
                    children = children.Where(c => c.DothtmlNode.IsNotEmpty()).ToArray();
                    if (children.Length > 1)
                    {
                        foreach (var c in children.Skip(1))
                        {
                            c.DothtmlNode.AddError($"The property '{property.MarkupOptions.Name}' can have only one child element!");
                        }
                    }
                }
                if (children.Length >= 1)
                {
                    return(treeBuilder.BuildPropertyControl(property, children[0], propertyWrapperElement));
                }
                else
                {
                    return(treeBuilder.BuildPropertyControl(property, null, propertyWrapperElement));
                }
            }
            else
            {
                control.DothtmlNode.AddError($"The property '{property.FullName}' is not supported!");
                return(treeBuilder.BuildPropertyValue(property, null, propertyWrapperElement));
            }
        }
Exemple #50
0
 public IAbstractPropertyControl BuildPropertyControl(IPropertyDescriptor property, IAbstractControl control)
 {
     return new ResolvedPropertyControl((DotvvmProperty)property, (ResolvedControl)control);
 }
 public bool TryGetProperty(string name, out IPropertyDescriptor value)
 {
     return Properties.TryGetValue(name, out value);
 }
Exemple #52
0
 protected virtual bool IsTemplateProperty(IPropertyDescriptor property)
 {
     return(property.PropertyType.IsAssignableTo(new ResolvedTypeDescriptor(typeof(ITemplate))));
 }
Exemple #53
0
 protected virtual bool IsControlProperty(IPropertyDescriptor property)
 {
     return(property.PropertyType.IsAssignableTo(new ResolvedTypeDescriptor(typeof(DotvvmControl))));
 }
Exemple #54
0
        /// <summary>
        /// Gets the data context change behavior for the specified control property.
        /// </summary>
        protected virtual IDataContextStack GetDataContextChange(IDataContextStack dataContext, IAbstractControl control, IPropertyDescriptor property)
        {
            if (dataContext == null)
            {
                return(null);
            }

            var manipulationAttribute = property != null ? property.DataContextManipulationAttribute : control.Metadata.DataContextManipulationAttribute;

            if (manipulationAttribute != null)
            {
                return(manipulationAttribute.ChangeStackForChildren(dataContext, control, property, (parent, changeType) => CreateDataContextTypeStack(changeType, parentDataContextStack: parent)));
            }

            var attributes = property != null ? property.DataContextChangeAttributes : control.Metadata.DataContextChangeAttributes;

            if (attributes == null || attributes.Length == 0)
            {
                return(dataContext);
            }

            try
            {
                var(type, extensionParameters) = ApplyContextChange(dataContext, attributes, control, property);

                if (type == null)
                {
                    return(dataContext);
                }
                else
                {
                    return(CreateDataContextTypeStack(type, parentDataContextStack: dataContext, extensionParameters: extensionParameters.ToArray()));
                }
            }
            catch (Exception exception)
            {
                var node = property != null && control.TryGetProperty(property, out var v) ? v.DothtmlNode : control.DothtmlNode;
                node?.AddError($"Could not compute the type of DataContext: {exception}");

                return(CreateDataContextTypeStack(null, parentDataContextStack: dataContext));
            }
        }
 public virtual bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value)
 {
     return nextVisitor.EnterMapping(key, value);
 }
 public override ITypeDescriptor GetChildDataContextType(ITypeDescriptor dataContext, IDataContextStack controlContextStack, IAbstractControl control, IPropertyDescriptor property = null)
 {
     return TypeDescriptorUtils.GetCollectionItemType(dataContext);
 }