From e442aa6e10aa18d1c822d1e66a76e6dec780cac4 Mon Sep 17 00:00:00 2001 From: euro20179 Date: Fri, 5 Sep 2025 15:17:55 -0700 Subject: [PATCH] LibWeb: Ensure parser cannot change the mode is handled This fixes at least 1 wpt bug where text/plain documents are rendered in quirks mode. The test in question: https://wpt.live/html/browsers/browsing-the-web/read-text/load-text-plain.html --- Libraries/LibWeb/DOM/Document.h | 5 +++ Libraries/LibWeb/DOM/DocumentLoading.cpp | 3 +- Libraries/LibWeb/HTML/Parser/HTMLParser.cpp | 14 ++++++- .../read-text/load-text-plain.txt | 8 ++++ .../input/wpt-import/common/text-plain.txt | 4 ++ .../read-text/load-text-plain.html | 40 +++++++++++++++++++ 6 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/browsers/browsing-the-web/read-text/load-text-plain.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/common/text-plain.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/browsers/browsing-the-web/read-text/load-text-plain.html diff --git a/Libraries/LibWeb/DOM/Document.h b/Libraries/LibWeb/DOM/Document.h index 016bb2dd6c6..a6aec7dec3e 100644 --- a/Libraries/LibWeb/DOM/Document.h +++ b/Libraries/LibWeb/DOM/Document.h @@ -414,6 +414,9 @@ public: bool in_limited_quirks_mode() const { return m_quirks_mode == QuirksMode::Limited; } void set_quirks_mode(QuirksMode mode) { m_quirks_mode = mode; } + bool parser_cannot_change_the_mode() const { return m_parser_cannot_change_the_mode; } + void set_parser_cannot_change_the_mode(bool parser_cannot_change_the_mode) { m_parser_cannot_change_the_mode = parser_cannot_change_the_mode; } + Type document_type() const { return m_type; } void set_document_type(Type type) { m_type = type; } @@ -1013,6 +1016,8 @@ private: QuirksMode m_quirks_mode { QuirksMode::No }; + bool m_parser_cannot_change_the_mode { false }; + // https://dom.spec.whatwg.org/#concept-document-type Type m_type { Type::XML }; diff --git a/Libraries/LibWeb/DOM/DocumentLoading.cpp b/Libraries/LibWeb/DOM/DocumentLoading.cpp index a82e7efb3da..c548b321130 100644 --- a/Libraries/LibWeb/DOM/DocumentLoading.cpp +++ b/Libraries/LibWeb/DOM/DocumentLoading.cpp @@ -208,7 +208,8 @@ static WebIDL::ExceptionOr> load_text_document(HTML::Navi // 1. Let document be the result of creating and initializing a Document object given "html", type, and navigationParams. auto document = TRY(DOM::Document::create_and_initialize(DOM::Document::Type::HTML, type.essence(), navigation_params)); - // FIXME: 2. Set document's parser cannot change the mode flag to true. + // 2. Set document's parser cannot change the mode flag to true. + document->set_parser_cannot_change_the_mode(true); // 3. Set document's mode to "no-quirks". document->set_quirks_mode(DOM::QuirksMode::No); diff --git a/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp b/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp index f025ae0ccfa..224c6becc82 100644 --- a/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp +++ b/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp @@ -606,16 +606,26 @@ void HTMLParser::handle_initial(HTMLToken& token) // Otherwise, if the document is not an iframe srcdoc document, and the parser cannot change the mode flag is false, // and the DOCTYPE token matches one of the conditions in the following list, then set the Document to limited-quirks mode: // [...] - document().set_quirks_mode(which_quirks_mode(token)); + if (!document().parser_cannot_change_the_mode()) + document().set_quirks_mode(which_quirks_mode(token)); // Then, switch the insertion mode to "before html". m_insertion_mode = InsertionMode::BeforeHTML; return; } + // -> Anything else + + // FIXME: If the document is not an iframe srcdoc document, then this is a parse error log_parse_error(); - document().set_quirks_mode(DOM::QuirksMode::Yes); + + // if the parser cannot change the mode flag is false, set the Document to quirks mode. + if (!document().parser_cannot_change_the_mode()) + document().set_quirks_mode(DOM::QuirksMode::Yes); + + // In any case, switch the insertion mode to "before html" m_insertion_mode = InsertionMode::BeforeHTML; + // then reprocess the token. process_using_the_rules_for(InsertionMode::BeforeHTML, token); } diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/browsers/browsing-the-web/read-text/load-text-plain.txt b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/browsing-the-web/read-text/load-text-plain.txt new file mode 100644 index 00000000000..8a93136bc56 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/browsers/browsing-the-web/read-text/load-text-plain.txt @@ -0,0 +1,8 @@ +Harness status: OK + +Found 3 tests + +3 Pass +Pass Checking document metadata for text file +Pass Checking DOM for text file +Pass Checking contents for text file \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/common/text-plain.txt b/Tests/LibWeb/Text/input/wpt-import/common/text-plain.txt new file mode 100644 index 00000000000..97ca870b6d5 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/common/text-plain.txt @@ -0,0 +1,4 @@ +This is a sample text/plain document. + +This is not an HTML document. + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/browsers/browsing-the-web/read-text/load-text-plain.html b/Tests/LibWeb/Text/input/wpt-import/html/browsers/browsing-the-web/read-text/load-text-plain.html new file mode 100644 index 00000000000..3b4e4f6ccad --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/browsers/browsing-the-web/read-text/load-text-plain.html @@ -0,0 +1,40 @@ + +Page load processing model for text files + + + + +
+