Title: [275664] trunk
Revision
275664
Author
[email protected]
Date
2021-04-08 11:23:02 -0700 (Thu, 08 Apr 2021)

Log Message

VoiceOver does not echo text insertions and deletions when a contenteditable div has a non editable descendant element with a content editable child
https://bugs.webkit.org/show_bug.cgi?id=223818

Reviewed by Chris Fleizach.

Source/WebCore:

Test: accessibility/nested-textareas-value-changed-notifications.html

AXObjectCache::textChanged now only notifies the closest non-native text
control of value changes. This avoid the problem of multiple value
changed notifications in a row when there are nested text areas.
Removed AccessibilityRenderObject::textChanged and moved that
functionality to AXObjectCache::textChanged, where it belongs.

* accessibility/AXObjectCache.cpp:
(WebCore::AXObjectCache::textChanged):
* accessibility/AccessibilityObject.h:
* accessibility/AccessibilityObjectInterface.h:
* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::textChanged): Deleted.
* accessibility/AccessibilityRenderObject.h:
* accessibility/isolatedtree/AXIsolatedObject.cpp:
(WebCore::AXIsolatedObject::textChanged): Deleted.
* accessibility/isolatedtree/AXIsolatedObject.h:

LayoutTests:

* accessibility/nested-textareas-value-changed-notifications-expected.txt: Added.
* accessibility/nested-textareas-value-changed-notifications.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (275663 => 275664)


--- trunk/LayoutTests/ChangeLog	2021-04-08 18:21:19 UTC (rev 275663)
+++ trunk/LayoutTests/ChangeLog	2021-04-08 18:23:02 UTC (rev 275664)
@@ -1,3 +1,13 @@
+2021-04-08  Andres Gonzalez  <[email protected]>
+
+        VoiceOver does not echo text insertions and deletions when a contenteditable div has a non editable descendant element with a content editable child
+        https://bugs.webkit.org/show_bug.cgi?id=223818
+
+        Reviewed by Chris Fleizach.
+
+        * accessibility/nested-textareas-value-changed-notifications-expected.txt: Added.
+        * accessibility/nested-textareas-value-changed-notifications.html: Added.
+
 2021-04-08  Sihui Liu  <[email protected]>
 
         Remove logging for investigating http/tests/IndexedDB/storage-limit-1.html failure

Added: trunk/LayoutTests/accessibility/nested-textareas-value-changed-notifications-expected.txt (0 => 275664)


--- trunk/LayoutTests/accessibility/nested-textareas-value-changed-notifications-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/accessibility/nested-textareas-value-changed-notifications-expected.txt	2021-04-08 18:23:02 UTC (rev 275664)
@@ -0,0 +1,41 @@
+aabc
+xyz
+dgef
+This tests that the correct AXValueChanged notifications are posted when editing nested text areas with an intermediate non-editable text area.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+outer_editable original AXValue: abc
+xyz
+def
+
+1 AXValueChanged for element  with AXRole: AXWebArea
+AXValue:
+2 AXValueChanged for element outer_editable with AXRole: AXTextArea
+AXValue: aabc
+xyz
+def
+
+3 AXValueChanged for element outer_editable with AXRole: AXTextArea
+AXValue: aabc
+xyz
+def
+
+4 AXValueChanged for element  with AXRole: AXWebArea
+AXValue:
+5 AXValueChanged for element  with AXRole: AXWebArea
+AXValue:
+6 AXValueChanged for element outer_editable with AXRole: AXTextArea
+AXValue: aabc
+xyz
+dgef
+
+7 AXValueChanged for element inner_editable with AXRole: AXTextArea
+AXValue: dgef
+8 AXValueChanged for element inner_editable with AXRole: AXTextArea
+AXValue: dgef
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/accessibility/nested-textareas-value-changed-notifications.html (0 => 275664)


--- trunk/LayoutTests/accessibility/nested-textareas-value-changed-notifications.html	                        (rev 0)
+++ trunk/LayoutTests/accessibility/nested-textareas-value-changed-notifications.html	2021-04-08 18:23:02 UTC (rev 275664)
@@ -0,0 +1,68 @@
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+
+<div contenteditable="true" id="outer_editable" tabindex="-1">
+    abc
+    <div contenteditable="false" id="middle_editable">
+        <button>xyz</button>
+        <div contenteditable="true" id="inner_editable">
+            def
+        </div>
+    </div>
+</div>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+    description("This tests that the correct AXValueChanged notifications are posted when editing nested text areas with an intermediate non-editable text area.");
+
+    if (window.accessibilityController) {
+        window.jsTestIsAsync = true;
+
+        let count = 0;
+        accessibilityController.addNotificationListener((axElement, notification) => {
+            if (notification != "AXValueChanged")
+                return;
+
+            debug(`${++count} ${notification} for element ${axElement.domIdentifier} with ${axElement.role}`);
+            debug(axElement.stringValue);
+
+            if (count >= 8) {
+                accessibilityController.removeNotificationListener();
+                finishJSTest();
+            }
+        });
+
+        const axOuter = accessibilityController.accessibleElementById("outer_editable");
+        axOuter.takeFocus();
+        setTimeout(async () => {
+            await waitFor(() => {
+                return accessibilityController.focusedElement.isEqual(axOuter);
+            });
+            // Log original value of outer_editable.
+            debug(`outer_editable original ${axOuter.stringValue}`);
+
+            // Set the insertion point before the second char and insert a new char.
+            axOuter.setSelectedTextRange(1, 0);
+            await waitFor(() => {
+                return axOuter.selectedTextRange == "{1, 0}";
+            });
+            axOuter.insertText("a");
+
+            // Set the insertion point before the second char of the inner_editable and insert a new char.
+            axOuter.setSelectedTextRange(10, 0);
+            await waitFor(() => {
+                return axOuter.selectedTextRange == "{10, 0}";
+            });
+            axOuter.insertText("g");
+        }, 0);
+    }
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (275663 => 275664)


--- trunk/LayoutTests/platform/mac-wk1/TestExpectations	2021-04-08 18:21:19 UTC (rev 275663)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations	2021-04-08 18:23:02 UTC (rev 275664)
@@ -980,6 +980,7 @@
 accessibility/aria-sort.html [ Skip ]
 accessibility/mac/aria-details.html [ Skip ]
 accessibility/mac/aria-errormessage.html [ Skip ]
+accessibility/nested-textareas-value-changed-notifications.html [ Skip ]
 
 # <rdar://problem/61066929> [ Stress GC ] flaky JSC::ExceptionScope::assertNoException crash under WebCore::ReadableStreamDefaultController
 webkit.org/b/211923 imported/w3c/web-platform-tests/fetch/api/basic/stream-safe-creation.any.html [ Pass Crash ]
@@ -1300,4 +1301,4 @@
 [ BigSur ] transforms/hittest-translated-content-off-to-infinity-and-back.html [ Pass ImageOnlyFailure ]
 [ BigSur ] transforms/2d/perspective-not-fixed-container.html [ Pass ImageOnlyFailure ]
 [ BigSur ] transforms/2d/rotate-change-composited.html [ Pass ImageOnlyFailure ]
-[ BigSur ] transforms/2d/rotate-composited.html [ Pass ImageOnlyFailure ]
\ No newline at end of file
+[ BigSur ] transforms/2d/rotate-composited.html [ Pass ImageOnlyFailure ]

Modified: trunk/LayoutTests/platform/win/TestExpectations (275663 => 275664)


--- trunk/LayoutTests/platform/win/TestExpectations	2021-04-08 18:21:19 UTC (rev 275663)
+++ trunk/LayoutTests/platform/win/TestExpectations	2021-04-08 18:23:02 UTC (rev 275664)
@@ -3450,6 +3450,7 @@
 accessibility/image-with-alt-and-map.html [ Skip ]
 accessibility/inline-continuations.html [ Skip ]
 accessibility/list-detection.html [ Skip ]
+accessibility/nested-textareas-value-changed-notifications.html [ Skip ]
 accessibility/minimal-table-with-aria-is-data-table.html [ Failure ]
 accessibility/presentation-role-iframe.html [ Failure ]
 accessibility/separator-values.html [ Failure ]

Modified: trunk/Source/WebCore/ChangeLog (275663 => 275664)


--- trunk/Source/WebCore/ChangeLog	2021-04-08 18:21:19 UTC (rev 275663)
+++ trunk/Source/WebCore/ChangeLog	2021-04-08 18:23:02 UTC (rev 275664)
@@ -1,3 +1,29 @@
+2021-04-08  Andres Gonzalez  <[email protected]>
+
+        VoiceOver does not echo text insertions and deletions when a contenteditable div has a non editable descendant element with a content editable child
+        https://bugs.webkit.org/show_bug.cgi?id=223818
+
+        Reviewed by Chris Fleizach.
+
+        Test: accessibility/nested-textareas-value-changed-notifications.html
+
+        AXObjectCache::textChanged now only notifies the closest non-native text
+        control of value changes. This avoid the problem of multiple value
+        changed notifications in a row when there are nested text areas.
+        Removed AccessibilityRenderObject::textChanged and moved that
+        functionality to AXObjectCache::textChanged, where it belongs.
+
+        * accessibility/AXObjectCache.cpp:
+        (WebCore::AXObjectCache::textChanged):
+        * accessibility/AccessibilityObject.h:
+        * accessibility/AccessibilityObjectInterface.h:
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::textChanged): Deleted.
+        * accessibility/AccessibilityRenderObject.h:
+        * accessibility/isolatedtree/AXIsolatedObject.cpp:
+        (WebCore::AXIsolatedObject::textChanged): Deleted.
+        * accessibility/isolatedtree/AXIsolatedObject.h:
+
 2021-04-08  Youenn Fablet  <[email protected]>
 
         Broken transition when video player with MediaStream changes size

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (275663 => 275664)


--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2021-04-08 18:21:19 UTC (rev 275663)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2021-04-08 18:23:02 UTC (rev 275664)
@@ -979,16 +979,31 @@
     textChanged(getOrCreate(node));
 }
 
-void AXObjectCache::textChanged(AccessibilityObject* obj)
+void AXObjectCache::textChanged(AccessibilityObject* object)
 {
-    if (!obj)
+    AXTRACE("AXObjectCache::textChanged");
+    AXLOG(object);
+
+    if (!object)
         return;
 
-    bool parentAlreadyExists = obj->parentObjectIfExists();
-    obj->textChanged();
-    postNotification(obj, obj->document(), AXObjectCache::AXTextChanged);
-    if (parentAlreadyExists)
-        obj->notifyIfIgnoredValueChanged();
+    // If this element supports ARIA live regions, or is part of a region with an ARIA editable role,
+    // then notify the AT of changes.
+    bool notifiedNonNativeTextControl = false;
+    for (auto* parent = object; parent; parent = parent->parentObject()) {
+        if (parent->supportsLiveRegion())
+            postLiveRegionChangeNotification(parent);
+
+        if (!notifiedNonNativeTextControl && parent->isNonNativeTextControl()) {
+            postNotification(parent, parent->document(), AXValueChanged);
+            notifiedNonNativeTextControl = true;
+        }
+    }
+
+    postNotification(object, object->document(), AXTextChanged);
+
+    if (object->parentObjectIfExists())
+        object->notifyIfIgnoredValueChanged();
 }
 
 void AXObjectCache::updateCacheAfterNodeIsAttached(Node* node)

Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.h (275663 => 275664)


--- trunk/Source/WebCore/accessibility/AccessibilityObject.h	2021-04-08 18:21:19 UTC (rev 275663)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.h	2021-04-08 18:23:02 UTC (rev 275664)
@@ -482,7 +482,6 @@
     void decrement() override { }
 
     void childrenChanged() override { }
-    void textChanged() override { }
     void updateAccessibilityRole() override { }
     const AccessibilityChildrenVector& children(bool updateChildrenIfNeeded = true) override;
     void addChildren() override { }
@@ -791,7 +790,6 @@
 
     bool allowsTextRanges() const;
     unsigned getLengthForTextRange() const;
-
     String innerHTML() const override;
     String outerHTML() const override;
 

Modified: trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h (275663 => 275664)


--- trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h	2021-04-08 18:21:19 UTC (rev 275663)
+++ trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h	2021-04-08 18:23:02 UTC (rev 275664)
@@ -1222,7 +1222,6 @@
     virtual void decrement() = 0;
 
     virtual void childrenChanged() = 0;
-    virtual void textChanged() = 0;
     virtual void updateAccessibilityRole() = 0;
 
     virtual const AccessibilityChildrenVector& children(bool updateChildrenIfNeeded = true) = 0;

Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp (275663 => 275664)


--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2021-04-08 18:21:19 UTC (rev 275663)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2021-04-08 18:23:02 UTC (rev 275664)
@@ -3157,27 +3157,6 @@
     return isTextControl();
 }
 
-void AccessibilityRenderObject::textChanged()
-{
-    // If this element supports ARIA live regions, or is part of a region with an ARIA editable role,
-    // then notify the AT of changes.
-    AXObjectCache* cache = axObjectCache();
-    if (!cache)
-        return;
-    
-    for (RenderObject* renderParent = renderer(); renderParent; renderParent = renderParent->parent()) {
-        AccessibilityObject* parent = cache->get(renderParent);
-        if (!parent)
-            continue;
-        
-        if (parent->supportsLiveRegion())
-            cache->postLiveRegionChangeNotification(parent);
-
-        if (parent->isNonNativeTextControl())
-            cache->postNotification(renderParent, AXObjectCache::AXValueChanged);
-    }
-}
-
 void AccessibilityRenderObject::clearChildren()
 {
     AccessibilityObject::clearChildren();

Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h (275663 => 275664)


--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h	2021-04-08 18:21:19 UTC (rev 275663)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h	2021-04-08 18:23:02 UTC (rev 275664)
@@ -151,7 +151,6 @@
     void setSelectedRows(AccessibilityChildrenVector&) override;
     AccessibilityOrientation orientation() const override;
 
-    void textChanged() override;
     void addChildren() override;
     bool canHaveChildren() const override;
     bool canHaveSelectedChildren() const override;

Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp (275663 => 275664)


--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp	2021-04-08 18:21:19 UTC (rev 275663)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp	2021-04-08 18:23:02 UTC (rev 275664)
@@ -2117,11 +2117,6 @@
     ASSERT_NOT_REACHED();
 }
 
-void AXIsolatedObject::textChanged()
-{
-    ASSERT_NOT_REACHED();
-}
-
 void AXIsolatedObject::updateAccessibilityRole()
 {
     ASSERT_NOT_REACHED();

Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h (275663 => 275664)


--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h	2021-04-08 18:21:19 UTC (rev 275663)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h	2021-04-08 18:23:02 UTC (rev 275664)
@@ -587,7 +587,6 @@
     ScrollView* scrollView() const override;
     ScrollView* scrollViewAncestor() const override;
     void childrenChanged() override;
-    void textChanged() override;
     void updateAccessibilityRole() override;
     void addChildren() override;
     void addChild(AXCoreObject*) override;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to