| Index: Source/devtools/front_end/accessibility/AccessibilitySidebarView.js
|
| diff --git a/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js b/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js
|
| index a2d5bfc7cc15f8922ea2133d380e15eb6d954dc8..70d4f79214fca8b9023c5713ff995549442d548d 100644
|
| --- a/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js
|
| +++ b/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js
|
| @@ -57,16 +57,27 @@ WebInspector.AXNodeSubPane = function()
|
|
|
| this.registerRequiredCSS("accessibility/accessibilityNode.css");
|
|
|
| - this._computedNameElement = this.bodyElement.createChild("div", "ax-computed-name");
|
| + this._computedNameElement = this.bodyElement.createChild("div", "ax-computed-name hidden");
|
|
|
| - this._infoElement = createElementWithClass("div", "info hidden");
|
| - this._infoElement.textContent = WebInspector.UIString("No Accessibility Node");
|
| - this.bodyElement.appendChild(this._infoElement);
|
| + this._noNodeInfo = createElementWithClass("div", "info");
|
| + this._noNodeInfo.textContent = WebInspector.UIString("No accessibility node");
|
| + this.bodyElement.appendChild(this._noNodeInfo);
|
| +
|
| + this._ignoredInfo = createElementWithClass("div", "ax-ignored-info hidden");
|
| + this._ignoredInfo.textContent = WebInspector.UIString("Accessibility node not exposed");
|
| + this.bodyElement.appendChild(this._ignoredInfo);
|
|
|
| this._treeOutline = new TreeOutlineInShadow('monospace');
|
| this._treeOutline.registerRequiredCSS("accessibility/accessibilityNode.css");
|
| this._treeOutline.registerRequiredCSS("components/objectValue.css");
|
| + this._treeOutline.element.classList.add("hidden");
|
| this.bodyElement.appendChild(this._treeOutline.element);
|
| +
|
| + this._ignoredReasonsTree = new TreeOutlineInShadow();
|
| + this._ignoredReasonsTree.element.classList.add("hidden");
|
| + this._ignoredReasonsTree.registerRequiredCSS("accessibility/accessibilityNode.css");
|
| + this._ignoredReasonsTree.registerRequiredCSS("components/objectValue.css");
|
| + this.bodyElement.appendChild(this._ignoredReasonsTree.element);
|
| };
|
|
|
|
|
| @@ -124,18 +135,42 @@ WebInspector.AXNodeSubPane.prototype = {
|
|
|
| var treeOutline = this._treeOutline;
|
| treeOutline.removeChildren();
|
| + var ignoredReasons = this._ignoredReasonsTree;
|
| + ignoredReasons.removeChildren();
|
| +
|
| + var target = this.parentView().parentView().node().target();
|
|
|
| if (!axNode) {
|
| this._computedNameElement.classList.add("hidden");
|
| treeOutline.element.classList.add("hidden");
|
| - this._infoElement.classList.remove("hidden");
|
| + this._ignoredInfo.classList.add("hidden");
|
| + ignoredReasons.element.classList.add("hidden");
|
| +
|
| + this._noNodeInfo.classList.remove("hidden");
|
| + return;
|
| + } else if (axNode.ignored) {
|
| + this._computedNameElement.classList.add("hidden");
|
| + this._noNodeInfo.classList.add("hidden");
|
| + treeOutline.element.classList.add("hidden");
|
| +
|
| + this._ignoredInfo.classList.remove("hidden");
|
| + ignoredReasons.element.classList.remove("hidden");
|
| + function addIgnoredReason(property) {
|
| + ignoredReasons.appendChild(new WebInspector.AXNodeIgnoredReasonTreeElement(property, target));
|
| + }
|
| + var ignoredReasonsArray = /** @type {!Array.<!Object>} */(axNode.ignoredReasons);
|
| + for (var reason of ignoredReasonsArray)
|
| + addIgnoredReason(reason);
|
| + if (!ignoredReasons.firstChild())
|
| + ignoredReasons.element.classList.add("hidden");
|
| return;
|
| }
|
| + this._ignoredInfo.classList.add("hidden");
|
| + ignoredReasons.element.classList.add("hidden");
|
| + this._noNodeInfo.classList.add("hidden");
|
| +
|
| this._computedNameElement.classList.remove("hidden");
|
| treeOutline.element.classList.remove("hidden");
|
| - this._infoElement.classList.add("hidden");
|
| -
|
| - var target = this.parentView().parentView().node().target();
|
|
|
| this._computedNameElement.removeChildren();
|
| if (axNode.name && axNode.name.value)
|
| @@ -154,7 +189,8 @@ WebInspector.AXNodeSubPane.prototype = {
|
| }
|
|
|
| var propertyMap = {};
|
| - for (var property of axNode.properties)
|
| + var propertiesArray = /** @type {!Array.<!Object>} */ (axNode.properties);
|
| + for (var property of propertiesArray)
|
| propertyMap[property.name] = property;
|
|
|
| for (var propertySet of [AccessibilityAgent.AXWidgetAttributes, AccessibilityAgent.AXWidgetStates, AccessibilityAgent.AXGlobalStates, AccessibilityAgent.AXLiveRegionAttributes, AccessibilityAgent.AXRelationshipAttributes]) {
|
| @@ -367,3 +403,111 @@ WebInspector.AXNodePropertyTreeElement.TypeStyles = {
|
| role: "ax-role",
|
| internalRole: "ax-internal-role"
|
| };
|
| +
|
| +/**
|
| + * @constructor
|
| + * @extends {TreeElement}
|
| + * @param {!AccessibilityAgent.AXProperty} property
|
| + * @param {!WebInspector.Target} target
|
| + */
|
| +WebInspector.AXNodeIgnoredReasonTreeElement = function(property, target)
|
| +{
|
| + this._property = property;
|
| + this._target = target;
|
| +
|
| + // Pass an empty title, the title gets made later in onattach.
|
| + TreeElement.call(this, "");
|
| + this.toggleOnClick = true;
|
| + this.selectable = false;
|
| +}
|
| +
|
| +WebInspector.AXNodeIgnoredReasonTreeElement.prototype = {
|
| + /**
|
| + * @override
|
| + */
|
| + onattach: function()
|
| + {
|
| + this.listItemElement.removeChildren();
|
| +
|
| + this._reasonElement = WebInspector.AXNodeIgnoredReasonTreeElement.createReasonElement(this._property.name);
|
| + this.listItemElement.appendChild(this._reasonElement);
|
| +
|
| + var value = this._property.value;
|
| + if (value.type === "idref") {
|
| + this._valueElement = WebInspector.AXNodePropertyTreeElement.createRelationshipValueElement(value, this._target);
|
| + this.listItemElement.appendChild(this._valueElement);
|
| + }
|
| + },
|
| +
|
| + __proto__: TreeElement.prototype
|
| +};
|
| +
|
| +/**
|
| + * @param {?string} reason
|
| + * @return {?Element}
|
| + */
|
| +WebInspector.AXNodeIgnoredReasonTreeElement.createReasonElement = function(reason)
|
| +{
|
| + var reasonElement = null;
|
| + switch(reason) {
|
| + case "activeModalDialog":
|
| + reasonElement = WebInspector.formatLocalized("Element is hidden by active modal dialog: ", [], "");
|
| + break;
|
| + case "ancestorDisallowsChild":
|
| + reasonElement = WebInspector.formatLocalized("Element is not permitted as child of ", [], "");
|
| + break;
|
| + // http://www.w3.org/TR/wai-aria/roles#childrenArePresentational
|
| + case "ancestorIsLeafNode":
|
| + reasonElement = WebInspector.formatLocalized("Ancestor's children are all presentational: ", [], "");
|
| + break;
|
| + case "ariaHidden":
|
| + var ariaHiddenSpan = createElement("span", "source-code").textContent = "aria-hidden";
|
| + reasonElement = WebInspector.formatLocalized("Element is %s.", [ ariaHiddenSpan ], "");
|
| + break;
|
| + case "ariaHiddenRoot":
|
| + var ariaHiddenSpan = createElement("span", "source-code").textContent = "aria-hidden";
|
| + var trueSpan = createElement("span", "source-code").textContent = "true";
|
| + reasonElement = WebInspector.formatLocalized("%s is %s on ancestor: ", [ ariaHiddenSpan, trueSpan ], "");
|
| + break;
|
| + case "emptyAlt":
|
| + reasonElement = WebInspector.formatLocalized("Element has empty alt text.", [], "");
|
| + break;
|
| + case "emptyText":
|
| + reasonElement = WebInspector.formatLocalized("No text content.", [], "");
|
| + break;
|
| + case "inert":
|
| + reasonElement = WebInspector.formatLocalized("Element is inert.", [], "");
|
| + break;
|
| + case "inheritsPresentation":
|
| + reasonElement = WebInspector.formatLocalized("Element inherits presentational role from ", [], "");
|
| + break;
|
| + case "labelContainer":
|
| + reasonElement = WebInspector.formatLocalized("Part of label element: ", [], "");
|
| + break;
|
| + case "labelFor":
|
| + reasonElement = WebInspector.formatLocalized("Label for ", [], "");
|
| + break;
|
| + case "notRendered":
|
| + reasonElement = WebInspector.formatLocalized("Element is not rendered.", [], "");
|
| + break;
|
| + case "notVisible":
|
| + reasonElement = WebInspector.formatLocalized("Element is not visible.", [], "");
|
| + break;
|
| + case "presentationRole":
|
| + var rolePresentationSpan = createElement("span", "source-code").textContent = "role=presentation";
|
| + reasonElement = WebInspector.formatLocalized("Element has %s.", [ rolePresentationSpan ], "");
|
| + break;
|
| + case "probablyPresentational":
|
| + reasonElement = WebInspector.formatLocalized("Element is presentational.", [], "");
|
| + break;
|
| + case "staticTextUsedAsNameFor":
|
| + reasonElement = WebInspector.formatLocalized("Static text node is used as name for ", [], "");
|
| + break;
|
| + case "uninteresting":
|
| + reasonElement = WebInspector.formatLocalized("Element not interesting for accessibility.", [], "")
|
| + break;
|
| + }
|
| + if (reasonElement)
|
| + reasonElement.classList.add("ax-reason");
|
| + return reasonElement;
|
| +}
|
|
|