Exemplo n.º 1
0
        /// <summary>
        /// Parses a start tag
        /// </summary>
        /// <param name="tagName">Tag name</param>
        /// <param name="tagNameInLowercase">Tag name in lowercase</param>
        /// <param name="attributes">List of attributes</param>
        /// <param name="isEmptyTag">Flag that tag is empty</param>
        private void ParseStartTag(string tagName, string tagNameInLowercase, List <HtmlAttribute> attributes,
                                   bool isEmptyTag)
        {
            HtmlTagFlags tagFlags = GetTagFlagsByName(tagNameInLowercase);

            if (tagFlags.IsSet(HtmlTagFlags.Optional))
            {
                HtmlTag lastStackedTag = _tagStack.LastOrDefault();
                if (lastStackedTag != null && lastStackedTag.NameInLowercase == tagNameInLowercase)
                {
                    ParseEndTag(lastStackedTag.Name, lastStackedTag.NameInLowercase);
                }
                else
                {
                    if (tagNameInLowercase == "body" && _tagStack.Any(t => t.NameInLowercase == "head"))
                    {
                        HtmlTag headTag = _tagStack.First(t => t.NameInLowercase == "head");
                        ParseEndTag(headTag.Name, headTag.NameInLowercase);
                    }
                }
            }

            if (tagFlags.IsSet(HtmlTagFlags.Empty))
            {
                isEmptyTag = true;
            }
            else if (isEmptyTag)
            {
                tagFlags |= HtmlTagFlags.Empty;
            }

            int attributeCount = attributes.Count;

            for (int attributeIndex = 0; attributeIndex < attributeCount; attributeIndex++)
            {
                HtmlAttribute attribute = attributes[attributeIndex];
                attribute.Type = _attributeTypeDeterminer.GetAttributeType(tagNameInLowercase, tagFlags,
                                                                           attribute.NameInLowercase, attributes);
            }

            var tag = new HtmlTag(tagName, tagNameInLowercase, attributes, tagFlags);

            if (!isEmptyTag)
            {
                if (_conditionalCommentOpened)
                {
                    HtmlConditionalComment     lastConditionalComment     = _conditionalCommentStack.Peek();
                    HtmlConditionalCommentType lastConditionalCommentType = lastConditionalComment.Type;

                    if (tagFlags.IsSet(HtmlTagFlags.EmbeddedCode) ||
                        lastConditionalCommentType == HtmlConditionalCommentType.RevealedValidating ||
                        lastConditionalCommentType == HtmlConditionalCommentType.RevealedValidatingSimplified)
                    {
                        _tagStack.Add(tag);
                    }
                }
                else
                {
                    _tagStack.Add(tag);
                }
            }

            _handlers.StartTag?.Invoke(_context, tag);

            if (tagFlags.IsSet(HtmlTagFlags.Xml) && !tagFlags.IsSet(HtmlTagFlags.NonIndependent))
            {
                _xmlTagStack.Push(tagNameInLowercase);
            }
        }
        /// <summary>
        /// If conditional comments handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="htmlConditionalComment">Conditional comment</param>
        private void IfConditionalCommentHandler(MarkupParsingContext context,
			HtmlConditionalComment htmlConditionalComment)
        {
            _currentNodeType = HtmlNodeType.IfConditionalComment;
            HtmlConditionalCommentType htmlConditionalCommentType = htmlConditionalComment.Type;

            string startPart;
            string endPart;

            switch (htmlConditionalCommentType)
            {
                case HtmlConditionalCommentType.Hidden:
                    startPart = "<!--[if ";
                    endPart = "]>";

                    break;
                case HtmlConditionalCommentType.RevealedValidating:
                    startPart = "<!--[if ";
                    endPart = "]><!-->";

                    break;
                case HtmlConditionalCommentType.RevealedValidatingSimplified:
                    startPart = "<!--[if ";
                    endPart = "]>-->";

                    break;
                case HtmlConditionalCommentType.Revealed:
                    startPart = "<![if ";
                    endPart = "]>";

                    break;
                default:
                    throw new NotSupportedException();
            }

            _buffer.Add(startPart);
            _buffer.Add(htmlConditionalComment.Expression);
            _buffer.Add(endPart);
        }