Commit 17f95119 authored by Chris Harrelson's avatar Chris Harrelson Committed by Commit Bot

Force a new token chunk after custom element start tags.

This ensures that that token is always at the end of
a token chunk. This is important because the parser can
only yield or pause at token chunk boundaries. Pausing
may be forced by a custom element because its createdCallback
routine may add a stylesheet, which blocks the HTML parser.

Bug: 904966

Change-Id: I9252067f435d048b860cc9725ba23d829c9f644d
Reviewed-on: https://chromium-review.googlesource.com/c/1351366Reviewed-by: default avatarKouhei Ueno <kouhei@chromium.org>
Commit-Queue: Chris Harrelson <chrishtr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611317}
parent 8e5a76db
...@@ -247,6 +247,7 @@ void BackgroundHTMLParser::PumpTokenizer() { ...@@ -247,6 +247,7 @@ void BackgroundHTMLParser::PumpTokenizer() {
if (simulated_token == HTMLTreeBuilderSimulator::kScriptEnd || if (simulated_token == HTMLTreeBuilderSimulator::kScriptEnd ||
simulated_token == HTMLTreeBuilderSimulator::kStyleEnd || simulated_token == HTMLTreeBuilderSimulator::kStyleEnd ||
simulated_token == HTMLTreeBuilderSimulator::kLink || simulated_token == HTMLTreeBuilderSimulator::kLink ||
simulated_token == HTMLTreeBuilderSimulator::kCustomElementBegin ||
pending_tokens_.size() >= kPendingTokenLimit) { pending_tokens_.size() >= kPendingTokenLimit) {
EnqueueTokenizedChunk(); EnqueueTokenizedChunk();
......
...@@ -237,6 +237,14 @@ HTMLTreeBuilderSimulator::SimulatedToken HTMLTreeBuilderSimulator::Simulate( ...@@ -237,6 +237,14 @@ HTMLTreeBuilderSimulator::SimulatedToken HTMLTreeBuilderSimulator::Simulate(
if (ThreadSafeMatch(tag_name, kStyleTag)) if (ThreadSafeMatch(tag_name, kStyleTag))
simulated_token = kStyleEnd; simulated_token = kStyleEnd;
} }
if (token.GetType() == HTMLToken::kStartTag &&
simulated_token == kOtherToken) {
const String& tag_name = token.Data();
// Use the presence of a dash in the tag name as a proxy for
// "is a custom element".
if (tag_name.find('-') != kNotFound)
simulated_token = kCustomElementBegin;
}
// FIXME: Also setForceNullCharacterReplacement when in text mode. // FIXME: Also setForceNullCharacterReplacement when in text mode.
tokenizer->SetForceNullCharacterReplacement(InForeignContent()); tokenizer->SetForceNullCharacterReplacement(InForeignContent());
......
...@@ -48,6 +48,7 @@ class CORE_EXPORT HTMLTreeBuilderSimulator { ...@@ -48,6 +48,7 @@ class CORE_EXPORT HTMLTreeBuilderSimulator {
kScriptEnd, kScriptEnd,
kLink, kLink,
kStyleEnd, kStyleEnd,
kCustomElementBegin,
kOtherToken kOtherToken
}; };
......
<!DOCTYPE html>
<html>
<body>
<span>This renders</span>
<h1>I am a custom element</h1>
<span>This should also render</span>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<script>
class MyThing extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'open' });
}
connectedCallback() {
let style = document.createElement('style');
style.innerText = '@import url("./styles.css");';
let h1 = document.createElement('h1');
h1.innerText = 'I am a custom element';
document.body.appendChild(style);
this.shadow.appendChild(h1);
}
}
customElements.define('my-thing', MyThing);
</script>
</head>
<body>
<span>This renders</span>
<my-thing></my-thing>
<span>This should also render</span>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment