// Opens structurig element such as Div or Table etc.
private void OpenStructuringElement(XmlElement htmlElement)
{
// Close all pending inline elements
// All block elements are considered as delimiters for inline elements
// which forces all inline elements to be closed and re-opened in the following
// structural element (if any).
// By doing that we guarantee that all inline elements appear only within most nested blocks
if (HtmlSchema.IsBlockElement(htmlElement.LocalName))
{
while (_openedElements.Count > 0 && HtmlSchema.IsInlineElement(_openedElements.Peek().LocalName))
{
XmlElement htmlInlineElement = _openedElements.Pop();
InvariantAssert(_openedElements.Count > 0, "OpenStructuringElement: stack of opened elements cannot become empty here");
_pendingInlineElements.Push(CreateElementCopy(htmlInlineElement));
}
}
// Add this block element to its parent
if (_openedElements.Count > 0)
{
XmlElement htmlParent = _openedElements.Peek();
// Check some known block elements for auto-closing (LI and P)
if (HtmlSchema.ClosesOnNextElementStart(htmlParent.LocalName, htmlElement.LocalName))
{
_openedElements.Pop();
htmlParent = _openedElements.Count > 0 ? _openedElements.Peek() : null;
}
if (htmlParent != null)
{
// NOTE:
// Actually we never expect null - it would mean two top-level P or LI (without a parent).
// In such weird case we will loose all paragraphs except the first one...
htmlParent.AppendChild(htmlElement);
}
}
// Push it onto a stack
_openedElements.Push(htmlElement);
}