diff --git a/lib/Exception.php b/lib/Exception.php index 8767976..da6f75b 100644 --- a/lib/Exception.php +++ b/lib/Exception.php @@ -10,7 +10,7 @@ class Exception extends \Exception { const PARSER_NONEMPTY_DOCUMENT = 10101; const STACK_INVALID_INDEX = 10201; - const STACK_DOCUMENTFRAG_ELEMENT_DOCUMENT_DOCUMENTFRAG_EXPECTED = 10202; + const STACK_ELEMENT_DOCUMENT_DOCUMENTFRAG_EXPECTED = 10202; const STACK_ELEMENT_STRING_ARRAY_EXPECTED = 10203; const STACK_STRING_ARRAY_EXPECTED = 10204; diff --git a/lib/OpenElementsStack.php b/lib/OpenElementsStack.php index 5d7954a..19d60d5 100644 --- a/lib/OpenElementsStack.php +++ b/lib/OpenElementsStack.php @@ -13,7 +13,7 @@ class OpenElementsStack extends Stack { // too. if ((!is_null($fragmentContext) && !$fragmentContext instanceof DOMDocumentFragment && !$fragmentContext instanceof DOMDocument && !$fragmentContext instanceof DOMElement) || (is_null($fragmentContext) && $fragmentCase)) { - throw new Exception(Exception::STACK_DOCUMENTFRAG_ELEMENT_DOCUMENT_DOCUMENTFRAG_EXPECTED); + throw new Exception(Exception::STACK_ELEMENT_DOCUMENT_DOCUMENTFRAG_EXPECTED); } $this->fragmentCase = $fragmentCase; diff --git a/lib/TreeBuilder.php b/lib/TreeBuilder.php index fa2bfd2..61b916d 100644 --- a/lib/TreeBuilder.php +++ b/lib/TreeBuilder.php @@ -1332,6 +1332,33 @@ class TreeBuilder { } } } + # An end tag whose tag name is one of: "address", "article", "aside", + # "blockquote", "button", "center", "details", "dialog", "dir", "div", "dl", + # "fieldset", "figcaption", "figure", "footer", "header", "listing", "main", + # "nav", "ol", "pre", "section", "summary", "ul" + elseif ($token->name === 'address' || $token->name === 'article' || $token->name === 'aside' || $token->name === 'blockquote' || $token->name === 'button' || $token->name === 'center' || $token->name === 'details' || $token->name === 'dialog' || $token->name === 'dir' || $token->name === 'div' || $token->name === 'dl' || $token->name === 'fieldset' || $token->name === 'figcaption' || $token->name === 'figure' || $token->name === 'footer' || $token->name === 'header' || $token->name === 'listing' || $token->name === 'main' || $token->name === 'nav' || $token->name === 'ol' || $token->name === 'pre' || $token->name === 'section' || $token->name === 'summary' || $token->name === 'ul') { + # If the stack of open elements does not have an element in scope that is an + # HTML element with the same tag name as that of the token, then this is a parse + # error; ignore the token. + if (!$this->stack->hasElementInScope($token->name)) { + ParseError::trigger(ParseError::UNEXPECTED_END_TAG, $token->name); + } + # Otherwise, run these steps: + else { + # 1. Generate implied end tags. + $this->stack->generateImpliedEndTags(); + + # 2. If the current node is not an HTML element with the same tag name as that + # of the token, then this is a parse error. + if ($this->stack->currentNodeName !== $token->name) { + ParseError::trigger(ParseError::UNEXPECTED_END_TAG, $token->name); + } + + # 3. Pop elements from the stack of open elements until an HTML element with the + # same tag name as the token has been popped from the stack. + $this->stack->popUntil($token->name); + } + } } # An end-of-file token elseif ($token instanceof EOFToken) {