Chromium Code Reviews| 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 d23ba6139b787362ccc9bbd6358ba352763fd952..aa8d08149e511636494fbb7a25fedb19f7fcaa88 100644 |
| --- a/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp |
| +++ b/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp |
| @@ -92,9 +92,17 @@ static bool tokenExitsMath(const CompactHTMLToken& token) { |
| threadSafeMatch(tagName, MathMLNames::mtextTag); |
| } |
| +static bool tokenExitsInSelect(const CompactHTMLToken& token) { |
| + // https://html.spec.whatwg.org/#parsing-main-inselect |
| + const String& tagName = token.data(); |
| + return threadSafeMatch(tagName, inputTag) || |
| + threadSafeMatch(tagName, keygenTag) || |
| + threadSafeMatch(tagName, textareaTag); |
| +} |
| + |
| HTMLTreeBuilderSimulator::HTMLTreeBuilderSimulator( |
| const HTMLParserOptions& options) |
| - : m_options(options) { |
| + : m_options(options), m_inSelectInsertionMode(false) { |
| m_namespaceStack.push_back(HTML); |
| } |
| @@ -140,20 +148,38 @@ HTMLTreeBuilderSimulator::SimulatedToken HTMLTreeBuilderSimulator::simulate( |
| if (threadSafeMatch(tagName, textareaTag) || |
| threadSafeMatch(tagName, titleTag)) { |
| tokenizer->setState(HTMLTokenizer::RCDATAState); |
| - } else if (threadSafeMatch(tagName, plaintextTag)) { |
| - tokenizer->setState(HTMLTokenizer::PLAINTEXTState); |
| } else if (threadSafeMatch(tagName, scriptTag)) { |
| tokenizer->setState(HTMLTokenizer::ScriptDataState); |
| simulatedToken = ScriptStart; |
| - } else if (threadSafeMatch(tagName, styleTag) || |
| - threadSafeMatch(tagName, iframeTag) || |
| - threadSafeMatch(tagName, xmpTag) || |
| - (threadSafeMatch(tagName, noembedTag) && |
| - m_options.pluginsEnabled) || |
| - threadSafeMatch(tagName, noframesTag) || |
| - (threadSafeMatch(tagName, noscriptTag) && |
| - m_options.scriptEnabled)) { |
| - tokenizer->setState(HTMLTokenizer::RAWTEXTState); |
| + } else if (!m_inSelectInsertionMode) { |
| + // If we're in the "in select" insertion mode, all of these tags are |
| + // ignored, so we shouldn't change the tokenizer state: |
| + // https://html.spec.whatwg.org/#parsing-main-inselect |
| + if (threadSafeMatch(tagName, plaintextTag) && |
| + !m_inSelectInsertionMode) { |
|
Yoav Weiss
2017/01/12 13:45:44
I'm most probably missing something, but I don't s
Mike West
2017/01/12 14:44:51
Sure. However, we have no idea what mode we're in
Yoav Weiss
2017/01/13 14:13:19
makes sense :)
|
| + tokenizer->setState(HTMLTokenizer::PLAINTEXTState); |
| + } else if (threadSafeMatch(tagName, styleTag) || |
| + threadSafeMatch(tagName, iframeTag) || |
| + threadSafeMatch(tagName, xmpTag) || |
| + (threadSafeMatch(tagName, noembedTag) && |
| + m_options.pluginsEnabled) || |
| + threadSafeMatch(tagName, noframesTag) || |
| + (threadSafeMatch(tagName, noscriptTag) && |
| + m_options.scriptEnabled)) { |
|
Yoav Weiss
2017/01/12 13:45:44
Here we're basically blocking anything not mention
Mike West
2017/01/12 14:44:51
No? This basically just moves the existing code (f
Yoav Weiss
2017/01/13 14:13:19
fair enough :)
|
| + tokenizer->setState(HTMLTokenizer::RAWTEXTState); |
| + } |
| + } |
| + |
| + // We need to track whether we're in the "in select" insertion mode |
| + // in order to determine whether '<plaintext>' will put the tokenizer |
| + // into PLAINTEXTState, and whether '<xmp>' and others will consume |
| + // textual content. |
| + // |
| + // https://html.spec.whatwg.org/#parsing-main-inselect |
| + if (threadSafeMatch(tagName, selectTag)) { |
| + m_inSelectInsertionMode = true; |
| + } else if (m_inSelectInsertionMode && tokenExitsInSelect(token)) { |
| + m_inSelectInsertionMode = false; |
| } |
| } |
| } |
| @@ -169,12 +195,15 @@ HTMLTreeBuilderSimulator::SimulatedToken HTMLTreeBuilderSimulator::simulate( |
| (m_namespaceStack.contains(SVG) && m_namespaceStack.back() == HTML && |
| tokenExitsSVG(token)) || |
| (m_namespaceStack.contains(MathML) && m_namespaceStack.back() == HTML && |
| - tokenExitsMath(token))) |
| + tokenExitsMath(token))) { |
| m_namespaceStack.pop_back(); |
| + } |
| if (threadSafeMatch(tagName, scriptTag)) { |
| if (!inForeignContent()) |
| tokenizer->setState(HTMLTokenizer::DataState); |
| return ScriptEnd; |
| + } else if (threadSafeMatch(tagName, selectTag)) { |
| + m_inSelectInsertionMode = false; |
| } |
| } |