Example #1
0
        public static int GetContentEndPosition(this DothtmlElementNode node)
        {
            var lastNode = node.Content.LastOrDefault();

            if (lastNode == null)
            {
                return(node.EndPosition);
            }

            if (lastNode is DothtmlElementNode lastElement)
            {
                if (lastElement.IsSelfClosingTag)
                {
                    return(lastElement.EndPosition);
                }
                else if (lastElement.CorrespondingEndTag != null)
                {
                    var closingTag = lastElement.CorrespondingEndTag;
                    return(closingTag.EndPosition);
                }
                else if (lastElement.Content.Count == 0)
                {
                    return(lastElement.EndPosition);
                }
                else
                {
                    return(lastElement.GetContentEndPosition());
                }
            }
            else
            {
                return(lastNode.EndPosition);
            }
        }
Example #2
0
        private void ReadWhiteSpaceOrComment(DothtmlElementNode node)
        {
            while (true)
            {
                switch (Peek().Type)
                {
                case DothtmlTokenType.WhiteSpace:
                    if (node.AttributeSeparators == null)
                    {
                        node.AttributeSeparators = new List <DothtmlToken>();
                    }
                    node.AttributeSeparators.Add(Read());
                    break;

                case DothtmlTokenType.OpenComment:
                    if (node.InnerComments == null)
                    {
                        node.InnerComments = new List <DotHtmlCommentNode>();
                    }
                    node.InnerComments.Add(ReadComment());
                    break;

                case DothtmlTokenType.OpenServerComment:
                    if (node.InnerComments == null)
                    {
                        node.InnerComments = new List <DotHtmlCommentNode>();
                    }
                    node.InnerComments.Add(ReadServerComment());
                    break;

                default:
                    return;
                }
            }
        }
Example #3
0
        private void ResolveWrongClosingTag(DothtmlElementNode element)
        {
            Debug.Assert(element.IsClosingTag);
            var startElement = ElementHierarchy.Peek() as DothtmlElementNode;

            Debug.Assert(startElement != null);
            Debug.Assert(startElement.FullTagName != element.FullTagName);

            while (startElement != null && !startElement.FullTagName.Equals(element.FullTagName, StringComparison.OrdinalIgnoreCase))
            {
                ElementHierarchy.Pop();
                if (HtmlWriter.SelfClosingTags.Contains(startElement.FullTagName))
                {
                    // automatic immediate close of the tag (for <img src="">)
                    ElementHierarchy.Peek().Content.AddRange(startElement.Content);
                    startElement.Content.Clear();
                }
                else if (AutomaticClosingTags.Contains(startElement.FullTagName))
                {
                    // elements than can contain itself like <p> are closed on the first occurance of element with the same name
                    var sameElementIndex = startElement.Content.FindIndex(a => (a as DothtmlElementNode)?.FullTagName == startElement.FullTagName);
                    if (sameElementIndex >= 0)
                    {
                        var count = startElement.Content.Count - sameElementIndex;
                        ElementHierarchy.Peek().Content.AddRange(startElement.Content.Skip(sameElementIndex));
                        startElement.Content.RemoveRange(sameElementIndex, count);
                    }
                }

                // otherwise just pop the element
                startElement = ElementHierarchy.Peek() as DothtmlElementNode;
            }
        }
Example #4
0
        /// <summary>
        /// Reads the element.
        /// </summary>
        private DothtmlElementNode ReadElement()
        {
            var startIndex = CurrentIndex;
            var node       = new DothtmlElementNode();

            Assert(DothtmlTokenType.OpenTag);
            Read();

            if (Peek().Type == DothtmlTokenType.Slash)
            {
                Read();
                node.IsClosingTag = true;
            }

            // element name
            var nameOrPrefix = ReadName(true, false, DothtmlTokenType.Text);

            if (Peek().Type == DothtmlTokenType.Colon)
            {
                node.TagPrefixNode   = nameOrPrefix;
                node.PrefixSeparator = Read();
                node.TagNameNode     = ReadName(false, false, DothtmlTokenType.Text);
            }
            else
            {
                node.TagNameNode = nameOrPrefix;
            }
            //no mans whitespaces
            SkipWhiteSpace();

            // attributes
            if (!node.IsClosingTag)
            {
                ReadWhiteSpaceOrComment(node);
                while (Peek().Type == DothtmlTokenType.Text)
                {
                    var attribute = ReadAttribute();
                    node.Attributes.Add(attribute);

                    ReadWhiteSpaceOrComment(node);
                }

                if (Peek().Type == DothtmlTokenType.Slash)
                {
                    Read();
                    SkipWhiteSpace();
                    node.IsSelfClosingTag = true;
                }
            }

            Assert(DothtmlTokenType.CloseTag);
            Read();

            node.Tokens.Add(GetTokensFrom(startIndex));
            return(node);
        }
Example #5
0
        private void ResolveWrongClosingTag(DothtmlElementNode element)
        {
            Debug.Assert(element.IsClosingTag);
            var startElement = ElementHierarchy.Peek() as DothtmlElementNode;

            Debug.Assert(startElement != null);
            Debug.Assert(startElement.FullTagName != element.FullTagName);

            while (startElement != null && !startElement.FullTagName.Equals(element.FullTagName, StringComparison.OrdinalIgnoreCase))
            {
                ElementHierarchy.Pop();
                if (HtmlWriter.IsSelfClosing(startElement.FullTagName))
                {
                    // automatic immediate close of the tag (for <img src="">)
                    ElementHierarchy.Peek().Content.AddRange(startElement.Content);
                    startElement.Content.Clear();
                    startElement.AddWarning("End tag is missing, the element is implicitly self-closed.");
                }
                else if (AutomaticClosingTags.Contains(startElement.FullTagName))
                {
                    // elements than can contain itself like <p> are closed on the first occurance of element with the same name
                    var sameElementIndex = startElement.Content.FindIndex(a => (a as DothtmlElementNode)?.FullTagName == startElement.FullTagName);

                    if (sameElementIndex < 0)
                    {
                        startElement.AddWarning($"End tag is missing, the element is implicitly closed with its parent tag or by the end of file.");
                    }
                    else if (sameElementIndex >= 0)
                    {
                        startElement.AddWarning($"End tag is missing, the element is implicitly closed by following <{startElement.Content[sameElementIndex].As<DothtmlElementNode>()?.FullTagName}> tag.");
                        startElement.Content[sameElementIndex].AddWarning($"Previous <{startElement.FullTagName}> is implicitly closed here.");

                        var count = startElement.Content.Count - sameElementIndex;
                        ElementHierarchy.Peek().Content.AddRange(startElement.Content.Skip(sameElementIndex));
                        startElement.Content.RemoveRange(sameElementIndex, count);
                    }
                }
                else
                {
                    startElement.AddWarning($"End tag is missing, the element is implicitly closed by </{element.FullTagName}>.");
                    element.AddWarning($"Element <{startElement.FullTagName}> is implicitly closed here.");
                }

                // otherwise just pop the element
                startElement = ElementHierarchy.Peek() as DothtmlElementNode;
            }
        }
Example #6
0
 public static int GetContentStartPosition(this DothtmlElementNode node)
 {
     return(node.Content.FirstOrDefault()?.StartPosition ?? (node.StartPosition + node.Length));
 }
 public void Visit(DothtmlElementNode element)
 {
     LastFoundNode = element;
 }
 public void Visit(DothtmlElementNode element)
 {
     LastFoundNode = element;
 }