/// <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); }