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

Unified Diff: third_party/WebKit/Source/devtools/front_end/accessibility/AXTreePane.js

Issue 2390783006: [DevTools] Accessibility: Show siblings and children of selected node (Closed)
Patch Set: Handle non-rendered nodes which are not top-level Created 4 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/front_end/accessibility/AXTreePane.js
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AXTreePane.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AXTreePane.js
index 4196b0d4ef241b8889dd4d0c48d1da4fbf40c31b..5c330518fdeb4b1021fa69fb6577029b48340083 100644
--- a/third_party/WebKit/Source/devtools/front_end/accessibility/AXTreePane.js
+++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AXTreePane.js
@@ -13,31 +13,119 @@ WebInspector.AXTreePane = function()
this._treeOutline = this.createTreeOutline();
this.element.classList.add("accessibility-computed");
+
+ this._expandedNodes = new Set();
};
WebInspector.AXTreePane.prototype = {
/**
- * @param {!Array<!WebInspector.AccessibilityNode>} nodes
+ * @param {?WebInspector.AccessibilityNode} axNode
+ * @override
*/
- setAXNodeAndAncestors: function(nodes)
+ setAXNode : function(axNode)
{
- this._nodes = nodes;
+ this._axNode = axNode;
- var target = this.node().target();
var treeOutline = this._treeOutline;
treeOutline.removeChildren();
+
+ // TODO(aboxhall): show no node UI
+ if (!axNode)
+ return;
+
treeOutline.element.classList.remove("hidden");
- var previous = treeOutline.rootElement();
- while (nodes.length) {
- var ancestor = nodes.pop();
- var ancestorTreeElement = new WebInspector.AXNodeTreeElement(ancestor, target);
- previous.appendChild(ancestorTreeElement);
- previous.expand();
- previous = ancestorTreeElement;
+ var previousTreeElement = treeOutline.rootElement();
+ var inspectedNodeTreeElement = new WebInspector.AXNodeTreeElement(axNode, this);
+ inspectedNodeTreeElement.setInspected(true);
+
+ var parent = axNode.parentNode();
+ if (parent) {
+ this.setExpanded(parent.domNode(), false);
+
+ var chain = [];
+ var ancestor = parent.parentNode();
+ while (ancestor) {
+ chain.unshift(ancestor);
+ ancestor = ancestor.parentNode();
+ }
+ for (var ancestorNode of chain) {
+ var ancestorTreeElement = new WebInspector.AXNodeTreeElement(ancestorNode, this);
+ previousTreeElement.appendChild(ancestorTreeElement);
+ previousTreeElement.expand();
+ previousTreeElement = ancestorTreeElement;
+ }
+ var parentTreeElement = new WebInspector.AXNodeTreeParentElement(parent, inspectedNodeTreeElement, this);
+ if (this.isExpanded(parent.domNode()))
+ parentTreeElement.appendSiblings();
+ else
+ parentTreeElement.appendChild(inspectedNodeTreeElement);
+ previousTreeElement.appendChild(parentTreeElement);
+ previousTreeElement.expand();
+ previousTreeElement = parentTreeElement;
+ } else {
+ previousTreeElement.appendChild(inspectedNodeTreeElement);
}
- previous.selectable = true;
- previous.select(true /* omitFocus */);
+
+ previousTreeElement.expand();
+
+ for (var child of axNode.children()) {
+ var childTreeElement = new WebInspector.AXNodeTreeElement(child, this);
+ inspectedNodeTreeElement.appendChild(childTreeElement);
+ }
+
+ inspectedNodeTreeElement.selectable = true;
+ inspectedNodeTreeElement.select(!this._selectedByUser /* omitFocus */, false);
+ if (this.isExpanded(axNode.domNode()))
+ inspectedNodeTreeElement.expand();
+ this.clearSelectedByUser();
+ },
+
+ /**
+ * @param {boolean} selectedByUser
+ */
+ setSelectedByUser: function(selectedByUser)
+ {
+ this._selectedByUser = true;
+ },
+
+ clearSelectedByUser: function()
+ {
+ delete this._selectedByUser;
+ },
+
+ /**
+ * @return {!WebInspector.Target}
+ */
+ target: function()
+ {
+ return this.node().target();
+ },
+
+ /**
+ * @param {?WebInspector.DOMNode} domNode
+ * @param {boolean} expanded
+ */
+ setExpanded: function(domNode, expanded)
+ {
+ if (!domNode)
+ return;
+ if (expanded)
+ this._expandedNodes.add(domNode.id);
+ else
+ this._expandedNodes.delete(domNode.id);
+ },
+
+ /**
+ * @param {?WebInspector.DOMNode} domNode
+ * @return {boolean}
+ */
+ isExpanded: function(domNode)
+ {
+ if (!domNode)
+ return false;
+
+ return this._expandedNodes.has(domNode.id);
},
__proto__: WebInspector.AccessibilitySubPane.prototype
@@ -47,20 +135,23 @@ WebInspector.AXTreePane.prototype = {
* @constructor
* @extends {TreeElement}
* @param {!WebInspector.AccessibilityNode} axNode
- * @param {!WebInspector.Target} target
+ * @param {!WebInspector.AXTreePane} treePane
*/
-WebInspector.AXNodeTreeElement = function(axNode, target)
+WebInspector.AXNodeTreeElement = function(axNode, treePane)
{
/** @type {!WebInspector.AccessibilityNode} */
this._axNode = axNode;
- /** @type {!WebInspector.Target} */
- this._target = target;
+ /** @type {!WebInspector.AXTreePane} */
+ this._treePane = treePane;
// Pass an empty title, the title gets made later in onattach.
- TreeElement.call(this, "");
+ TreeElement.call(this, "", true);
+
+ if (!this._axNode.domNode())
+ this.listItemElement.classList.add("no-dom-node");
- this.selectable = false;
+ this.selectable = true;
};
/** @type {!Object<string, string>} */
@@ -71,6 +162,52 @@ WebInspector.AXNodeTreeElement.RoleStyles = {
WebInspector.AXNodeTreeElement.prototype = {
/**
+ * @return {!WebInspector.AccessibilityNode}
+ */
+ axNode: function()
+ {
+ return this._axNode;
+ },
+
+ /**
+ * @param {boolean} inspected
+ */
+ setInspected: function(inspected)
+ {
+ if (inspected)
+ this.listItemElement.classList.add("inspected");
+ else
+ this.listItemElement.classList.remove("inspected");
+ },
+
+ /**
+ * @override
+ * @return {boolean}
+ */
+ onenter: function()
+ {
+ this.inspectDOMNode();
+ return true;
+ },
+
+ /**
+ * @override
+ * @param {!Event} event
+ * @return {boolean}
+ */
+ ondblclick: function(event)
+ {
+ this.inspectDOMNode();
+ return true;
+ },
+
+ inspectDOMNode: function()
+ {
+ this._treePane.setSelectedByUser(true);
+ WebInspector.Revealer.reveal(this._axNode.domNode());
+ },
+
+ /**
* @override
*/
onattach: function()
@@ -91,6 +228,38 @@ WebInspector.AXNodeTreeElement.prototype = {
this._appendNameElement(/** @type {string} */ (this._axNode.name().value));
}
}
+
+ if (this._axNode.hasOnlyUnloadedChildren()) {
+ this._hasOnlyUnloadedChildren = true;
+ this.listItemElement.classList.add("children-unloaded");
+ this.setExpandable(true);
+ } else {
+ this.setExpandable(!!this._axNode.numChildren());
+ }
+ },
+
+ /**
+ * @override
+ */
+ expand: function()
+ {
+ if (this._hasOnlyUnloadedChildren)
+ return;
+
+ this._treePane.setExpanded(this._axNode.domNode(), true);
+ TreeElement.prototype.expand.call(this);
+ },
+
+ /**
+ * @override
+ */
+ collapse: function()
+ {
+ if (this._hasOnlyUnloadedChildren)
+ return;
+
+ this._treePane.setExpanded(this._axNode.domNode(), false);
+ TreeElement.prototype.collapse.call(this);
},
/**
@@ -127,5 +296,128 @@ WebInspector.AXNodeTreeElement.prototype = {
this.listItemElement.appendChild(ignoredNodeElement);
},
+ /**
+ * @param {boolean=} omitFocus
+ * @param {boolean=} selectedByUser
+ * @return {boolean}
+ * @override
+ */
+ select: function(omitFocus, selectedByUser)
+ {
+ this._ensureSelection();
+
+ this._treePane.setSelectedByUser(!!selectedByUser);
+ if (selectedByUser)
+ WebInspector.context.setFlavor(WebInspector.AccessibilityNode, this._axNode);
+
+ return TreeElement.prototype.select.call(this, omitFocus, selectedByUser);
+ },
+
__proto__: TreeElement.prototype
};
+
+/**
+ * @constructor
+ * @param {!WebInspector.AXNodeTreeParentElement} treeElement
+ */
+WebInspector.ExpandSiblingsButton = function(treeElement)
+{
+ this._treeElement = treeElement;
+
+ this.element = createElementWithClass("button", "expand-siblings");
+ this.element.addEventListener("mousedown", this._handleMouseDown.bind(this));
+};
+
+WebInspector.ExpandSiblingsButton.prototype = {
+ _handleMouseDown: function(event) {
+ this._treeElement.expandSiblings();
+ event.consume();
+ }
+};
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.AXNodeTreeElement}
+ * @param {!WebInspector.AccessibilityNode} axNode
+ * @param {!WebInspector.AXNodeTreeElement} inspectedNodeTreeElement
+ * @param {!WebInspector.AXTreePane} treePane
+ */
+WebInspector.AXNodeTreeParentElement = function(axNode, inspectedNodeTreeElement, treePane)
+{
+ this._inspectedNodeTreeElement = inspectedNodeTreeElement;
+ this._treePane = treePane;
+
+ WebInspector.AXNodeTreeElement.call(this, axNode, treePane);
+
+ this._expandSibingsButton = new WebInspector.ExpandSiblingsButton(this);
+ this._partiallyExpanded = false;
+};
+
+WebInspector.AXNodeTreeParentElement.prototype = {
+ /**
+ * @override
+ */
+ onattach: function(){
+ WebInspector.AXNodeTreeElement.prototype.onattach.call(this);
+ if (this._treePane.isExpanded(this._axNode.domNode()))
+ this._listItemNode.classList.add("siblings-expanded");
+ if (this._axNode.numChildren() > 1)
+ this._listItemNode.appendChild(this._expandSibingsButton.element);
+ },
+
+ /**
+ * @param {boolean} altKey
+ * @return {boolean}
+ * @override
+ */
+ descendOrExpand: function(altKey)
+ {
+ if (!this.expanded || !this._partiallyExpanded)
+ return TreeElement.prototype.descendOrExpand.call(this, altKey);
+
+ this.expandSiblings();
+ if (altKey)
+ this.expandRecursively();
+ return true;
+ },
+
+ /**
+ * @override
+ */
+ expand: function()
+ {
+ TreeElement.prototype.expand.call(this);
+ this._partiallyExpanded = true;
+ },
+
+ expandSiblings: function()
+ {
+ this._listItemNode.classList.add("siblings-expanded");
+ this.appendSiblings();
+ this.expanded = true;
+ this._partiallyExpanded = false;
+ this._treePane.setExpanded(this._axNode.domNode(), true);
+ },
+
+ appendSiblings: function()
+ {
+ var inspectedAXNode = this._inspectedNodeTreeElement.axNode();
+ var nextIndex = 0;
+ var foundInspectedNode = false;
+ for (var sibling of this._axNode.children()) {
+ var siblingTreeElement = null;
+ if (sibling === inspectedAXNode) {
+ foundInspectedNode = true;
+ continue;
+ }
+ siblingTreeElement = new WebInspector.AXNodeTreeElement(sibling, this._treePane);
+ if (foundInspectedNode)
+ this.appendChild(siblingTreeElement);
+ else
+ this.insertChild(siblingTreeElement, nextIndex++);
+ }
+ },
+
+ __proto__: WebInspector.AXNodeTreeElement.prototype
+};

Powered by Google App Engine
This is Rietveld 408576698