AX: Implement support for ARIA 1.1 'switch' role
authorjdiggs@igalia.com <jdiggs@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Feb 2015 01:43:42 +0000 (01:43 +0000)
committerjdiggs@igalia.com <jdiggs@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Feb 2015 01:43:42 +0000 (01:43 +0000)
https://bugs.webkit.org/show_bug.cgi?id=141986

Reviewed by Chris Fleizach.

Source/WebCore:

Map the role to ATK_ROLE_TOGGLE_BUTTON for Gtk and Efl; on the Mac, to
AXCheckBox with a subrole of AXSwitch. Ensure it looks and acts like a
widget to accessibility APIs (supports and emits notifications when
toggled, doesn't have children, exposes a name and description when
provided).

Tests: accessibility/aria-switch-checked.html
       accessibility/aria-switch-sends-notification.html
       accessibility/aria-switch-text.html

* accessibility/AccessibilityNodeObject.cpp:
(WebCore::AccessibilityNodeObject::canHaveChildren):
(WebCore::AccessibilityNodeObject::isChecked):
(WebCore::AccessibilityNodeObject::visibleText):
(WebCore::AccessibilityNodeObject::title):
* accessibility/AccessibilityObject.cpp:
(WebCore::AccessibilityObject::isARIAInput):
(WebCore::AccessibilityObject::actionVerb):
(WebCore::initializeRoleMap):
(WebCore::AccessibilityObject::supportsChecked):
(WebCore::AccessibilityObject::checkboxOrRadioValue):
* accessibility/AccessibilityObject.h:
(WebCore::AccessibilityObject::isSwitch):
* accessibility/atk/AXObjectCacheAtk.cpp:
(WebCore::AXObjectCache::postPlatformNotification):
* accessibility/atk/WebKitAccessibleWrapperAtk.cpp:
(atkRole):
* accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
(-[WebAccessibilityObjectWrapper accessibilityCanFuzzyHitTest]):
(-[WebAccessibilityObjectWrapper accessibilityTraits]):
(-[WebAccessibilityObjectWrapper determineIsAccessibilityElement]):
* accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
(createAccessibilityRoleMap):
(-[WebAccessibilityObjectWrapper subrole]):
(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):

LayoutTests:

* accessibility/aria-switch-checked-expected.txt: Added.
* accessibility/aria-switch-checked.html: Added.
* accessibility/aria-switch-sends-notification-expected.txt: Added.
* accessibility/aria-switch-sends-notification.html: Added.
* accessibility/aria-switch-text.html: Added.
* accessibility/roles-exposed.html: Added a test case for the new role.
* platform/efl/accessibility/aria-fallback-roles-expected.txt: Added.
* platform/efl/accessibility/aria-switch-text-expected.txt: Added.
* platform/efl/accessibility/roles-exposed-expected.txt: Updated for the new role.
* platform/gtk/accessibility/aria-fallback-roles-expected.txt: Added.
* platform/gtk/accessibility/aria-switch-text-expected.txt: Added.
* platform/gtk/accessibility/roles-exposed-expected.txt: Updated for the new role.
* platform/mac-mavericks/accessibility/roles-exposed-expected.txt: Updated for the new role.
* platform/mac/TestExpectations: Skip the 'checked' notifcation as the Mac doesn't have it.
* platform/mac/accessibility/aria-switch-text-expected.txt: Added.
* platform/mac/accessibility/roles-exposed-expected.txt: Updated for the new role.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@180600 268f45cc-cd09-0410-ab3c-d52691b4dbfc

25 files changed:
LayoutTests/ChangeLog
LayoutTests/accessibility/aria-switch-checked-expected.txt [new file with mode: 0644]
LayoutTests/accessibility/aria-switch-checked.html [new file with mode: 0644]
LayoutTests/accessibility/aria-switch-sends-notification-expected.txt [new file with mode: 0644]
LayoutTests/accessibility/aria-switch-sends-notification.html [new file with mode: 0644]
LayoutTests/accessibility/aria-switch-text.html [new file with mode: 0644]
LayoutTests/accessibility/roles-exposed.html
LayoutTests/platform/efl/accessibility/aria-fallback-roles-expected.txt [new file with mode: 0644]
LayoutTests/platform/efl/accessibility/aria-switch-text-expected.txt [new file with mode: 0644]
LayoutTests/platform/efl/accessibility/roles-exposed-expected.txt
LayoutTests/platform/gtk/accessibility/aria-fallback-roles-expected.txt [new file with mode: 0644]
LayoutTests/platform/gtk/accessibility/aria-switch-text-expected.txt [new file with mode: 0644]
LayoutTests/platform/gtk/accessibility/roles-exposed-expected.txt
LayoutTests/platform/mac-mavericks/accessibility/roles-exposed-expected.txt
LayoutTests/platform/mac/TestExpectations
LayoutTests/platform/mac/accessibility/aria-switch-text-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/accessibility/roles-exposed-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/accessibility/AccessibilityNodeObject.cpp
Source/WebCore/accessibility/AccessibilityObject.cpp
Source/WebCore/accessibility/AccessibilityObject.h
Source/WebCore/accessibility/atk/AXObjectCacheAtk.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleWrapperAtk.cpp
Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm
Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm

index 1918037..7e3724b 100644 (file)
@@ -1,3 +1,27 @@
+2015-02-24  Joanmarie Diggs  <jdiggs@igalia.com>
+
+        AX: Implement support for ARIA 1.1 'switch' role
+        https://bugs.webkit.org/show_bug.cgi?id=141986
+
+        Reviewed by Chris Fleizach.
+
+        * accessibility/aria-switch-checked-expected.txt: Added.
+        * accessibility/aria-switch-checked.html: Added.
+        * accessibility/aria-switch-sends-notification-expected.txt: Added.
+        * accessibility/aria-switch-sends-notification.html: Added.
+        * accessibility/aria-switch-text.html: Added.
+        * accessibility/roles-exposed.html: Added a test case for the new role.
+        * platform/efl/accessibility/aria-fallback-roles-expected.txt: Added.
+        * platform/efl/accessibility/aria-switch-text-expected.txt: Added.
+        * platform/efl/accessibility/roles-exposed-expected.txt: Updated for the new role.
+        * platform/gtk/accessibility/aria-fallback-roles-expected.txt: Added.
+        * platform/gtk/accessibility/aria-switch-text-expected.txt: Added.
+        * platform/gtk/accessibility/roles-exposed-expected.txt: Updated for the new role.
+        * platform/mac-mavericks/accessibility/roles-exposed-expected.txt: Updated for the new role.
+        * platform/mac/TestExpectations: Skip the 'checked' notifcation as the Mac doesn't have it.
+        * platform/mac/accessibility/aria-switch-text-expected.txt: Added.
+        * platform/mac/accessibility/roles-exposed-expected.txt: Updated for the new role.
+
 2015-02-24  Myles C. Maxfield  <mmaxfield@apple.com>
 
         Parsing support for -webkit-trailing-word
diff --git a/LayoutTests/accessibility/aria-switch-checked-expected.txt b/LayoutTests/accessibility/aria-switch-checked-expected.txt
new file mode 100644 (file)
index 0000000..55ea200
--- /dev/null
@@ -0,0 +1,17 @@
+X
+X
+X
+This tests that ARIA switches correctly handle the aria-checked attribute.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS widget.isChecked is false
+PASS widget.isChecked is true
+PASS widget.isChecked is false
+PASS widget.isChecked is true
+PASS widget.isChecked is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/accessibility/aria-switch-checked.html b/LayoutTests/accessibility/aria-switch-checked.html
new file mode 100644 (file)
index 0000000..9c24841
--- /dev/null
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../resources/js-test-pre.js"></script>
+</head>
+<body id="body">
+<div role="switch" id="switch1">X</div>
+<div role="switch" id="switch2" aria-checked="true">X</div>
+<div role="switch" id="switch3" aria-checked="false">X</div>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+
+    description("This tests that ARIA switches correctly handle the aria-checked attribute.");
+
+    if (window.accessibilityController) {
+        // If aria-checked is absent, it should be not checked.
+        var widget = accessibilityController.accessibleElementById("switch1");
+        shouldBeFalse("widget.isChecked");
+
+        // If aria-checked is present and true, it's clearly checked.
+        widget = accessibilityController.accessibleElementById("switch2");
+        shouldBeTrue("widget.isChecked");
+
+        // If aria-checked is present and false, it's clearly not checked.
+        widget = accessibilityController.accessibleElementById("switch3");
+        shouldBeFalse("widget.isChecked");
+
+        // Change the value on the element and be sure we see the change
+        var element = document.getElementById("switch3");
+        element.setAttribute("aria-checked", "true");
+        shouldBeTrue("widget.isChecked");
+
+        // Remove the attribute from the element and be sure we see the change
+        element.removeAttribute("aria-checked");
+        shouldBeFalse("widget.isChecked");
+    }
+
+</script>
+
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/accessibility/aria-switch-sends-notification-expected.txt b/LayoutTests/accessibility/aria-switch-sends-notification-expected.txt
new file mode 100644 (file)
index 0000000..4f390de
--- /dev/null
@@ -0,0 +1,12 @@
+Test Switch
+This tests that toggling an aria switch sends a notification.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Got notification: CheckedStateChanged
+Got notification: CheckedStateChanged
+
diff --git a/LayoutTests/accessibility/aria-switch-sends-notification.html b/LayoutTests/accessibility/aria-switch-sends-notification.html
new file mode 100644 (file)
index 0000000..7d33170
--- /dev/null
@@ -0,0 +1,44 @@
+<html>
+<head>
+<script src="../resources/js-test-pre.js"></script>
+<script>
+    function runTest() {
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        description("This tests that toggling an aria switch sends a notification.");
+
+        var widget = accessibilityController.accessibleElementById("switch");
+        var notificationCount = 0;
+
+        function listener(notification) {
+            if (notification == "CheckedStateChanged")
+                notificationCount++;
+
+            document.getElementById("console").innerText += "Got notification: " + notification + "\n";
+
+            if (notificationCount == 2) {
+                widget.removeNotificationListener(listener);
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }
+        }
+        widget.addNotificationListener(listener);
+
+        document.getElementById('switch').setAttribute('aria-checked', 'true');
+        document.getElementById('switch').setAttribute('aria-checked', 'false');
+    };
+</script>
+</head>
+<body>
+
+<div id="switch" role="switch" aria-checked="false">Test Switch</div>
+
+<p id="description"></p>
+<div id="console"></div>
+<script>
+    runTest();
+</script>
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/accessibility/aria-switch-text.html b/LayoutTests/accessibility/aria-switch-text.html
new file mode 100644 (file)
index 0000000..b57a37f
--- /dev/null
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../resources/js-test-pre.js"></script>
+</head>
+<body id="body">
+<div role="radiobuttongroup">
+        <div role="switch" id="switch1" aria-checked="true">One</div>
+        <div role="switch" id="switch2">Two</div>
+        <div role="switch" id="switch3" aria-label="foo">Three</div>
+</div>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+
+    description("This tests that ARIA switches use accessible name computation and have no child text.");
+
+    if (window.accessibilityController) {
+        var widget = accessibilityController.accessibleElementById("switch1");
+        debug("widget.title is " + widget.title);
+        debug("widget.description is " + widget.description);
+        debug("widget.childrenCount is " + widget.childrenCount);
+
+        widget = accessibilityController.accessibleElementById("switch2");
+        debug("widget.title is " + widget.title);
+        debug("widget.description is " + widget.description);
+        debug("widget.childrenCount is " + widget.childrenCount);
+
+        widget = accessibilityController.accessibleElementById("switch3");
+        debug("widget.title is " + widget.title);
+        debug("widget.description is " + widget.description);
+        debug("widget.childrenCount is " + widget.childrenCount);
+    }
+
+</script>
+
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
index 8107ec1..d48b061 100644 (file)
 <div role="slider"                   data-platform="atk,mac" class="ex">X</div>
 <div role="spinbutton"               data-platform="atk,mac" class="ex">X</div>
 <div role="status" data-platform="atk,mac" class="ex">X</div>
+<div role="switch" data-platform="atk,mac" class="ex">X</div>
 <div role="tablist"                  data-platform="atk,mac" class="ex">
     <div role="tab"                  data-platform="atk,mac" class="ex">X</div>
 </div>
diff --git a/LayoutTests/platform/efl/accessibility/aria-fallback-roles-expected.txt b/LayoutTests/platform/efl/accessibility/aria-fallback-roles-expected.txt
new file mode 100644 (file)
index 0000000..98bdb50
--- /dev/null
@@ -0,0 +1,8 @@
+test
+This tests that aria fallback roles work correctly.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Role should be: AXRole: AXToggleButton
+
diff --git a/LayoutTests/platform/efl/accessibility/aria-switch-text-expected.txt b/LayoutTests/platform/efl/accessibility/aria-switch-text-expected.txt
new file mode 100644 (file)
index 0000000..27bf530
--- /dev/null
@@ -0,0 +1,21 @@
+One
+Two
+Three
+This tests that ARIA switches use accessible name computation and have no child text.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+widget.title is AXTitle: One
+widget.description is AXDescription: 
+widget.childrenCount is 0
+widget.title is AXTitle: Two
+widget.description is AXDescription: 
+widget.childrenCount is 0
+widget.title is AXTitle: Three
+widget.description is AXDescription: foo
+widget.childrenCount is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
index 80b9bb5..69a61ee 100644 (file)
@@ -643,6 +643,9 @@ div[role=spinbutton]
 div[role=status]
       AXRole: AXStatusBar
       
+div[role=switch]
+      AXRole: AXToggleButton
+      
 div[role=tablist]
       AXRole: AXTabGroup
       
diff --git a/LayoutTests/platform/gtk/accessibility/aria-fallback-roles-expected.txt b/LayoutTests/platform/gtk/accessibility/aria-fallback-roles-expected.txt
new file mode 100644 (file)
index 0000000..98bdb50
--- /dev/null
@@ -0,0 +1,8 @@
+test
+This tests that aria fallback roles work correctly.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Role should be: AXRole: AXToggleButton
+
diff --git a/LayoutTests/platform/gtk/accessibility/aria-switch-text-expected.txt b/LayoutTests/platform/gtk/accessibility/aria-switch-text-expected.txt
new file mode 100644 (file)
index 0000000..27bf530
--- /dev/null
@@ -0,0 +1,21 @@
+One
+Two
+Three
+This tests that ARIA switches use accessible name computation and have no child text.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+widget.title is AXTitle: One
+widget.description is AXDescription: 
+widget.childrenCount is 0
+widget.title is AXTitle: Two
+widget.description is AXDescription: 
+widget.childrenCount is 0
+widget.title is AXTitle: Three
+widget.description is AXDescription: foo
+widget.childrenCount is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
index 96b0110..1f753ed 100644 (file)
@@ -643,6 +643,9 @@ div[role=spinbutton]
 div[role=status]
       AXRole: AXStatusBar
       
+div[role=switch]
+      AXRole: AXToggleButton
+      
 div[role=tablist]
       AXRole: AXTabGroup
       
index cc5da38..843cadd 100644 (file)
@@ -1069,6 +1069,11 @@ div[role=status]
       AXSubrole: AXApplicationStatus
       AXRoleDescription: application status
       
+div[role=switch]
+      AXRole: AXCheckBox
+      AXSubrole: AXSwitch
+      AXRoleDescription: switch
+      
 div[role=tablist]
       AXRole: AXTabGroup
       AXSubrole: 
index 44a4d2d..a1217a2 100644 (file)
@@ -31,6 +31,7 @@ webkit.org/b/116637 accessibility/selection-states.html [ Failure ]
 
 # Accessibility tests for notifications that don't exist or aren't needed on Mac OS X.
 accessibility/aria-checkbox-sends-notification.html
+accessibility/aria-switch-sends-notification.html
 accessibility/combo-box-collapsed-selection-changed.html
 accessibility/children-changed-sends-notification.html
 accessibility/menu-list-sends-change-notification.html
diff --git a/LayoutTests/platform/mac/accessibility/aria-switch-text-expected.txt b/LayoutTests/platform/mac/accessibility/aria-switch-text-expected.txt
new file mode 100644 (file)
index 0000000..e7f890b
--- /dev/null
@@ -0,0 +1,21 @@
+One
+Two
+Three
+This tests that ARIA switches use accessible name computation and have no child text.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+widget.title is AXTitle: One
+widget.description is AXDescription: 
+widget.childrenCount is 0
+widget.title is AXTitle: Two
+widget.description is AXDescription: 
+widget.childrenCount is 0
+widget.title is AXTitle: 
+widget.description is AXDescription: foo
+widget.childrenCount is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
index c68bc38..46df8c6 100644 (file)
@@ -1069,6 +1069,11 @@ div[role=status]
       AXSubrole: AXApplicationStatus
       AXRoleDescription: application status
       
+div[role=switch]
+      AXRole: AXCheckBox
+      AXSubrole: AXSwitch
+      AXRoleDescription: switch
+      
 div[role=tablist]
       AXRole: AXTabGroup
       AXSubrole: 
index d4cadd7..25eb684 100644 (file)
@@ -1,3 +1,46 @@
+2015-02-24  Joanmarie Diggs  <jdiggs@igalia.com>
+
+        AX: Implement support for ARIA 1.1 'switch' role
+        https://bugs.webkit.org/show_bug.cgi?id=141986
+
+        Reviewed by Chris Fleizach.
+
+        Map the role to ATK_ROLE_TOGGLE_BUTTON for Gtk and Efl; on the Mac, to
+        AXCheckBox with a subrole of AXSwitch. Ensure it looks and acts like a
+        widget to accessibility APIs (supports and emits notifications when
+        toggled, doesn't have children, exposes a name and description when
+        provided).
+
+        Tests: accessibility/aria-switch-checked.html
+               accessibility/aria-switch-sends-notification.html
+               accessibility/aria-switch-text.html
+
+        * accessibility/AccessibilityNodeObject.cpp:
+        (WebCore::AccessibilityNodeObject::canHaveChildren):
+        (WebCore::AccessibilityNodeObject::isChecked):
+        (WebCore::AccessibilityNodeObject::visibleText):
+        (WebCore::AccessibilityNodeObject::title):
+        * accessibility/AccessibilityObject.cpp:
+        (WebCore::AccessibilityObject::isARIAInput):
+        (WebCore::AccessibilityObject::actionVerb):
+        (WebCore::initializeRoleMap):
+        (WebCore::AccessibilityObject::supportsChecked):
+        (WebCore::AccessibilityObject::checkboxOrRadioValue):
+        * accessibility/AccessibilityObject.h:
+        (WebCore::AccessibilityObject::isSwitch):
+        * accessibility/atk/AXObjectCacheAtk.cpp:
+        (WebCore::AXObjectCache::postPlatformNotification):
+        * accessibility/atk/WebKitAccessibleWrapperAtk.cpp:
+        (atkRole):
+        * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
+        (-[WebAccessibilityObjectWrapper accessibilityCanFuzzyHitTest]):
+        (-[WebAccessibilityObjectWrapper accessibilityTraits]):
+        (-[WebAccessibilityObjectWrapper determineIsAccessibilityElement]):
+        * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+        (createAccessibilityRoleMap):
+        (-[WebAccessibilityObjectWrapper subrole]):
+        (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
+
 2015-02-24  Myles C. Maxfield  <mmaxfield@apple.com>
 
         [Mac] [iOS] Parsing support for -apple-trailing-word
index af20291..e0b1599 100644 (file)
@@ -403,6 +403,7 @@ bool AccessibilityNodeObject::canHaveChildren() const
     case ListBoxOptionRole:
     case ScrollBarRole:
     case ProgressIndicatorRole:
+    case SwitchRole:
         return false;
     default:
         return true;
@@ -699,6 +700,7 @@ bool AccessibilityNodeObject::isChecked() const
     case MenuItemRole:
     case MenuItemCheckboxRole:
     case MenuItemRadioRole:
+    case SwitchRole:
         validRole = true;
         break;
     default:
@@ -1356,6 +1358,7 @@ void AccessibilityNodeObject::visibleText(Vector<AccessibilityText>& textOrder)
     case MenuItemCheckboxRole:
     case MenuItemRadioRole:
     case RadioButtonRole:
+    case SwitchRole:
     case TabRole:
     case ProgressIndicatorRole:
         useTextUnderElement = true;
@@ -1734,6 +1737,7 @@ String AccessibilityNodeObject::title() const
     case MenuItemCheckboxRole:
     case MenuItemRadioRole:
     case RadioButtonRole:
+    case SwitchRole:
     case TabRole:
         return textUnderElement();
     // SVGRoots should not use the text under itself as a title. That could include the text of objects like <text>.
index d86e000..7c55761 100644 (file)
@@ -779,7 +779,7 @@ bool AccessibilityObject::hasAttributesRequiredForInclusion() const
 
 bool AccessibilityObject::isARIAInput(AccessibilityRole ariaRole)
 {
-    return ariaRole == RadioButtonRole || ariaRole == CheckBoxRole || ariaRole == TextFieldRole;
+    return ariaRole == RadioButtonRole || ariaRole == CheckBoxRole || ariaRole == TextFieldRole || ariaRole == SwitchRole;
 }    
     
 bool AccessibilityObject::isARIAControl(AccessibilityRole ariaRole)
@@ -1733,6 +1733,7 @@ const String& AccessibilityObject::actionVerb() const
     case RadioButtonRole:
         return radioButtonAction;
     case CheckBoxRole:
+    case SwitchRole:
         return isChecked() ? checkedCheckBoxAction : uncheckedCheckBoxAction;
     case LinkRole:
     case WebCoreLinkRole:
@@ -1915,6 +1916,7 @@ static void initializeRoleMap()
         { "slider", SliderRole },
         { "spinbutton", SpinButtonRole },
         { "status", ApplicationStatusRole },
+        { "switch", SwitchRole },
         { "tab", TabRole },
         { "tablist", TabListRole },
         { "tabpanel", TabPanelRole },
@@ -2212,6 +2214,7 @@ bool AccessibilityObject::supportsChecked() const
     case MenuItemCheckboxRole:
     case MenuItemRadioRole:
     case RadioButtonRole:
+    case SwitchRole:
         return true;
     default:
         return false;
@@ -2221,15 +2224,15 @@ bool AccessibilityObject::supportsChecked() const
 AccessibilityButtonState AccessibilityObject::checkboxOrRadioValue() const
 {
     // If this is a real checkbox or radio button, AccessibilityRenderObject will handle.
-    // If it's an ARIA checkbox or radio, the aria-checked attribute should be used.
+    // If it's an ARIA checkbox, radio, or switch the aria-checked attribute should be used.
 
     const AtomicString& result = getAttribute(aria_checkedAttr);
     if (equalIgnoringCase(result, "true"))
         return ButtonStateOn;
     if (equalIgnoringCase(result, "mixed")) {
-        // ARIA says that radio and menuitemradio elements must NOT expose button state mixed.
+        // ARIA says that radio, menuitemradio, and switch elements must NOT expose button state mixed.
         AccessibilityRole ariaRole = ariaRoleAttribute();
-        if (ariaRole == RadioButtonRole || ariaRole == MenuItemRadioRole)
+        if (ariaRole == RadioButtonRole || ariaRole == MenuItemRadioRole || ariaRole == SwitchRole)
             return ButtonStateOff;
         return ButtonStateMixed;
     }
index e37c532..1b99ac6 100644 (file)
@@ -188,6 +188,7 @@ enum AccessibilityRole {
     SplitGroupRole,
     SplitterRole,
     StaticTextRole,
+    SwitchRole,
     SystemWideRole,
     SVGRootRole,
     TabGroupRole,
@@ -499,6 +500,7 @@ public:
     virtual bool isSpinButtonPart() const { return false; }
     virtual bool isMockObject() const { return false; }
     virtual bool isMediaControlLabel() const { return false; }
+    bool isSwitch() const { return roleValue() == SwitchRole; }
     bool isTextControl() const;
     bool isARIATextControl() const;
     bool isTabList() const { return roleValue() == TabListRole; }
index 55c85e7..47ab96a 100644 (file)
@@ -194,7 +194,7 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* coreObject, AX
 
     switch (notification) {
     case AXCheckedStateChanged:
-        if (!coreObject->isCheckboxOrRadio())
+        if (!coreObject->isCheckboxOrRadio() && !coreObject->isSwitch())
             return;
         atk_object_notify_state_change(axObject, ATK_STATE_CHECKED, coreObject->isChecked());
         break;
index f5808c9..eb43bb2 100644 (file)
@@ -510,6 +510,7 @@ static AtkRole atkRole(AccessibilityObject* coreObject)
         return ATK_ROLE_EMBEDDED;
     case ButtonRole:
         return ATK_ROLE_PUSH_BUTTON;
+    case SwitchRole:
     case ToggleButtonRole:
         return ATK_ROLE_TOGGLE_BUTTON;
     case RadioButtonRole:
index b87f506..2cc3756 100644 (file)
@@ -299,6 +299,7 @@ static AccessibilityObjectWrapper* AccessibilityUnignoredAncestor(AccessibilityO
     case ScrollBarRole:
     case SliderRole:
     case StaticTextRole:
+    case SwitchRole:
     case TabRole:
     case TextFieldRole:
     case ToggleButtonRole:
@@ -566,6 +567,7 @@ static AccessibilityObjectWrapper* AccessibilityUnignoredAncestor(AccessibilityO
             break;
         case ToggleButtonRole:
         case CheckBoxRole:
+        case SwitchRole:
             traits |= ([self _axButtonTrait] | [self _axToggleTrait]);
             break;
         case HeadingRole:
@@ -645,6 +647,7 @@ static AccessibilityObjectWrapper* AccessibilityUnignoredAncestor(AccessibilityO
         case TabRole:
         case DocumentMathRole:
         case HorizontalRuleRole:
+        case SwitchRole:
             return true;
         case StaticTextRole:
         {
index 805004a..87c967f 100644 (file)
@@ -1942,7 +1942,8 @@ static const AccessibilityRoleMap& createAccessibilityRoleMap()
         { AudioRole, NSAccessibilityGroupRole },
         { VideoRole, NSAccessibilityGroupRole },
         { HorizontalRuleRole, NSAccessibilitySplitterRole },
-        { BlockquoteRole, NSAccessibilityGroupRole }
+        { BlockquoteRole, NSAccessibilityGroupRole },
+        { SwitchRole, NSAccessibilityCheckBoxRole },
     };
     AccessibilityRoleMap& roleMap = *new AccessibilityRoleMap;
     
@@ -2117,6 +2118,9 @@ static NSString* roleValueToNSString(AccessibilityRole value)
     
     if (m_object->isMediaTimeline())
         return NSAccessibilityTimelineSubrole;
+
+    if (m_object->isSwitch())
+        return NSAccessibilitySwitchSubrole;
     
     return nil;
 }
@@ -2434,7 +2438,7 @@ static NSString* roleValueToNSString(AccessibilityRole value)
         if (m_object->isHeading())
             return [NSNumber numberWithInt:m_object->headingLevel()];
         
-        if (m_object->isCheckboxOrRadio() || m_object->isMenuItem()) {
+        if (m_object->isCheckboxOrRadio() || m_object->isMenuItem() || m_object->isSwitch()) {
             switch (m_object->checkboxOrRadioValue()) {
                 case ButtonStateOff:
                     return [NSNumber numberWithInt:0];