mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 09:17:35 +00:00
LibWeb: Improve support for "a" and "li" during "in body" insertion
We can now parse welcome.html once again, without resorting to hacks or fallbacks during "in body" :^)
This commit is contained in:
parent
30d64fccde
commit
6854f726ce
4 changed files with 47 additions and 7 deletions
|
@ -623,10 +623,7 @@ void HTMLDocumentParser::run_the_adoption_agency_algorithm(HTMLToken& token)
|
||||||
PARSE_ERROR();
|
PARSE_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Let furthest block be the topmost node in the stack of open elements
|
RefPtr<Element> furthest_block = m_stack_of_open_elements.topmost_special_node_below(*formatting_element);
|
||||||
// that is lower in the stack than formatting element, and is an element
|
|
||||||
// in the special category. There might not be one.
|
|
||||||
RefPtr<Element> furthest_block = nullptr;
|
|
||||||
|
|
||||||
if (!furthest_block) {
|
if (!furthest_block) {
|
||||||
while (¤t_node() != formatting_element)
|
while (¤t_node() != formatting_element)
|
||||||
|
@ -642,7 +639,7 @@ void HTMLDocumentParser::run_the_adoption_agency_algorithm(HTMLToken& token)
|
||||||
TODO();
|
TODO();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_special_tag(const FlyString& tag_name)
|
bool HTMLDocumentParser::is_special_tag(const FlyString& tag_name)
|
||||||
{
|
{
|
||||||
return tag_name.is_one_of(
|
return tag_name.is_one_of(
|
||||||
"address",
|
"address",
|
||||||
|
@ -911,7 +908,17 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token.is_end_tag() && token.tag_name() == "li") {
|
if (token.is_end_tag() && token.tag_name() == "li") {
|
||||||
TODO();
|
if (!m_stack_of_open_elements.has_in_list_item_scope("li")) {
|
||||||
|
PARSE_ERROR();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
generate_implied_end_tags("li");
|
||||||
|
if (current_node().tag_name() != "li") {
|
||||||
|
PARSE_ERROR();
|
||||||
|
dbg() << "Expected <li> current node, but had <" << current_node().tag_name() << ">";
|
||||||
|
}
|
||||||
|
m_stack_of_open_elements.pop_until_an_element_with_tag_name_has_been_popped("li");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token.is_end_tag() && token.tag_name().is_one_of("dd", "dt")) {
|
if (token.is_end_tag() && token.tag_name().is_one_of("dd", "dt")) {
|
||||||
|
@ -943,7 +950,13 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token.is_start_tag() && token.tag_name() == "a") {
|
if (token.is_start_tag() && token.tag_name() == "a") {
|
||||||
TODO();
|
if (m_list_of_active_formatting_elements.last_element_with_tag_name_before_marker("a")) {
|
||||||
|
TODO();
|
||||||
|
}
|
||||||
|
reconstruct_the_active_formatting_elements();
|
||||||
|
auto element = insert_html_element(token);
|
||||||
|
m_list_of_active_formatting_elements.add(*element);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token.is_start_tag() && token.tag_name().is_one_of("b", "big", "code", "em", "font", "i", "s", "small", "strike", "strong", "tt", "u")) {
|
if (token.is_start_tag() && token.tag_name().is_one_of("b", "big", "code", "em", "font", "i", "s", "small", "strike", "strong", "tt", "u")) {
|
||||||
|
|
|
@ -76,6 +76,8 @@ public:
|
||||||
|
|
||||||
InsertionMode insertion_mode() const { return m_insertion_mode; }
|
InsertionMode insertion_mode() const { return m_insertion_mode; }
|
||||||
|
|
||||||
|
static bool is_special_tag(const FlyString& tag_name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char* insertion_mode_name() const;
|
const char* insertion_mode_name() const;
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <LibWeb/DOM/Element.h>
|
#include <LibWeb/DOM/Element.h>
|
||||||
|
#include <LibWeb/Parser/HTMLDocumentParser.h>
|
||||||
#include <LibWeb/Parser/StackOfOpenElements.h>
|
#include <LibWeb/Parser/StackOfOpenElements.h>
|
||||||
|
|
||||||
namespace Web {
|
namespace Web {
|
||||||
|
@ -85,6 +86,14 @@ bool StackOfOpenElements::has_in_table_scope(const FlyString& tag_name) const
|
||||||
return has_in_scope_impl(tag_name, list);
|
return has_in_scope_impl(tag_name, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool StackOfOpenElements::has_in_list_item_scope(const FlyString& tag_name) const
|
||||||
|
{
|
||||||
|
auto list = s_base_list;
|
||||||
|
list.append("ol");
|
||||||
|
list.append("ul");
|
||||||
|
return has_in_scope_impl(tag_name, list);
|
||||||
|
}
|
||||||
|
|
||||||
bool StackOfOpenElements::contains(const Element& element) const
|
bool StackOfOpenElements::contains(const Element& element) const
|
||||||
{
|
{
|
||||||
for (auto& element_on_stack : m_elements) {
|
for (auto& element_on_stack : m_elements) {
|
||||||
|
@ -101,4 +110,17 @@ void StackOfOpenElements::pop_until_an_element_with_tag_name_has_been_popped(con
|
||||||
pop();
|
pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Element* StackOfOpenElements::topmost_special_node_below(const Element& formatting_element)
|
||||||
|
{
|
||||||
|
Element* found_element = nullptr;
|
||||||
|
for (ssize_t i = m_elements.size() - 1; i >= 0; ++i) {
|
||||||
|
auto& element = m_elements[i];
|
||||||
|
if (&element == &formatting_element)
|
||||||
|
break;
|
||||||
|
if (HTMLDocumentParser::is_special_tag(element.tag_name()))
|
||||||
|
found_element = &element;
|
||||||
|
}
|
||||||
|
return found_element;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ public:
|
||||||
bool has_in_scope(const FlyString& tag_name) const;
|
bool has_in_scope(const FlyString& tag_name) const;
|
||||||
bool has_in_button_scope(const FlyString& tag_name) const;
|
bool has_in_button_scope(const FlyString& tag_name) const;
|
||||||
bool has_in_table_scope(const FlyString& tag_name) const;
|
bool has_in_table_scope(const FlyString& tag_name) const;
|
||||||
|
bool has_in_list_item_scope(const FlyString& tag_name) const;
|
||||||
|
|
||||||
bool has_in_scope(const Element&) const;
|
bool has_in_scope(const Element&) const;
|
||||||
|
|
||||||
|
@ -59,6 +60,8 @@ public:
|
||||||
|
|
||||||
void pop_until_an_element_with_tag_name_has_been_popped(const FlyString&);
|
void pop_until_an_element_with_tag_name_has_been_popped(const FlyString&);
|
||||||
|
|
||||||
|
Element* topmost_special_node_below(const Element&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool has_in_scope_impl(const FlyString& tag_name, const Vector<FlyString>&) const;
|
bool has_in_scope_impl(const FlyString& tag_name, const Vector<FlyString>&) const;
|
||||||
bool has_in_scope_impl(const Element& target_node, const Vector<FlyString>&) const;
|
bool has_in_scope_impl(const Element& target_node, const Vector<FlyString>&) const;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue