Skip to content

Commit 55a2864

Browse files
committed
REGRESSION (STP): Video won't play on bilibili.com
https://bugs.webkit.org/show_bug.cgi?id=263196 rdar://117020123 Reviewed by Chris Dumez. bilibili injects DOM objects in the tree by calling: ``` var t = (new DOMParser).parseFromString(e, "text/html"); return document.adoptNode(t.body.firstChild) ``` Per spec, when parsing HTML to create a document through DOMParser::parseFromString() [1] you are to skip the whitespace tokens for the "initial" insertion mode [2]. The trailing spaces however must be kept [3] This behaviour was regressed by 267202@main. On this site, the observable behaviour was that the firstChild became a "#text" node rather the expected first DIV one. So we trim the leading whitespaces before calling the fast parser. Which restore the original behaviour prior 267202@main [1] https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#parse-html-from-a-string [2] https://html.spec.whatwg.org/multipage/parsing.html#the-initial-insertion-mode [3] https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-afterbody * LayoutTests/fast/dom/document-contentType-DOMParser-expected.txt: * LayoutTests/fast/dom/document-contentType-DOMParser.html: Added tests. * Source/WebCore/html/parser/HTMLDocumentParserFastPath.cpp: (WebCore::tryFastParsingHTMLFragment): * Source/WebCore/html/parser/HTMLDocumentParserFastPath.h: Change type to StringView (WebCore::requires): * Source/WebCore/xml/DOMParser.cpp: (WebCore::DOMParser::parseFromString): Canonical link: https://commits.webkit.org/269457@main
1 parent ab95121 commit 55a2864

File tree

5 files changed

+26
-4
lines changed

5 files changed

+26
-4
lines changed

LayoutTests/fast/dom/document-contentType-DOMParser-expected.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ PASS new DOMParser().parseFromString(xslContent, "text/xsl").contentType threw e
66
PASS new DOMParser().parseFromString(xmlContent, "text/dummy+xml").contentType threw exception TypeError: Type error.
77
PASS new DOMParser().parseFromString(xmlContent, "text/XML").contentType threw exception TypeError: Type error.
88
PASS new DOMParser().parseFromString(htmlContent, "TEXT/html").contentType threw exception TypeError: Type error.
9+
PASS parsedContent.body.firstChild.nodeName is "DIV"
10+
PASS parsedContent.body.childNodes.length is 2
11+
PASS parsedContent.body.childNodes[1].nodeName is "#text"
12+
PASS div.firstChild.nodeName is "#text"
13+
PASS div.childNodes.length is 3
14+
PASS div.childNodes[2].nodeName is "#text"
15+
PASS new DOMParser().parseFromString(htmlContentWithJustSpaces, "text/html").body.childNodes.length is 0
916
PASS successfullyParsed is true
1017

1118
TEST COMPLETE

LayoutTests/fast/dom/document-contentType-DOMParser.html

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
</head>
77
<body>
88
<script>
9-
9+
1010
var htmlContent =
1111
"<html>" +
1212
"<head>" +
@@ -80,6 +80,21 @@
8080
shouldThrow('new DOMParser().parseFromString(xmlContent, "text/XML").contentType', "'TypeError: Type error'");
8181
shouldThrow('new DOMParser().parseFromString(htmlContent, "TEXT/html").contentType', "'TypeError: Type error'");
8282

83+
var htmlContentWithSpace = "\n <div class=\"bpx-player-container\"></div> \n";
84+
var parsedContent = new DOMParser().parseFromString(htmlContentWithSpace, "text/html");
85+
shouldBeEqualToString('parsedContent.body.firstChild.nodeName', 'DIV');
86+
shouldBe('parsedContent.body.childNodes.length', '2');
87+
shouldBeEqualToString('parsedContent.body.childNodes[1].nodeName', '#text');
88+
89+
var div = document.createElement("div");
90+
div.innerHTML = htmlContentWithSpace;
91+
shouldBeEqualToString('div.firstChild.nodeName', '#text');
92+
shouldBe('div.childNodes.length', '3');
93+
shouldBeEqualToString('div.childNodes[2].nodeName', '#text');
94+
95+
var htmlContentWithJustSpaces = "\n \n";
96+
shouldBe('new DOMParser().parseFromString(htmlContentWithJustSpaces, "text/html").body.childNodes.length', '0');
97+
8398
</script>
8499
<script src="../../resources/js-test-post.js"></script>
85100
</body>

Source/WebCore/html/parser/HTMLDocumentParserFastPath.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ static bool tryFastParsingHTMLFragmentImpl(const std::span<const CharacterType>&
895895
return parser.parse(contextElement);
896896
}
897897

898-
bool tryFastParsingHTMLFragment(const String& source, Document& document, ContainerNode& destinationParent, Element& contextElement, OptionSet<ParserContentPolicy> policy)
898+
bool tryFastParsingHTMLFragment(StringView source, Document& document, ContainerNode& destinationParent, Element& contextElement, OptionSet<ParserContentPolicy> policy)
899899
{
900900
if (!canUseFastPath(contextElement, policy))
901901
return false;

Source/WebCore/html/parser/HTMLDocumentParserFastPath.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class Element;
4141

4242
enum class ParserContentPolicy : uint8_t;
4343

44-
WEBCORE_EXPORT bool tryFastParsingHTMLFragment(const String& source, Document&, ContainerNode&, Element& contextElement, OptionSet<ParserContentPolicy>);
44+
WEBCORE_EXPORT bool tryFastParsingHTMLFragment(StringView source, Document&, ContainerNode&, Element& contextElement, OptionSet<ParserContentPolicy>);
4545

4646
} // namespace WebCore
4747

Source/WebCore/xml/DOMParser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ ExceptionOr<Ref<Document>> DOMParser::parseFromString(const String& string, cons
6060
bool usedFastPath = false;
6161
if (contentType == "text/html"_s) {
6262
auto body = HTMLBodyElement::create(document);
63-
usedFastPath = tryFastParsingHTMLFragment(string, document, body, body, parsingOptions);
63+
usedFastPath = tryFastParsingHTMLFragment(StringView { string }.substring(string.find(isNotASCIIWhitespace<UChar>)), document, body, body, parsingOptions);
6464
if (LIKELY(usedFastPath)) {
6565
auto html = HTMLHtmlElement::create(document);
6666
document->appendChild(html);

0 commit comments

Comments
 (0)