diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/syntax/parsing/html5lib_namespace-sensitivity.txt b/Tests/LibWeb/Text/expected/wpt-import/html/syntax/parsing/html5lib_namespace-sensitivity.txt index c92520b0735..0c8148f9a05 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/html/syntax/parsing/html5lib_namespace-sensitivity.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/html/syntax/parsing/html5lib_namespace-sensitivity.txt @@ -6,6 +6,6 @@ Rerun Found 1 tests -1 Fail +1 Pass Details -Result Test Name MessageFail html5lib_namespace-sensitivity.html de0a2051123e97a540e3aeb58375103bda021122 \ No newline at end of file +Result Test Name MessagePass html5lib_namespace-sensitivity.html de0a2051123e97a540e3aeb58375103bda021122 \ No newline at end of file diff --git a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp b/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp index e8ea236556f..91b5f45704b 100644 --- a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp +++ b/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp @@ -771,7 +771,7 @@ JS::NonnullGCPtr HTMLParser::create_element_for(HTMLToken const& t auto& html_element = form_associated_element->form_associated_element_to_html_element(); if (m_form_element.ptr() - && !m_stack_of_open_elements.contains(HTML::TagNames::template_) + && !m_stack_of_open_elements.contains_template_element() && (!form_associated_element->is_listed() || !html_element.has_attribute(HTML::AttributeNames::form)) && &intended_parent.root() == &m_form_element->root()) { form_associated_element->set_form(m_form_element.ptr()); @@ -1056,7 +1056,7 @@ void HTMLParser::handle_in_head(HTMLToken& token) // -> An end tag whose tag name is "template" if (token.is_end_tag() && token.tag_name() == HTML::TagNames::template_) { // If there is no template element on the stack of open elements, then this is a parse error; ignore the token. - if (!m_stack_of_open_elements.contains(HTML::TagNames::template_)) { + if (!m_stack_of_open_elements.contains_template_element()) { log_parse_error(); return; } @@ -1768,7 +1768,7 @@ void HTMLParser::handle_in_body(HTMLToken& token) log_parse_error(); // If there is a template element on the stack of open elements, then ignore the token. - if (m_stack_of_open_elements.contains(HTML::TagNames::template_)) + if (m_stack_of_open_elements.contains_template_element()) return; // Otherwise, for each attribute on the token, check to see if the attribute is already present on the top element of the stack of open elements. @@ -1806,7 +1806,7 @@ void HTMLParser::handle_in_body(HTMLToken& token) // (fragment case or there is a template element on the stack) if (m_stack_of_open_elements.elements().size() == 1 || m_stack_of_open_elements.elements().at(1)->local_name() != HTML::TagNames::body - || m_stack_of_open_elements.contains(HTML::TagNames::template_)) { + || m_stack_of_open_elements.contains_template_element()) { return; } @@ -1832,7 +1832,7 @@ void HTMLParser::handle_in_body(HTMLToken& token) // (fragment case or there is a template element on the stack) if (m_stack_of_open_elements.elements().size() == 1 || m_stack_of_open_elements.elements().at(1)->local_name() != HTML::TagNames::body) { - VERIFY(m_parsing_fragment || m_stack_of_open_elements.contains(HTML::TagNames::template_)); + VERIFY(m_parsing_fragment || m_stack_of_open_elements.contains_template_element()); return; } @@ -1986,7 +1986,7 @@ void HTMLParser::handle_in_body(HTMLToken& token) // -> A start tag whose tag name is "form" if (token.is_start_tag() && token.tag_name() == HTML::TagNames::form) { // If the form element pointer is not null, and there is no template element on the stack of open elements, then this is a parse error; ignore the token. - if (m_form_element.ptr() && !m_stack_of_open_elements.contains(HTML::TagNames::template_)) { + if (m_form_element.ptr() && !m_stack_of_open_elements.contains_template_element()) { log_parse_error(); return; } @@ -1998,7 +1998,7 @@ void HTMLParser::handle_in_body(HTMLToken& token) // Insert an HTML element for the token, and, if there is no template element on the stack of open elements, set the form element pointer to point to the element created. auto element = insert_html_element(token); - if (!m_stack_of_open_elements.contains(HTML::TagNames::template_)) + if (!m_stack_of_open_elements.contains_template_element()) m_form_element = verify_cast(*element); return; } @@ -2163,7 +2163,7 @@ void HTMLParser::handle_in_body(HTMLToken& token) // -> An end tag whose tag name is "form" if (token.is_end_tag() && token.tag_name() == HTML::TagNames::form) { // If there is no template element on the stack of open elements, then run these substeps: - if (!m_stack_of_open_elements.contains(HTML::TagNames::template_)) { + if (!m_stack_of_open_elements.contains_template_element()) { // 1. Let node be the element that the form element pointer is set to, or null if it is not set to an element. auto node = m_form_element; @@ -3521,7 +3521,7 @@ void HTMLParser::handle_in_table(HTMLToken& token) // If there is a template element on the stack of open elements, // or if the form element pointer is not null, ignore the token. - if (m_form_element.ptr() || m_stack_of_open_elements.contains(HTML::TagNames::template_)) { + if (m_form_element.ptr() || m_stack_of_open_elements.contains_template_element()) { return; } @@ -3939,7 +3939,7 @@ void HTMLParser::handle_in_template(HTMLToken& token) // -> An end-of-file token if (token.is_end_of_file()) { // If there is no template element on the stack of open elements, then stop parsing. (fragment case) - if (!m_stack_of_open_elements.contains(HTML::TagNames::template_)) { + if (!m_stack_of_open_elements.contains_template_element()) { VERIFY(m_parsing_fragment); stop_parsing(); return; @@ -4316,6 +4316,9 @@ void HTMLParser::reset_the_insertion_mode_appropriately() node = m_stack_of_open_elements.elements().at(i).ptr(); } + if (node->namespace_uri() != Namespace::HTML) + continue; + if (node->local_name() == HTML::TagNames::select) { if (!last) { for (ssize_t j = i; j > 0; --j) { diff --git a/Userland/Libraries/LibWeb/HTML/Parser/StackOfOpenElements.cpp b/Userland/Libraries/LibWeb/HTML/Parser/StackOfOpenElements.cpp index 48f09b0d338..d2ee6958a65 100644 --- a/Userland/Libraries/LibWeb/HTML/Parser/StackOfOpenElements.cpp +++ b/Userland/Libraries/LibWeb/HTML/Parser/StackOfOpenElements.cpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace Web::HTML { @@ -105,10 +106,12 @@ bool StackOfOpenElements::contains(const DOM::Element& element) const return false; } -bool StackOfOpenElements::contains(FlyString const& tag_name) const +bool StackOfOpenElements::contains_template_element() const { - for (auto& element_on_stack : m_elements) { - if (element_on_stack->local_name() == tag_name) + for (auto const& element : m_elements) { + if (element->namespace_uri() != Namespace::HTML) + continue; + if (element->local_name() == HTML::TagNames::template_) return true; } return false; @@ -116,7 +119,7 @@ bool StackOfOpenElements::contains(FlyString const& tag_name) const void StackOfOpenElements::pop_until_an_element_with_tag_name_has_been_popped(FlyString const& tag_name) { - while (m_elements.last()->local_name() != tag_name) + while (m_elements.last()->namespace_uri() != Namespace::HTML || m_elements.last()->local_name() != tag_name) (void)pop(); (void)pop(); } diff --git a/Userland/Libraries/LibWeb/HTML/Parser/StackOfOpenElements.h b/Userland/Libraries/LibWeb/HTML/Parser/StackOfOpenElements.h index f412a17f42b..7cf1fa1041d 100644 --- a/Userland/Libraries/LibWeb/HTML/Parser/StackOfOpenElements.h +++ b/Userland/Libraries/LibWeb/HTML/Parser/StackOfOpenElements.h @@ -44,12 +44,12 @@ public: bool has_in_scope(const DOM::Element&) const; bool contains(const DOM::Element&) const; - bool contains(FlyString const& tag_name) const; + [[nodiscard]] bool contains_template_element() const; auto const& elements() const { return m_elements; } auto& elements() { return m_elements; } - void pop_until_an_element_with_tag_name_has_been_popped(FlyString const&); + void pop_until_an_element_with_tag_name_has_been_popped(FlyString const& local_name); JS::GCPtr topmost_special_node_below(DOM::Element const&);