| Index: third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp
|
| diff --git a/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp b/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp
|
| index 9e0703333a4871dcc5cf76c47a9893afc981ef4e..c520f936b695e82295b5148c828078a2e8d37fdb 100644
|
| --- a/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp
|
| +++ b/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp
|
| @@ -104,63 +104,28 @@ static bool tokenExitsMath(const CompactHTMLToken& token)
|
| || threadSafeMatch(tagName, MathMLNames::mtextTag);
|
| }
|
|
|
| -// We always push tokens which may be related to elements which are
|
| -// HTML integration points. elementMayBeHTMLIntegrationPoint gives
|
| -// conservative false positives. Specifically, annotation-xml end tags
|
| -// may not be related to HTML integration points; it depends on the
|
| -// opening tags' attributes. But elementMayBeHTMLIntegrationPoint
|
| -// returns true for these elements.
|
| -static bool elementMayBeHTMLIntegrationPoint(const String& tagName)
|
| -{
|
| - return threadSafeMatch(tagName, MathMLNames::annotation_xmlTag)
|
| - || threadSafeMatch(tagName, SVGNames::descTag)
|
| - || threadSafeMatch(tagName, SVGNames::foreignObjectTag)
|
| - || threadSafeMatch(tagName, titleTag);
|
| -}
|
| -
|
| -// https://html.spec.whatwg.org/#html-integration-point
|
| -// See also HTMLElementStack::isHTMLIntegrationPoint
|
| -static bool tokenStartsHTMLIntegrationPoint(const CompactHTMLToken& token)
|
| -{
|
| - if (token.type() != HTMLToken::StartTag)
|
| - return false;
|
| -
|
| - const String& tagName = token.data();
|
| - if (threadSafeMatch(tagName, MathMLNames::annotation_xmlTag)) {
|
| - if (const CompactHTMLToken::Attribute* encoding = token.getAttributeItem(MathMLNames::encodingAttr)) {
|
| - return equalIgnoringCase(encoding->value(), "text/html")
|
| - || equalIgnoringCase(encoding->value(), "application/xhtml+xml");
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - return threadSafeMatch(tagName, SVGNames::descTag)
|
| - || threadSafeMatch(tagName, SVGNames::foreignObjectTag)
|
| - || threadSafeMatch(tagName, titleTag);
|
| -}
|
| -
|
| HTMLTreeBuilderSimulator::HTMLTreeBuilderSimulator(const HTMLParserOptions& options)
|
| : m_options(options)
|
| {
|
| - m_stack.append(StateFlags {HTML, false});
|
| + m_namespaceStack.append(HTML);
|
| }
|
|
|
| HTMLTreeBuilderSimulator::State HTMLTreeBuilderSimulator::stateFor(HTMLTreeBuilder* treeBuilder)
|
| {
|
| ASSERT(isMainThread());
|
| - State stack;
|
| + State namespaceStack;
|
| for (HTMLElementStack::ElementRecord* record = treeBuilder->openElements()->topRecord(); record; record = record->next()) {
|
| - Namespace recordNamespace = HTML;
|
| + Namespace currentNamespace = HTML;
|
| if (record->namespaceURI() == SVGNames::svgNamespaceURI)
|
| - recordNamespace = SVG;
|
| + currentNamespace = SVG;
|
| else if (record->namespaceURI() == MathMLNames::mathmlNamespaceURI)
|
| - recordNamespace = MathML;
|
| + currentNamespace = MathML;
|
|
|
| - if (stack.isEmpty() || static_cast<Namespace>(stack.last().ns) != recordNamespace || elementMayBeHTMLIntegrationPoint(record->stackItem()->localName()))
|
| - stack.append(StateFlags {static_cast<unsigned>(recordNamespace), HTMLElementStack::isHTMLIntegrationPoint(record->stackItem())});
|
| + if (namespaceStack.isEmpty() || namespaceStack.last() != currentNamespace)
|
| + namespaceStack.append(currentNamespace);
|
| }
|
| - stack.reverse();
|
| - return stack;
|
| + namespaceStack.reverse();
|
| + return namespaceStack;
|
| }
|
|
|
| HTMLTreeBuilderSimulator::SimulatedToken HTMLTreeBuilderSimulator::simulate(const CompactHTMLToken& token, HTMLTokenizer* tokenizer)
|
| @@ -169,23 +134,16 @@ HTMLTreeBuilderSimulator::SimulatedToken HTMLTreeBuilderSimulator::simulate(cons
|
|
|
| if (token.type() == HTMLToken::StartTag) {
|
| const String& tagName = token.data();
|
| - bool currentNodeIsHTMLIntegrationPoint = m_stack.last().isHTMLIntegrationPoint;
|
| - Namespace currentNodeNamespace = currentNamespace();
|
| -
|
| - if (inForeignContent() && tokenExitsForeignContent(token))
|
| - m_stack.removeLast();
|
| -
|
| if (threadSafeMatch(tagName, SVGNames::svgTag))
|
| - m_stack.append(StateFlags {SVG, tokenStartsHTMLIntegrationPoint(token)});
|
| - else if (threadSafeMatch(tagName, MathMLNames::mathTag))
|
| - m_stack.append(StateFlags {MathML, tokenStartsHTMLIntegrationPoint(token)});
|
| - else if ((currentNodeNamespace == SVG && tokenExitsSVG(token))
|
| - || (currentNodeNamespace == MathML && tokenExitsMath(token)))
|
| - m_stack.append(StateFlags {HTML, tokenStartsHTMLIntegrationPoint(token)});
|
| - else if (elementMayBeHTMLIntegrationPoint(token.data()) != currentNodeIsHTMLIntegrationPoint)
|
| - m_stack.append(StateFlags {static_cast<unsigned>(currentNodeNamespace), tokenStartsHTMLIntegrationPoint(token)});
|
| -
|
| - if (!inForeignContent() || currentNodeIsHTMLIntegrationPoint) {
|
| + m_namespaceStack.append(SVG);
|
| + if (threadSafeMatch(tagName, MathMLNames::mathTag))
|
| + m_namespaceStack.append(MathML);
|
| + if (inForeignContent() && tokenExitsForeignContent(token))
|
| + m_namespaceStack.removeLast();
|
| + if ((m_namespaceStack.last() == SVG && tokenExitsSVG(token))
|
| + || (m_namespaceStack.last() == MathML && tokenExitsMath(token)))
|
| + m_namespaceStack.append(HTML);
|
| + if (!inForeignContent()) {
|
| // FIXME: This is just a copy of Tokenizer::updateStateFor which uses threadSafeMatches.
|
| if (threadSafeMatch(tagName, textareaTag) || threadSafeMatch(tagName, titleTag)) {
|
| tokenizer->setState(HTMLTokenizer::RCDATAState);
|
| @@ -207,18 +165,11 @@ HTMLTreeBuilderSimulator::SimulatedToken HTMLTreeBuilderSimulator::simulate(cons
|
|
|
| if (token.type() == HTMLToken::EndTag) {
|
| const String& tagName = token.data();
|
| - if ((currentNamespace() == SVG && threadSafeMatch(tagName, SVGNames::svgTag))
|
| - || (currentNamespace() == MathML && threadSafeMatch(tagName, MathMLNames::mathTag))
|
| - || (stackContainsNamespace(SVG) && currentNamespace() == HTML && tokenExitsSVG(token))
|
| - || (stackContainsNamespace(MathML) && currentNamespace() == HTML && tokenExitsMath(token))
|
| - // By checking the namespace, the above tests subtly avoid
|
| - // popping the base stack entry which is 'HTML'. Because
|
| - // HTML title is an integration point, we must explicitly
|
| - // check we are not popping the base entry when presented
|
| - // malformed input like </title> with no opening tag.
|
| - || (m_stack.size() > 1 && elementMayBeHTMLIntegrationPoint(token.data()) != static_cast<bool>(m_stack.last().isHTMLIntegrationPoint)))
|
| - m_stack.removeLast();
|
| -
|
| + if ((m_namespaceStack.last() == SVG && threadSafeMatch(tagName, SVGNames::svgTag))
|
| + || (m_namespaceStack.last() == MathML && threadSafeMatch(tagName, MathMLNames::mathTag))
|
| + || (m_namespaceStack.contains(SVG) && m_namespaceStack.last() == HTML && tokenExitsSVG(token))
|
| + || (m_namespaceStack.contains(MathML) && m_namespaceStack.last() == HTML && tokenExitsMath(token)))
|
| + m_namespaceStack.removeLast();
|
| if (threadSafeMatch(tagName, scriptTag)) {
|
| if (!inForeignContent())
|
| tokenizer->setState(HTMLTokenizer::DataState);
|
|
|