LibWeb/DOM: Implement spec changes to dir=auto directionality

Computing the "contained text auto directionality" is now its own
algorithm, with an extra parameter, and is additionally called from
step 2.1.3.2 instead of calling "auto directionality".
This commit is contained in:
Sam Atkins 2024-09-18 11:56:53 +01:00 committed by Alexander Kalenik
commit d757c8b78d
Notes: github-actions[bot] 2024-09-18 13:19:03 +00:00
2 changed files with 34 additions and 15 deletions

View file

@ -2617,8 +2617,8 @@ Optional<Element::Directionality> Element::auto_directionality() const
// 1. Assert: child is an Element node. // 1. Assert: child is an Element node.
VERIFY(child->is_element()); VERIFY(child->is_element());
// 2. Set childDirection to the auto directionality of child. // 2. Set childDirection to the contained text auto directionality of child with canExcludeRoot set to true.
child_direction = static_cast<HTML::HTMLElement const&>(*child).auto_directionality(); child_direction = static_cast<Element const&>(*child).contained_text_auto_directionality(true);
} }
// 4. If childDirection is not null, then return childDirection. // 4. If childDirection is not null, then return childDirection.
@ -2631,20 +2631,38 @@ Optional<Element::Directionality> Element::auto_directionality() const
} }
} }
// 3. For each node descendant of element's descendants, in tree order: // 3. Return the contained text auto directionality of element with canExcludeRoot set to false.
return contained_text_auto_directionality(false);
}
// https://html.spec.whatwg.org/multipage/dom.html#contained-text-auto-directionality
Optional<Element::Directionality> Element::contained_text_auto_directionality(bool can_exclude_root) const
{
// To compute the contained text auto directionality of an element element with a boolean canExcludeRoot:
// 1. For each node descendant of element's descendants, in tree order:
Optional<Directionality> result; Optional<Directionality> result;
for_each_in_subtree([&](auto& descendant) { for_each_in_subtree([&](auto& descendant) {
// 1. If descendant, or any of its ancestor elements that are descendants of element, is one of // 1. If any of
// - FIXME: a bdi element // - descendant
// - a script element // - any ancestor element of descendant that is a descendant of element
// - a style element // - if canExcludeRoot is true, element
// - a textarea element // is one of
// - an element whose dir attribute is not in the undefined state // - FIXME: a bdi element
// then continue. // - a script element
if (is<HTML::HTMLScriptElement>(descendant) // - a style element
|| is<HTML::HTMLStyleElement>(descendant) // - a textarea element
|| is<HTML::HTMLTextAreaElement>(descendant) // - an element whose dir attribute is not in the undefined state
|| (is<Element>(descendant) && static_cast<Element const&>(descendant).dir().has_value())) { // then continue.
// NOTE: "any ancestor element of descendant that is a descendant of element" will be iterated already.
auto is_one_of_the_filtered_elements = [](auto& descendant) -> bool {
return is<HTML::HTMLScriptElement>(descendant)
|| is<HTML::HTMLStyleElement>(descendant)
|| is<HTML::HTMLTextAreaElement>(descendant)
|| (is<Element>(descendant) && static_cast<Element const&>(descendant).dir().has_value());
};
if (is_one_of_the_filtered_elements(descendant)
|| (can_exclude_root && is_one_of_the_filtered_elements(*this))) {
return TraversalDecision::SkipChildrenAndContinue; return TraversalDecision::SkipChildrenAndContinue;
} }
@ -2676,7 +2694,7 @@ Optional<Element::Directionality> Element::auto_directionality() const
if (result.has_value()) if (result.has_value())
return result; return result;
// 4. Return null. // 2. Return null.
return {}; return {};
} }

View file

@ -439,6 +439,7 @@ private:
void enqueue_an_element_on_the_appropriate_element_queue(); void enqueue_an_element_on_the_appropriate_element_queue();
Optional<Directionality> auto_directionality() const; Optional<Directionality> auto_directionality() const;
Optional<Directionality> contained_text_auto_directionality(bool can_exclude_root) const;
Directionality parent_directionality() const; Directionality parent_directionality() const;
bool is_auto_directionality_form_associated_element() const; bool is_auto_directionality_form_associated_element() const;