private void EndTagHandler(MarkupParsingContext context, HtmlTag tag)
{
HtmlNodeType previousNodeType = _currentNodeType;
HtmlTag previousTag = _currentTag ?? HtmlTag.Empty;
string previousTagNameInLowercase = previousTag.NameInLowercase;
string previousText = _currentText;
_currentNodeType = HtmlNodeType.EndTag;
_currentTag = tag;
_currentText = string.Empty;
string tagName = tag.Name;
string tagNameInLowercase = tag.NameInLowercase;
HtmlTagFlags tagFlags = tag.Flags;
WhitespaceMinificationMode whitespaceMinificationMode = _settings.WhitespaceMinificationMode;
if (whitespaceMinificationMode != WhitespaceMinificationMode.None)
{
if (_tagsWithNotRemovableWhitespaceQueue.Count == 0 && !tagFlags.HasFlag(HtmlTagFlags.EmbeddedCode))
{
// Processing of whitespace, that followed before the end tag
bool allowTrimEnd = false;
if (tagFlags.HasFlag(HtmlTagFlags.Invisible)
|| (previousTag.Flags.HasFlag(HtmlTagFlags.NonIndependent)
&& CanRemoveWhitespaceAfterEndNonIndependentTagByParentTag(previousTag, tag)))
{
allowTrimEnd = true;
}
else
{
if (whitespaceMinificationMode == WhitespaceMinificationMode.Medium)
{
allowTrimEnd = tagFlags.HasFlag(HtmlTagFlags.Block);
}
else if (whitespaceMinificationMode == WhitespaceMinificationMode.Aggressive)
{
allowTrimEnd = tagFlags.HasFlag(HtmlTagFlags.Block)
|| tagFlags.HasFlag(HtmlTagFlags.Inline)
|| tagFlags.HasFlag(HtmlTagFlags.InlineBlock)
;
}
}
if (allowTrimEnd)
{
TrimEndLastBufferItem();
}
}
// Check if current tag is in a whitespace queue
if (_tagsWithNotRemovableWhitespaceQueue.Count > 0
&& tagNameInLowercase == _tagsWithNotRemovableWhitespaceQueue.Last())
{
_tagsWithNotRemovableWhitespaceQueue.Dequeue();
}
}
if (_settings.RemoveOptionalEndTags
&& previousTag.Flags.HasFlag(HtmlTagFlags.Optional)
&& (previousNodeType == HtmlNodeType.EndTag
|| (previousTagNameInLowercase != tagNameInLowercase && string.IsNullOrWhiteSpace(previousText)))
&& CanRemoveOptionalEndTagByParentTag(previousTag, tag))
{
RemoveLastEndTagFromBuffer(previousTag);
}
bool isElementEmpty = string.IsNullOrWhiteSpace(previousText)
&& previousTagNameInLowercase == tagNameInLowercase
&& previousNodeType != HtmlNodeType.EndTag;
if (_settings.RemoveTagsWithoutContent && isElementEmpty
&& CanRemoveTagWithoutContent(previousTag))
{
// Remove last "element" from buffer, return
if (RemoveLastStartTagFromBuffer(tag))
{
FlushBuffer();
return;
}
}
if (_settings.RemoveOptionalEndTags
&& tagFlags.HasFlag(HtmlTagFlags.Optional)
&& CanRemoveSafeOptionalEndTag(tag))
{
// Leave only start tag in buffer
FlushBuffer();
return;
}
// Add end tag to buffer
_buffer.Add("</");
_buffer.Add(CanPreserveCase() ? tagName : tagNameInLowercase);
_buffer.Add(">");
}