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
parent 2a5390ef4f
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.
VERIFY(child->is_element());
// 2. Set childDirection to the auto directionality of child.
child_direction = static_cast<HTML::HTMLElement const&>(*child).auto_directionality();
// 2. Set childDirection to the contained text auto directionality of child with canExcludeRoot set to true.
child_direction = static_cast<Element const&>(*child).contained_text_auto_directionality(true);
}
// 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;
for_each_in_subtree([&](auto& descendant) {
// 1. If descendant, or any of its ancestor elements that are descendants of element, is one of
// - FIXME: a bdi element
// - a script element
// - a style element
// - a textarea element
// - an element whose dir attribute is not in the undefined state
// then continue.
if (is<HTML::HTMLScriptElement>(descendant)
|| is<HTML::HTMLStyleElement>(descendant)
|| is<HTML::HTMLTextAreaElement>(descendant)
|| (is<Element>(descendant) && static_cast<Element const&>(descendant).dir().has_value())) {
// 1. If any of
// - descendant
// - any ancestor element of descendant that is a descendant of element
// - if canExcludeRoot is true, element
// is one of
// - FIXME: a bdi element
// - a script element
// - a style element
// - a textarea element
// - an element whose dir attribute is not in the undefined state
// 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;
}
@ -2676,7 +2694,7 @@ Optional<Element::Directionality> Element::auto_directionality() const
if (result.has_value())
return result;
// 4. Return null.
// 2. Return null.
return {};
}

View file

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