private void CloseElement(string htmlElementName)
{
// Check if the element is opened and already added to the parent
InvariantAssert(_openedElements.Count > 0, "CloseElement: Stack of opened elements cannot be empty, as we have at least one artificial root element");
// Check if the element is opened and still waiting to be added to the parent
if (_pendingInlineElements.Count > 0 && _pendingInlineElements.Peek().LocalName == htmlElementName)
{
// Closing an empty inline element.
// Note that HtmlConverter will skip empty inlines, but for completeness we keep them here on parser level.
XmlElement htmlInlineElement = _pendingInlineElements.Pop();
InvariantAssert(_openedElements.Count > 0, "CloseElement: Stack of opened elements cannot be empty, as we have at least one artificial root element");
XmlElement htmlParent = _openedElements.Peek();
htmlParent.AppendChild(htmlInlineElement);
return;
}
else if (IsElementOpened(htmlElementName))
{
while (_openedElements.Count > 1) // we never pop the last element - the artificial root
{
// Close all unbalanced elements.
XmlElement htmlOpenedElement = _openedElements.Pop();
if (htmlOpenedElement.LocalName == htmlElementName)
{
return;
}
if (HtmlSchema.IsInlineElement(htmlOpenedElement.LocalName))
{
// Unbalances Inlines will be transfered to the next element content
_pendingInlineElements.Push(CreateElementCopy(htmlOpenedElement));
}
}
}
// If element was not opened, we simply ignore the unbalanced closing tag
return;
}