Web Inspector: Convert TreeElement classes to ES6
https://bugs.webkit.org/show_bug.cgi?id=143111
Reviewed by Joseph Pecoraro.
* UserInterface/Views/ApplicationCacheFrameTreeElement.js:
* UserInterface/Views/ApplicationCacheManifestTreeElement.js:
* UserInterface/Views/BreakpointTreeElement.js:
* UserInterface/Views/CallFrameTreeElement.js:
* UserInterface/Views/ContentFlowTreeElement.js:
* UserInterface/Views/CookieStorageTreeElement.js:
* UserInterface/Views/DOMStorageTreeElement.js:
* UserInterface/Views/DOMTreeElement.js:
* UserInterface/Views/DOMTreeOutline.js:
* UserInterface/Views/DatabaseHostTreeElement.js:
* UserInterface/Views/DatabaseTableTreeElement.js:
* UserInterface/Views/DatabaseTreeElement.js:
* UserInterface/Views/FolderTreeElement.js:
* UserInterface/Views/FolderizedTreeElement.js:
* UserInterface/Views/FrameTreeElement.js:
* UserInterface/Views/GeneralTreeElement.js:
* UserInterface/Views/IndexedDatabaseHostTreeElement.js:
* UserInterface/Views/IndexedDatabaseObjectStoreIndexTreeElement.js:
* UserInterface/Views/IndexedDatabaseObjectStoreTreeElement.js:
* UserInterface/Views/IndexedDatabaseTreeElement.js:
* UserInterface/Views/LegacyConsoleMessageImpl.js:
* UserInterface/Views/LogTreeElement.js:
* UserInterface/Views/NavigationSidebarPanel.js:
* UserInterface/Views/ObjectTreeArrayIndexTreeElement.js:
* UserInterface/Views/ObjectTreeBaseTreeElement.js:
* UserInterface/Views/ObjectTreeMapEntryTreeElement.js:
* UserInterface/Views/ObjectTreePropertyTreeElement.js:
* UserInterface/Views/ObjectTreeSetIndexTreeElement.js:
* UserInterface/Views/ObjectTreeView.js:
* UserInterface/Views/ProfileNodeTreeElement.js:
* UserInterface/Views/PropertiesSection.js:
* UserInterface/Views/ResourceTreeElement.js:
* UserInterface/Views/ScriptTreeElement.js:
* UserInterface/Views/SearchResultTreeElement.js:
* UserInterface/Views/SourceCodeTimelineTreeElement.js:
* UserInterface/Views/SourceCodeTreeElement.js:
* UserInterface/Views/SourceMapResourceTreeElement.js:
* UserInterface/Views/StorageTreeElement.js:
* UserInterface/Views/TimelineDataGrid.js:
* UserInterface/Views/TimelineRecordTreeElement.js:
* UserInterface/Views/TreeElementStatusButton.js:
* UserInterface/Views/TreeOutline.js:
* UserInterface/Views/TreeOutlineDataGridSynchronizer.js:
* UserInterface/Views/TypePropertiesSection.js:
Converted to ES6 classes where possible.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@182042 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js b/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js
index 27cb058..2c0f9de 100644
--- a/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js
+++ b/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2013, 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,187 +26,147 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-function TreeOutline(listNode)
+WebInspector.TreeOutline = class TreeOutline extends WebInspector.Object
{
- // FIXME: Convert this to a WebInspector.Object subclass, and call super().
- // WebInspector.Object.call(this);
+ constructor(listNode)
+ {
+ super();
- this.element = listNode;
+ this.element = listNode;
- this.children = [];
- this.selectedTreeElement = null;
- this._childrenListNode = listNode;
- this._childrenListNode.removeChildren();
- this._knownTreeElements = [];
- this._treeElementsExpandedState = [];
- this.expandTreeElementsWhenArrowing = false;
- this.allowsRepeatSelection = false;
- this.root = true;
- this.hasChildren = false;
- this.expanded = true;
- this.selected = false;
- this.treeOutline = this;
-
- this._childrenListNode.tabIndex = 0;
- this._childrenListNode.addEventListener("keydown", this._treeKeyDown.bind(this), true);
-}
-
-TreeOutline._knownTreeElementNextIdentifier = 1;
-TreeOutline.prototype.constructor = TreeOutline;
-
-TreeOutline.prototype.appendChild = function(child)
-{
- if (!child)
- throw "child can't be undefined or null";
-
- var lastChild = this.children[this.children.length - 1];
- if (lastChild) {
- lastChild.nextSibling = child;
- child.previousSibling = lastChild;
- } else {
- child.previousSibling = null;
- child.nextSibling = null;
- }
-
- var isFirstChild = !this.children.length;
-
- this.children.push(child);
- this.hasChildren = true;
- child.parent = this;
- child.treeOutline = this.treeOutline;
- child.treeOutline._rememberTreeElement(child);
-
- var current = child.children[0];
- while (current) {
- current.treeOutline = this.treeOutline;
- current.treeOutline._rememberTreeElement(current);
- current = current.traverseNextTreeElement(false, child, true);
- }
-
- if (child.hasChildren && child.treeOutline._treeElementsExpandedState[child.identifier] !== undefined)
- child.expanded = child.treeOutline._treeElementsExpandedState[child.identifier];
-
- if (this._childrenListNode)
- child._attach();
-
- if (this.treeOutline.onadd)
- this.treeOutline.onadd(child);
-
- if (isFirstChild && this.expanded)
- this.expand();
-};
-
-TreeOutline.prototype.insertChild = function(child, index)
-{
- if (!child)
- throw "child can't be undefined or null";
-
- var previousChild = (index > 0 ? this.children[index - 1] : null);
- if (previousChild) {
- previousChild.nextSibling = child;
- child.previousSibling = previousChild;
- } else {
- child.previousSibling = null;
- }
-
- var nextChild = this.children[index];
- if (nextChild) {
- nextChild.previousSibling = child;
- child.nextSibling = nextChild;
- } else {
- child.nextSibling = null;
- }
-
- var isFirstChild = !this.children.length;
-
- this.children.splice(index, 0, child);
- this.hasChildren = true;
- child.parent = this;
- child.treeOutline = this.treeOutline;
- child.treeOutline._rememberTreeElement(child);
-
- var current = child.children[0];
- while (current) {
- current.treeOutline = this.treeOutline;
- current.treeOutline._rememberTreeElement(current);
- current = current.traverseNextTreeElement(false, child, true);
- }
-
- if (child.hasChildren && child.treeOutline._treeElementsExpandedState[child.identifier] !== undefined)
- child.expanded = child.treeOutline._treeElementsExpandedState[child.identifier];
-
- if (this._childrenListNode)
- child._attach();
-
- if (this.treeOutline.onadd)
- this.treeOutline.onadd(child);
-
- if (isFirstChild && this.expanded)
- this.expand();
-};
-
-TreeOutline.prototype.removeChildAtIndex = function(childIndex, suppressOnDeselect, suppressSelectSibling)
-{
- if (childIndex < 0 || childIndex >= this.children.length)
- throw "childIndex out of range";
-
- var child = this.children[childIndex];
- this.children.splice(childIndex, 1);
-
- var parent = child.parent;
- if (child.deselect(suppressOnDeselect)) {
- if (child.previousSibling && !suppressSelectSibling)
- child.previousSibling.select(true, false);
- else if (child.nextSibling && !suppressSelectSibling)
- child.nextSibling.select(true, false);
- else if (!suppressSelectSibling)
- parent.select(true, false);
- }
-
- if (child.previousSibling)
- child.previousSibling.nextSibling = child.nextSibling;
- if (child.nextSibling)
- child.nextSibling.previousSibling = child.previousSibling;
-
- if (child.treeOutline) {
- child.treeOutline._forgetTreeElement(child);
- child.treeOutline._forgetChildrenRecursive(child);
- }
-
- child._detach();
- child.treeOutline = null;
- child.parent = null;
- child.nextSibling = null;
- child.previousSibling = null;
-
- if (this.treeOutline && this.treeOutline.onremove)
- this.treeOutline.onremove(child);
-};
-
-TreeOutline.prototype.removeChild = function(child, suppressOnDeselect, suppressSelectSibling)
-{
- if (!child)
- throw "child can't be undefined or null";
-
- var childIndex = this.children.indexOf(child);
- if (childIndex === -1)
- throw "child not found in this node's children";
-
- this.removeChildAtIndex(childIndex, suppressOnDeselect, suppressSelectSibling);
-
- if (!this.children.length) {
- this._listItemNode.classList.remove("parent");
+ this.children = [];
+ this.selectedTreeElement = null;
+ this._childrenListNode = listNode;
+ this._childrenListNode.removeChildren();
+ this._knownTreeElements = [];
+ this._treeElementsExpandedState = [];
+ this.expandTreeElementsWhenArrowing = false;
+ this.allowsRepeatSelection = false;
+ this.root = true;
this.hasChildren = false;
+ this.expanded = true;
+ this.selected = false;
+ this.treeOutline = this;
+
+ this._childrenListNode.tabIndex = 0;
+ this._childrenListNode.addEventListener("keydown", this._treeKeyDown.bind(this), true);
}
-};
-TreeOutline.prototype.removeChildren = function(suppressOnDeselect)
-{
- var treeOutline = this.treeOutline;
+ // Methods
- for (var i = 0; i < this.children.length; ++i) {
- var child = this.children[i];
- child.deselect(suppressOnDeselect);
+ appendChild(child)
+ {
+ if (!child)
+ throw "child can't be undefined or null";
+
+ var lastChild = this.children[this.children.length - 1];
+ if (lastChild) {
+ lastChild.nextSibling = child;
+ child.previousSibling = lastChild;
+ } else {
+ child.previousSibling = null;
+ child.nextSibling = null;
+ }
+
+ var isFirstChild = !this.children.length;
+
+ this.children.push(child);
+ this.hasChildren = true;
+ child.parent = this;
+ child.treeOutline = this.treeOutline;
+ child.treeOutline._rememberTreeElement(child);
+
+ var current = child.children[0];
+ while (current) {
+ current.treeOutline = this.treeOutline;
+ current.treeOutline._rememberTreeElement(current);
+ current = current.traverseNextTreeElement(false, child, true);
+ }
+
+ if (child.hasChildren && child.treeOutline._treeElementsExpandedState[child.identifier] !== undefined)
+ child.expanded = child.treeOutline._treeElementsExpandedState[child.identifier];
+
+ if (this._childrenListNode)
+ child._attach();
+
+ if (this.treeOutline.onadd)
+ this.treeOutline.onadd(child);
+
+ if (isFirstChild && this.expanded)
+ this.expand();
+ }
+
+ insertChild(child, index)
+ {
+ if (!child)
+ throw "child can't be undefined or null";
+
+ var previousChild = (index > 0 ? this.children[index - 1] : null);
+ if (previousChild) {
+ previousChild.nextSibling = child;
+ child.previousSibling = previousChild;
+ } else {
+ child.previousSibling = null;
+ }
+
+ var nextChild = this.children[index];
+ if (nextChild) {
+ nextChild.previousSibling = child;
+ child.nextSibling = nextChild;
+ } else {
+ child.nextSibling = null;
+ }
+
+ var isFirstChild = !this.children.length;
+
+ this.children.splice(index, 0, child);
+ this.hasChildren = true;
+ child.parent = this;
+ child.treeOutline = this.treeOutline;
+ child.treeOutline._rememberTreeElement(child);
+
+ var current = child.children[0];
+ while (current) {
+ current.treeOutline = this.treeOutline;
+ current.treeOutline._rememberTreeElement(current);
+ current = current.traverseNextTreeElement(false, child, true);
+ }
+
+ if (child.hasChildren && child.treeOutline._treeElementsExpandedState[child.identifier] !== undefined)
+ child.expanded = child.treeOutline._treeElementsExpandedState[child.identifier];
+
+ if (this._childrenListNode)
+ child._attach();
+
+ if (this.treeOutline.onadd)
+ this.treeOutline.onadd(child);
+
+ if (isFirstChild && this.expanded)
+ this.expand();
+ }
+
+ removeChildAtIndex(childIndex, suppressOnDeselect, suppressSelectSibling)
+ {
+ if (childIndex < 0 || childIndex >= this.children.length)
+ throw "childIndex out of range";
+
+ var child = this.children[childIndex];
+ this.children.splice(childIndex, 1);
+
+ var parent = child.parent;
+ if (child.deselect(suppressOnDeselect)) {
+ if (child.previousSibling && !suppressSelectSibling)
+ child.previousSibling.select(true, false);
+ else if (child.nextSibling && !suppressSelectSibling)
+ child.nextSibling.select(true, false);
+ else if (!suppressSelectSibling)
+ parent.select(true, false);
+ }
+
+ if (child.previousSibling)
+ child.previousSibling.nextSibling = child.nextSibling;
+ if (child.nextSibling)
+ child.nextSibling.previousSibling = child.previousSibling;
if (child.treeOutline) {
child.treeOutline._forgetTreeElement(child);
@@ -219,376 +179,439 @@
child.nextSibling = null;
child.previousSibling = null;
- if (treeOutline && treeOutline.onremove)
- treeOutline.onremove(child);
+ if (this.treeOutline && this.treeOutline.onremove)
+ this.treeOutline.onremove(child);
}
- this.children = [];
-};
+ removeChild(child, suppressOnDeselect, suppressSelectSibling)
+ {
+ if (!child)
+ throw "child can't be undefined or null";
-TreeOutline.prototype.removeChildrenRecursive = function(suppressOnDeselect)
-{
- var childrenToRemove = this.children;
+ var childIndex = this.children.indexOf(child);
+ if (childIndex === -1)
+ throw "child not found in this node's children";
- var treeOutline = this.treeOutline;
+ this.removeChildAtIndex(childIndex, suppressOnDeselect, suppressSelectSibling);
- var child = this.children[0];
- while (child) {
- if (child.children.length)
- childrenToRemove = childrenToRemove.concat(child.children);
- child = child.traverseNextTreeElement(false, this, true);
- }
-
- for (var i = 0; i < childrenToRemove.length; ++i) {
- child = childrenToRemove[i];
- child.deselect(suppressOnDeselect);
-
- if (child.treeOutline)
- child.treeOutline._forgetTreeElement(child);
-
- child._detach();
- child.children = [];
- child.treeOutline = null;
- child.parent = null;
- child.nextSibling = null;
- child.previousSibling = null;
-
- if (treeOutline && treeOutline.onremove)
- treeOutline.onremove(child);
- }
-
- this.children = [];
-};
-
-TreeOutline.prototype._rememberTreeElement = function(element)
-{
- if (!this._knownTreeElements[element.identifier])
- this._knownTreeElements[element.identifier] = [];
-
- // check if the element is already known
- var elements = this._knownTreeElements[element.identifier];
- if (elements.indexOf(element) !== -1)
- return;
-
- // add the element
- elements.push(element);
-};
-
-TreeOutline.prototype._forgetTreeElement = function(element)
-{
- if (this.selectedTreeElement === element)
- this.selectedTreeElement = null;
- if (this._knownTreeElements[element.identifier])
- this._knownTreeElements[element.identifier].remove(element, true);
-};
-
-TreeOutline.prototype._forgetChildrenRecursive = function(parentElement)
-{
- var child = parentElement.children[0];
- while (child) {
- this._forgetTreeElement(child);
- child = child.traverseNextTreeElement(false, parentElement, true);
- }
-};
-
-TreeOutline.prototype.getCachedTreeElement = function(representedObject)
-{
- if (!representedObject)
- return null;
-
- if (representedObject.__treeElementIdentifier) {
- // If this representedObject has a tree element identifier, and it is a known TreeElement
- // in our tree we can just return that tree element.
- var elements = this._knownTreeElements[representedObject.__treeElementIdentifier];
- if (elements) {
- for (var i = 0; i < elements.length; ++i)
- if (elements[i].representedObject === representedObject)
- return elements[i];
- }
- }
- return null;
-};
-
-TreeOutline.prototype.findTreeElement = function(representedObject, isAncestor, getParent)
-{
- if (!representedObject)
- return null;
-
- var cachedElement = this.getCachedTreeElement(representedObject);
- if (cachedElement)
- return cachedElement;
-
- // The representedObject isn't known, so we start at the top of the tree and work down to find the first
- // tree element that represents representedObject or one of its ancestors.
- var item;
- var found = false;
- for (var i = 0; i < this.children.length; ++i) {
- item = this.children[i];
- if (item.representedObject === representedObject || (isAncestor && isAncestor(item.representedObject, representedObject))) {
- found = true;
- break;
+ if (!this.children.length) {
+ this._listItemNode.classList.remove("parent");
+ this.hasChildren = false;
}
}
- if (!found)
- return null;
+ removeChildren(suppressOnDeselect)
+ {
+ var treeOutline = this.treeOutline;
- // Make sure the item that we found is connected to the root of the tree.
- // Build up a list of representedObject's ancestors that aren't already in our tree.
- var ancestors = [];
- var currentObject = representedObject;
- while (currentObject) {
- ancestors.unshift(currentObject);
- if (currentObject === item.representedObject)
- break;
- currentObject = getParent(currentObject);
- }
+ for (var i = 0; i < this.children.length; ++i) {
+ var child = this.children[i];
+ child.deselect(suppressOnDeselect);
- // For each of those ancestors we populate them to fill in the tree.
- for (var i = 0; i < ancestors.length; ++i) {
- // Make sure we don't call findTreeElement with the same representedObject
- // again, to prevent infinite recursion.
- if (ancestors[i] === representedObject)
- continue;
+ if (child.treeOutline) {
+ child.treeOutline._forgetTreeElement(child);
+ child.treeOutline._forgetChildrenRecursive(child);
+ }
- // FIXME: we could do something faster than findTreeElement since we will know the next
- // ancestor exists in the tree.
- item = this.findTreeElement(ancestors[i], isAncestor, getParent);
- if (item)
- item.onpopulate();
- }
+ child._detach();
+ child.treeOutline = null;
+ child.parent = null;
+ child.nextSibling = null;
+ child.previousSibling = null;
- return this.getCachedTreeElement(representedObject);
-};
-
-TreeOutline.prototype._treeElementDidChange = function(treeElement)
-{
- if (treeElement.treeOutline !== this)
- return;
-
- if (this.onchange)
- this.onchange(treeElement);
-};
-
-TreeOutline.prototype.treeElementFromNode = function(node)
-{
- var listNode = node.enclosingNodeOrSelfWithNodeNameInArray(["ol", "li"]);
- if (listNode)
- return listNode.parentTreeElement || listNode.treeElement;
- return null;
-};
-
-TreeOutline.prototype.treeElementFromPoint = function(x, y)
-{
- var node = this._childrenListNode.ownerDocument.elementFromPoint(x, y);
- if (!node)
- return null;
-
- return this.treeElementFromNode(node);
-};
-
-TreeOutline.prototype._treeKeyDown = function(event)
-{
- if (event.target !== this._childrenListNode)
- return;
-
- if (!this.selectedTreeElement || event.shiftKey || event.metaKey || event.ctrlKey)
- return;
-
- var handled = false;
- var nextSelectedElement;
- if (event.keyIdentifier === "Up" && !event.altKey) {
- nextSelectedElement = this.selectedTreeElement.traversePreviousTreeElement(true);
- while (nextSelectedElement && !nextSelectedElement.selectable)
- nextSelectedElement = nextSelectedElement.traversePreviousTreeElement(!this.expandTreeElementsWhenArrowing);
- handled = nextSelectedElement ? true : false;
- } else if (event.keyIdentifier === "Down" && !event.altKey) {
- nextSelectedElement = this.selectedTreeElement.traverseNextTreeElement(true);
- while (nextSelectedElement && !nextSelectedElement.selectable)
- nextSelectedElement = nextSelectedElement.traverseNextTreeElement(!this.expandTreeElementsWhenArrowing);
- handled = nextSelectedElement ? true : false;
- } else if (event.keyIdentifier === "Left") {
- if (this.selectedTreeElement.expanded) {
- if (event.altKey)
- this.selectedTreeElement.collapseRecursively();
- else
- this.selectedTreeElement.collapse();
- handled = true;
- } else if (this.selectedTreeElement.parent && !this.selectedTreeElement.parent.root) {
- handled = true;
- if (this.selectedTreeElement.parent.selectable) {
- nextSelectedElement = this.selectedTreeElement.parent;
- while (nextSelectedElement && !nextSelectedElement.selectable)
- nextSelectedElement = nextSelectedElement.parent;
- handled = nextSelectedElement ? true : false;
- } else if (this.selectedTreeElement.parent)
- this.selectedTreeElement.parent.collapse();
+ if (treeOutline && treeOutline.onremove)
+ treeOutline.onremove(child);
}
- } else if (event.keyIdentifier === "Right") {
- if (!this.selectedTreeElement.revealed()) {
- this.selectedTreeElement.reveal();
- handled = true;
- } else if (this.selectedTreeElement.hasChildren) {
- handled = true;
- if (this.selectedTreeElement.expanded) {
- nextSelectedElement = this.selectedTreeElement.children[0];
- while (nextSelectedElement && !nextSelectedElement.selectable)
- nextSelectedElement = nextSelectedElement.nextSibling;
- handled = nextSelectedElement ? true : false;
- } else {
- if (event.altKey)
- this.selectedTreeElement.expandRecursively();
- else
- this.selectedTreeElement.expand();
+
+ this.children = [];
+ }
+
+ removeChildrenRecursive(suppressOnDeselect)
+ {
+ var childrenToRemove = this.children;
+
+ var treeOutline = this.treeOutline;
+
+ var child = this.children[0];
+ while (child) {
+ if (child.children.length)
+ childrenToRemove = childrenToRemove.concat(child.children);
+ child = child.traverseNextTreeElement(false, this, true);
+ }
+
+ for (var i = 0; i < childrenToRemove.length; ++i) {
+ child = childrenToRemove[i];
+ child.deselect(suppressOnDeselect);
+
+ if (child.treeOutline)
+ child.treeOutline._forgetTreeElement(child);
+
+ child._detach();
+ child.children = [];
+ child.treeOutline = null;
+ child.parent = null;
+ child.nextSibling = null;
+ child.previousSibling = null;
+
+ if (treeOutline && treeOutline.onremove)
+ treeOutline.onremove(child);
+ }
+
+ this.children = [];
+ }
+
+ _rememberTreeElement(element)
+ {
+ if (!this._knownTreeElements[element.identifier])
+ this._knownTreeElements[element.identifier] = [];
+
+ // check if the element is already known
+ var elements = this._knownTreeElements[element.identifier];
+ if (elements.indexOf(element) !== -1)
+ return;
+
+ // add the element
+ elements.push(element);
+ }
+
+ _forgetTreeElement(element)
+ {
+ if (this.selectedTreeElement === element)
+ this.selectedTreeElement = null;
+ if (this._knownTreeElements[element.identifier])
+ this._knownTreeElements[element.identifier].remove(element, true);
+ }
+
+ _forgetChildrenRecursive(parentElement)
+ {
+ var child = parentElement.children[0];
+ while (child) {
+ this._forgetTreeElement(child);
+ child = child.traverseNextTreeElement(false, parentElement, true);
+ }
+ }
+
+ getCachedTreeElement(representedObject)
+ {
+ if (!representedObject)
+ return null;
+
+ if (representedObject.__treeElementIdentifier) {
+ // If this representedObject has a tree element identifier, and it is a known TreeElement
+ // in our tree we can just return that tree element.
+ var elements = this._knownTreeElements[representedObject.__treeElementIdentifier];
+ if (elements) {
+ for (var i = 0; i < elements.length; ++i)
+ if (elements[i].representedObject === representedObject)
+ return elements[i];
}
}
- } else if (event.keyCode === 8 /* Backspace */ || event.keyCode === 46 /* Delete */) {
- if (this.selectedTreeElement.ondelete)
- handled = this.selectedTreeElement.ondelete();
- if (!handled && this.treeOutline.ondelete)
- handled = this.treeOutline.ondelete(this.selectedTreeElement);
- } else if (isEnterKey(event)) {
- if (this.selectedTreeElement.onenter)
- handled = this.selectedTreeElement.onenter();
- if (!handled && this.treeOutline.onenter)
- handled = this.treeOutline.onenter(this.selectedTreeElement);
- } else if (event.keyIdentifier === "U+0020" /* Space */) {
- if (this.selectedTreeElement.onspace)
- handled = this.selectedTreeElement.onspace();
- if (!handled && this.treeOutline.onspace)
- handled = this.treeOutline.onspace(this.selectedTreeElement);
+ return null;
}
- if (nextSelectedElement) {
- nextSelectedElement.reveal();
- nextSelectedElement.select(false, true);
+ findTreeElement(representedObject, isAncestor, getParent)
+ {
+ if (!representedObject)
+ return null;
+
+ var cachedElement = this.getCachedTreeElement(representedObject);
+ if (cachedElement)
+ return cachedElement;
+
+ // The representedObject isn't known, so we start at the top of the tree and work down to find the first
+ // tree element that represents representedObject or one of its ancestors.
+ var item;
+ var found = false;
+ for (var i = 0; i < this.children.length; ++i) {
+ item = this.children[i];
+ if (item.representedObject === representedObject || (isAncestor && isAncestor(item.representedObject, representedObject))) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ return null;
+
+ // Make sure the item that we found is connected to the root of the tree.
+ // Build up a list of representedObject's ancestors that aren't already in our tree.
+ var ancestors = [];
+ var currentObject = representedObject;
+ while (currentObject) {
+ ancestors.unshift(currentObject);
+ if (currentObject === item.representedObject)
+ break;
+ currentObject = getParent(currentObject);
+ }
+
+ // For each of those ancestors we populate them to fill in the tree.
+ for (var i = 0; i < ancestors.length; ++i) {
+ // Make sure we don't call findTreeElement with the same representedObject
+ // again, to prevent infinite recursion.
+ if (ancestors[i] === representedObject)
+ continue;
+
+ // FIXME: we could do something faster than findTreeElement since we will know the next
+ // ancestor exists in the tree.
+ item = this.findTreeElement(ancestors[i], isAncestor, getParent);
+ if (item)
+ item.onpopulate();
+ }
+
+ return this.getCachedTreeElement(representedObject);
}
- if (handled) {
- event.preventDefault();
- event.stopPropagation();
+ _treeElementDidChange(treeElement)
+ {
+ if (treeElement.treeOutline !== this)
+ return;
+
+ if (this.onchange)
+ this.onchange(treeElement);
+ }
+
+ treeElementFromNode(node)
+ {
+ var listNode = node.enclosingNodeOrSelfWithNodeNameInArray(["ol", "li"]);
+ if (listNode)
+ return listNode.parentTreeElement || listNode.treeElement;
+ return null;
+ }
+
+ treeElementFromPoint(x, y)
+ {
+ var node = this._childrenListNode.ownerDocument.elementFromPoint(x, y);
+ if (!node)
+ return null;
+
+ return this.treeElementFromNode(node);
+ }
+
+ _treeKeyDown(event)
+ {
+ if (event.target !== this._childrenListNode)
+ return;
+
+ if (!this.selectedTreeElement || event.shiftKey || event.metaKey || event.ctrlKey)
+ return;
+
+ var handled = false;
+ var nextSelectedElement;
+ if (event.keyIdentifier === "Up" && !event.altKey) {
+ nextSelectedElement = this.selectedTreeElement.traversePreviousTreeElement(true);
+ while (nextSelectedElement && !nextSelectedElement.selectable)
+ nextSelectedElement = nextSelectedElement.traversePreviousTreeElement(!this.expandTreeElementsWhenArrowing);
+ handled = nextSelectedElement ? true : false;
+ } else if (event.keyIdentifier === "Down" && !event.altKey) {
+ nextSelectedElement = this.selectedTreeElement.traverseNextTreeElement(true);
+ while (nextSelectedElement && !nextSelectedElement.selectable)
+ nextSelectedElement = nextSelectedElement.traverseNextTreeElement(!this.expandTreeElementsWhenArrowing);
+ handled = nextSelectedElement ? true : false;
+ } else if (event.keyIdentifier === "Left") {
+ if (this.selectedTreeElement.expanded) {
+ if (event.altKey)
+ this.selectedTreeElement.collapseRecursively();
+ else
+ this.selectedTreeElement.collapse();
+ handled = true;
+ } else if (this.selectedTreeElement.parent && !this.selectedTreeElement.parent.root) {
+ handled = true;
+ if (this.selectedTreeElement.parent.selectable) {
+ nextSelectedElement = this.selectedTreeElement.parent;
+ while (nextSelectedElement && !nextSelectedElement.selectable)
+ nextSelectedElement = nextSelectedElement.parent;
+ handled = nextSelectedElement ? true : false;
+ } else if (this.selectedTreeElement.parent)
+ this.selectedTreeElement.parent.collapse();
+ }
+ } else if (event.keyIdentifier === "Right") {
+ if (!this.selectedTreeElement.revealed()) {
+ this.selectedTreeElement.reveal();
+ handled = true;
+ } else if (this.selectedTreeElement.hasChildren) {
+ handled = true;
+ if (this.selectedTreeElement.expanded) {
+ nextSelectedElement = this.selectedTreeElement.children[0];
+ while (nextSelectedElement && !nextSelectedElement.selectable)
+ nextSelectedElement = nextSelectedElement.nextSibling;
+ handled = nextSelectedElement ? true : false;
+ } else {
+ if (event.altKey)
+ this.selectedTreeElement.expandRecursively();
+ else
+ this.selectedTreeElement.expand();
+ }
+ }
+ } else if (event.keyCode === 8 /* Backspace */ || event.keyCode === 46 /* Delete */) {
+ if (this.selectedTreeElement.ondelete)
+ handled = this.selectedTreeElement.ondelete();
+ if (!handled && this.treeOutline.ondelete)
+ handled = this.treeOutline.ondelete(this.selectedTreeElement);
+ } else if (isEnterKey(event)) {
+ if (this.selectedTreeElement.onenter)
+ handled = this.selectedTreeElement.onenter();
+ if (!handled && this.treeOutline.onenter)
+ handled = this.treeOutline.onenter(this.selectedTreeElement);
+ } else if (event.keyIdentifier === "U+0020" /* Space */) {
+ if (this.selectedTreeElement.onspace)
+ handled = this.selectedTreeElement.onspace();
+ if (!handled && this.treeOutline.onspace)
+ handled = this.treeOutline.onspace(this.selectedTreeElement);
+ }
+
+ if (nextSelectedElement) {
+ nextSelectedElement.reveal();
+ nextSelectedElement.select(false, true);
+ }
+
+ if (handled) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+
+ expand()
+ {
+ // this is the root, do nothing
+ }
+
+ collapse()
+ {
+ // this is the root, do nothing
+ }
+
+ revealed()
+ {
+ return true;
+ }
+
+ reveal()
+ {
+ // this is the root, do nothing
+ }
+
+ select()
+ {
+ // this is the root, do nothing
+ }
+
+ revealAndSelect(omitFocus)
+ {
+ // this is the root, do nothing
}
};
-TreeOutline.prototype.expand = function()
+WebInspector.TreeOutline._knownTreeElementNextIdentifier = 1;
+
+WebInspector.TreeElement = class TreeElement extends WebInspector.Object
{
- // this is the root, do nothing
-};
+ constructor(title, representedObject, hasChildren)
+ {
+ super();
-TreeOutline.prototype.collapse = function()
-{
- // this is the root, do nothing
-};
+ this._title = title;
+ this.representedObject = (representedObject || {});
-TreeOutline.prototype.revealed = function()
-{
- return true;
-};
+ if (this.representedObject.__treeElementIdentifier)
+ this.identifier = this.representedObject.__treeElementIdentifier;
+ else {
+ this.identifier = WebInspector.TreeOutline._knownTreeElementNextIdentifier++;
+ this.representedObject.__treeElementIdentifier = this.identifier;
+ }
-TreeOutline.prototype.reveal = function()
-{
- // this is the root, do nothing
-};
-
-TreeOutline.prototype.select = function()
-{
- // this is the root, do nothing
-};
-
-TreeOutline.prototype.revealAndSelect = function(omitFocus)
-{
- // this is the root, do nothing
-};
-
-TreeOutline.prototype.__proto__ = WebInspector.Object.prototype;
-
-function TreeElement(title, representedObject, hasChildren)
-{
- // FIXME: Convert this to a WebInspector.Object subclass, and call super().
- // WebInspector.Object.call(this);
-
- this._title = title;
- this.representedObject = (representedObject || {});
-
- if (this.representedObject.__treeElementIdentifier)
- this.identifier = this.representedObject.__treeElementIdentifier;
- else {
- this.identifier = TreeOutline._knownTreeElementNextIdentifier++;
- this.representedObject.__treeElementIdentifier = this.identifier;
+ this._hidden = false;
+ this._selectable = true;
+ this.expanded = false;
+ this.selected = false;
+ this.hasChildren = hasChildren;
+ this.children = [];
+ this.treeOutline = null;
+ this.parent = null;
+ this.previousSibling = null;
+ this.nextSibling = null;
+ this._listItemNode = null;
}
- this._hidden = false;
- this._selectable = true;
- this.expanded = false;
- this.selected = false;
- this.hasChildren = hasChildren;
- this.children = [];
- this.treeOutline = null;
- this.parent = null;
- this.previousSibling = null;
- this.nextSibling = null;
- this._listItemNode = null;
-}
+ // Methods
-TreeElement.prototype = {
- constructor: TreeElement,
+ appendChild() { return WebInspector.TreeOutline.prototype.appendChild.apply(this, arguments); }
+ insertChild() { return WebInspector.TreeOutline.prototype.insertChild.apply(this, arguments); }
+ removeChild() { return WebInspector.TreeOutline.prototype.removeChild.apply(this, arguments); }
+ removeChildAtIndex() { return WebInspector.TreeOutline.prototype.removeChildAtIndex.apply(this, arguments); }
+ removeChildren() { return WebInspector.TreeOutline.prototype.removeChildren.apply(this, arguments); }
+ removeChildrenRecursive() { return WebInspector.TreeOutline.prototype.removeChildrenRecursive.apply(this, arguments); }
- arrowToggleWidth: 10,
+ get arrowToggleWidth()
+ {
+ return 10;
+ }
- get selectable() {
+ get selectable()
+ {
if (this._hidden)
return false;
return this._selectable;
- },
+ }
- set selectable(x) {
+ set selectable(x)
+ {
this._selectable = x;
- },
+ }
- get listItemElement() {
+ get listItemElement()
+ {
return this._listItemNode;
- },
+ }
- get childrenListElement() {
+ get childrenListElement()
+ {
return this._childrenListNode;
- },
+ }
- get title() {
+ get title()
+ {
return this._title;
- },
+ }
- set title(x) {
+ set title(x)
+ {
this._title = x;
this._setListItemNodeContent();
this.didChange();
- },
+ }
- get titleHTML() {
+ get titleHTML()
+ {
return this._titleHTML;
- },
+ }
- set titleHTML(x) {
+ set titleHTML(x)
+ {
this._titleHTML = x;
this._setListItemNodeContent();
this.didChange();
- },
+ }
- get tooltip() {
+ get tooltip()
+ {
return this._tooltip;
- },
+ }
- set tooltip(x) {
+ set tooltip(x)
+ {
this._tooltip = x;
if (this._listItemNode)
this._listItemNode.title = x ? x : "";
this.didChange();
- },
+ }
- get hasChildren() {
+ get hasChildren()
+ {
return this._hasChildren;
- },
+ }
- set hasChildren(x) {
+ set hasChildren(x)
+ {
if (this._hasChildren === x)
return;
@@ -605,13 +628,15 @@
}
this.didChange();
- },
+ }
- get hidden() {
+ get hidden()
+ {
return this._hidden;
- },
+ }
- set hidden(x) {
+ set hidden(x)
+ {
if (this._hidden === x)
return;
@@ -631,27 +656,29 @@
if (this.treeOutline && this.treeOutline.onhidden)
this.treeOutline.onhidden(this, x);
- },
+ }
- get shouldRefreshChildren() {
+ get shouldRefreshChildren()
+ {
return this._shouldRefreshChildren;
- },
+ }
- set shouldRefreshChildren(x) {
+ set shouldRefreshChildren(x)
+ {
this._shouldRefreshChildren = x;
if (x && this.expanded)
this.expand();
- },
+ }
- _fireDidChange: function()
+ _fireDidChange()
{
delete this._didChangeTimeoutIdentifier;
if (this.treeOutline)
this.treeOutline._treeElementDidChange(this);
- },
+ }
- didChange: function()
+ didChange()
{
if (!this.treeOutline)
return;
@@ -659,9 +686,9 @@
// Prevent telling the TreeOutline multiple times in a row by delaying it with a timeout.
if (!this._didChangeTimeoutIdentifier)
this._didChangeTimeoutIdentifier = setTimeout(this._fireDidChange.bind(this), 0);
- },
+ }
- _setListItemNodeContent: function()
+ _setListItemNodeContent()
{
if (!this._listItemNode)
return;
@@ -679,401 +706,393 @@
this._listItemNode.appendChild(this._title);
}
}
-};
-TreeElement.prototype.appendChild = TreeOutline.prototype.appendChild;
-TreeElement.prototype.insertChild = TreeOutline.prototype.insertChild;
-TreeElement.prototype.removeChild = TreeOutline.prototype.removeChild;
-TreeElement.prototype.removeChildAtIndex = TreeOutline.prototype.removeChildAtIndex;
-TreeElement.prototype.removeChildren = TreeOutline.prototype.removeChildren;
-TreeElement.prototype.removeChildrenRecursive = TreeOutline.prototype.removeChildrenRecursive;
+ _attach()
+ {
+ if (!this._listItemNode || this.parent._shouldRefreshChildren) {
+ if (this._listItemNode && this._listItemNode.parentNode)
+ this._listItemNode.parentNode.removeChild(this._listItemNode);
-TreeElement.prototype._attach = function()
-{
- if (!this._listItemNode || this.parent._shouldRefreshChildren) {
+ this._listItemNode = this.treeOutline._childrenListNode.ownerDocument.createElement("li");
+ this._listItemNode.treeElement = this;
+ this._setListItemNodeContent();
+ this._listItemNode.title = this._tooltip ? this._tooltip : "";
+
+ if (this.hidden)
+ this._listItemNode.classList.add("hidden");
+ if (this.hasChildren)
+ this._listItemNode.classList.add("parent");
+ if (this.expanded)
+ this._listItemNode.classList.add("expanded");
+ if (this.selected)
+ this._listItemNode.classList.add("selected");
+
+ this._listItemNode.addEventListener("mousedown", WebInspector.TreeElement.treeElementMouseDown);
+ this._listItemNode.addEventListener("click", WebInspector.TreeElement.treeElementToggled);
+ this._listItemNode.addEventListener("dblclick", WebInspector.TreeElement.treeElementDoubleClicked);
+
+ if (this.onattach)
+ this.onattach(this);
+ }
+
+ var nextSibling = null;
+ if (this.nextSibling && this.nextSibling._listItemNode && this.nextSibling._listItemNode.parentNode === this.parent._childrenListNode)
+ nextSibling = this.nextSibling._listItemNode;
+ this.parent._childrenListNode.insertBefore(this._listItemNode, nextSibling);
+ if (this._childrenListNode)
+ this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling);
+ if (this.selected)
+ this.select();
+ if (this.expanded)
+ this.expand();
+ }
+
+ _detach()
+ {
+ if (this.ondetach)
+ this.ondetach(this);
if (this._listItemNode && this._listItemNode.parentNode)
this._listItemNode.parentNode.removeChild(this._listItemNode);
-
- this._listItemNode = this.treeOutline._childrenListNode.ownerDocument.createElement("li");
- this._listItemNode.treeElement = this;
- this._setListItemNodeContent();
- this._listItemNode.title = this._tooltip ? this._tooltip : "";
-
- if (this.hidden)
- this._listItemNode.classList.add("hidden");
- if (this.hasChildren)
- this._listItemNode.classList.add("parent");
- if (this.expanded)
- this._listItemNode.classList.add("expanded");
- if (this.selected)
- this._listItemNode.classList.add("selected");
-
- this._listItemNode.addEventListener("mousedown", TreeElement.treeElementMouseDown, false);
- this._listItemNode.addEventListener("click", TreeElement.treeElementToggled, false);
- this._listItemNode.addEventListener("dblclick", TreeElement.treeElementDoubleClicked, false);
-
- if (this.onattach)
- this.onattach(this);
- }
-
- var nextSibling = null;
- if (this.nextSibling && this.nextSibling._listItemNode && this.nextSibling._listItemNode.parentNode === this.parent._childrenListNode)
- nextSibling = this.nextSibling._listItemNode;
- this.parent._childrenListNode.insertBefore(this._listItemNode, nextSibling);
- if (this._childrenListNode)
- this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling);
- if (this.selected)
- this.select();
- if (this.expanded)
- this.expand();
-};
-
-TreeElement.prototype._detach = function()
-{
- if (this.ondetach)
- this.ondetach(this);
- if (this._listItemNode && this._listItemNode.parentNode)
- this._listItemNode.parentNode.removeChild(this._listItemNode);
- if (this._childrenListNode && this._childrenListNode.parentNode)
- this._childrenListNode.parentNode.removeChild(this._childrenListNode);
-};
-
-TreeElement.treeElementMouseDown = function(event)
-{
- var element = event.currentTarget;
- if (!element || !element.treeElement || !element.treeElement.selectable)
- return;
-
- if (element.treeElement.isEventWithinDisclosureTriangle(event)) {
- event.preventDefault();
- return;
- }
-
- element.treeElement.selectOnMouseDown(event);
-};
-
-TreeElement.treeElementToggled = function(event)
-{
- var element = event.currentTarget;
- if (!element || !element.treeElement)
- return;
-
- var toggleOnClick = element.treeElement.toggleOnClick && !element.treeElement.selectable;
- var isInTriangle = element.treeElement.isEventWithinDisclosureTriangle(event);
- if (!toggleOnClick && !isInTriangle)
- return;
-
- if (element.treeElement.expanded) {
- if (event.altKey)
- element.treeElement.collapseRecursively();
- else
- element.treeElement.collapse();
- } else {
- if (event.altKey)
- element.treeElement.expandRecursively();
- else
- element.treeElement.expand();
- }
- event.stopPropagation();
-};
-
-TreeElement.treeElementDoubleClicked = function(event)
-{
- var element = event.currentTarget;
- if (!element || !element.treeElement)
- return;
-
- if (element.treeElement.isEventWithinDisclosureTriangle(event))
- return;
-
- if (element.treeElement.ondblclick)
- element.treeElement.ondblclick.call(element.treeElement, event);
- else if (element.treeElement.hasChildren && !element.treeElement.expanded)
- element.treeElement.expand();
-};
-
-TreeElement.prototype.collapse = function()
-{
- if (this._listItemNode)
- this._listItemNode.classList.remove("expanded");
- if (this._childrenListNode)
- this._childrenListNode.classList.remove("expanded");
-
- this.expanded = false;
- if (this.treeOutline)
- this.treeOutline._treeElementsExpandedState[this.identifier] = false;
-
- if (this.oncollapse)
- this.oncollapse(this);
-
- if (this.treeOutline && this.treeOutline.oncollapse)
- this.treeOutline.oncollapse(this);
-};
-
-TreeElement.prototype.collapseRecursively = function()
-{
- var item = this;
- while (item) {
- if (item.expanded)
- item.collapse();
- item = item.traverseNextTreeElement(false, this, true);
- }
-};
-
-TreeElement.prototype.expand = function()
-{
- if (this.expanded && !this._shouldRefreshChildren && this._childrenListNode)
- return;
-
- // Set this before onpopulate. Since onpopulate can add elements and call onadd, this makes
- // sure the expanded flag is true before calling those functions. This prevents the possibility
- // of an infinite loop if onpopulate or onadd were to call expand.
-
- this.expanded = true;
- if (this.treeOutline)
- this.treeOutline._treeElementsExpandedState[this.identifier] = true;
-
- // If there are no children, return. We will be expanded once we have children.
- if (!this.hasChildren)
- return;
-
- if (this.treeOutline && (!this._childrenListNode || this._shouldRefreshChildren)) {
if (this._childrenListNode && this._childrenListNode.parentNode)
this._childrenListNode.parentNode.removeChild(this._childrenListNode);
+ }
- this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");
- this._childrenListNode.parentTreeElement = this;
- this._childrenListNode.classList.add("children");
+ static treeElementMouseDown(event)
+ {
+ var element = event.currentTarget;
+ if (!element || !element.treeElement || !element.treeElement.selectable)
+ return;
+ if (element.treeElement.isEventWithinDisclosureTriangle(event)) {
+ event.preventDefault();
+ return;
+ }
+
+ element.treeElement.selectOnMouseDown(event);
+ }
+
+ static treeElementToggled(event)
+ {
+ var element = event.currentTarget;
+ if (!element || !element.treeElement)
+ return;
+
+ var toggleOnClick = element.treeElement.toggleOnClick && !element.treeElement.selectable;
+ var isInTriangle = element.treeElement.isEventWithinDisclosureTriangle(event);
+ if (!toggleOnClick && !isInTriangle)
+ return;
+
+ if (element.treeElement.expanded) {
+ if (event.altKey)
+ element.treeElement.collapseRecursively();
+ else
+ element.treeElement.collapse();
+ } else {
+ if (event.altKey)
+ element.treeElement.expandRecursively();
+ else
+ element.treeElement.expand();
+ }
+ event.stopPropagation();
+ }
+
+ static treeElementDoubleClicked(event)
+ {
+ var element = event.currentTarget;
+ if (!element || !element.treeElement)
+ return;
+
+ if (element.treeElement.isEventWithinDisclosureTriangle(event))
+ return;
+
+ if (element.treeElement.ondblclick)
+ element.treeElement.ondblclick.call(element.treeElement, event);
+ else if (element.treeElement.hasChildren && !element.treeElement.expanded)
+ element.treeElement.expand();
+ }
+
+ collapse()
+ {
+ if (this._listItemNode)
+ this._listItemNode.classList.remove("expanded");
+ if (this._childrenListNode)
+ this._childrenListNode.classList.remove("expanded");
+
+ this.expanded = false;
+ if (this.treeOutline)
+ this.treeOutline._treeElementsExpandedState[this.identifier] = false;
+
+ if (this.oncollapse)
+ this.oncollapse(this);
+
+ if (this.treeOutline && this.treeOutline.oncollapse)
+ this.treeOutline.oncollapse(this);
+ }
+
+ collapseRecursively()
+ {
+ var item = this;
+ while (item) {
+ if (item.expanded)
+ item.collapse();
+ item = item.traverseNextTreeElement(false, this, true);
+ }
+ }
+
+ expand()
+ {
+ if (this.expanded && !this._shouldRefreshChildren && this._childrenListNode)
+ return;
+
+ // Set this before onpopulate. Since onpopulate can add elements and call onadd, this makes
+ // sure the expanded flag is true before calling those functions. This prevents the possibility
+ // of an infinite loop if onpopulate or onadd were to call expand.
+
+ this.expanded = true;
+ if (this.treeOutline)
+ this.treeOutline._treeElementsExpandedState[this.identifier] = true;
+
+ // If there are no children, return. We will be expanded once we have children.
+ if (!this.hasChildren)
+ return;
+
+ if (this.treeOutline && (!this._childrenListNode || this._shouldRefreshChildren)) {
+ if (this._childrenListNode && this._childrenListNode.parentNode)
+ this._childrenListNode.parentNode.removeChild(this._childrenListNode);
+
+ this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");
+ this._childrenListNode.parentTreeElement = this;
+ this._childrenListNode.classList.add("children");
+
+ if (this.hidden)
+ this._childrenListNode.classList.add("hidden");
+
+ this.onpopulate();
+
+ for (var i = 0; i < this.children.length; ++i)
+ this.children[i]._attach();
+
+ delete this._shouldRefreshChildren;
+ }
+
+ if (this._listItemNode) {
+ this._listItemNode.classList.add("expanded");
+ if (this._childrenListNode && this._childrenListNode.parentNode !== this._listItemNode.parentNode)
+ this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling);
+ }
+
+ if (this._childrenListNode)
+ this._childrenListNode.classList.add("expanded");
+
+ if (this.onexpand)
+ this.onexpand(this);
+
+ if (this.treeOutline && this.treeOutline.onexpand)
+ this.treeOutline.onexpand(this);
+ }
+
+ expandRecursively(maxDepth)
+ {
+ var item = this;
+ var info = {};
+ var depth = 0;
+
+ // The Inspector uses TreeOutlines to represents object properties, so recursive expansion
+ // in some case can be infinite, since JavaScript objects can hold circular references.
+ // So default to a recursion cap of 3 levels, since that gives fairly good results.
+ if (maxDepth === undefined)
+ maxDepth = 3;
+
+ while (item) {
+ if (depth < maxDepth)
+ item.expand();
+ item = item.traverseNextTreeElement(false, this, (depth >= maxDepth), info);
+ depth += info.depthChange;
+ }
+ }
+
+ hasAncestor(ancestor)
+ {
+ if (!ancestor)
+ return false;
+
+ var currentNode = this.parent;
+ while (currentNode) {
+ if (ancestor === currentNode)
+ return true;
+ currentNode = currentNode.parent;
+ }
+
+ return false;
+ }
+
+ reveal()
+ {
+ var currentAncestor = this.parent;
+ while (currentAncestor && !currentAncestor.root) {
+ if (!currentAncestor.expanded)
+ currentAncestor.expand();
+ currentAncestor = currentAncestor.parent;
+ }
+
+ if (this.onreveal)
+ this.onreveal(this);
+ }
+
+ revealed()
+ {
if (this.hidden)
- this._childrenListNode.classList.add("hidden");
-
- this.onpopulate();
-
- for (var i = 0; i < this.children.length; ++i)
- this.children[i]._attach();
-
- delete this._shouldRefreshChildren;
- }
-
- if (this._listItemNode) {
- this._listItemNode.classList.add("expanded");
- if (this._childrenListNode && this._childrenListNode.parentNode !== this._listItemNode.parentNode)
- this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling);
- }
-
- if (this._childrenListNode)
- this._childrenListNode.classList.add("expanded");
-
- if (this.onexpand)
- this.onexpand(this);
-
- if (this.treeOutline && this.treeOutline.onexpand)
- this.treeOutline.onexpand(this);
-};
-
-TreeElement.prototype.expandRecursively = function(maxDepth)
-{
- var item = this;
- var info = {};
- var depth = 0;
-
- // The Inspector uses TreeOutlines to represents object properties, so recursive expansion
- // in some case can be infinite, since JavaScript objects can hold circular references.
- // So default to a recursion cap of 3 levels, since that gives fairly good results.
- if (maxDepth === undefined)
- maxDepth = 3;
-
- while (item) {
- if (depth < maxDepth)
- item.expand();
- item = item.traverseNextTreeElement(false, this, (depth >= maxDepth), info);
- depth += info.depthChange;
- }
-};
-
-TreeElement.prototype.hasAncestor = function(ancestor) {
- if (!ancestor)
- return false;
-
- var currentNode = this.parent;
- while (currentNode) {
- if (ancestor === currentNode)
- return true;
- currentNode = currentNode.parent;
- }
-
- return false;
-};
-
-TreeElement.prototype.reveal = function()
-{
- var currentAncestor = this.parent;
- while (currentAncestor && !currentAncestor.root) {
- if (!currentAncestor.expanded)
- currentAncestor.expand();
- currentAncestor = currentAncestor.parent;
- }
-
- if (this.onreveal)
- this.onreveal(this);
-};
-
-TreeElement.prototype.revealed = function()
-{
- if (this.hidden)
- return false;
-
- var currentAncestor = this.parent;
- while (currentAncestor && !currentAncestor.root) {
- if (!currentAncestor.expanded)
return false;
- if (currentAncestor.hidden)
- return false;
- currentAncestor = currentAncestor.parent;
+
+ var currentAncestor = this.parent;
+ while (currentAncestor && !currentAncestor.root) {
+ if (!currentAncestor.expanded)
+ return false;
+ if (currentAncestor.hidden)
+ return false;
+ currentAncestor = currentAncestor.parent;
+ }
+
+ return true;
}
- return true;
-};
+ selectOnMouseDown(event)
+ {
+ this.select(false, true);
+ }
-TreeElement.prototype.selectOnMouseDown = function(event)
-{
- this.select(false, true);
-};
+ select(omitFocus, selectedByUser, suppressOnSelect, suppressOnDeselect)
+ {
+ if (!this.treeOutline || !this.selectable)
+ return;
-TreeElement.prototype.select = function(omitFocus, selectedByUser, suppressOnSelect, suppressOnDeselect)
-{
- if (!this.treeOutline || !this.selectable)
- return;
+ if (this.selected && !this.treeOutline.allowsRepeatSelection)
+ return;
- if (this.selected && !this.treeOutline.allowsRepeatSelection)
- return;
+ if (!omitFocus)
+ this.treeOutline._childrenListNode.focus();
- if (!omitFocus)
- this.treeOutline._childrenListNode.focus();
+ // Focusing on another node may detach "this" from tree.
+ if (!this.treeOutline)
+ return;
- // Focusing on another node may detach "this" from tree.
- if (!this.treeOutline)
- return;
+ this.treeOutline.processingSelectionChange = true;
- this.treeOutline.processingSelectionChange = true;
+ if (!this.selected) {
+ if (this.treeOutline.selectedTreeElement)
+ this.treeOutline.selectedTreeElement.deselect(suppressOnDeselect);
- if (!this.selected) {
- if (this.treeOutline.selectedTreeElement)
- this.treeOutline.selectedTreeElement.deselect(suppressOnDeselect);
+ this.selected = true;
+ this.treeOutline.selectedTreeElement = this;
- this.selected = true;
- this.treeOutline.selectedTreeElement = this;
+ if (this._listItemNode)
+ this._listItemNode.classList.add("selected");
+ }
+
+ if (this.onselect && !suppressOnSelect)
+ this.onselect(this, selectedByUser);
+
+ if (this.treeOutline.onselect && !suppressOnSelect)
+ this.treeOutline.onselect(this, selectedByUser);
+
+ delete this.treeOutline.processingSelectionChange;
+ }
+
+ revealAndSelect(omitFocus, selectedByUser, suppressOnSelect, suppressOnDeselect)
+ {
+ this.reveal();
+ this.select(omitFocus, selectedByUser, suppressOnSelect, suppressOnDeselect);
+ }
+
+ deselect(suppressOnDeselect)
+ {
+ if (!this.treeOutline || this.treeOutline.selectedTreeElement !== this || !this.selected)
+ return false;
+
+ this.selected = false;
+ this.treeOutline.selectedTreeElement = null;
if (this._listItemNode)
- this._listItemNode.classList.add("selected");
+ this._listItemNode.classList.remove("selected");
+
+ if (this.ondeselect && !suppressOnDeselect)
+ this.ondeselect(this);
+
+ if (this.treeOutline.ondeselect && !suppressOnDeselect)
+ this.treeOutline.ondeselect(this);
+
+ return true;
}
- if (this.onselect && !suppressOnSelect)
- this.onselect(this, selectedByUser);
+ onpopulate()
+ {
+ // Overriden by subclasses.
+ }
- if (this.treeOutline.onselect && !suppressOnSelect)
- this.treeOutline.onselect(this, selectedByUser);
+ traverseNextTreeElement(skipUnrevealed, stayWithin, dontPopulate, info)
+ {
+ if (!dontPopulate && this.hasChildren)
+ this.onpopulate.call(this); // FIXME: This shouldn't need to use call, but this is working around a JSC bug. https://webkit.org/b/74811
- delete this.treeOutline.processingSelectionChange;
-};
-
-TreeElement.prototype.revealAndSelect = function(omitFocus, selectedByUser, suppressOnSelect, suppressOnDeselect)
-{
- this.reveal();
- this.select(omitFocus, selectedByUser, suppressOnSelect, suppressOnDeselect);
-};
-
-TreeElement.prototype.deselect = function(suppressOnDeselect)
-{
- if (!this.treeOutline || this.treeOutline.selectedTreeElement !== this || !this.selected)
- return false;
-
- this.selected = false;
- this.treeOutline.selectedTreeElement = null;
-
- if (this._listItemNode)
- this._listItemNode.classList.remove("selected");
-
- if (this.ondeselect && !suppressOnDeselect)
- this.ondeselect(this);
-
- if (this.treeOutline.ondeselect && !suppressOnDeselect)
- this.treeOutline.ondeselect(this);
-
- return true;
-};
-
-TreeElement.prototype.onpopulate = function()
-{
- // Overriden by subclasses.
-};
-
-TreeElement.prototype.traverseNextTreeElement = function(skipUnrevealed, stayWithin, dontPopulate, info)
-{
- if (!dontPopulate && this.hasChildren)
- this.onpopulate.call(this); // FIXME: This shouldn't need to use call, but this is working around a JSC bug. https://webkit.org/b/74811
-
- if (info)
- info.depthChange = 0;
-
- var element = skipUnrevealed ? (this.revealed() ? this.children[0] : null) : this.children[0];
- if (element && (!skipUnrevealed || (skipUnrevealed && this.expanded))) {
if (info)
- info.depthChange = 1;
- return element;
+ info.depthChange = 0;
+
+ var element = skipUnrevealed ? (this.revealed() ? this.children[0] : null) : this.children[0];
+ if (element && (!skipUnrevealed || (skipUnrevealed && this.expanded))) {
+ if (info)
+ info.depthChange = 1;
+ return element;
+ }
+
+ if (this === stayWithin)
+ return null;
+
+ element = skipUnrevealed ? (this.revealed() ? this.nextSibling : null) : this.nextSibling;
+ if (element)
+ return element;
+
+ element = this;
+ while (element && !element.root && !(skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling) && element.parent !== stayWithin) {
+ if (info)
+ info.depthChange -= 1;
+ element = element.parent;
+ }
+
+ if (!element)
+ return null;
+
+ return (skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling);
}
- if (this === stayWithin)
- return null;
-
- element = skipUnrevealed ? (this.revealed() ? this.nextSibling : null) : this.nextSibling;
- if (element)
- return element;
-
- element = this;
- while (element && !element.root && !(skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling) && element.parent !== stayWithin) {
- if (info)
- info.depthChange -= 1;
- element = element.parent;
- }
-
- if (!element)
- return null;
-
- return (skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling);
-};
-
-TreeElement.prototype.traversePreviousTreeElement = function(skipUnrevealed, dontPopulate)
-{
- var element = skipUnrevealed ? (this.revealed() ? this.previousSibling : null) : this.previousSibling;
- if (!dontPopulate && element && element.hasChildren)
- element.onpopulate();
-
- while (element && (skipUnrevealed ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1])) {
- if (!dontPopulate && element.hasChildren)
+ traversePreviousTreeElement(skipUnrevealed, dontPopulate)
+ {
+ var element = skipUnrevealed ? (this.revealed() ? this.previousSibling : null) : this.previousSibling;
+ if (!dontPopulate && element && element.hasChildren)
element.onpopulate();
- element = (skipUnrevealed ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1]);
+
+ while (element && (skipUnrevealed ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1])) {
+ if (!dontPopulate && element.hasChildren)
+ element.onpopulate();
+ element = (skipUnrevealed ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1]);
+ }
+
+ if (element)
+ return element;
+
+ if (!this.parent || this.parent.root)
+ return null;
+
+ return this.parent;
}
- if (element)
- return element;
+ isEventWithinDisclosureTriangle(event)
+ {
+ if (!document.contains(this._listItemNode))
+ return false;
- if (!this.parent || this.parent.root)
- return null;
-
- return this.parent;
+ // FIXME: We should not use getComputedStyle(). For that we need to get rid of using ::before for disclosure triangle. (http://webk.it/74446)
+ var computedLeftPadding = window.getComputedStyle(this._listItemNode).getPropertyCSSValue("padding-left").getFloatValue(CSSPrimitiveValue.CSS_PX);
+ var left = this._listItemNode.totalOffsetLeft + computedLeftPadding;
+ return event.pageX >= left && event.pageX <= left + this.arrowToggleWidth && this.hasChildren;
+ }
};
-
-TreeElement.prototype.isEventWithinDisclosureTriangle = function(event)
-{
- if (!document.contains(this._listItemNode))
- return false;
-
- // FIXME: We should not use getComputedStyle(). For that we need to get rid of using ::before for disclosure triangle. (http://webk.it/74446)
- var computedLeftPadding = window.getComputedStyle(this._listItemNode).getPropertyCSSValue("padding-left").getFloatValue(CSSPrimitiveValue.CSS_PX);
- var left = this._listItemNode.totalOffsetLeft + computedLeftPadding;
- return event.pageX >= left && event.pageX <= left + this.arrowToggleWidth && this.hasChildren;
-};
-
-TreeElement.prototype.__proto__ = WebInspector.Object.prototype;