Changeset 240309 in webkit


Ignore:
Timestamp:
Jan 22, 2019 4:32:59 PM (5 years ago)
Author:
Devin Rousso
Message:

Web Inspector: Audit: provide a way to get related Accessibility properties for a given node
https://bugs.webkit.org/show_bug.cgi?id=193227
<rdar://problem/46787862>

Reviewed by Joseph Pecoraro.

Source/WebCore:

Test: inspector/audit/run-accessibility.html

  • inspector/InspectorAuditAccessibilityObject.idl:
  • inspector/InspectorAuditAccessibilityObject.h:
  • inspector/InspectorAuditAccessibilityObject.cpp:

(WebCore::InspectorAuditAccessibilityObject::getComputedProperties): Added.

LayoutTests:

  • inspector/audit/run-accessibility.html:
  • inspector/audit/run-accessibility-expected.txt:
Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r240307 r240309  
     12019-01-22  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Audit: provide a way to get related Accessibility properties for a given node
     4        https://bugs.webkit.org/show_bug.cgi?id=193227
     5        <rdar://problem/46787862>
     6
     7        Reviewed by Joseph Pecoraro.
     8
     9        * inspector/audit/run-accessibility.html:
     10        * inspector/audit/run-accessibility-expected.txt:
     11
    1122019-01-22  Simon Fraser  <simon.fraser@apple.com>
    213
  • trunk/LayoutTests/inspector/audit/run-accessibility-expected.txt

    r240277 r240309  
    6464Audit teardown...
    6565
     66-- Running test case: Audit.run.Accessibility.getComputedProperties.parent
     67Audit setup...
     68Audit run `WebInspectorAudit.Accessibility.getComputedProperties(document.querySelector("#parent"))`...
     69Result: {
     70    "busy": false,
     71    "currentState": "false",
     72    "disabled": false,
     73    "headingLevel": 0,
     74    "hidden": false,
     75    "hierarchicalLevel": 0,
     76    "ignored": false,
     77    "ignoredByDefault": false,
     78    "invalidStatus": "false",
     79    "isPopUpButton": false,
     80    "pressed": false,
     81    "role": "tree",
     82    "selected": false
     83}
     84Audit teardown...
     85
     86-- Running test case: Audit.run.Accessibility.getComputedProperties.child
     87Audit setup...
     88Audit run `WebInspectorAudit.Accessibility.getComputedProperties(document.querySelector("#child"))`...
     89Result: {
     90    "busy": false,
     91    "currentState": "false",
     92    "disabled": false,
     93    "headingLevel": 0,
     94    "hidden": false,
     95    "hierarchicalLevel": 1,
     96    "ignored": false,
     97    "ignoredByDefault": false,
     98    "invalidStatus": "false",
     99    "isPopUpButton": false,
     100    "pressed": false,
     101    "role": "treeitem",
     102    "selected": true
     103}
     104Audit teardown...
     105
    66106-- Running test case: Audit.run.Accessibility.getControlledNodes.parent
    67107Audit setup...
     
    115155Audit setup...
    116156Audit run `WebInspectorAudit.Accessibility.getParentNode(document.querySelector("#parent"))`...
    117 Result: undefined
     157Result: <document>
    118158Audit teardown...
    119159
     
    149189PASS: Should produce an exception.
    150190Error: NotAllowedError: Cannot be called outside of a Web Inspector Audit
     191Testing copied getComputedProperties...
     192PASS: Should produce an exception.
     193Error: NotAllowedError: Cannot be called outside of a Web Inspector Audit
    151194Testing copied getControlledNodes...
    152195PASS: Should produce an exception.
  • trunk/LayoutTests/inspector/audit/run-accessibility.html

    r240277 r240309  
    77
    88function stringify(result) {
     9    if (result === null || result === undefined || typeof result === "boolean" || typeof result === "string" || typeof result === "number")
     10        return result;
    911    if (result instanceof Element)
    1012        return "#" + result.id;
     13    if (result instanceof HTMLDocument)
     14        return "<document>";
    1115    if (Array.isArray(result))
    1216        return JSON.stringify(result.map(stringify));
    13     if (result === null || result === undefined);
    14         return result;
     17    if (typeof result === "object" && result.constructor === Object) {
     18        let mapped = {};
     19        for (let key in result)
     20            mapped[key] = stringify(result[key]);
     21        return JSON.stringify(mapped, null, 4);
     22    }
    1523    return "UNEXPECTED " + result;
    1624}
     
    4452        { func: "getChildNodes", target: "parent" },
    4553        { func: "getChildNodes", target: "child" },
     54
     55        { func: "getComputedProperties", target: "parent" },
     56        { func: "getComputedProperties", target: "child" },
    4657
    4758        { func: "getControlledNodes", target: "parent" },
  • trunk/Source/WebCore/ChangeLog

    r240307 r240309  
     12019-01-22  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Audit: provide a way to get related Accessibility properties for a given node
     4        https://bugs.webkit.org/show_bug.cgi?id=193227
     5        <rdar://problem/46787862>
     6
     7        Reviewed by Joseph Pecoraro.
     8
     9        Test: inspector/audit/run-accessibility.html
     10
     11        * inspector/InspectorAuditAccessibilityObject.idl:
     12        * inspector/InspectorAuditAccessibilityObject.h:
     13        * inspector/InspectorAuditAccessibilityObject.cpp:
     14        (WebCore::InspectorAuditAccessibilityObject::getComputedProperties): Added.
     15
    1162019-01-22  Simon Fraser  <simon.fraser@apple.com>
    217
  • trunk/Source/WebCore/inspector/InspectorAuditAccessibilityObject.cpp

    r240277 r240309  
    3737#include "HTMLNames.h"
    3838#include "Node.h"
     39#include "SpaceSplitString.h"
    3940#include <wtf/Vector.h>
     41#include <wtf/text/WTFString.h>
    4042
    4143namespace WebCore {
     
    116118}
    117119
     120ExceptionOr<Optional<InspectorAuditAccessibilityObject::ComputedProperties>> InspectorAuditAccessibilityObject::getComputedProperties(Node& node)
     121{
     122    ERROR_IF_NO_ACTIVE_AUDIT();
     123
     124    Optional<InspectorAuditAccessibilityObject::ComputedProperties> result;
     125
     126    if (AccessibilityObject* axObject = accessiblityObjectForNode(node)) {
     127        ComputedProperties computedProperties;
     128
     129        AccessibilityObject* current = axObject;
     130        while (current && (!computedProperties.busy || !computedProperties.busy.value())) {
     131            computedProperties.busy = current->isBusy();
     132            current = current->parentObject();
     133        }
     134
     135        if (axObject->supportsChecked()) {
     136            AccessibilityButtonState checkValue = axObject->checkboxOrRadioValue();
     137            if (checkValue == AccessibilityButtonState::On)
     138                computedProperties.checked = "true"_s;
     139            else if (checkValue == AccessibilityButtonState::Mixed)
     140                computedProperties.checked = "mixed"_s;
     141            else if (axObject->isChecked())
     142                computedProperties.checked = "true"_s;
     143            else
     144                computedProperties.checked = "false"_s;
     145        }
     146
     147        switch (axObject->currentState()) {
     148        case AccessibilityCurrentState::False:
     149            computedProperties.currentState = "false"_s;
     150            break;
     151        case AccessibilityCurrentState::True:
     152            computedProperties.currentState = "true"_s;
     153            break;
     154        case AccessibilityCurrentState::Page:
     155            computedProperties.currentState = "page"_s;
     156            break;
     157        case AccessibilityCurrentState::Step:
     158            computedProperties.currentState = "step"_s;
     159            break;
     160        case AccessibilityCurrentState::Location:
     161            computedProperties.currentState = "location"_s;
     162            break;
     163        case AccessibilityCurrentState::Date:
     164            computedProperties.currentState = "date"_s;
     165            break;
     166        case AccessibilityCurrentState::Time:
     167            computedProperties.currentState = "time"_s;
     168            break;
     169        }
     170
     171        computedProperties.disabled = !axObject->isEnabled();
     172
     173        if (axObject->supportsExpanded())
     174            computedProperties.expanded = axObject->isExpanded();
     175
     176        if (is<Element>(node) && axObject->canSetFocusAttribute())
     177            computedProperties.focused = axObject->isFocused();
     178
     179        computedProperties.headingLevel = axObject->headingLevel();
     180        computedProperties.hidden = axObject->isAXHidden() || axObject->isDOMHidden();
     181        computedProperties.hierarchicalLevel = axObject->hierarchicalLevel();
     182        computedProperties.ignored = axObject->accessibilityIsIgnored();
     183        computedProperties.ignoredByDefault = axObject->accessibilityIsIgnoredByDefault();
     184
     185        String invalidValue = axObject->invalidStatus();
     186        if (invalidValue == "false")
     187            computedProperties.invalidStatus = "false"_s;
     188        else if (invalidValue == "grammar")
     189            computedProperties.invalidStatus = "grammar"_s;
     190        else if (invalidValue == "spelling")
     191            computedProperties.invalidStatus = "spelling"_s;
     192        else
     193            computedProperties.invalidStatus = "true"_s;
     194
     195        computedProperties.isPopUpButton = axObject->isPopUpButton() || axObject->hasPopup();
     196        computedProperties.label = axObject->computedLabel();
     197
     198        if (axObject->supportsLiveRegion()) {
     199            computedProperties.liveRegionAtomic = axObject->liveRegionAtomic();
     200
     201            String ariaRelevantAttrValue = axObject->liveRegionRelevant();
     202            if (!ariaRelevantAttrValue.isEmpty()) {
     203                Vector<String> liveRegionRelevant;
     204                String ariaRelevantAdditions = "additions";
     205                String ariaRelevantRemovals = "removals";
     206                String ariaRelevantText = "text";
     207
     208                const auto& values = SpaceSplitString(ariaRelevantAttrValue, true);
     209                if (values.contains("all")) {
     210                    liveRegionRelevant.append(ariaRelevantAdditions);
     211                    liveRegionRelevant.append(ariaRelevantRemovals);
     212                    liveRegionRelevant.append(ariaRelevantText);
     213                } else {
     214                    if (values.contains(ariaRelevantAdditions))
     215                        liveRegionRelevant.append(ariaRelevantAdditions);
     216                    if (values.contains(ariaRelevantRemovals))
     217                        liveRegionRelevant.append(ariaRelevantRemovals);
     218                    if (values.contains(ariaRelevantText))
     219                        liveRegionRelevant.append(ariaRelevantText);
     220                }
     221                computedProperties.liveRegionRelevant = liveRegionRelevant;
     222            }
     223
     224            computedProperties.liveRegionStatus = axObject->liveRegionStatus();
     225        }
     226
     227        computedProperties.pressed = axObject->pressedIsPresent() && axObject->isPressed();
     228
     229        if (axObject->isTextControl())
     230            computedProperties.readonly = !axObject->canSetValueAttribute();
     231
     232        if (axObject->supportsRequiredAttribute())
     233            computedProperties.required = axObject->isRequired();
     234
     235        computedProperties.role = axObject->computedRoleString();
     236        computedProperties.selected = axObject->isSelected();
     237
     238        result = computedProperties;
     239    }
     240
     241    return result;
     242}
    118243
    119244ExceptionOr<Optional<Vector<RefPtr<Node>>>> InspectorAuditAccessibilityObject::getControlledNodes(Node& node)
  • trunk/Source/WebCore/inspector/InspectorAuditAccessibilityObject.h

    r240277 r240309  
    4747    ExceptionOr<Vector<Ref<Node>>> getElementsByComputedRole(Document&, const String& role, Node* container);
    4848
     49    struct ComputedProperties {
     50        Optional<bool> busy;
     51        String checked;
     52        String currentState;
     53        Optional<bool> disabled;
     54        Optional<bool> expanded;
     55        Optional<bool> focused;
     56        Optional<int> headingLevel;
     57        Optional<bool> hidden;
     58        Optional<int> hierarchicalLevel;
     59        Optional<bool> ignored;
     60        Optional<bool> ignoredByDefault;
     61        String invalidStatus;
     62        Optional<bool> isPopUpButton;
     63        String label;
     64        Optional<bool> liveRegionAtomic;
     65        Optional<Vector<String>> liveRegionRelevant;
     66        String liveRegionStatus;
     67        Optional<bool> pressed;
     68        Optional<bool> readonly;
     69        Optional<bool> required;
     70        String role;
     71        Optional<bool> selected;
     72    };
     73
    4974    ExceptionOr<RefPtr<Node>> getActiveDescendant(Node&);
    5075    ExceptionOr<Optional<Vector<RefPtr<Node>>>> getChildNodes(Node&);
     76    ExceptionOr<Optional<ComputedProperties>> getComputedProperties(Node&);
    5177    ExceptionOr<Optional<Vector<RefPtr<Node>>>> getControlledNodes(Node&);
    5278    ExceptionOr<Optional<Vector<RefPtr<Node>>>> getFlowedNodes(Node&);
  • trunk/Source/WebCore/inspector/InspectorAuditAccessibilityObject.idl

    r240277 r240309  
    3333    [MayThrowException] Node? getActiveDescendant(Node node);
    3434    [MayThrowException] sequence<Node>? getChildNodes(Node node);
     35    [MayThrowException] ComputedProperties? getComputedProperties(Node node);
    3536    [MayThrowException] sequence<Node>? getControlledNodes(Node node);
    3637    [MayThrowException] sequence<Node>? getFlowedNodes(Node node);
     
    4041    [MayThrowException] sequence<Node>? getSelectedChildNodes(Node node);
    4142};
     43
     44[
     45    JSGenerateToJSObject,
     46] dictionary ComputedProperties {
     47    boolean? busy;
     48    DOMString? checked;
     49    DOMString? currentState;
     50    boolean? disabled;
     51    boolean? expanded;
     52    boolean? focused;
     53    long? headingLevel;
     54    boolean? hidden;
     55    long? hierarchicalLevel;
     56    boolean? ignored;
     57    boolean? ignoredByDefault;
     58    DOMString? invalidStatus;
     59    boolean? isPopUpButton;
     60    DOMString? label;
     61    boolean? liveRegionAtomic;
     62    sequence<DOMString>? liveRegionRelevant;
     63    DOMString? liveRegionStatus;
     64    boolean? pressed;
     65    boolean? readonly;
     66    boolean? required;
     67    DOMString? role;
     68    boolean? selected;
     69};
Note: See TracChangeset for help on using the changeset viewer.