Ejemplo n.º 1
0
        /// <summary>
        /// Parses the token stream and gets the node.
        /// </summary>
        public DothtmlRootNode Parse(List <DothtmlToken> tokens)
        {
            Root             = null;
            Tokens           = tokens;
            CurrentIndex     = 0;
            ElementHierarchy = new Stack <DothtmlNodeWithContent>();

            // read file
            var root = new DothtmlRootNode();

            root.Tokens.Add(Tokens);
            ElementHierarchy.Push(root);

            // read content
            var doNotAppend = false;

            while (Peek() != null)
            {
                if (Peek().Type == DothtmlTokenType.DirectiveStart)
                {
                    // directive
                    root.Directives.Add(ReadDirective());
                    doNotAppend = true;
                }
                else if (Peek().Type == DothtmlTokenType.OpenTag)
                {
                    // element - check element hierarchy
                    var element = ReadElement();
                    if (ElementHierarchy.Any())
                    {
                        element.ParentNode = ElementHierarchy.Peek() as DothtmlElementNode;
                    }

                    if (!element.IsSelfClosingTag)
                    {
                        if (!element.IsClosingTag)
                        {
                            // open tag
                            CurrentElementContent.Add(element);
                            ElementHierarchy.Push(element);
                        }
                        else
                        {
                            // close tag
                            if (ElementHierarchy.Count <= 1)
                            {
                                element.AddWarning($"The closing tag '</{element.FullTagName}>' doesn't have a matching opening tag!");
                                CurrentElementContent.Add(element);
                            }
                            else
                            {
                                var beginTag     = (DothtmlElementNode)ElementHierarchy.Peek();
                                var beginTagName = beginTag.FullTagName;
                                if (!beginTagName.Equals(element.FullTagName, StringComparison.OrdinalIgnoreCase))
                                {
                                    element.AddWarning($"The closing tag '</{element.FullTagName}>' doesn't have a matching opening tag!");
                                    ResolveWrongClosingTag(element);
                                    beginTag = ElementHierarchy.Peek() as DothtmlElementNode;

                                    if (beginTag != null && beginTagName != beginTag.FullTagName)
                                    {
                                        beginTag.CorrespondingEndTag = element;
                                        ElementHierarchy.Pop();
                                    }
                                    else
                                    {
                                        CurrentElementContent.Add(element);
                                    }
                                }
                                else
                                {
                                    ElementHierarchy.Pop();
                                    beginTag.CorrespondingEndTag = element;
                                }
                            }
                        }
                    }
                    else
                    {
                        // self closing tag
                        CurrentElementContent.Add(element);
                    }
                }
                else if (Peek().Type == DothtmlTokenType.OpenBinding)
                {
                    // binding
                    CurrentElementContent.Add(ReadBinding());
                }
                else if (Peek().Type == DothtmlTokenType.OpenCData)
                {
                    CurrentElementContent.Add(ReadCData());
                }
                else if (Peek().Type == DothtmlTokenType.OpenComment)
                {
                    CurrentElementContent.Add(ReadComment());
                }
                else if (Peek().Type == DothtmlTokenType.OpenServerComment)
                {
                    // skip server-side comment
                    CurrentElementContent.Add(ReadServerComment());
                }
                else
                {
                    // text
                    if (!doNotAppend &&
                        CurrentElementContent.Count > 0 &&
                        CurrentElementContent[CurrentElementContent.Count - 1].GetType() == typeof(DothtmlLiteralNode) &&
                        !(CurrentElementContent[CurrentElementContent.Count - 1] is DotHtmlCommentNode))
                    {
                        // append to the previous literal
                        var lastLiteral = (DothtmlLiteralNode)CurrentElementContent[CurrentElementContent.Count - 1];
                        if (lastLiteral.Escape)
                        {
                            CurrentElementContent.Add(new DothtmlLiteralNode()
                            {
                                Tokens = { PeekPart() }
                            });
                        }
                        else
                        {
                            lastLiteral.Tokens.Add(PeekPart());
                        }
                    }
                    else
                    {
                        CurrentElementContent.Add(new DothtmlLiteralNode()
                        {
                            Tokens = { PeekPart() }
                        });
                    }
                    Read();

                    doNotAppend = false;
                }
            }

            // check element hierarchy
            if (ElementHierarchy.Count > 1)
            {
                ElementHierarchy.Peek().AddError($"Unexpected end of file! The tag '<{ElementHierarchy.Peek().CastTo<DothtmlElementNode>().TagName}>' was not closed!");
            }

            ResolveParents(root);

            Root = root;
            return(root);
        }
Ejemplo n.º 2
0
        private void ResolveParents(DothtmlRootNode root)
        {
            var parentResolver = new ParentResolvingVisitor();

            root.Accept(parentResolver);
        }
Ejemplo n.º 3
0
        public DothtmlRootNode Parse(List <DothtmlToken> tokens)
        {
            Root         = null;
            Tokens       = tokens;
            CurrentIndex = 0;
            ElementHierarchy.Clear();

            // read file
            var root = new DothtmlRootNode();

            root.Tokens.Add(Tokens);
            ElementHierarchy.Push(root);

            // read content
            var doNotAppend = false;

            while (Peek() is DothtmlToken token)
            {
                if (token.Type == DothtmlTokenType.DirectiveStart)
                {
                    // directive
                    root.Directives.Add(ReadDirective());
                    doNotAppend = true;
                }
                else if (token.Type == DothtmlTokenType.OpenTag)
                {
                    // element - check element hierarchy
                    var element = ReadElement();
                    if (ElementHierarchy.Any())
                    {
                        element.ParentNode = ElementHierarchy.Peek() as DothtmlElementNode;
                    }

                    if (!element.IsSelfClosingTag)
                    {
                        if (!element.IsClosingTag)
                        {
                            // open tag
                            CurrentElementContent.Add(element);
                            ElementHierarchy.Push(element);
                        }
                        else
                        {
                            // close tag
                            if (ElementHierarchy.Count <= 1)
                            {
                                element.AddWarning($"The closing tag '</{element.FullTagName}>' doesn't have a matching opening tag!");
                                CurrentElementContent.Add(element);
                            }
                            else
                            {
                                var beginTag     = (DothtmlElementNode)ElementHierarchy.Peek();
                                var beginTagName = beginTag.FullTagName;
                                if (!beginTagName.Equals(element.FullTagName, StringComparison.OrdinalIgnoreCase))
                                {
                                    element.AddWarning($"The closing tag '</{element.FullTagName}>' doesn't have a matching opening tag!");
                                    ResolveWrongClosingTag(element);

                                    if (ElementHierarchy.Peek() is DothtmlElementNode newBeginTag && beginTagName != newBeginTag.FullTagName)
                                    {
                                        newBeginTag.CorrespondingEndTag = element;
                                        ElementHierarchy.Pop();
                                    }
                                    else
                                    {
                                        CurrentElementContent.Add(element);
                                    }
                                }
                                else
                                {
                                    ElementHierarchy.Pop();
                                    beginTag.CorrespondingEndTag = element;
                                }
                            }
                        }
                    }
Ejemplo n.º 4
0
 public void Visit(DothtmlRootNode root)
 {
     LastFoundNode = root;
 }
Ejemplo n.º 5
0
 public void Visit(DothtmlRootNode root)
 {
     LastFoundNode = root;
 }
Ejemplo n.º 6
0
 public IAbstractTreeRoot BuildTreeRoot(IControlTreeResolver controlTreeResolver, IControlResolverMetadata metadata, DothtmlRootNode node, IDataContextStack dataContext)
 {
     return new ResolvedTreeRoot((ControlResolverMetadata)metadata, node, (DataContextStack)dataContext);
 }