private static ReactElementTemplate ParseElement(XmlReader xmlReader)
        {
            if (xmlReader.NodeType != XmlNodeType.Element)
            {
                throw new Exception();
            }

            var template = new ReactElementTemplate()
            {
            };

            var tagName = xmlReader.Name;

            template.Type = new ReactElementTemplateType()
            {
                Value = tagName,
            };
            if (tagName.Length == 0)
            {
                throw new Exception();
            }

            if (char.IsLower(tagName[0]))
            {
                template.Type.Evaluator = ReactValueEvaluatorFactory.CreateValue(tagName);
            }
            else
            {
                template.Type.Evaluator =
                    ReactValueEvaluatorFactory.CreateValue(ReactComponentTypeResolver.ResolveComponent(tagName));
            }

            template.Children = new List <ReactElementTemplateChild>();
            template.Props    = new List <ReactElementTemplateProp>();

            if (xmlReader.HasAttributes)
            {
                while (xmlReader.MoveToNextAttribute())
                {
                    var propValue = xmlReader.Value;
                    var propName  = xmlReader.Name;

                    var propTemplate = new ReactElementTemplateProp()
                    {
                        Name  = propName,
                        Value = propValue,
                    };

                    var m = exactAttributeRegex.Match(propValue);

                    if (m.Success)
                    {
                        var index = int.Parse(m.Groups["index"].Value);
                        propTemplate.Evaluator = ReactValueEvaluatorFactory.CreateByIndex(index);
                    }
                    else if (containsAttributeRegex.IsMatch(propValue))
                    {
                        propTemplate.Evaluator = ReactValueEvaluatorFactory.CreateByFormat(propValue);
                    }
                    else
                    {
                        propTemplate.Evaluator = ReactValueEvaluatorFactory.CreateValue(propValue);
                    }

                    template.Props.Add(propTemplate);
                }
            }

            if (!xmlReader.IsEmptyElement)
            {
                while (xmlReader.Read())
                {
                    if (xmlReader.NodeType == XmlNodeType.Element)
                    {
                        var childTemplate = ParseElement(xmlReader);
                        template.Children.Add(new ReactElementTemplateChild()
                        {
                            Value     = childTemplate,
                            Evaluator = ReactValueEvaluatorFactory.CreateFromTemplate(childTemplate)
                        });
                    }
                    else if (xmlReader.NodeType == XmlNodeType.EndElement)
                    {
                        break;
                    }
                    else if (xmlReader.NodeType == XmlNodeType.Whitespace)
                    {
                        template.Children.Add(new ReactElementTemplateChild()
                        {
                            Value     = xmlReader.Value,
                            Evaluator = ReactValueEvaluatorFactory.CreateValue(xmlReader.Value)
                        });
                    }
                    else if (xmlReader.NodeType == XmlNodeType.Text)
                    {
                        var matches = containsAttributeRegex.Matches(xmlReader.Value);
                        if (matches.Count > 0)
                        {
                            var previousIndex = 0;

                            foreach (Match match in matches)
                            {
                                if (previousIndex < match.Index)
                                {
                                    var contentValue =
                                        xmlReader.Value.Substring(previousIndex,
                                                                  match.Index - previousIndex);

                                    template.Children.Add(new ReactElementTemplateChild()
                                    {
                                        Value     = contentValue,
                                        Evaluator = ReactValueEvaluatorFactory.CreateValue(contentValue)
                                    });
                                }

                                var contentIndex = int.Parse(match.Groups["index"].Value);

                                template.Children.Add(new ReactElementTemplateChild()
                                {
                                    Value     = match.Value,
                                    Evaluator = ReactValueEvaluatorFactory.CreateByIndex(contentIndex)
                                });

                                previousIndex = match.Index + match.Length;
                            }


                            if (previousIndex < xmlReader.Value.Length)
                            {
                                var contentValue =
                                    xmlReader.Value.Remove(0, previousIndex);

                                template.Children.Add(new ReactElementTemplateChild()
                                {
                                    Value     = contentValue,
                                    Evaluator = ReactValueEvaluatorFactory.CreateValue(contentValue)
                                });
                            }
                        }
                        else
                        {
                            var value = xmlReader.Value;

                            template.Children.Add(new ReactElementTemplateChild()
                            {
                                Value     = value,
                                Evaluator = ReactValueEvaluatorFactory.CreateValue(value)
                            });
                        }
                    }
                }
            }

            return(template);
        }
Пример #2
0
 public ReactElement(ReactElementTemplate template, object[] data)
 {
     Init(template.Type.Evaluator(data),
          template.Props.ToDictionary(i => i.Name, i => i.Evaluator(data)),
          template.Children.Select(i => i.Evaluator(data)).ToArray());
 }