Parse() static private méthode

static private Parse ( string attribute, string expression ) : Binding
attribute string
expression string
Résultat Binding
Exemple #1
0
 static Binding GetBinding(XmlElement element, string attributeName)
 {
     return(element.HasAttribute(attributeName) ? Binding.Parse(attributeName, element.GetAttribute(attributeName)) : null);
 }
Exemple #2
0
 static List <Attribute> GetAttributes(XmlElement element, params string[] exceptions)
 {
     return(element.Attributes
            .Cast <XmlAttribute>()
            .Where(a => exceptions == null || !exceptions.Contains(a.Name))
            .Select(a => new Attribute()
     {
         Name = a.Name.ToLower(),
         Value = a.Name.ToLower() == "class" ? a.Value.Replace("sys-template", "").Trim() : a.Value,
         Binding = a.Name.ToLower().StartsWith("sys:") && a.Value.Trim().StartsWith("{") && a.Value.Trim().EndsWith("}") ? Binding.Parse(a.Name.ToLower(), a.Value.Trim()) : null
     })
            .ToList());
 }
Exemple #3
0
        /// <summary>
        /// Parses the children of the specified element into a list of template blocks.
        /// </summary>
        /// <param name="source">The original string source of the template.</param>
        /// <param name="element">The element to parse</param>
        /// <param name="withinTemplate">Indicates that the children of the given element are within a template control.</param>
        /// <param name="lastNestedTemplateIndex">Tracks the index of the last template element that was encountered. Passed through to recursive calls excluding templates.</param>
        /// <param name="nestedTemplates">Out parameter that returns the number of template controls represented by the children of the given element.</param>
        /// <returns>A list of template blocks.</returns>
        static List <Block> ParseChildren(string source, XmlElement element, bool withinTemplate, int lastNestedTemplateIndex, out int nestedTemplates)
        {
            // Track the blocks represented by the current element
            var blocks = new List <Block>();

            nestedTemplates = 0;

            // Process the child nodes of the current element
            foreach (XmlNode node in element.ChildNodes)
            {
                switch (node.NodeType)
                {
                // XML Element, which could be a control, bound element start tag, or just literal content
                case XmlNodeType.Element:

                    var child = (XmlElement)node;

                    // Control
                    if (child.HasAttribute("sys:attach") ||
                        child.HasAttribute("sys:if") ||
                        child.HasAttribute("sys:content-template") ||
                        child.HasAttribute("sys:id") ||
                        child.HasAttribute("id"))
                    {
                        bool    parseChildren = true;
                        Control control;
                        if (child.HasAttribute("sys:attach"))
                        {
                            switch (child.GetAttribute("sys:attach"))
                            {
                            // Template
                            case "template":
                                control = new Template()
                                {
                                    Attributes           = GetAttributes(child, "class", "sys:attach", "sys:if", "sys:content-template", "template:name", "template:kind", "template:datatype", "template:islist", "template:isreference"),
                                    Name                 = GetLiteralTokens(child, "template:name"),
                                    Source               = source + " [" + child.GetAttribute("template:name") + "]" + (child.HasAttribute("template:datatype") ? " - " + child.GetAttribute("template:datatype") : ""),
                                    IsList               = GetBoolean(child, "template:islist"),
                                    IsReference          = GetBoolean(child, "template:isreference"),
                                    Kind                 = GetStringLiteral(child, "template:kind"),
                                    DataType             = GetStringLiteral(child, "template:datatype"),
                                    Class                = GetLiteralTokens(child, "class").Where(c => c.ToLower() != "sys-template").ToArray(),
                                    ContentTemplateNames = GetLiteralTokens(child, "sys:content-template")
                                };
                                break;

                            // DataView
                            case "dataview":
                                control = new DataView()
                                {
                                    Attributes      = GetAttributes(child, "sys:attach", "sys:if", "sys:content-template", "dataview:data"),
                                    Data            = GetBinding(child, "dataview:data"),
                                    Template        = GetTemplate(child),
                                    ContentTemplate = GetBinding(child, "sys:content-template")
                                };
                                break;

                            // Content
                            case "content":
                                control = new Content()
                                {
                                    Attributes      = GetAttributes(child, "sys:attach", "sys:if", "sys:content-template", "content:data", "content:template"),
                                    Data            = GetBinding(child, "content:data"),
                                    Template        = GetBinding(child, "content:template"),
                                    DataType        = GetBinding(child, "content:datatype"),
                                    ContentTemplate = GetBinding(child, "sys:content-template")
                                };
                                break;

                            // Toggle
                            case "toggle":
                                control = new Toggle()
                                {
                                    Attributes      = GetAttributes(child, "sys:attach", "sys:if", "sys:content-template", "toggle:on", "toggle:action", "toggle:class", "toggle:groupname", "toggle:strictmode", "toggle:when"),
                                    On              = GetBinding(child, "toggle:on"),
                                    Class           = GetBinding(child, "toggle:class"),
                                    ClassName       = GetBinding(child, "toggle:classname"),
                                    Action          = GetBinding(child, "toggle:action"),
                                    GroupName       = GetBinding(child, "toggle:groupname"),
                                    StrictMode      = GetBinding(child, "toggle:strictmode"),
                                    When            = GetBinding(child, "toggle:when"),
                                    ContentTemplate = GetBinding(child, "sys:content-template")
                                };
                                break;

                            // ToggleGroup
                            case "togglegroup":
                                control = new ToggleGroup()
                                {
                                    Attributes      = GetAttributes(child, "sys:attach", "sys:if", "sys:content-template"),
                                    ContentTemplate = GetBinding(child, "sys:content-template")
                                };
                                break;

                            // Behavior
                            case "behavior":
                                control = new Behavior()
                                {
                                    Attributes      = GetAttributes(child, "sys:attach", "sys:if", "sys:content-template"),
                                    ContentTemplate = GetBinding(child, "sys:content-template")
                                };
                                break;

                            // Html
                            case "html":
                                control = new Html()
                                {
                                    Attributes      = GetAttributes(child, "sys:attach", "sys:if", "sys:content-template"),
                                    ContentTemplate = GetBinding(child, "sys:content-template")
                                };
                                break;

                            default:
                                throw new ArgumentException("Controls of type '" + child.GetAttribute("sys:attach") + "' are not supported for server rendering.");
                            }

                            // Add data-sys-attach to indicate the control type when performing linking on the client
                            control.Attributes.Add(new Attribute()
                            {
                                Name = "data-sys-attach", Value = child.GetAttribute("sys:attach")
                            });
                        }
                        else
                        {
                            control = new Control()
                            {
                                Attributes      = GetAttributes(child, "sys:if", "sys:content-template", "sys:innerhtml", "sys:innertext"),
                                ContentTemplate = GetBinding(child, "sys:content-template"),
                                IsEmpty         = child.ChildNodes.Count == 0
                            };
                            if (child.InnerXml.Trim().StartsWith("{") && child.InnerXml.Trim().EndsWith("}"))
                            {
                                parseChildren = false;
                                control.Attributes.Add(new Attribute()
                                {
                                    Name = "innerhtml", Binding = Binding.Parse(GetDefaultProperty(child), child.InnerXml.Trim()), Value = child.InnerXml.Trim()
                                });
                                control.IsEmpty = true;
                            }
                        }

                        var isTemplate = IsTemplate(control);

                        // If the sys:content-template attribute is found, then ensure it is within or on a templated control
                        if (child.HasAttribute("sys:content-template") && !withinTemplate && !isTemplate)
                        {
                            throw new ApplicationException("The sys:content-template attribute must be used on or within an control that implements Sys.UI.IContentTemplateConsumer.");
                        }

                        // Process the controls child blocks
                        if (parseChildren)
                        {
                            // Determine the number of top-level templates represented by this node
                            int numTopLevelTemplates;

                            if (isTemplate)
                            {
                                // A templated control represents only 1 top-level nested template
                                numTopLevelTemplates = 1;

                                // Set nested template index
                                control.NestedTemplateIndex = lastNestedTemplateIndex + 1;

                                // Parse child blocks as a new template region.  This means that lastNestedTemplateIndex
                                // starts fresh (-1) and the number of child templates are not relevant here.
                                control.Blocks = ParseChildren(source, child, true);
                            }
                            else
                            {
                                // Parse children and capture the number of top-level templates contained within
                                control.Blocks = ParseChildren(source, child, withinTemplate, lastNestedTemplateIndex, out numTopLevelTemplates);
                            }

                            // Increment the number of nested templates and last index by
                            // the number of top-level templates that this node represents
                            nestedTemplates         += numTopLevelTemplates;
                            lastNestedTemplateIndex += numTopLevelTemplates;
                        }
                        else
                        {
                            // A non-control with a binding expression as its inner-html contains no blocks
                            control.Blocks = new List <Block>();
                        }

                        control.Tag    = child.Name;
                        control.Markup = GetMarkup(child);
                        control.If     = GetBinding(child, "sys:if");

                        // Add the control
                        blocks.Add(control);
                    }

                    // Element
                    else if (child.Attributes.Cast <XmlAttribute>().Any(a => a.Value.StartsWith("{") && a.Value.EndsWith("}")) ||
                             (child.ChildNodes.Cast <XmlNode>().All(n => n.NodeType != XmlNodeType.Element) && child.InnerXml.Trim().StartsWith("{") && child.InnerXml.Trim().EndsWith("}")))
                    {
                        var isBinding = child.InnerXml.Trim().StartsWith("{") && child.InnerXml.Trim().EndsWith("}");

                        // Add the bound element
                        var e = new Element()
                        {
                            Markup     = isBinding || child.ChildNodes.Count == 0 ? GetMarkup(child) : GetElementMarkup(child),
                            Attributes = GetAttributes(child),
                            Tag        = child.Name,
                            IsEmpty    = isBinding || child.ChildNodes.Count == 0
                        };

                        if (isBinding)
                        {
                            e.Attributes.Add(new Attribute()
                            {
                                Name = "innerhtml", Binding = Binding.Parse(GetDefaultProperty(child), child.InnerXml.Trim())
                            });
                        }

                        blocks.Add(e);

                        // Process child nodes, if the element content is not bound
                        if (!e.IsEmpty)
                        {
                            int numTopLevelTemplates;
                            var children = ParseChildren(source, child, withinTemplate, lastNestedTemplateIndex, out numTopLevelTemplates);
                            lastNestedTemplateIndex += numTopLevelTemplates;
                            nestedTemplates         += numTopLevelTemplates;

                            blocks.AddRange(children);
                            blocks.Add(new Block()
                            {
                                Markup = "</" + child.Name + ">"
                            });
                        }
                    }

                    // Literal
                    else
                    {
                        // Get the blocks contained by the literal element
                        int numTopLevelTemplates;
                        var children = ParseChildren(source, child, withinTemplate, lastNestedTemplateIndex, out numTopLevelTemplates);
                        lastNestedTemplateIndex += numTopLevelTemplates;
                        nestedTemplates         += numTopLevelTemplates;

                        // Add the entire element as a block if it only contains literal content
                        if (children.Count == 0 || (children.Count == 1 && children.First().GetType() == typeof(Block)))
                        {
                            blocks.Add(new Block()
                            {
                                Markup = GetMarkup(child)
                            });
                        }

                        // Otherwise, process the child blocks
                        else
                        {
                            blocks.Add(new Block()
                            {
                                Markup = GetElementMarkup(child)
                            });
                            blocks.AddRange(children);
                            blocks.Add(new Block()
                            {
                                Markup = "</" + child.Name + ">"
                            });
                        }
                    }
                    break;

                // Literal content
                case XmlNodeType.Text:
                    blocks.Add(new Block()
                    {
                        Markup = GetMarkup(node)
                    });
                    break;
                }
            }

            // Condense adjacent literal blocks
            Block literal = null;

            for (int i = blocks.Count - 1; i >= 0; i--)
            {
                if (blocks[i].GetType() == typeof(Block))
                {
                    if (literal == null)
                    {
                        literal = blocks[i];
                    }
                    else
                    {
                        literal.Markup = blocks[i].Markup + literal.Markup;
                        blocks.RemoveAt(i);
                    }
                }
                else
                {
                    literal = null;
                }
            }

            return(blocks);
        }