Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
AX: After a dynamic contenteditable change, accessibility objects do …
…not update their role

https://bugs.webkit.org/show_bug.cgi?id=244126
rdar://problem/98886191

Reviewed by Chris Fleizach.

With this patch, we now update the role of the object associated with
the contenteditable change.

* LayoutTests/accessibility/dynamically-unignored-contenteditable-expected.txt: Added.
* LayoutTests/accessibility/dynamically-unignored-contenteditable.html: Added.
* LayoutTests/platform/glib/accessibility/dynamically-unignored-contenteditable-expected.txt: Added.
* Source/WebCore/accessibility/AXObjectCache.cpp:
(WebCore::AXObjectCache::handleAttributeChange):

Canonical link: https://commits.webkit.org/253630@main
  • Loading branch information
twilco committed Aug 21, 2022
1 parent 16a4b06 commit c05d71c
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 0 deletions.
@@ -0,0 +1,23 @@
This test ensures that we properly change an object's ignored status after dynamically changing its contenteditable attribute.

#div is initially ignored: true
#wrapper children:

Adding contenteditable='true' to #div.
#div is ignored: false
#wrapper children:
AXRole: AXTextArea

Removing contenteditable='true' from #div.
#div is ignored: true
#wrapper children:

Adding role='button' to #div.
#div is ignored: false
#wrapper children:
AXRole: AXButton

PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,64 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../resources/accessibility-helper.js"></script>
<script src="../resources/js-test.js"></script>
</head>
<body>

<div id="wrapper" role="group">
<div id="div"></div>
</div>

<script>
var testOutput = "This test ensures that we properly change an object's ignored status after dynamically changing its contenteditable attribute.\n\n";

function isIgnored(id) {
const axElement = accessibilityController.accessibleElementById(id);
if (!axElement)
return true;
return axElement.isIgnored;
}

function addWrapperChildrenToOutput() {
testOutput += "#wrapper children:\n";
const wrapper = accessibilityController.accessibleElementById("wrapper");
for (let i = 0; i < wrapper.childrenCount; i++)
testOutput += `${wrapper.childAtIndex(i).role}\n`;
}

if (window.accessibilityController) {
window.jsTestIsAsync = true;

testOutput += `#div is initially ignored: ${isIgnored("div")}\n`;
addWrapperChildrenToOutput();

testOutput += "\nAdding contenteditable='true' to #div.\n";
document.getElementById("div").contentEditable = "true";
setTimeout(async function() {
await waitFor(() => !isIgnored("div"));
testOutput += `#div is ignored: ${isIgnored("div")}\n`;
addWrapperChildrenToOutput();

testOutput += "\nRemoving contenteditable='true' from #div.\n";
document.getElementById("div").removeAttribute("contenteditable");

await waitFor(() => isIgnored("div"));
testOutput += `#div is ignored: ${isIgnored("div")}\n`;
addWrapperChildrenToOutput();

testOutput += "\nAdding role='button' to #div.\n";
document.getElementById("div").setAttribute("role", "button");

await waitFor(() => !isIgnored("div"));
testOutput += `#div is ignored: ${isIgnored("div")}\n`;
addWrapperChildrenToOutput();

debug(testOutput);
finishJSTest();
}, 0);
}
</script>
</body>
</html>

@@ -0,0 +1,23 @@
This test ensures that we properly change an object's ignored status after dynamically changing its contenteditable attribute.

#div is initially ignored: true
#wrapper children:

Adding contenteditable='true' to #div.
#div is ignored: false
#wrapper children:
AXRole: AXTextField

Removing contenteditable='true' from #div.
#div is ignored: true
#wrapper children:

Adding role='button' to #div.
#div is ignored: false
#wrapper children:
AXRole: AXButton

PASS successfullyParsed is true

TEST COMPLETE

3 changes: 3 additions & 0 deletions LayoutTests/platform/win/TestExpectations
Expand Up @@ -467,6 +467,9 @@ fast/events/mouseover-button.html [ Skip ]
# TODO Accept header is handled by the browser
http/tests/misc/image-checks-for-accept.html [ Skip ]

# Failing since added in https://bugs.webkit.org/show_bug.cgi?id=244126.
accessibility/dynamically-unignored-contenteditable.html [ Skip ]

# Timing out since added in https://bugs.webkit.org/show_bug.cgi?id=240750 (likely some missing AccessibilityUIElement implementation).
accessibility/table-exposure-updates-dynamically.html [ Skip ]

Expand Down
4 changes: 4 additions & 0 deletions Source/WebCore/accessibility/AXObjectCache.cpp
Expand Up @@ -1953,6 +1953,10 @@ void AXObjectCache::handleAttributeChange(Element* element, const QualifiedName&
handleRoleChanged(element);
else if (attrName == altAttr || attrName == titleAttr)
handleTextChanged(getOrCreate(element));
else if (attrName == contenteditableAttr) {
if (auto* axObject = get(element))
axObject->updateRole();
}
else if (attrName == disabledAttr)
postNotification(element, AXObjectCache::AXDisabledStateChanged);
else if (attrName == forAttr && is<HTMLLabelElement>(*element))
Expand Down

0 comments on commit c05d71c

Please sign in to comment.