| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |