Skip to content
Permalink
Browse files
Setting textContent can leave dir=auto content in wrong directionality
https://bugs.webkit.org/show_bug.cgi?id=244446

Reviewed by Darin Adler.

This patch addresses three different bugs leading to the directionality of text not getting reset
when setting textContent:
 1. setHasDirAutoFlagRecursively skips any element with dir content attribute
    regardless of whether the value is valid or not.
 2. setHasDirAutoFlagRecursively prematurely stops setting SelfOrPrecedingNodesAffectDirAuto flag
    when it encounters a node with the matching value. This could occur when there is a node
    between `firstNode` and newly inserted content.
 3. HTMLElement::dirAttributeChanged erroneously clears SelfOrPrecedingNodesAffectDirAuto flag
    when an invalid dir content attribute is specified. In this case, dir content attribute has
    no effect and the strongly directional content within the element can continue to affect
    the directionality of the dir=auto element.

* Source/WebCore/html/HTMLElement.cpp:
(WebCore::isValidDirValue): Moved.
(WebCore::elementAffectsDirectionality): Addresses (1).
(WebCore::setHasDirAutoFlagRecursively): Addresses (2).
(WebCore::HTMLElement::dirAttributeChanged): Addresses (3).

Canonical link: https://commits.webkit.org/253881@main
  • Loading branch information
rniwa committed Aug 28, 2022
1 parent 74b1edf commit 553beb07a3690c6194b1190adbdca6ebaf2eb7a0
Showing 1 changed file with 9 additions and 12 deletions.
@@ -719,9 +719,16 @@ FormAssociatedElement* HTMLElement::asFormAssociatedElement()
return nullptr;
}

static bool isValidDirValue(const AtomString& direction)
{
return equalLettersIgnoringASCIICase(direction, "ltr"_s)
|| equalLettersIgnoringASCIICase(direction, "rtl"_s)
|| equalLettersIgnoringASCIICase(direction, "auto"_s);
}

static bool elementAffectsDirectionality(const HTMLElement& element)
{
return is<HTMLBDIElement>(element) || element.hasAttributeWithoutSynchronization(dirAttr);
return is<HTMLBDIElement>(element) || isValidDirValue(element.attributeWithoutSynchronization(dirAttr));
}

static bool elementAffectsDirectionality(const Node& node)
@@ -736,9 +743,6 @@ static void setHasDirAutoFlagRecursively(Node* firstNode, bool flag, Node* lastN
RefPtr<Node> node = firstNode->firstChild();

while (node) {
if (node->selfOrPrecedingNodesAffectDirAuto() == flag)
return;

if (elementAffectsDirectionality(*node)) {
if (node == lastNode)
return;
@@ -758,13 +762,6 @@ void HTMLElement::childrenChanged(const ChildChange& change)
adjustDirectionalityIfNeededAfterChildrenChanged(change.previousSiblingElement, change.type);
}

static bool isValidDirValue(const AtomString& direction)
{
return equalLettersIgnoringASCIICase(direction, "ltr"_s)
|| equalLettersIgnoringASCIICase(direction, "rtl"_s)
|| equalLettersIgnoringASCIICase(direction, "auto"_s);
}

bool HTMLElement::hasDirectionAuto() const
{
const AtomString& direction = attributeWithoutSynchronization(dirAttr);
@@ -840,7 +837,7 @@ void HTMLElement::dirAttributeChanged(const AtomString& value)
{
RefPtr<Element> parent = parentElement();

if (is<HTMLElement>(parent) && parent->selfOrPrecedingNodesAffectDirAuto())
if (is<HTMLElement>(parent) && parent->selfOrPrecedingNodesAffectDirAuto() && isValidDirValue(value))
downcast<HTMLElement>(*parent).adjustDirectionalityIfNeededAfterChildAttributeChanged(this);

if (equalLettersIgnoringASCIICase(value, "auto"_s))

0 comments on commit 553beb0

Please sign in to comment.