| 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
|
| +};
|
|
|