⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 263823 in webkit


Ignore:
Timestamp:
Jul 1, 2020, 4:35:43 PM (6 years ago)
Author:
Chris Fleizach
Message:

AX: Implement relevant simulated key presses for custom ARIA widgets for increment/decrement
https://bugs.webkit.org/show_bug.cgi?id=213744

Reviewed by Darin Adler.

Source/WebCore:

In order to allow custom ARIA widgets to work, we can post keyboard events for specific ax actions
that are not handled natively.

Spec: https://github.com/WICG/aom/blob/gh-pages/explainer.md#user-action-events-from-assistive-technology

Test: accessibility/keyevents-posted-for-increment-actions.html

accessibility/keyevents-for-increment-actions-with-node-removal.html

  • accessibility/AccessibilityNodeObject.cpp:

(WebCore::AccessibilityNodeObject::postKeyboardKeysForValueChange):
(WebCore::AccessibilityNodeObject::setNodeValue):
(WebCore::AccessibilityNodeObject::changeValueByStep):
(WebCore::AccessibilityNodeObject::changeValueByPercent):

  • accessibility/AccessibilityNodeObject.h:
  • accessibility/AccessibilityObject.h:
  • accessibility/AccessibilityObjectInterface.h:
  • accessibility/AccessibilityRenderObject.cpp:

(WebCore::AccessibilityRenderObject::setValue):

  • accessibility/AccessibilityRenderObject.h:
  • accessibility/AccessibilityScrollbar.cpp:

(WebCore::AccessibilityScrollbar::setValue):

  • accessibility/AccessibilityScrollbar.h:
  • accessibility/AccessibilitySlider.cpp:

(WebCore::AccessibilitySlider::setValue):

  • accessibility/AccessibilitySlider.h:
  • accessibility/isolatedtree/AXIsolatedObject.cpp:

(WebCore::AXIsolatedObject::setValue):

  • accessibility/isolatedtree/AXIsolatedObject.h:

LayoutTests:

  • accessibility/keyevents-posted-for-increment-actions-expected.txt: Added.
  • accessibility/keyevents-posted-for-increment-actions.html: Added.
  • accessibility/keyevents-for-increment-actions-with-node-removal-expected.txt: Added.
  • accessibility/keyevents-for-increment-actions-with-node-removal.htmk: Added.
Location:
trunk
Files:
4 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r263822 r263823  
     12020-07-01  Chris Fleizach  <cfleizach@apple.com>
     2
     3        AX: Implement relevant simulated key presses for custom ARIA widgets for increment/decrement
     4        https://bugs.webkit.org/show_bug.cgi?id=213744
     5
     6        Reviewed by Darin Adler.
     7
     8        * accessibility/keyevents-posted-for-increment-actions-expected.txt: Added.
     9        * accessibility/keyevents-posted-for-increment-actions.html: Added.
     10        * accessibility/keyevents-for-increment-actions-with-node-removal-expected.txt: Added.
     11        * accessibility/keyevents-for-increment-actions-with-node-removal.htmk: Added.
     12
    1132020-07-01  Chris Dumez  <cdumez@apple.com>
    214
  • trunk/LayoutTests/platform/win/TestExpectations

    r263567 r263823  
    13811381accessibility/menu-list-sends-change-notification.html [ Skip ]
    13821382accessibility/multiselect-list-reports-active-option.html [ Skip ]
     1383
     1384# increment/decrement not implemented in test runner
     1385accessibility/keyevents-for-increment-actions-with-node-removal.html [ Skip ]
     1386accessibility/keyevents-posted-for-increment-actions.html [ Skip ]
    13831387
    13841388webkit.org/b/140796 accessibility/alt-tag-on-image-with-nonimage-role.html [ Skip ]
  • trunk/Source/WebCore/ChangeLog

    r263814 r263823  
     12020-07-01  Chris Fleizach  <cfleizach@apple.com>
     2
     3        AX: Implement relevant simulated key presses for custom ARIA widgets for increment/decrement
     4        https://bugs.webkit.org/show_bug.cgi?id=213744
     5
     6        Reviewed by Darin Adler.
     7
     8        In order to allow custom ARIA widgets to work, we can post keyboard events for specific ax actions
     9        that are not handled natively.
     10
     11        Spec: https://github.com/WICG/aom/blob/gh-pages/explainer.md#user-action-events-from-assistive-technology
     12
     13        Test: accessibility/keyevents-posted-for-increment-actions.html
     14              accessibility/keyevents-for-increment-actions-with-node-removal.html
     15
     16        * accessibility/AccessibilityNodeObject.cpp:
     17        (WebCore::AccessibilityNodeObject::postKeyboardKeysForValueChange):
     18        (WebCore::AccessibilityNodeObject::setNodeValue):
     19        (WebCore::AccessibilityNodeObject::changeValueByStep):
     20        (WebCore::AccessibilityNodeObject::changeValueByPercent):
     21        * accessibility/AccessibilityNodeObject.h:
     22        * accessibility/AccessibilityObject.h:
     23        * accessibility/AccessibilityObjectInterface.h:
     24        * accessibility/AccessibilityRenderObject.cpp:
     25        (WebCore::AccessibilityRenderObject::setValue):
     26        * accessibility/AccessibilityRenderObject.h:
     27        * accessibility/AccessibilityScrollbar.cpp:
     28        (WebCore::AccessibilityScrollbar::setValue):
     29        * accessibility/AccessibilityScrollbar.h:
     30        * accessibility/AccessibilitySlider.cpp:
     31        (WebCore::AccessibilitySlider::setValue):
     32        * accessibility/AccessibilitySlider.h:
     33        * accessibility/isolatedtree/AXIsolatedObject.cpp:
     34        (WebCore::AXIsolatedObject::setValue):
     35        * accessibility/isolatedtree/AXIsolatedObject.h:
     36
    1372020-07-01  Wenson Hsieh  <wenson_hsieh@apple.com>
    238
  • trunk/Source/WebCore/accessibility/AccessibilityNodeObject.cpp

    r262224 r263823  
    5858#include "HTMLTextAreaElement.h"
    5959#include "HTMLTextFormControlElement.h"
     60#include "KeyboardEvent.h"
    6061#include "LabelableElement.h"
    6162#include "LocalizedStrings.h"
     
    10951096}
    10961097
     1098// Fire a keyboard event if we were not able to set this value natively.
     1099void AccessibilityNodeObject::postKeyboardKeysForValueChange(bool increase)
     1100{
     1101    // In case the keyboard event causes this element to be removed.
     1102    Ref<AccessibilityObject> protectedThis(*this);
     1103
     1104    auto keyInit = KeyboardEvent::Init();
     1105    bool vertical = orientation() == AccessibilityOrientation::Vertical;
     1106    bool isLTR = page()->userInterfaceLayoutDirection() == UserInterfaceLayoutDirection::LTR;
     1107   
     1108    keyInit.key = increase ? vertical ? "ArrowUp"_s : isLTR ? "ArrowRight"_s : "ArrowLeft"_s : vertical ? "ArrowDown"_s : isLTR ? "ArrowLeft"_s : "ArrowRight"_s;
     1109    keyInit.keyIdentifier = increase ? vertical ? "up"_s : isLTR ? "right"_s : "left"_s : vertical ? "down"_s : isLTR ? "left"_s : "right"_s;
     1110
     1111    if (auto* node = this->node())
     1112        node->dispatchEvent(KeyboardEvent::create(eventNames().keydownEvent, keyInit));
     1113
     1114    // Ensure node is still valid and wasn't removed after the keydown.
     1115    if (auto* node = this->node())
     1116        node->dispatchEvent(KeyboardEvent::create(eventNames().keyupEvent, keyInit));
     1117}
     1118
     1119void AccessibilityNodeObject::setNodeValue(bool increase, float value)
     1120{
     1121    bool didSet = setValue(String::number(value));
     1122   
     1123    if (didSet) {
     1124        if (auto* cache = axObjectCache())
     1125            cache->postNotification(this, document(), AXObjectCache::AXValueChanged);
     1126    } else
     1127        postKeyboardKeysForValueChange(increase);
     1128}
     1129
    10971130void AccessibilityNodeObject::changeValueByStep(bool increase)
    10981131{
     
    11011134
    11021135    value += increase ? step : -step;
    1103 
    1104     setValue(String::number(value));
    1105 
    1106     auto objectCache = axObjectCache();
    1107     if (objectCache)
    1108         objectCache->postNotification(node(), AXObjectCache::AXValueChanged);
     1136    setNodeValue(increase, value);
    11091137}
    11101138
     
    11201148
    11211149    value += step;
    1122     setValue(String::number(value));
    1123 
    1124     auto objectCache = axObjectCache();
    1125     if (objectCache)
    1126         objectCache->postNotification(node(), AXObjectCache::AXValueChanged);
     1150    setNodeValue(percentChange > 0, value);
    11271151}
    11281152
  • trunk/Source/WebCore/accessibility/AccessibilityNodeObject.h

    r262224 r263823  
    190190    bool usesAltTagForTextComputation() const;
    191191    bool roleIgnoresTitle() const;
    192    
     192    void postKeyboardKeysForValueChange(bool increase);
     193    void setNodeValue(bool increase, float value);
    193194    Node* m_node;
    194195};
  • trunk/Source/WebCore/accessibility/AccessibilityObject.h

    r262224 r263823  
    464464    void setSelectedText(const String&) override { }
    465465    void setSelectedTextRange(const PlainTextRange&) override { }
    466     void setValue(const String&) override { }
     466    bool setValue(const String&) override { return false; }
    467467    bool replaceTextInRange(const String&, const PlainTextRange&) override;
    468468    bool insertText(const String&) override;
    469469
    470     void setValue(float) override { }
     470    bool setValue(float) override { return false; }
    471471    void setSelected(bool) override { }
    472472    void setSelectedRows(AccessibilityChildrenVector&) override { }
  • trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h

    r262966 r263823  
    897897    virtual void setSelectedText(const String&) = 0;
    898898    virtual void setSelectedTextRange(const PlainTextRange&) = 0;
    899     virtual void setValue(const String&) = 0;
     899    virtual bool setValue(const String&) = 0;
    900900    virtual bool replaceTextInRange(const String&, const PlainTextRange&) = 0;
    901901    virtual bool insertText(const String&) = 0;
    902902
    903     virtual void setValue(float) = 0;
     903    virtual bool setValue(float) = 0;
    904904    virtual void setSelected(bool) = 0;
    905905    virtual void setSelectedRows(AccessibilityChildrenVector&) = 0;
  • trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp

    r263673 r263823  
    16641664        auto node = this->node();
    16651665        ASSERT(node);
     1666        auto elementRange = this->elementRange();
    16661667        VisiblePosition start = visiblePositionForIndexUsingCharacterIterator(*node, range.start);
     1668        if (!elementRange->contains(start))
     1669            start = VisiblePosition(elementRange->startPosition());
     1670       
    16671671        VisiblePosition end = visiblePositionForIndexUsingCharacterIterator(*node, range.start + range.length);
     1672        if (!elementRange->contains(end))
     1673            end = VisiblePosition(elementRange->endPosition());
     1674       
    16681675        m_renderer->frame().selection().setSelection(VisibleSelection(start, end), FrameSelection::defaultSetSelectionOptions(UserTriggered));
    16691676    }
     
    18611868}
    18621869   
    1863 void AccessibilityRenderObject::setValue(const String& string)
     1870bool AccessibilityRenderObject::setValue(const String& string)
    18641871{
    18651872    if (!m_renderer || !is<Element>(m_renderer->node()))
    1866         return;
     1873        return false;
    18671874   
    18681875    Element& element = downcast<Element>(*m_renderer->node());
     
    18761883            editor.clearText();
    18771884            editor.insertText(string, nullptr);
    1878             return;
     1885            return true;
    18791886        }
    18801887    }
    18811888    // FIXME: Do we want to do anything here for ARIA textboxes?
    1882     if (renderer.isTextField() && is<HTMLInputElement>(element))
     1889    if (renderer.isTextField() && is<HTMLInputElement>(element)) {
    18831890        downcast<HTMLInputElement>(element).setValue(string);
    1884     else if (renderer.isTextArea() && is<HTMLTextAreaElement>(element))
     1891        return true;
     1892    }
     1893    if (renderer.isTextArea() && is<HTMLTextAreaElement>(element)) {
    18851894        downcast<HTMLTextAreaElement>(element).setValue(string);
     1895        return true;
     1896    }
     1897   
     1898    return false;
    18861899}
    18871900
  • trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h

    r261705 r263823  
    147147    void setFocused(bool) override;
    148148    void setSelectedTextRange(const PlainTextRange&) override;
    149     void setValue(const String&) override;
     149    bool setValue(const String&) override;
    150150    void setSelectedRows(AccessibilityChildrenVector&) override;
    151151    AccessibilityOrientation orientation() const override;
  • trunk/Source/WebCore/accessibility/AccessibilityScrollbar.cpp

    r244582 r263823  
    9393}
    9494
    95 void AccessibilityScrollbar::setValue(float value)
     95bool AccessibilityScrollbar::setValue(float value)
    9696{
    9797    if (!m_scrollbar)
    98         return;
     98        return false;
    9999   
    100100    float newValue = value * m_scrollbar->maximum();
    101101    m_scrollbar->scrollableArea().scrollToOffsetWithoutAnimation(m_scrollbar->orientation(), newValue);
     102    return true;
    102103}
    103104   
  • trunk/Source/WebCore/accessibility/AccessibilityScrollbar.h

    r224074 r263823  
    5656   
    5757    // Assumes float [0..1]
    58     void setValue(float) override;
     58    bool setValue(float) override;
    5959    float valueForRange() const override;
    6060
  • trunk/Source/WebCore/accessibility/AccessibilitySlider.cpp

    r251798 r263823  
    127127}
    128128
    129 void AccessibilitySlider::setValue(const String& value)
     129bool AccessibilitySlider::setValue(const String& value)
    130130{
    131131    HTMLInputElement* input = inputElement();
    132132   
    133133    if (input->value() == value)
    134         return;
     134        return true;
    135135
    136136    input->setValue(value, DispatchChangeEvent);
     137    return true;
    137138}
    138139
  • trunk/Source/WebCore/accessibility/AccessibilitySlider.h

    r251798 r263823  
    5858    const AtomString& getAttribute(const QualifiedName&) const override;
    5959   
    60     void setValue(const String&) override;
     60    bool setValue(const String&) override;
    6161    float valueForRange() const override;
    6262    float maxValueForRange() const override;
  • trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp

    r263120 r263823  
    630630    });
    631631}
    632 void AXIsolatedObject::setValue(float value)
    633 {
    634     performFunctionOnMainThread([&value](AXCoreObject* object) {
    635         object->setValue(value);
     632
     633bool AXIsolatedObject::setValue(float value)
     634{
     635    return Accessibility::retrieveValueFromMainThread<bool>([&value, this] () -> bool {
     636        if (auto* axObject = associatedAXObject())
     637            return axObject->setValue(value);
     638        return false;
     639    });
     640}
     641
     642bool AXIsolatedObject::setValue(const String& value)
     643{
     644    return Accessibility::retrieveValueFromMainThread<bool>([&value, this] () -> bool {
     645        if (auto* axObject = associatedAXObject())
     646            return axObject->setValue(value);
     647        return false;
    636648    });
    637649}
     
    669681    performFunctionOnMainThread([&value](AXCoreObject* object) {
    670682        object->setSelectedTextRange(value);
    671     });
    672 }
    673 
    674 void AXIsolatedObject::setValue(const String& value)
    675 {
    676     performFunctionOnMainThread([&value](AXCoreObject* object) {
    677         object->setValue(value);
    678683    });
    679684}
  • trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h

    r263573 r263823  
    704704    void setARIAGrabbed(bool) override;
    705705    void setIsExpanded(bool) override;
    706     void setValue(float) override;
     706    bool setValue(float) override;
    707707    void setSelected(bool) override;
    708708    void setSelectedRows(AccessibilityChildrenVector&) override;
     
    710710    void setSelectedText(const String&) override;
    711711    void setSelectedTextRange(const PlainTextRange&) override;
    712     void setValue(const String&) override;
     712    bool setValue(const String&) override;
    713713#if PLATFORM(COCOA) && !PLATFORM(IOS_FAMILY)
    714714    void setCaretBrowsingEnabled(bool) override;
Note: See TracChangeset for help on using the changeset viewer.