Web Inspector: AXI: support for live regions
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 29 Mar 2014 05:33:33 +0000 (05:33 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 29 Mar 2014 05:33:33 +0000 (05:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=130725

Patch by James Craig <jcraig@apple.com> on 2014-03-28
Reviewed by Timothy Hatcher.

Source/WebCore:

Tests: inspector-protocol/dom/getAccessibilityPropertiesForNode.html
       inspector-protocol/dom/getAccessibilityPropertiesForNode_liveRegion.html

Initial support for @aria-live, @aria-atomic, and @aria-busy.

* inspector/InspectorDOMAgent.cpp:
(WebCore::InspectorDOMAgent::buildObjectForAccessibilityProperties):
* inspector/protocol/DOM.json:

Source/WebInspectorUI:

Initial support for @aria-live, @aria-atomic, and @aria-busy.

* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Models/DOMNode.js:
* UserInterface/Views/DOMNodeDetailsSidebarPanel.js:
* UserInterface/Views/Main.css:

Websites/webkit.org:

Demo update to show off the new Inspector support for live regions.

* blog-files/aria1.0/combobox_with_live_region_status.html:

LayoutTests:

Initial support for @aria-live, @aria-atomic, and @aria-busy.

* inspector-protocol/dom/getAccessibilityPropertiesForNode-expected.txt: Updated.
* inspector-protocol/dom/getAccessibilityPropertiesForNode.html: Updated.
* inspector-protocol/dom/getAccessibilityPropertiesForNode_liveRegion-expected.txt: Added.
* inspector-protocol/dom/getAccessibilityPropertiesForNode_liveRegion.html: Added.

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

15 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector-protocol/dom/getAccessibilityPropertiesForNode-expected.txt
LayoutTests/inspector-protocol/dom/getAccessibilityPropertiesForNode.html
LayoutTests/inspector-protocol/dom/getAccessibilityPropertiesForNode_liveRegion-expected.txt [new file with mode: 0644]
LayoutTests/inspector-protocol/dom/getAccessibilityPropertiesForNode_liveRegion.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/inspector/InspectorDOMAgent.cpp
Source/WebCore/inspector/protocol/DOM.json
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
Source/WebInspectorUI/UserInterface/Models/DOMNode.js
Source/WebInspectorUI/UserInterface/Views/DOMNodeDetailsSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/Main.css
Websites/webkit.org/ChangeLog
Websites/webkit.org/blog-files/aria1.0/combobox_with_live_region_status.html

index 22e0f74..68e78ab 100644 (file)
@@ -1,3 +1,17 @@
+2014-03-28  James Craig  <jcraig@apple.com>
+
+        Web Inspector: AXI: support for live regions
+        https://bugs.webkit.org/show_bug.cgi?id=130725
+
+        Reviewed by Timothy Hatcher.
+
+        Initial support for @aria-live, @aria-atomic, and @aria-busy.
+
+        * inspector-protocol/dom/getAccessibilityPropertiesForNode-expected.txt: Updated.
+        * inspector-protocol/dom/getAccessibilityPropertiesForNode.html: Updated.
+        * inspector-protocol/dom/getAccessibilityPropertiesForNode_liveRegion-expected.txt: Added.
+        * inspector-protocol/dom/getAccessibilityPropertiesForNode_liveRegion.html: Added.
+
 2014-03-28  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: console.warn is showing as error instead of warning
index e3ecf35..e3c4603 100644 (file)
@@ -4,10 +4,10 @@ Checking Web Inspector protocol for the Accessibility Node Inspector.
     exists: true
     label: 
     role: 
-    childNodeIds.length: 21
+    childNodeIds.length: 25
 
 
-Total elements to be tested: 59.
+Total elements to be tested: 63.
 
 <div onclick="void(0);">click</div>
     exists: true
@@ -402,6 +402,42 @@ Total elements to be tested: 59.
     focused: false
     parentNodeId: exists
 
+<div role="group" aria-live="assertive" aria-atomic="true">assertive (and atomic)</div>
+    exists: true
+    label: 
+    role: group
+    childNodeIds.length: 1
+    liveRegionAtomic: true
+    liveRegionStatus: assertive
+    parentNodeId: exists
+
+<div role="group" aria-live="polite">polite</div>
+    exists: true
+    label: 
+    role: group
+    childNodeIds.length: 1
+    liveRegionAtomic: false
+    liveRegionStatus: polite
+    parentNodeId: exists
+
+<div role="group" aria-live="off">off</div>
+    exists: true
+    label: 
+    role: group
+    childNodeIds.length: 1
+    parentNodeId: exists
+
+<div role="listbox" aria-busy="true">
+    <!-- Despite having no required option children, this is valid because it is marked as busy. -->
+    <!-- For example, waiting for a script to load its contents. -->
+</div>
+    exists: true
+    label: 
+    role: listbox
+    busy: true
+    parentNodeId: exists
+    required: false
+
 <span aria-hidden="true"></span>
     exists: true
     label: 
index 39bbf82..6a7ff30 100644 (file)
 <span class="ex"></span>
 <span class="ex" aria-hidden="true"></span>
 
+<div role="listbox" class="ex" aria-busy="true">
+    <!-- Despite having no required option children, this is valid because it is marked as busy. -->
+    <!-- For example, waiting for a script to load its contents. -->
+</div>
+
+<!-- Full coverage of live regions in getAccessibilityPropertiesForNode_liveRegion.html. -->
+<div class="ex" role="group" aria-live="off">off</div>
+<div class="ex" role="group" aria-live="polite">polite</div>
+<div class="ex" role="group" aria-live="assertive" aria-atomic="true">assertive (and atomic)</div>
+
 <div class="ex" role="button" tabindex="0"></div>
 <div class="ex" role="button" tabindex="0" aria-disabled="true">disabled</div>
 <div class="ex" role="button" tabindex="0" aria-pressed="true">FIXME: Pressed is false. Expected true. http://webkit.org/b/129830</div>
diff --git a/LayoutTests/inspector-protocol/dom/getAccessibilityPropertiesForNode_liveRegion-expected.txt b/LayoutTests/inspector-protocol/dom/getAccessibilityPropertiesForNode_liveRegion-expected.txt
new file mode 100644 (file)
index 0000000..b5270bc
--- /dev/null
@@ -0,0 +1,81 @@
+Checking Web Inspector protocol (specifically live region properties) for the Accessibility Node Inspector.
+
+Total elements to be tested: 17.
+
+<div role="timer">off (default)</div>
+    exists: true
+
+<div role="status" aria-live="off">off</div>
+    exists: true
+
+<div role="status" aria-live="assertive">assertive <!-- FIXME: atomic should be true http://webkit.org/b/130907 --></div>
+    exists: true
+    liveRegionAtomic: false
+    liveRegionStatus: assertive
+
+<div role="status">polite (default) <!-- FIXME: atomic should be true http://webkit.org/b/130907 --></div>
+    exists: true
+    liveRegionAtomic: false
+    liveRegionStatus: polite
+
+<div role="marquee">off (default)</div>
+    exists: true
+
+<div role="log" aria-live="off">off</div>
+    exists: true
+
+<div role="log" aria-live="assertive">assertive</div>
+    exists: true
+    liveRegionAtomic: false
+    liveRegionStatus: assertive
+
+<div role="log">polite (default)</div>
+    exists: true
+    liveRegionAtomic: false
+    liveRegionStatus: polite
+
+<div role="alert" aria-live="polite">polite <!-- FIXME: atomic should be true http://webkit.org/b/130907 --></div>
+    exists: true
+    liveRegionAtomic: false
+    liveRegionStatus: polite
+
+<div role="alert" aria-live="off">off</div>
+    exists: true
+
+<div role="alert">assertive (default) <!-- FIXME: atomic should be true http://webkit.org/b/130907 --></div>
+    exists: true
+    liveRegionAtomic: false
+    liveRegionStatus: assertive
+
+<div role="group" aria-live="assertive" aria-busy="true" aria-atomic="false">assertive</div>
+    exists: true
+    busy: true
+    liveRegionAtomic: false
+    liveRegionStatus: assertive
+
+<div role="group" aria-live="polite" aria-busy="true" aria-atomic="false">polite</div>
+    exists: true
+    busy: true
+    liveRegionAtomic: false
+    liveRegionStatus: polite
+
+<div role="group" aria-live="off" aria-busy="true" aria-atomic="false">off</div>
+    exists: true
+    busy: true
+
+<div role="group" aria-live="assertive" aria-busy="true" aria-atomic="true">assertive</div>
+    exists: true
+    busy: true
+    liveRegionAtomic: true
+    liveRegionStatus: assertive
+
+<div role="group" aria-live="polite" aria-busy="true" aria-atomic="true">polite</div>
+    exists: true
+    busy: true
+    liveRegionAtomic: true
+    liveRegionStatus: polite
+
+<div role="group" aria-live="off" aria-busy="true" aria-atomic="true">off</div>
+    exists: true
+    busy: true
+
diff --git a/LayoutTests/inspector-protocol/dom/getAccessibilityPropertiesForNode_liveRegion.html b/LayoutTests/inspector-protocol/dom/getAccessibilityPropertiesForNode_liveRegion.html
new file mode 100644 (file)
index 0000000..9180eda
--- /dev/null
@@ -0,0 +1,112 @@
+<html>
+<head>
+<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/protocol-test.js"></script>
+</head>
+<body onLoad="runTest()">
+
+<p>Checking Web Inspector protocol (specifically live region properties) for the Accessibility Node Inspector.</p>
+
+<div id="examples">
+
+       <div class="ex" role="group" aria-live="off" aria-busy="true" aria-atomic="true">off</div>
+    <div class="ex" role="group" aria-live="polite" aria-busy="true" aria-atomic="true">polite</div>
+    <div class="ex" role="group" aria-live="assertive" aria-busy="true" aria-atomic="true">assertive</div>
+    <div class="ex" role="group" aria-live="off" aria-busy="true" aria-atomic="false">off</div>
+    <div class="ex" role="group" aria-live="polite" aria-busy="true" aria-atomic="false">polite</div>
+    <div class="ex" role="group" aria-live="assertive" aria-busy="true" aria-atomic="false">assertive</div>
+    
+    <div class="ex" role="alert">assertive (default) <!-- FIXME: atomic should be true http://webkit.org/b/130907 --></div>
+       <div class="ex" role="alert" aria-live="off">off</div>
+       <div class="ex" role="alert" aria-live="polite">polite <!-- FIXME: atomic should be true http://webkit.org/b/130907 --></div>
+       <div class="ex" role="log">polite (default)</div>
+       <div class="ex" role="log" aria-live="assertive">assertive</div>
+       <div class="ex" role="log" aria-live="off">off</div>
+       <div class="ex" role="marquee">off (default)</div>
+       <div class="ex" role="status">polite (default) <!-- FIXME: atomic should be true http://webkit.org/b/130907 --></div>
+       <div class="ex" role="status" aria-live="assertive">assertive <!-- FIXME: atomic should be true http://webkit.org/b/130907 --></div>
+       <div class="ex" role="status" aria-live="off">off</div>
+       <div class="ex" role="timer">off (default)</div>
+
+</div>
+
+<script type="text/javascript">
+
+function $(id) {
+    return document.getElementById(id);
+}
+
+function cleanup() {
+    // Hide the test element container to avoid irrelevant output diffs on subsequent updates.
+    $("examples").style.display = "none";
+}
+
+function test() {
+
+    var examples = [];
+    var documentNodeId = null;
+    var bodyNodeId = null;
+
+    function onGotDocument(response) {
+        InspectorTest.checkForError(response);
+        documentNodeId = response.result.root.nodeId;
+        InspectorTest.sendCommand("DOM.querySelectorAll", {"nodeId": documentNodeId, "selector": ".ex"}, onGotQuerySelectorAll);
+    }
+
+    function onGotQuerySelectorAll(response) {
+        InspectorTest.checkForError(response);
+        examples = response.result.nodeIds;
+        InspectorTest.log("Total elements to be tested: " + examples.length + ".");
+        loop();
+    }
+
+    function loop() {
+        if (examples.length) {
+            InspectorTest.sendCommand("DOM.getOuterHTML", {"nodeId": examples[examples.length-1]}, onGotOuterHTML);
+        } else {
+            finishTest();
+        }
+    }
+
+    function onGotOuterHTML(response) {
+        InspectorTest.checkForError(response);
+        var outerHTML = response.result.outerHTML;
+        outerHTML = outerHTML.replace(/ class="ex"/g, ""); // remove any duplicated, unnecessary class attributes
+        InspectorTest.log("\n" + outerHTML);
+        InspectorTest.sendCommand("DOM.getAccessibilityPropertiesForNode", {"nodeId": examples[examples.length-1]}, onGotAccessibilityProperties);
+    }
+
+    function onGotAccessibilityProperties(response) {
+        InspectorTest.checkForError(response);
+        logAccessibilityProperties(response.result.properties);
+        examples.pop();
+        loop();
+    }
+
+    function logAccessibilityProperties(properties) {
+        for (var key in properties) {
+            var value = properties[key];
+            switch (key){
+            case "busy":
+            case "exists":
+            case "liveRegionAtomic":
+            case "liveRegionStatus":
+                InspectorTest.log("    " + key + ": " + value);
+                break;
+            default:
+                continue;
+            }
+        }
+    }
+
+    function finishTest() {
+        InspectorTest.sendCommand("Runtime.evaluate", {"expression": "cleanup()"}, function(){
+            InspectorTest.completeTest();
+        });
+    }
+
+    InspectorTest.sendCommand("DOM.getDocument", {}, onGotDocument);
+
+}
+</script>
+</body>
+</html>
\ No newline at end of file
index 04a7c2f..f11f9c9 100644 (file)
@@ -1,3 +1,19 @@
+2014-03-28  James Craig  <jcraig@apple.com>
+
+        Web Inspector: AXI: support for live regions
+        https://bugs.webkit.org/show_bug.cgi?id=130725
+
+        Reviewed by Timothy Hatcher.
+
+        Tests: inspector-protocol/dom/getAccessibilityPropertiesForNode.html
+               inspector-protocol/dom/getAccessibilityPropertiesForNode_liveRegion.html
+
+        Initial support for @aria-live, @aria-atomic, and @aria-busy.
+
+        * inspector/InspectorDOMAgent.cpp:
+        (WebCore::InspectorDOMAgent::buildObjectForAccessibilityProperties):
+        * inspector/protocol/DOM.json:
+
 2014-03-28  Darin Adler  <darin@apple.com>
 
         Fix recently-introduced off-by-one error in centerTruncateToBuffer
index a78f18b..f77a20d 100644 (file)
@@ -1426,6 +1426,7 @@ PassRefPtr<TypeBuilder::DOM::AccessibilityProperties> InspectorDOMAgent::buildOb
         WebCore::AXObjectCache::enableAccessibility();
 
     Node* activeDescendantNode = nullptr;
+    bool busy = false;
     TypeBuilder::DOM::AccessibilityProperties::Checked::Enum checked = TypeBuilder::DOM::AccessibilityProperties::Checked::False;
     RefPtr<Inspector::TypeBuilder::Array<int>> childNodeIds;
     RefPtr<Inspector::TypeBuilder::Array<int>> controlledNodeIds;
@@ -1439,6 +1440,8 @@ PassRefPtr<TypeBuilder::DOM::AccessibilityProperties> InspectorDOMAgent::buildOb
     TypeBuilder::DOM::AccessibilityProperties::Invalid::Enum invalid = TypeBuilder::DOM::AccessibilityProperties::Invalid::False;
     bool hidden = false;
     String label; // FIXME: Waiting on http://webkit.org/b/121134
+    bool liveRegionAtomic = false;
+    TypeBuilder::DOM::AccessibilityProperties::LiveRegionStatus::Enum liveRegionStatus = TypeBuilder::DOM::AccessibilityProperties::LiveRegionStatus::Off;
     Node* mouseEventNode = nullptr;
     RefPtr<Inspector::TypeBuilder::Array<int>> ownedNodeIds;
     Node* parentNode = nullptr;
@@ -1450,6 +1453,7 @@ PassRefPtr<TypeBuilder::DOM::AccessibilityProperties> InspectorDOMAgent::buildOb
     RefPtr<Inspector::TypeBuilder::Array<int>> selectedChildNodeIds;
     bool supportsChecked = false;
     bool supportsExpanded = false;
+    bool supportsLiveRegion = false;
     bool supportsPressed = false;
     bool supportsRequired = false;
     bool supportsFocused = false;
@@ -1460,6 +1464,8 @@ PassRefPtr<TypeBuilder::DOM::AccessibilityProperties> InspectorDOMAgent::buildOb
             if (AccessibilityObject* activeDescendant = axObject->activeDescendant())
                 activeDescendantNode = activeDescendant->node();
 
+            busy = axObject->ariaLiveRegionBusy();
+
             supportsChecked = axObject->supportsChecked();
             if (supportsChecked) {
                 int checkValue = axObject->checkboxOrRadioValue(); // Element using aria-checked.
@@ -1529,6 +1535,16 @@ PassRefPtr<TypeBuilder::DOM::AccessibilityProperties> InspectorDOMAgent::buildOb
             if (axObject->isARIAHidden() || axObject->isDOMHidden())
                 hidden = true;
             
+            if (axObject->supportsARIALiveRegion()) {
+                supportsLiveRegion = true;
+                liveRegionAtomic = axObject->ariaLiveRegionAtomic();
+                String ariaLive = axObject->ariaLiveRegionStatus();
+                if (ariaLive == "assertive")
+                    liveRegionStatus = TypeBuilder::DOM::AccessibilityProperties::LiveRegionStatus::Assertive;
+                else if (ariaLive == "polite")
+                    liveRegionStatus = TypeBuilder::DOM::AccessibilityProperties::LiveRegionStatus::Polite;
+            }
+
             if (axObject->isAccessibilityNodeObject())
                 mouseEventNode = toAccessibilityNodeObject(axObject)->mouseButtonListener(MouseButtonListenerResultFilter::IncludeBodyElement);
 
@@ -1580,6 +1596,8 @@ PassRefPtr<TypeBuilder::DOM::AccessibilityProperties> InspectorDOMAgent::buildOb
     if (exists) {
         if (activeDescendantNode)
             value->setActiveDescendantNodeId(pushNodePathToFrontend(activeDescendantNode));
+        if (busy)
+            value->setBusy(busy);
         if (supportsChecked)
             value->setChecked(checked);
         if (childNodeIds)
@@ -1602,6 +1620,10 @@ PassRefPtr<TypeBuilder::DOM::AccessibilityProperties> InspectorDOMAgent::buildOb
             value->setInvalid(invalid);
         if (hidden)
             value->setHidden(hidden);
+        if (supportsLiveRegion) {
+            value->setLiveRegionAtomic(liveRegionAtomic);
+            value->setLiveRegionStatus(liveRegionStatus);
+        }
         if (mouseEventNode)
             value->setMouseEventNodeId(pushNodePathToFrontend(mouseEventNode));
         if (ownedNodeIds)
index 8baa185..c9a444a 100644 (file)
@@ -61,6 +61,7 @@
             "type": "object",
             "properties": [
                 { "name": "activeDescendantNodeId", "$ref": "NodeId", "optional": true, "description": "<code>DOMNode</code> id of the accessibility object referenced by aria-activedescendant." },
+                { "name": "busy", "type": "boolean", "optional": true, "description": "Value of @aria-busy on current or ancestor node." },
                 { "name": "checked", "type": "string", "optional": true, "enum": ["true", "false", "mixed"], "description": "Checked state of certain form controls." },
                 { "name": "childNodeIds", "type": "array", "items": { "$ref": "NodeId" }, "optional": true, "description": "Array of <code>DOMNode</code> ids of the accessibility tree children if available." },
                 { "name": "controlledNodeIds", "type": "array", "items": { "$ref": "NodeId" }, "optional": true, "description": "Array of <code>DOMNode</code> ids of any nodes referenced via @aria-controls." },
@@ -74,6 +75,8 @@
                 { "name": "invalid", "type": "string", "optional": true, "enum": ["true", "false", "grammar", "spelling"], "description": "Invalid status of form controls." },
                 { "name": "hidden", "type": "boolean", "optional": true, "description": "Hidden state. True if node or an ancestor is hidden via CSS or explicit @aria-hidden, to clarify why the element is ignored." },
                 { "name": "label", "type": "string", "description": "Computed label value for the node, sometimes calculated by referencing other nodes." },
+                { "name": "liveRegionAtomic", "type": "boolean", "optional": true, "description": "Value of @aria-atomic." },
+                { "name": "liveRegionStatus", "type": "string", "optional": true, "enum": ["assertive", "polite", "off"], "description": "Value of element's @aria-live attribute." },
                 { "name": "mouseEventNodeId", "$ref": "NodeId", "optional": true, "description": "<code>DOMNode</code> id of node or closest ancestor node that has a mousedown, mouseup, or click event handler." },
                 { "name": "nodeId", "$ref": "NodeId", "description": "Target <code>DOMNode</code> id." },
                 { "name": "ownedNodeIds", "type": "array", "items": { "$ref": "NodeId" }, "optional": true, "description": "Array of <code>DOMNode</code> ids of any nodes referenced via @aria-owns." },
index 222c33c..1d6c00b 100644 (file)
@@ -1,3 +1,17 @@
+2014-03-28  James Craig  <jcraig@apple.com>
+
+        Web Inspector: AXI: support for live regions
+        https://bugs.webkit.org/show_bug.cgi?id=130725
+
+        Reviewed by Timothy Hatcher.
+
+        Initial support for @aria-live, @aria-atomic, and @aria-busy.
+
+        * Localizations/en.lproj/localizedStrings.js:
+        * UserInterface/Models/DOMNode.js:
+        * UserInterface/Views/DOMNodeDetailsSidebarPanel.js:
+        * UserInterface/Views/Main.css: 
+
 2014-03-28  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: console.warn is showing as error instead of warning
index 9923fc0..665b25e 100644 (file)
Binary files a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js and b/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js differ
index 7cab93e..803fe86 100644 (file)
@@ -457,6 +457,7 @@ WebInspector.DOMNode.prototype = {
             if (!error && callback && accessibilityProperties) {
                 callback({
                     activeDescendantNodeId: accessibilityProperties.activeDescendantNodeId,
+                    busy: accessibilityProperties.busy,
                     checked: accessibilityProperties.checked,
                     childNodeIds: accessibilityProperties.childNodeIds,
                     controlledNodeIds: accessibilityProperties.controlledNodeIds,
@@ -470,6 +471,8 @@ WebInspector.DOMNode.prototype = {
                     invalid: accessibilityProperties.invalid,
                     hidden: accessibilityProperties.hidden,
                     label: accessibilityProperties.label,
+                    liveRegionAtomic: accessibilityProperties.liveRegionAtomic,
+                    liveRegionStatus: accessibilityProperties.liveRegionStatus,
                     mouseEventNodeId: accessibilityProperties.mouseEventNodeId,
                     nodeId: accessibilityProperties.nodeId,
                     ownedNodeIds: accessibilityProperties.ownedNodeIds,
index bfce132..19a2aa2 100644 (file)
@@ -59,6 +59,7 @@ WebInspector.DOMNodeDetailsSidebarPanel = function() {
     if (this._accessibilitySupported()) {
         this._accessibilityEmptyRow = new WebInspector.DetailsSectionRow(WebInspector.UIString("No Accessibility Information"));
         this._accessibilityNodeActiveDescendantRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Shared Focus"));
+        this._accessibilityNodeBusyRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Busy"));
         this._accessibilityNodeCheckedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Checked"));
         this._accessibilityNodeChildrenRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Children"));
         this._accessibilityNodeControlsRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Controls"));
@@ -68,6 +69,7 @@ WebInspector.DOMNodeDetailsSidebarPanel = function() {
         this._accessibilityNodeFocusedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Focused"));
         this._accessibilityNodeIgnoredRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Ignored"));
         this._accessibilityNodeInvalidRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Invalid"));
+        this._accessibilityNodeLiveRegionStatusRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Live"));
         this._accessibilityNodeMouseEventRow = new WebInspector.DetailsSectionSimpleRow("");
         this._accessibilityNodeLabelRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Label"));
         this._accessibilityNodeOwnsRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Owns"));
@@ -320,6 +322,7 @@ WebInspector.DOMNodeDetailsSidebarPanel.prototype = {
             if (accessibilityProperties && accessibilityProperties.exists) {
 
                 var activeDescendantLink = linkForNodeId(accessibilityProperties.activeDescendantNodeId);
+                var busy = booleanValueToLocalizedStringIfPropertyDefined("busy");
 
                 var checked = "";
                 if (accessibilityProperties.checked !== undefined) {
@@ -357,6 +360,30 @@ WebInspector.DOMNodeDetailsSidebarPanel.prototype = {
                 else if (accessibilityProperties.invalid === DOMAgent.AccessibilityPropertiesInvalid.Spelling)
                     invalid = WebInspector.UIString("Spelling");
 
+                var liveRegionStatus = "";
+                var liveRegionStatusNode = null;
+                var liveRegionStatusToken = accessibilityProperties.liveRegionStatus;
+                switch(liveRegionStatusToken) {
+                case DOMAgent.AccessibilityPropertiesLiveRegionStatus.Assertive:
+                    liveRegionStatus = WebInspector.UIString("Assertive");
+                    break;
+                case DOMAgent.AccessibilityPropertiesLiveRegionStatus.Polite:
+                    liveRegionStatus = WebInspector.UIString("Polite");
+                    break;
+                default:
+                    liveRegionStatus = "";
+                }
+                if (liveRegionStatus && accessibilityProperties.liveRegionAtomic === true) {
+                    liveRegionStatusNode = document.createElement("div");
+                    liveRegionStatusNode.className = "value-with-clarification";
+                    liveRegionStatusNode.setAttribute("role", "text");
+                    liveRegionStatusNode.appendChild(document.createTextNode(liveRegionStatus));
+                    var clarificationNode = document.createElement("div");
+                    clarificationNode.className = "clarification";
+                    clarificationNode.appendChild(document.createTextNode(WebInspector.UIString("Region announced in its entirety.")));
+                    liveRegionStatusNode.appendChild(clarificationNode);
+                }
+
                 var mouseEventNodeId = accessibilityProperties.mouseEventNodeId;
                 var mouseEventTextValue = "";
                 var mouseEventNodeLink = null;
@@ -396,6 +423,7 @@ WebInspector.DOMNodeDetailsSidebarPanel.prototype = {
 
                 // Assign all the properties to their respective views.
                 this._accessibilityNodeActiveDescendantRow.value = activeDescendantLink || "";
+                this._accessibilityNodeBusyRow.value = busy;
                 this._accessibilityNodeCheckedRow.value = checked;
                 this._accessibilityNodeChildrenRow.value = childNodeLinkList || "";
                 this._accessibilityNodeControlsRow.value = controlledNodeLinkList || "";
@@ -405,12 +433,13 @@ WebInspector.DOMNodeDetailsSidebarPanel.prototype = {
                 this._accessibilityNodeFocusedRow.value = focused;
                 this._accessibilityNodeIgnoredRow.value = ignored;
                 this._accessibilityNodeInvalidRow.value = invalid;
+                this._accessibilityNodeLabelRow.value = label;
+                this._accessibilityNodeLiveRegionStatusRow.value = liveRegionStatusNode || liveRegionStatus;
                 
                 // Row label changes based on whether the value is a delegate node link.
                 this._accessibilityNodeMouseEventRow.label = mouseEventNodeLink ? WebInspector.UIString("Click Listener") : WebInspector.UIString("Clickable");
                 this._accessibilityNodeMouseEventRow.value = mouseEventNodeLink || mouseEventTextValue;
 
-                this._accessibilityNodeLabelRow.value = label;
                 this._accessibilityNodeOwnsRow.value = ownedNodeLinkList || "";
                 this._accessibilityNodeParentRow.value = parentNodeLink || "";
                 this._accessibilityNodePressedRow.value = pressed;
@@ -439,6 +468,8 @@ WebInspector.DOMNodeDetailsSidebarPanel.prototype = {
                     this._accessibilityNodeFlowsRow,
                     this._accessibilityNodeMouseEventRow,
                     this._accessibilityNodeFocusedRow,
+                    this._accessibilityNodeBusyRow,
+                    this._accessibilityNodeLiveRegionStatusRow,
 
                     // Properties exposed for all input-type elements.
                     this._accessibilityNodeDisabledRow,
index 5cfa571..0d33e32 100644 (file)
@@ -270,3 +270,7 @@ body.docked.right #navigation-sidebar.collapsed > .resizer {
 .node-link-list li:last-child {
     margin: 0;
 }
+
+.value-with-clarification .clarification {
+    color: #666;
+}
index ea8613d..daef1dc 100644 (file)
@@ -1,3 +1,14 @@
+2014-03-28  James Craig  <jcraig@apple.com>
+
+        Web Inspector: AXI: support for live regions
+        https://bugs.webkit.org/show_bug.cgi?id=130725
+
+        Reviewed by Timothy Hatcher.
+
+        Demo update to show off the new Inspector support for live regions.
+
+        * blog-files/aria1.0/combobox_with_live_region_status.html:
+
 2014-03-27  James Craig  <jcraig@apple.com>
 
         Web Inspector: AXI: expose selectedChildNodeIds of list boxes, tree controls, etc., and reconcile UI with childNodeIds
index 24fd9db..03e4917 100644 (file)
     <p>Some <a href="#">focusable content</a> before the combobox.</p>
     <form class="pc">
         <!-- Note that this field is labelled by itself, which in this case, is an explicit pointer to use the placeholder attribute value. -->
-        <input type="text" tabindex="0" id="state" aria-labelledby="state" role="combobox" aria-autocomplete="list" aria-owns="statelist" placeholder="US State or Territory" autocomplete="off" autocorrect="off" autocapitalize="off">
-        <div role="status" aria-live="polite" aria-expanded="false">
+        <input type="text" tabindex="0" id="state" aria-labelledby="state" role="combobox" aria-autocomplete="list" aria-owns="statelist" aria-expanded="false" placeholder="US State or Territory" autocomplete="off" autocorrect="off" autocapitalize="off">
+        <div role="status">
             <!-- This is the list status live region: e.g. "4 items." -->
-            <!-- The attribute value, aria-live="polite" is the default for role="status". -->
-            <!-- It's just included here for demo clarity. -->
         </div>
         <ul role="listbox" id="statelist" hidden>
             <li id="AL" role="option">Alabama</li>