Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(625)

Side by Side Diff: Source/devtools/front_end/accessibility/AccessibilitySidebarView.js

Issue 1076453004: Show reasons why nodes are ignored in accessibility sidebar (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Add a catch-all return to ignoredReasonName Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @constructor 6 * @constructor
7 * @extends {WebInspector.ThrottledElementsSidebarView} 7 * @extends {WebInspector.ThrottledElementsSidebarView}
8 */ 8 */
9 WebInspector.AccessibilitySidebarView = function() 9 WebInspector.AccessibilitySidebarView = function()
10 { 10 {
11 WebInspector.ThrottledElementsSidebarView.call(this); 11 WebInspector.ThrottledElementsSidebarView.call(this);
12 this._axNodeSubPane = null;
12 } 13 }
13 14
14 WebInspector.AccessibilitySidebarView.prototype = { 15 WebInspector.AccessibilitySidebarView.prototype = {
15 /** 16 /**
16 * @override 17 * @override
17 * @param {!WebInspector.Throttler.FinishCallback} finishCallback 18 * @param {!WebInspector.Throttler.FinishCallback} finishCallback
18 * @protected 19 * @protected
19 */ 20 */
20 doUpdate: function(finishCallback) 21 doUpdate: function(finishCallback)
21 { 22 {
22 if (this._axNodeSubPane) 23 if (this._axNodeSubPane)
23 this._axNodeSubPane.doUpdate(finishCallback); 24 this._axNodeSubPane.doUpdate(finishCallback);
24 }, 25 },
25 26
26 /** 27 /**
27 * @override 28 * @override
28 */ 29 */
29 wasShown: function() 30 wasShown: function()
30 { 31 {
31 WebInspector.ElementsSidebarPane.prototype.wasShown.call(this); 32 WebInspector.ElementsSidebarPane.prototype.wasShown.call(this);
32 if (this._axNodeSubPane) 33 if (this._axNodeSubPane)
33 return; 34 return;
34 35
35 this._axNodeSubPane = new WebInspector.AXNodeSubPane(); 36 this._axNodeSubPane = new WebInspector.AXNodeSubPane();
37 this._axNodeSubPane.setNode(this.node());
36 this._axNodeSubPane.show(this.element); 38 this._axNodeSubPane.show(this.element);
37 this._axNodeSubPane.expand(); 39 this._axNodeSubPane.expand();
38 40
39 var sidebarPaneStack = new WebInspector.SidebarPaneStack(); 41 var sidebarPaneStack = new WebInspector.SidebarPaneStack();
40 sidebarPaneStack.element.classList.add("flex-auto"); 42 sidebarPaneStack.element.classList.add("flex-auto");
41 sidebarPaneStack.show(this.element); 43 sidebarPaneStack.show(this.element);
42 sidebarPaneStack.addPane(this._axNodeSubPane); 44 sidebarPaneStack.addPane(this._axNodeSubPane);
43 }, 45 },
44 46
47 /**
48 * @param {?WebInspector.DOMNode} node
49 * @override
50 */
51 setNode: function(node)
52 {
53 WebInspector.ThrottledElementsSidebarView.prototype.setNode.call(this, n ode);
54 if (this._axNodeSubPane)
55 this._axNodeSubPane.setNode(node);
56 },
57
45 58
46 __proto__: WebInspector.ThrottledElementsSidebarView.prototype 59 __proto__: WebInspector.ThrottledElementsSidebarView.prototype
47 }; 60 };
48 61
49 62
50 /** 63 /**
51 * @constructor 64 * @constructor
52 * @extends {WebInspector.SidebarPane} 65 * @extends {WebInspector.SidebarPane}
53 */ 66 */
54 WebInspector.AXNodeSubPane = function() 67 WebInspector.AXNodeSubPane = function()
55 { 68 {
56 WebInspector.SidebarPane.call(this, WebInspector.UIString("Accessibility Nod e")); 69 WebInspector.SidebarPane.call(this, WebInspector.UIString("Accessibility Nod e"));
57 70
58 this.registerRequiredCSS("accessibility/accessibilityNode.css"); 71 this.registerRequiredCSS("accessibility/accessibilityNode.css");
59 72
60 this._computedNameElement = this.bodyElement.createChild("div", "ax-computed -name"); 73 this._computedNameElement = this.bodyElement.createChild("div", "ax-computed -name hidden");
61 74
62 this._infoElement = createElementWithClass("div", "info hidden"); 75 this._noNodeInfo = createElementWithClass("div", "info");
63 this._infoElement.textContent = WebInspector.UIString("No Accessibility Node "); 76 this._noNodeInfo.textContent = WebInspector.UIString("No accessibility node" );
64 this.bodyElement.appendChild(this._infoElement); 77 this.bodyElement.appendChild(this._noNodeInfo);
78
79 this._ignoredInfo = createElementWithClass("div", "ax-ignored-info hidden");
80 this._ignoredInfo.textContent = WebInspector.UIString("Accessibility node no t exposed");
81 this.bodyElement.appendChild(this._ignoredInfo);
65 82
66 this._treeOutline = new TreeOutlineInShadow('monospace'); 83 this._treeOutline = new TreeOutlineInShadow('monospace');
67 this._treeOutline.registerRequiredCSS("accessibility/accessibilityNode.css") ; 84 this._treeOutline.registerRequiredCSS("accessibility/accessibilityNode.css") ;
68 this._treeOutline.registerRequiredCSS("components/objectValue.css"); 85 this._treeOutline.registerRequiredCSS("components/objectValue.css");
86 this._treeOutline.element.classList.add("hidden");
69 this.bodyElement.appendChild(this._treeOutline.element); 87 this.bodyElement.appendChild(this._treeOutline.element);
88
89 this._ignoredReasonsTree = new TreeOutlineInShadow();
90 this._ignoredReasonsTree.element.classList.add("hidden");
91 this._ignoredReasonsTree.registerRequiredCSS("accessibility/accessibilityNod e.css");
92 this._ignoredReasonsTree.registerRequiredCSS("components/objectValue.css");
93 this.bodyElement.appendChild(this._ignoredReasonsTree.element);
70 }; 94 };
71 95
72 96
73 WebInspector.AXNodeSubPane.prototype = { 97 WebInspector.AXNodeSubPane.prototype = {
74 /** 98 /**
99 * @return {?WebInspector.DOMNode}
100 */
101 node: function()
102 {
103 return this._node;
104 },
105
106 /**
107 * @param {?WebInspector.DOMNode} node
108 */
109 setNode: function(node)
110 {
111 this._node = node;
112 },
113
114 /**
75 * @param {!WebInspector.Throttler.FinishCallback} callback 115 * @param {!WebInspector.Throttler.FinishCallback} callback
76 */ 116 */
77 doUpdate: function(callback) 117 doUpdate: function(callback)
78 { 118 {
79 /** 119 /**
80 * @param {?AccessibilityAgent.AXNode} accessibilityNode 120 * @param {?AccessibilityAgent.AXNode} accessibilityNode
81 * @this {WebInspector.AXNodeSubPane} 121 * @this {WebInspector.AXNodeSubPane}
82 */ 122 */
83 function accessibilityNodeCallback(accessibilityNode) 123 function accessibilityNodeCallback(accessibilityNode)
84 { 124 {
85 this._setAXNode(accessibilityNode); 125 this._setAXNode(accessibilityNode);
86 callback(); 126 callback();
87 } 127 }
88 var node = this.parentWidget().parentWidget().node(); 128 var node = this.node();
89 WebInspector.AccessibilityModel.fromTarget(node.target()).getAXNode(node .id, accessibilityNodeCallback.bind(this)); 129 WebInspector.AccessibilityModel.fromTarget(node.target()).getAXNode(node .id, accessibilityNodeCallback.bind(this));
90 }, 130 },
91 131
92 /** 132 /**
93 * @override 133 * @override
94 */ 134 */
95 wasShown: function() 135 wasShown: function()
96 { 136 {
97 WebInspector.SidebarPane.prototype.wasShown.call(this); 137 WebInspector.SidebarPane.prototype.wasShown.call(this);
98 138
(...skipping 18 matching lines...) Expand all
117 * @param {?AccessibilityAgent.AXNode} axNode 157 * @param {?AccessibilityAgent.AXNode} axNode
118 */ 158 */
119 _setAXNode: function(axNode) 159 _setAXNode: function(axNode)
120 { 160 {
121 if (this._axNode === axNode) 161 if (this._axNode === axNode)
122 return; 162 return;
123 this._axNode = axNode; 163 this._axNode = axNode;
124 164
125 var treeOutline = this._treeOutline; 165 var treeOutline = this._treeOutline;
126 treeOutline.removeChildren(); 166 treeOutline.removeChildren();
167 var ignoredReasons = this._ignoredReasonsTree;
168 ignoredReasons.removeChildren();
169 var target = this.node().target();
127 170
128 if (!axNode) { 171 if (!axNode) {
129 this._computedNameElement.classList.add("hidden"); 172 this._computedNameElement.classList.add("hidden");
130 treeOutline.element.classList.add("hidden"); 173 treeOutline.element.classList.add("hidden");
131 this._infoElement.classList.remove("hidden"); 174 this._ignoredInfo.classList.add("hidden");
175 ignoredReasons.element.classList.add("hidden");
176
177 this._noNodeInfo.classList.remove("hidden");
178 return;
179 } else if (axNode.ignored) {
180 this._computedNameElement.classList.add("hidden");
181 this._noNodeInfo.classList.add("hidden");
182 treeOutline.element.classList.add("hidden");
183
184 this._ignoredInfo.classList.remove("hidden");
185 ignoredReasons.element.classList.remove("hidden");
186 /**
187 * @param {!AccessibilityAgent.AXProperty} property
188 */
189 function addIgnoredReason(property)
190 {
191 ignoredReasons.appendChild(new WebInspector.AXNodeIgnoredReasonT reeElement(property, axNode, target));
192 }
193 var ignoredReasonsArray = /** @type {!Array.<!Object>} */(axNode.ign oredReasons);
194 for (var reason of ignoredReasonsArray)
195 addIgnoredReason(reason);
196 if (!ignoredReasons.firstChild())
197 ignoredReasons.element.classList.add("hidden");
132 return; 198 return;
133 } 199 }
200 this._ignoredInfo.classList.add("hidden");
201 ignoredReasons.element.classList.add("hidden");
202 this._noNodeInfo.classList.add("hidden");
203
134 this._computedNameElement.classList.remove("hidden"); 204 this._computedNameElement.classList.remove("hidden");
135 treeOutline.element.classList.remove("hidden"); 205 treeOutline.element.classList.remove("hidden");
136 this._infoElement.classList.add("hidden");
137
138 var target = this.parentWidget().parentWidget().node().target();
139 206
140 this._computedNameElement.removeChildren(); 207 this._computedNameElement.removeChildren();
141 if (axNode.name && axNode.name.value) 208 if (axNode.name && axNode.name.value)
142 this._computedNameElement.textContent = axNode.name.value; 209 this._computedNameElement.textContent = axNode.name.value;
143 210
211 /**
212 * @param {!AccessibilityAgent.AXProperty} property
213 */
144 function addProperty(property) 214 function addProperty(property)
145 { 215 {
146 treeOutline.appendChild(new WebInspector.AXNodePropertyTreeElement(p roperty, target)); 216 treeOutline.appendChild(new WebInspector.AXNodePropertyTreeElement(p roperty, target));
147 } 217 }
148 218
149 addProperty({name: "role", value: axNode.role}); 219 var roleProperty = /** @type {!AccessibilityAgent.AXProperty} */ ({name: "role", value: axNode.role});
220 addProperty(roleProperty);
150 221
151 for (var propertyName of ["description", "help", "value"]) { 222 for (var propertyName of ["description", "help", "value"]) {
152 if (propertyName in axNode) 223 if (propertyName in axNode) {
153 addProperty({name: propertyName, value: axNode[propertyName]}); 224 var defaultProperty = /** @type {!AccessibilityAgent.AXProperty} */ ({name: propertyName, value: axNode[propertyName]});
225 addProperty(defaultProperty);
226 }
154 } 227 }
155 228
156 var propertyMap = {}; 229 var propertyMap = {};
157 for (var property of axNode.properties) 230 var propertiesArray = /** @type {!Array.<!AccessibilityAgent.AXProperty> } */ (axNode.properties);
231 for (var property of propertiesArray)
158 propertyMap[property.name] = property; 232 propertyMap[property.name] = property;
159 233
160 for (var propertySet of [AccessibilityAgent.AXWidgetAttributes, Accessib ilityAgent.AXWidgetStates, AccessibilityAgent.AXGlobalStates, AccessibilityAgent .AXLiveRegionAttributes, AccessibilityAgent.AXRelationshipAttributes]) { 234 for (var propertySet of [AccessibilityAgent.AXWidgetAttributes, Accessib ilityAgent.AXWidgetStates, AccessibilityAgent.AXGlobalStates, AccessibilityAgent .AXLiveRegionAttributes, AccessibilityAgent.AXRelationshipAttributes]) {
161 for (var propertyKey in propertySet) { 235 for (var propertyKey in propertySet) {
162 var property = propertySet[propertyKey]; 236 var property = propertySet[propertyKey];
163 if (property in propertyMap) 237 if (property in propertyMap)
164 addProperty(propertyMap[property]); 238 addProperty(propertyMap[property]);
165 } 239 }
166 } 240 }
167 }, 241 },
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 WebInspector.AXNodePropertyTreeElement.TypeStyles = { 434 WebInspector.AXNodePropertyTreeElement.TypeStyles = {
361 boolean: "object-value-boolean", 435 boolean: "object-value-boolean",
362 booleanOrUndefined: "object-value-boolean", 436 booleanOrUndefined: "object-value-boolean",
363 tristate: "object-value-boolean", 437 tristate: "object-value-boolean",
364 number: "object-value-number", 438 number: "object-value-number",
365 integer: "object-value-number", 439 integer: "object-value-number",
366 string: "object-value-string", 440 string: "object-value-string",
367 role: "ax-role", 441 role: "ax-role",
368 internalRole: "ax-internal-role" 442 internalRole: "ax-internal-role"
369 }; 443 };
444
445 /**
446 * @constructor
447 * @extends {TreeElement}
448 * @param {!AccessibilityAgent.AXProperty} property
449 * @param {?AccessibilityAgent.AXNode} axNode
450 * @param {!WebInspector.Target} target
451 */
452 WebInspector.AXNodeIgnoredReasonTreeElement = function(property, axNode, target)
453 {
454 this._property = property;
455 this._axNode = axNode;
456 this._target = target;
457
458 // Pass an empty title, the title gets made later in onattach.
459 TreeElement.call(this, "");
460 this.toggleOnClick = true;
461 this.selectable = false;
462 }
463
464 WebInspector.AXNodeIgnoredReasonTreeElement.prototype = {
465 /**
466 * @override
467 */
468 onattach: function()
469 {
470 this.listItemElement.removeChildren();
471
472 this._reasonElement = WebInspector.AXNodeIgnoredReasonTreeElement.create ReasonElement(this._property.name, this._axNode);
473 this.listItemElement.appendChild(this._reasonElement);
474
475 var value = this._property.value;
476 if (value.type === "idref") {
477 this._valueElement = WebInspector.AXNodePropertyTreeElement.createRe lationshipValueElement(value, this._target);
478 this.listItemElement.appendChild(this._valueElement);
479 }
480 },
481
482 __proto__: TreeElement.prototype
483 };
484
485 /**
486 * @param {?string} reason
487 * @param {?AccessibilityAgent.AXNode} axNode
488 * @return {?Element}
489 */
490 WebInspector.AXNodeIgnoredReasonTreeElement.createReasonElement = function(reaso n, axNode)
491 {
492 var reasonElement = null;
493 switch(reason) {
494 case "activeModalDialog":
495 reasonElement = WebInspector.formatLocalized("Element is hidden by activ e modal dialog: ", [], "");
496 break;
497 case "ancestorDisallowsChild":
498 reasonElement = WebInspector.formatLocalized("Element is not permitted a s child of ", [], "");
499 break;
500 // http://www.w3.org/TR/wai-aria/roles#childrenArePresentational
501 case "ancestorIsLeafNode":
502 reasonElement = WebInspector.formatLocalized("Ancestor's children are al l presentational: ", [], "");
503 break;
504 case "ariaHidden":
505 var ariaHiddenSpan = createElement("span", "source-code").textContent = "aria-hidden";
506 reasonElement = WebInspector.formatLocalized("Element is %s.", [ ariaHid denSpan ], "");
507 break;
508 case "ariaHiddenRoot":
509 var ariaHiddenSpan = createElement("span", "source-code").textContent = "aria-hidden";
510 var trueSpan = createElement("span", "source-code").textContent = "true" ;
511 reasonElement = WebInspector.formatLocalized("%s is %s on ancestor: ", [ ariaHiddenSpan, trueSpan ], "");
512 break;
513 case "emptyAlt":
514 reasonElement = WebInspector.formatLocalized("Element has empty alt text .", [], "");
515 break;
516 case "emptyText":
517 reasonElement = WebInspector.formatLocalized("No text content.", [], "") ;
518 break;
519 case "inert":
520 reasonElement = WebInspector.formatLocalized("Element is inert.", [], "" );
521 break;
522 case "inheritsPresentation":
523 reasonElement = WebInspector.formatLocalized("Element inherits presentat ional role from ", [], "");
524 break;
525 case "labelContainer":
526 reasonElement = WebInspector.formatLocalized("Part of label element: ", [], "");
527 break;
528 case "labelFor":
529 reasonElement = WebInspector.formatLocalized("Label for ", [], "");
530 break;
531 case "notRendered":
532 reasonElement = WebInspector.formatLocalized("Element is not rendered.", [], "");
533 break;
534 case "notVisible":
535 reasonElement = WebInspector.formatLocalized("Element is not visible.", [], "");
536 break;
537 case "presentationalRole":
538 var rolePresentationSpan = createElement("span", "source-code").textCont ent = "role=" + axNode.role.value;
539 reasonElement = WebInspector.formatLocalized("Element has %s.", [ rolePr esentationSpan ], "");
540 break;
541 case "probablyPresentational":
542 reasonElement = WebInspector.formatLocalized("Element is presentational. ", [], "");
543 break;
544 case "staticTextUsedAsNameFor":
545 reasonElement = WebInspector.formatLocalized("Static text node is used a s name for ", [], "");
546 break;
547 case "uninteresting":
548 reasonElement = WebInspector.formatLocalized("Element not interesting fo r accessibility.", [], "")
549 break;
550 }
551 if (reasonElement)
552 reasonElement.classList.add("ax-reason");
553 return reasonElement;
554 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698