Title: [203114] trunk/Source/WebInspectorUI
Revision
203114
Author
[email protected]
Date
2016-07-12 06:05:13 -0700 (Tue, 12 Jul 2016)

Log Message

Web Inspector: Use separate files for TreeOutline/TreeElement and DataGrid/DataGridNode
https://bugs.webkit.org/show_bug.cgi?id=159659

Patch by Joseph Pecoraro <[email protected]> on 2016-07-12
Reviewed by Timothy Hatcher.

* UserInterface/Main.html:
* UserInterface/Views/DataGrid.js:
* UserInterface/Views/DataGridNode.js: Added.
* UserInterface/Views/TreeElement.js: Added.
* UserInterface/Views/TreeOutline.js:
Extra the component classes to their own file.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebInspectorUI/ChangeLog (203113 => 203114)


--- trunk/Source/WebInspectorUI/ChangeLog	2016-07-12 13:04:38 UTC (rev 203113)
+++ trunk/Source/WebInspectorUI/ChangeLog	2016-07-12 13:05:13 UTC (rev 203114)
@@ -1,3 +1,17 @@
+2016-07-12  Joseph Pecoraro  <[email protected]>
+
+        Web Inspector: Use separate files for TreeOutline/TreeElement and DataGrid/DataGridNode
+        https://bugs.webkit.org/show_bug.cgi?id=159659
+
+        Reviewed by Timothy Hatcher.
+
+        * UserInterface/Main.html:
+        * UserInterface/Views/DataGrid.js:
+        * UserInterface/Views/DataGridNode.js: Added.
+        * UserInterface/Views/TreeElement.js: Added.
+        * UserInterface/Views/TreeOutline.js:
+        Extra the component classes to their own file.
+
 2016-07-11  Joseph Pecoraro  <[email protected]>
 
         Web Inspector: ProfileView sometimes shows Top Functions data despite Top Functions being disabled

Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (203113 => 203114)


--- trunk/Source/WebInspectorUI/UserInterface/Main.html	2016-07-12 13:04:38 UTC (rev 203113)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html	2016-07-12 13:05:13 UTC (rev 203114)
@@ -386,13 +386,14 @@
     <script src=""
 
     <script src=""
-    <script src=""
 
     <script src=""
     <script src=""
     <script src=""
     <script src=""
+    <script src=""
     <script src=""
+    <script src=""
     <script src=""
     <script src=""
     <script src=""
@@ -403,6 +404,7 @@
     <script src=""
     <script src=""
     <script src=""
+    <script src=""
     <script src=""
 
     <script src=""

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js (203113 => 203114)


--- trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js	2016-07-12 13:04:38 UTC (rev 203113)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js	2016-07-12 13:05:13 UTC (rev 203114)
@@ -1,26 +1,26 @@
 /*
- * Copyright (C) 2008, 2013-2015 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2013-2016 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
- *        notice, this list of conditions and the following disclaimer.
+ *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
- *        notice, this list of conditions and the following disclaimer in the
- *        documentation and/or other materials provided with the distribution.
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
  *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.         IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 WebInspector.DataGrid = class DataGrid extends WebInspector.View
@@ -962,7 +962,7 @@
                 resizer = this.resizers[i] = new WebInspector.Resizer(WebInspector.Resizer.RuleOrientation.Vertical, this);
                 this.element.appendChild(resizer.element);
             }
-            
+
             left = columnWidths[i];
 
             if (this._isColumnVisible(this.orderedColumns[i])) {
@@ -1916,729 +1916,3 @@
 WebInspector.DataGrid.SortColumnAscendingStyleClassName = "sort-ascending";
 WebInspector.DataGrid.SortColumnDescendingStyleClassName = "sort-descending";
 WebInspector.DataGrid.SortableColumnStyleClassName = "sortable";
-
-WebInspector.DataGridNode = class DataGridNode extends WebInspector.Object
-{
-    constructor(data, hasChildren)
-    {
-        super();
-
-        this._expanded = false;
-        this._hidden = false;
-        this._selected = false;
-        this._copyable = true;
-        this._shouldRefreshChildren = true;
-        this._data = data || {};
-        this.hasChildren = hasChildren || false;
-        this.children = [];
-        this.dataGrid = null;
-        this.parent = null;
-        this.previousSibling = null;
-        this.nextSibling = null;
-        this.disclosureToggleWidth = 10;
-    }
-
-    get hidden()
-    {
-        return this._hidden;
-    }
-
-    set hidden(x)
-    {
-        x = !!x;
-
-        if (this._hidden === x)
-            return;
-
-        this._hidden = x;
-        if (this._element)
-            this._element.classList.toggle("hidden", this._hidden);
-
-        if (this.dataGrid)
-            this.dataGrid._noteRowsChanged();
-    }
-
-    get selectable()
-    {
-        return this._element && !this._hidden;
-    }
-
-    get copyable()
-    {
-        return this._copyable;
-    }
-
-    set copyable(x)
-    {
-        this._copyable = x;
-    }
-
-    get element()
-    {
-        if (this._element)
-            return this._element;
-
-        if (!this.dataGrid)
-            return null;
-
-        this._element = document.createElement("tr");
-        this._element._dataGridNode = this;
-
-        if (this.hasChildren)
-            this._element.classList.add("parent");
-        if (this.expanded)
-            this._element.classList.add("expanded");
-        if (this.selected)
-            this._element.classList.add("selected");
-        if (this.revealed)
-            this._element.classList.add("revealed");
-        if (this._hidden)
-            this._element.classList.add("hidden");
-
-        this.createCells();
-        return this._element;
-    }
-
-    createCells()
-    {
-        for (var columnIdentifier of this.dataGrid.orderedColumns)
-            this._element.appendChild(this.createCell(columnIdentifier));
-    }
-
-    refreshIfNeeded()
-    {
-        if (!this._needsRefresh)
-            return;
-
-        this._needsRefresh = false;
-
-        this.refresh();
-    }
-
-    needsRefresh()
-    {
-        this._needsRefresh = true;
-
-        if (!this._revealed)
-            return;
-
-        if (this._scheduledRefreshIdentifier)
-            return;
-
-        this._scheduledRefreshIdentifier = requestAnimationFrame(this.refresh.bind(this));
-    }
-
-    get data()
-    {
-        return this._data;
-    }
-
-    set data(x)
-    {
-        console.assert(typeof x === "object", "Data should be an object.");
-
-        x = x || {};
-
-        if (Object.shallowEqual(this._data, x))
-            return;
-
-        this._data = x;
-        this.needsRefresh();
-    }
-
-    get filterableData()
-    {
-        if (this._cachedFilterableData)
-            return this._cachedFilterableData;
-
-        this._cachedFilterableData = [];
-
-        for (let column of this.dataGrid.columns.values()) {
-            if (column.hidden)
-                continue;
-
-            let value = this.filterableDataForColumn(column.columnIdentifier);
-            if (!value)
-                continue;
-
-            if (!(value instanceof Array))
-                value = [value];
-
-            if (!value.length)
-                continue;
-
-            this._cachedFilterableData = this._cachedFilterableData.concat(value);
-        }
-
-        return this._cachedFilterableData;
-    }
-
-    get revealed()
-    {
-        if ("_revealed" in this)
-            return this._revealed;
-
-        var currentAncestor = this.parent;
-        while (currentAncestor && !currentAncestor.root) {
-            if (!currentAncestor.expanded) {
-                this._revealed = false;
-                return false;
-            }
-
-            currentAncestor = currentAncestor.parent;
-        }
-
-        this._revealed = true;
-        return true;
-    }
-
-    set hasChildren(x)
-    {
-        if (this._hasChildren === x)
-            return;
-
-        this._hasChildren = x;
-
-        if (!this._element)
-            return;
-
-        if (this._hasChildren) {
-            this._element.classList.add("parent");
-            if (this.expanded)
-                this._element.classList.add("expanded");
-        } else
-            this._element.classList.remove("parent", "expanded");
-    }
-
-    get hasChildren()
-    {
-        return this._hasChildren;
-    }
-
-    set revealed(x)
-    {
-        if (this._revealed === x)
-            return;
-
-        this._revealed = x;
-
-        if (this._element) {
-            if (this._revealed)
-                this._element.classList.add("revealed");
-            else
-                this._element.classList.remove("revealed");
-        }
-
-        this.refreshIfNeeded();
-
-        for (var i = 0; i < this.children.length; ++i)
-            this.children[i].revealed = x && this.expanded;
-    }
-
-    get depth()
-    {
-        if ("_depth" in this)
-            return this._depth;
-        if (this.parent && !this.parent.root)
-            this._depth = this.parent.depth + 1;
-        else
-            this._depth = 0;
-        return this._depth;
-    }
-
-    get leftPadding()
-    {
-        if (typeof(this._leftPadding) === "number")
-            return this._leftPadding;
-
-        this._leftPadding = this.depth * this.dataGrid.indentWidth;
-        return this._leftPadding;
-    }
-
-    get shouldRefreshChildren()
-    {
-        return this._shouldRefreshChildren;
-    }
-
-    set shouldRefreshChildren(x)
-    {
-        this._shouldRefreshChildren = x;
-        if (x && this.expanded)
-            this.expand();
-    }
-
-    get selected()
-    {
-        return this._selected;
-    }
-
-    set selected(x)
-    {
-        if (x)
-            this.select();
-        else
-            this.deselect();
-    }
-
-    get expanded()
-    {
-        return this._expanded;
-    }
-
-    set expanded(x)
-    {
-        if (x)
-            this.expand();
-        else
-            this.collapse();
-    }
-
-    hasAncestor(ancestor)
-    {
-        if (!ancestor)
-            return false;
-
-        let currentAncestor = this.parent;
-        while (currentAncestor) {
-            if (ancestor === currentAncestor)
-                return true;
-
-            currentAncestor = currentAncestor.parent;
-        }
-
-        return false;
-    }
-
-    refresh()
-    {
-        if (!this._element || !this.dataGrid)
-            return;
-
-        if (this._scheduledRefreshIdentifier) {
-            cancelAnimationFrame(this._scheduledRefreshIdentifier);
-            this._scheduledRefreshIdentifier = undefined;
-        }
-
-        this._cachedFilterableData = null;
-        this._needsRefresh = false;
-
-        this._element.removeChildren();
-        this.createCells();
-    }
-
-    refreshRecursively()
-    {
-        this.refresh();
-        this.forEachChildInSubtree((node) => node.refresh());
-    }
-
-    updateLayout()
-    {
-        // Implemented by subclasses if needed.
-    }
-
-    createCell(columnIdentifier)
-    {
-        var cellElement = document.createElement("td");
-        cellElement.className = columnIdentifier + "-column";
-        cellElement.__columnIdentifier = columnIdentifier;
-
-        var column = this.dataGrid.columns.get(columnIdentifier);
-
-        if (column["aligned"])
-            cellElement.classList.add(column["aligned"]);
-
-        if (column["group"])
-            cellElement.classList.add("column-group-" + column["group"]);
-
-        var div = cellElement.createChild("div", "cell-content");
-        var content = this.createCellContent(columnIdentifier, cellElement);
-        div.append(content);
-
-        if (column["icon"]) {
-            let iconElement = document.createElement("div");
-            iconElement.classList.add("icon");
-            div.insertBefore(iconElement, div.firstChild);
-        }
-
-        if (columnIdentifier === this.dataGrid.disclosureColumnIdentifier) {
-            cellElement.classList.add("disclosure");
-            if (this.leftPadding)
-                cellElement.style.setProperty("padding-left", this.leftPadding + "px");
-        }
-
-        return cellElement;
-    }
-
-    createCellContent(columnIdentifier)
-    {
-        return this.data[columnIdentifier] || "\u200b"; // Zero width space to keep the cell from collapsing.
-    }
-
-    elementWithColumnIdentifier(columnIdentifier)
-    {
-        if (!this.dataGrid)
-            return null;
-
-        let index = this.dataGrid.orderedColumns.indexOf(columnIdentifier);
-        if (index === -1)
-            return null;
-
-        return this.element.children[index];
-    }
-
-    // Share these functions with DataGrid. They are written to work with a DataGridNode this object.
-    appendChild() { return WebInspector.DataGrid.prototype.appendChild.apply(this, arguments); }
-    insertChild() { return WebInspector.DataGrid.prototype.insertChild.apply(this, arguments); }
-    removeChild() { return WebInspector.DataGrid.prototype.removeChild.apply(this, arguments); }
-    removeChildren() { return WebInspector.DataGrid.prototype.removeChildren.apply(this, arguments); }
-    removeChildrenRecursive() { return WebInspector.DataGrid.prototype.removeChildrenRecursive.apply(this, arguments); }
-
-    _recalculateSiblings(myIndex)
-    {
-        if (!this.parent)
-            return;
-
-        var previousChild = (myIndex > 0 ? this.parent.children[myIndex - 1] : null);
-
-        if (previousChild) {
-            previousChild.nextSibling = this;
-            this.previousSibling = previousChild;
-        } else
-            this.previousSibling = null;
-
-        var nextChild = this.parent.children[myIndex + 1];
-
-        if (nextChild) {
-            nextChild.previousSibling = this;
-            this.nextSibling = nextChild;
-        } else
-            this.nextSibling = null;
-    }
-
-    collapse()
-    {
-        if (this._element)
-            this._element.classList.remove("expanded");
-
-        this._expanded = false;
-
-        for (var i = 0; i < this.children.length; ++i)
-            this.children[i].revealed = false;
-
-        this.dispatchEventToListeners("collapsed");
-
-        if (this.dataGrid) {
-            this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Event.CollapsedNode, {dataGridNode: this});
-            this.dataGrid._noteRowsChanged();
-        }
-    }
-
-    collapseRecursively()
-    {
-        var item = this;
-        while (item) {
-            if (item.expanded)
-                item.collapse();
-            item = item.traverseNextNode(false, this, true);
-        }
-    }
-
-    expand()
-    {
-        if (!this.hasChildren || this.expanded)
-            return;
-
-        if (this.revealed && !this._shouldRefreshChildren)
-            for (var i = 0; i < this.children.length; ++i)
-                this.children[i].revealed = true;
-
-        if (this._shouldRefreshChildren) {
-            for (var i = 0; i < this.children.length; ++i)
-                this.children[i]._detach();
-
-            this.dispatchEventToListeners("populate");
-
-            if (this._attached) {
-                for (var i = 0; i < this.children.length; ++i) {
-                    var child = this.children[i];
-                    if (this.revealed)
-                        child.revealed = true;
-                    child._attach();
-                }
-            }
-
-            this._shouldRefreshChildren = false;
-        }
-
-        if (this._element)
-            this._element.classList.add("expanded");
-
-        this._expanded = true;
-
-        this.dispatchEventToListeners("expanded");
-
-        if (this.dataGrid) {
-            this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Event.ExpandedNode, {dataGridNode: this});
-            this.dataGrid._noteRowsChanged();
-        }
-    }
-
-    expandRecursively()
-    {
-        var item = this;
-        while (item) {
-            item.expand();
-            item = item.traverseNextNode(false, this);
-        }
-    }
-
-    forEachImmediateChild(callback)
-    {
-        for (let node of this.children)
-            callback(node);
-    }
-
-    forEachChildInSubtree(callback)
-    {
-        let node = this.traverseNextNode(false, this, true);
-        while (node) {
-            callback(node);
-            node = node.traverseNextNode(false, this, true);
-        }
-    }
-
-    isInSubtreeOfNode(baseNode)
-    {
-        let node = baseNode;
-        while (node) {
-            if (node === this)
-                return true;
-            node = node.traverseNextNode(false, baseNode, true);
-        }
-        return false;
-    }
-
-    reveal()
-    {
-        var currentAncestor = this.parent;
-        while (currentAncestor && !currentAncestor.root) {
-            if (!currentAncestor.expanded)
-                currentAncestor.expand();
-            currentAncestor = currentAncestor.parent;
-        }
-
-        this.element.scrollIntoViewIfNeeded(false);
-
-        this.dispatchEventToListeners("revealed");
-    }
-
-    select(suppressSelectedEvent)
-    {
-        if (!this.dataGrid || !this.selectable || this.selected)
-            return;
-
-        let oldSelectedNode = this.dataGrid.selectedNode;
-        if (oldSelectedNode)
-            oldSelectedNode.deselect(true);
-
-        this._selected = true;
-        this.dataGrid.selectedNode = this;
-
-        if (this._element)
-            this._element.classList.add("selected");
-
-        if (!suppressSelectedEvent)
-            this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Event.SelectedNodeChanged, {oldSelectedNode});
-    }
-
-    revealAndSelect()
-    {
-        this.reveal();
-        this.select();
-    }
-
-    deselect(suppressDeselectedEvent)
-    {
-        if (!this.dataGrid || this.dataGrid.selectedNode !== this || !this.selected)
-            return;
-
-        this._selected = false;
-        this.dataGrid.selectedNode = null;
-
-        if (this._element)
-            this._element.classList.remove("selected");
-
-        if (!suppressDeselectedEvent)
-            this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Event.SelectedNodeChanged, {oldSelectedNode: this});
-    }
-
-    traverseNextNode(skipHidden, stayWithin, dontPopulate, info)
-    {
-        if (!dontPopulate && this.hasChildren)
-            this.dispatchEventToListeners("populate");
-
-        if (info)
-            info.depthChange = 0;
-
-        var node = (!skipHidden || this.revealed) ? this.children[0] : null;
-        if (node && (!skipHidden || this.expanded)) {
-            if (info)
-                info.depthChange = 1;
-            return node;
-        }
-
-        if (this === stayWithin)
-            return null;
-
-        node = (!skipHidden || this.revealed) ? this.nextSibling : null;
-        if (node)
-            return node;
-
-        node = this;
-        while (node && !node.root && !((!skipHidden || node.revealed) ? node.nextSibling : null) && node.parent !== stayWithin) {
-            if (info)
-                info.depthChange -= 1;
-            node = node.parent;
-        }
-
-        if (!node)
-            return null;
-
-        return (!skipHidden || node.revealed) ? node.nextSibling : null;
-    }
-
-    traversePreviousNode(skipHidden, dontPopulate)
-    {
-        var node = (!skipHidden || this.revealed) ? this.previousSibling : null;
-        if (!dontPopulate && node && node.hasChildren)
-            node.dispatchEventToListeners("populate");
-
-        while (node && ((!skipHidden || (node.revealed && node.expanded)) ? node.children.lastValue : null)) {
-            if (!dontPopulate && node.hasChildren)
-                node.dispatchEventToListeners("populate");
-            node = ((!skipHidden || (node.revealed && node.expanded)) ? node.children.lastValue : null);
-        }
-
-        if (node)
-            return node;
-
-        if (!this.parent || this.parent.root)
-            return null;
-
-        return this.parent;
-    }
-
-    isEventWithinDisclosureTriangle(event)
-    {
-        if (!this.hasChildren)
-            return false;
-        let cell = event.target.enclosingNodeOrSelfWithNodeName("td");
-        if (!cell || !cell.classList.contains("disclosure"))
-            return false;
-
-        let computedLeftPadding = window.getComputedStyle(cell).getPropertyCSSValue("padding-left").getFloatValue(CSSPrimitiveValue.CSS_PX);
-        let left = cell.totalOffsetLeft + computedLeftPadding;
-        return event.pageX >= left && event.pageX <= left + this.disclosureToggleWidth;
-    }
-
-    _attach()
-    {
-        if (!this.dataGrid || this._attached)
-            return;
-
-        this._attached = true;
-
-        let insertionIndex = -1;
-
-        if (!this.isPlaceholderNode) {
-            var previousGridNode = this.traversePreviousNode(true, true);
-            insertionIndex = this.dataGrid._rows.indexOf(previousGridNode);
-            if (insertionIndex === -1)
-                insertionIndex = 0;
-            else
-                insertionIndex++;
-        }
-
-        if (insertionIndex === -1)
-            this.dataGrid._rows.push(this);
-        else
-            this.dataGrid._rows.insertAtIndex(this, insertionIndex);
-
-        this.dataGrid._noteRowsChanged();
-
-        if (this.expanded) {
-            for (var i = 0; i < this.children.length; ++i)
-                this.children[i]._attach();
-        }
-    }
-
-    _detach()
-    {
-        if (!this._attached)
-            return;
-
-        this._attached = false;
-
-        this.dataGrid._rows.remove(this, true);
-        this.dataGrid._noteRowRemoved(this);
-
-        for (var i = 0; i < this.children.length; ++i)
-            this.children[i]._detach();
-    }
-
-    savePosition()
-    {
-        if (this._savedPosition)
-            return;
-
-        console.assert(this.parent);
-        if (!this.parent)
-            return;
-
-        this._savedPosition = {
-            parent: this.parent,
-            index: this.parent.children.indexOf(this)
-        };
-    }
-
-    restorePosition()
-    {
-        if (!this._savedPosition)
-            return;
-
-        if (this.parent !== this._savedPosition.parent)
-            this._savedPosition.parent.insertChild(this, this._savedPosition.index);
-
-        this._savedPosition = null;
-    }
-
-    appendContextMenuItems(contextMenu)
-    {
-        // Subclasses may override
-        return null;
-    }
-
-    // Protected
-
-    filterableDataForColumn(columnIdentifier)
-    {
-        let value = this.data[columnIdentifier];
-        return typeof value === "string" ? value : null;
-    }
-};
-
-// Used to create a new table row when entering new data by editing cells.
-WebInspector.PlaceholderDataGridNode = class PlaceholderDataGridNode extends WebInspector.DataGridNode
-{
-    constructor(data)
-    {
-        super(data, false);
-        this.isPlaceholderNode = true;
-    }
-
-    makeNormal()
-    {
-        this.isPlaceholderNode = false;
-    }
-};

Added: trunk/Source/WebInspectorUI/UserInterface/Views/DataGridNode.js (0 => 203114)


--- trunk/Source/WebInspectorUI/UserInterface/Views/DataGridNode.js	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DataGridNode.js	2016-07-12 13:05:13 UTC (rev 203114)
@@ -0,0 +1,750 @@
+/*
+ * Copyright (C) 2008, 2013-2016 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.DataGridNode = class DataGridNode extends WebInspector.Object
+{
+    constructor(data, hasChildren)
+    {
+        super();
+
+        this._expanded = false;
+        this._hidden = false;
+        this._selected = false;
+        this._copyable = true;
+        this._shouldRefreshChildren = true;
+        this._data = data || {};
+        this.hasChildren = hasChildren || false;
+        this.children = [];
+        this.dataGrid = null;
+        this.parent = null;
+        this.previousSibling = null;
+        this.nextSibling = null;
+        this.disclosureToggleWidth = 10;
+    }
+
+    get hidden()
+    {
+        return this._hidden;
+    }
+
+    set hidden(x)
+    {
+        x = !!x;
+
+        if (this._hidden === x)
+            return;
+
+        this._hidden = x;
+        if (this._element)
+            this._element.classList.toggle("hidden", this._hidden);
+
+        if (this.dataGrid)
+            this.dataGrid._noteRowsChanged();
+    }
+
+    get selectable()
+    {
+        return this._element && !this._hidden;
+    }
+
+    get copyable()
+    {
+        return this._copyable;
+    }
+
+    set copyable(x)
+    {
+        this._copyable = x;
+    }
+
+    get element()
+    {
+        if (this._element)
+            return this._element;
+
+        if (!this.dataGrid)
+            return null;
+
+        this._element = document.createElement("tr");
+        this._element._dataGridNode = this;
+
+        if (this.hasChildren)
+            this._element.classList.add("parent");
+        if (this.expanded)
+            this._element.classList.add("expanded");
+        if (this.selected)
+            this._element.classList.add("selected");
+        if (this.revealed)
+            this._element.classList.add("revealed");
+        if (this._hidden)
+            this._element.classList.add("hidden");
+
+        this.createCells();
+        return this._element;
+    }
+
+    createCells()
+    {
+        for (var columnIdentifier of this.dataGrid.orderedColumns)
+            this._element.appendChild(this.createCell(columnIdentifier));
+    }
+
+    refreshIfNeeded()
+    {
+        if (!this._needsRefresh)
+            return;
+
+        this._needsRefresh = false;
+
+        this.refresh();
+    }
+
+    needsRefresh()
+    {
+        this._needsRefresh = true;
+
+        if (!this._revealed)
+            return;
+
+        if (this._scheduledRefreshIdentifier)
+            return;
+
+        this._scheduledRefreshIdentifier = requestAnimationFrame(this.refresh.bind(this));
+    }
+
+    get data()
+    {
+        return this._data;
+    }
+
+    set data(x)
+    {
+        console.assert(typeof x === "object", "Data should be an object.");
+
+        x = x || {};
+
+        if (Object.shallowEqual(this._data, x))
+            return;
+
+        this._data = x;
+        this.needsRefresh();
+    }
+
+    get filterableData()
+    {
+        if (this._cachedFilterableData)
+            return this._cachedFilterableData;
+
+        this._cachedFilterableData = [];
+
+        for (let column of this.dataGrid.columns.values()) {
+            if (column.hidden)
+                continue;
+
+            let value = this.filterableDataForColumn(column.columnIdentifier);
+            if (!value)
+                continue;
+
+            if (!(value instanceof Array))
+                value = [value];
+
+            if (!value.length)
+                continue;
+
+            this._cachedFilterableData = this._cachedFilterableData.concat(value);
+        }
+
+        return this._cachedFilterableData;
+    }
+
+    get revealed()
+    {
+        if ("_revealed" in this)
+            return this._revealed;
+
+        var currentAncestor = this.parent;
+        while (currentAncestor && !currentAncestor.root) {
+            if (!currentAncestor.expanded) {
+                this._revealed = false;
+                return false;
+            }
+
+            currentAncestor = currentAncestor.parent;
+        }
+
+        this._revealed = true;
+        return true;
+    }
+
+    set hasChildren(x)
+    {
+        if (this._hasChildren === x)
+            return;
+
+        this._hasChildren = x;
+
+        if (!this._element)
+            return;
+
+        if (this._hasChildren) {
+            this._element.classList.add("parent");
+            if (this.expanded)
+                this._element.classList.add("expanded");
+        } else
+            this._element.classList.remove("parent", "expanded");
+    }
+
+    get hasChildren()
+    {
+        return this._hasChildren;
+    }
+
+    set revealed(x)
+    {
+        if (this._revealed === x)
+            return;
+
+        this._revealed = x;
+
+        if (this._element) {
+            if (this._revealed)
+                this._element.classList.add("revealed");
+            else
+                this._element.classList.remove("revealed");
+        }
+
+        this.refreshIfNeeded();
+
+        for (var i = 0; i < this.children.length; ++i)
+            this.children[i].revealed = x && this.expanded;
+    }
+
+    get depth()
+    {
+        if ("_depth" in this)
+            return this._depth;
+        if (this.parent && !this.parent.root)
+            this._depth = this.parent.depth + 1;
+        else
+            this._depth = 0;
+        return this._depth;
+    }
+
+    get leftPadding()
+    {
+        if (typeof(this._leftPadding) === "number")
+            return this._leftPadding;
+
+        this._leftPadding = this.depth * this.dataGrid.indentWidth;
+        return this._leftPadding;
+    }
+
+    get shouldRefreshChildren()
+    {
+        return this._shouldRefreshChildren;
+    }
+
+    set shouldRefreshChildren(x)
+    {
+        this._shouldRefreshChildren = x;
+        if (x && this.expanded)
+            this.expand();
+    }
+
+    get selected()
+    {
+        return this._selected;
+    }
+
+    set selected(x)
+    {
+        if (x)
+            this.select();
+        else
+            this.deselect();
+    }
+
+    get expanded()
+    {
+        return this._expanded;
+    }
+
+    set expanded(x)
+    {
+        if (x)
+            this.expand();
+        else
+            this.collapse();
+    }
+
+    hasAncestor(ancestor)
+    {
+        if (!ancestor)
+            return false;
+
+        let currentAncestor = this.parent;
+        while (currentAncestor) {
+            if (ancestor === currentAncestor)
+                return true;
+
+            currentAncestor = currentAncestor.parent;
+        }
+
+        return false;
+    }
+
+    refresh()
+    {
+        if (!this._element || !this.dataGrid)
+            return;
+
+        if (this._scheduledRefreshIdentifier) {
+            cancelAnimationFrame(this._scheduledRefreshIdentifier);
+            this._scheduledRefreshIdentifier = undefined;
+        }
+
+        this._cachedFilterableData = null;
+        this._needsRefresh = false;
+
+        this._element.removeChildren();
+        this.createCells();
+    }
+
+    refreshRecursively()
+    {
+        this.refresh();
+        this.forEachChildInSubtree((node) => node.refresh());
+    }
+
+    updateLayout()
+    {
+        // Implemented by subclasses if needed.
+    }
+
+    createCell(columnIdentifier)
+    {
+        var cellElement = document.createElement("td");
+        cellElement.className = columnIdentifier + "-column";
+        cellElement.__columnIdentifier = columnIdentifier;
+
+        var column = this.dataGrid.columns.get(columnIdentifier);
+
+        if (column["aligned"])
+            cellElement.classList.add(column["aligned"]);
+
+        if (column["group"])
+            cellElement.classList.add("column-group-" + column["group"]);
+
+        var div = cellElement.createChild("div", "cell-content");
+        var content = this.createCellContent(columnIdentifier, cellElement);
+        div.append(content);
+
+        if (column["icon"]) {
+            let iconElement = document.createElement("div");
+            iconElement.classList.add("icon");
+            div.insertBefore(iconElement, div.firstChild);
+        }
+
+        if (columnIdentifier === this.dataGrid.disclosureColumnIdentifier) {
+            cellElement.classList.add("disclosure");
+            if (this.leftPadding)
+                cellElement.style.setProperty("padding-left", this.leftPadding + "px");
+        }
+
+        return cellElement;
+    }
+
+    createCellContent(columnIdentifier)
+    {
+        return this.data[columnIdentifier] || "\u200b"; // Zero width space to keep the cell from collapsing.
+    }
+
+    elementWithColumnIdentifier(columnIdentifier)
+    {
+        if (!this.dataGrid)
+            return null;
+
+        let index = this.dataGrid.orderedColumns.indexOf(columnIdentifier);
+        if (index === -1)
+            return null;
+
+        return this.element.children[index];
+    }
+
+    // Share these functions with DataGrid. They are written to work with a DataGridNode this object.
+    appendChild() { return WebInspector.DataGrid.prototype.appendChild.apply(this, arguments); }
+    insertChild() { return WebInspector.DataGrid.prototype.insertChild.apply(this, arguments); }
+    removeChild() { return WebInspector.DataGrid.prototype.removeChild.apply(this, arguments); }
+    removeChildren() { return WebInspector.DataGrid.prototype.removeChildren.apply(this, arguments); }
+    removeChildrenRecursive() { return WebInspector.DataGrid.prototype.removeChildrenRecursive.apply(this, arguments); }
+
+    _recalculateSiblings(myIndex)
+    {
+        if (!this.parent)
+            return;
+
+        var previousChild = (myIndex > 0 ? this.parent.children[myIndex - 1] : null);
+
+        if (previousChild) {
+            previousChild.nextSibling = this;
+            this.previousSibling = previousChild;
+        } else
+            this.previousSibling = null;
+
+        var nextChild = this.parent.children[myIndex + 1];
+
+        if (nextChild) {
+            nextChild.previousSibling = this;
+            this.nextSibling = nextChild;
+        } else
+            this.nextSibling = null;
+    }
+
+    collapse()
+    {
+        if (this._element)
+            this._element.classList.remove("expanded");
+
+        this._expanded = false;
+
+        for (var i = 0; i < this.children.length; ++i)
+            this.children[i].revealed = false;
+
+        this.dispatchEventToListeners("collapsed");
+
+        if (this.dataGrid) {
+            this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Event.CollapsedNode, {dataGridNode: this});
+            this.dataGrid._noteRowsChanged();
+        }
+    }
+
+    collapseRecursively()
+    {
+        var item = this;
+        while (item) {
+            if (item.expanded)
+                item.collapse();
+            item = item.traverseNextNode(false, this, true);
+        }
+    }
+
+    expand()
+    {
+        if (!this.hasChildren || this.expanded)
+            return;
+
+        if (this.revealed && !this._shouldRefreshChildren)
+            for (var i = 0; i < this.children.length; ++i)
+                this.children[i].revealed = true;
+
+        if (this._shouldRefreshChildren) {
+            for (var i = 0; i < this.children.length; ++i)
+                this.children[i]._detach();
+
+            this.dispatchEventToListeners("populate");
+
+            if (this._attached) {
+                for (var i = 0; i < this.children.length; ++i) {
+                    var child = this.children[i];
+                    if (this.revealed)
+                        child.revealed = true;
+                    child._attach();
+                }
+            }
+
+            this._shouldRefreshChildren = false;
+        }
+
+        if (this._element)
+            this._element.classList.add("expanded");
+
+        this._expanded = true;
+
+        this.dispatchEventToListeners("expanded");
+
+        if (this.dataGrid) {
+            this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Event.ExpandedNode, {dataGridNode: this});
+            this.dataGrid._noteRowsChanged();
+        }
+    }
+
+    expandRecursively()
+    {
+        var item = this;
+        while (item) {
+            item.expand();
+            item = item.traverseNextNode(false, this);
+        }
+    }
+
+    forEachImmediateChild(callback)
+    {
+        for (let node of this.children)
+            callback(node);
+    }
+
+    forEachChildInSubtree(callback)
+    {
+        let node = this.traverseNextNode(false, this, true);
+        while (node) {
+            callback(node);
+            node = node.traverseNextNode(false, this, true);
+        }
+    }
+
+    isInSubtreeOfNode(baseNode)
+    {
+        let node = baseNode;
+        while (node) {
+            if (node === this)
+                return true;
+            node = node.traverseNextNode(false, baseNode, true);
+        }
+        return false;
+    }
+
+    reveal()
+    {
+        var currentAncestor = this.parent;
+        while (currentAncestor && !currentAncestor.root) {
+            if (!currentAncestor.expanded)
+                currentAncestor.expand();
+            currentAncestor = currentAncestor.parent;
+        }
+
+        this.element.scrollIntoViewIfNeeded(false);
+
+        this.dispatchEventToListeners("revealed");
+    }
+
+    select(suppressSelectedEvent)
+    {
+        if (!this.dataGrid || !this.selectable || this.selected)
+            return;
+
+        let oldSelectedNode = this.dataGrid.selectedNode;
+        if (oldSelectedNode)
+            oldSelectedNode.deselect(true);
+
+        this._selected = true;
+        this.dataGrid.selectedNode = this;
+
+        if (this._element)
+            this._element.classList.add("selected");
+
+        if (!suppressSelectedEvent)
+            this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Event.SelectedNodeChanged, {oldSelectedNode});
+    }
+
+    revealAndSelect()
+    {
+        this.reveal();
+        this.select();
+    }
+
+    deselect(suppressDeselectedEvent)
+    {
+        if (!this.dataGrid || this.dataGrid.selectedNode !== this || !this.selected)
+            return;
+
+        this._selected = false;
+        this.dataGrid.selectedNode = null;
+
+        if (this._element)
+            this._element.classList.remove("selected");
+
+        if (!suppressDeselectedEvent)
+            this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Event.SelectedNodeChanged, {oldSelectedNode: this});
+    }
+
+    traverseNextNode(skipHidden, stayWithin, dontPopulate, info)
+    {
+        if (!dontPopulate && this.hasChildren)
+            this.dispatchEventToListeners("populate");
+
+        if (info)
+            info.depthChange = 0;
+
+        var node = (!skipHidden || this.revealed) ? this.children[0] : null;
+        if (node && (!skipHidden || this.expanded)) {
+            if (info)
+                info.depthChange = 1;
+            return node;
+        }
+
+        if (this === stayWithin)
+            return null;
+
+        node = (!skipHidden || this.revealed) ? this.nextSibling : null;
+        if (node)
+            return node;
+
+        node = this;
+        while (node && !node.root && !((!skipHidden || node.revealed) ? node.nextSibling : null) && node.parent !== stayWithin) {
+            if (info)
+                info.depthChange -= 1;
+            node = node.parent;
+        }
+
+        if (!node)
+            return null;
+
+        return (!skipHidden || node.revealed) ? node.nextSibling : null;
+    }
+
+    traversePreviousNode(skipHidden, dontPopulate)
+    {
+        var node = (!skipHidden || this.revealed) ? this.previousSibling : null;
+        if (!dontPopulate && node && node.hasChildren)
+            node.dispatchEventToListeners("populate");
+
+        while (node && ((!skipHidden || (node.revealed && node.expanded)) ? node.children.lastValue : null)) {
+            if (!dontPopulate && node.hasChildren)
+                node.dispatchEventToListeners("populate");
+            node = ((!skipHidden || (node.revealed && node.expanded)) ? node.children.lastValue : null);
+        }
+
+        if (node)
+            return node;
+
+        if (!this.parent || this.parent.root)
+            return null;
+
+        return this.parent;
+    }
+
+    isEventWithinDisclosureTriangle(event)
+    {
+        if (!this.hasChildren)
+            return false;
+        let cell = event.target.enclosingNodeOrSelfWithNodeName("td");
+        if (!cell || !cell.classList.contains("disclosure"))
+            return false;
+
+        let computedLeftPadding = window.getComputedStyle(cell).getPropertyCSSValue("padding-left").getFloatValue(CSSPrimitiveValue.CSS_PX);
+        let left = cell.totalOffsetLeft + computedLeftPadding;
+        return event.pageX >= left && event.pageX <= left + this.disclosureToggleWidth;
+    }
+
+    _attach()
+    {
+        if (!this.dataGrid || this._attached)
+            return;
+
+        this._attached = true;
+
+        let insertionIndex = -1;
+
+        if (!this.isPlaceholderNode) {
+            var previousGridNode = this.traversePreviousNode(true, true);
+            insertionIndex = this.dataGrid._rows.indexOf(previousGridNode);
+            if (insertionIndex === -1)
+                insertionIndex = 0;
+            else
+                insertionIndex++;
+        }
+
+        if (insertionIndex === -1)
+            this.dataGrid._rows.push(this);
+        else
+            this.dataGrid._rows.insertAtIndex(this, insertionIndex);
+
+        this.dataGrid._noteRowsChanged();
+
+        if (this.expanded) {
+            for (var i = 0; i < this.children.length; ++i)
+                this.children[i]._attach();
+        }
+    }
+
+    _detach()
+    {
+        if (!this._attached)
+            return;
+
+        this._attached = false;
+
+        this.dataGrid._rows.remove(this, true);
+        this.dataGrid._noteRowRemoved(this);
+
+        for (var i = 0; i < this.children.length; ++i)
+            this.children[i]._detach();
+    }
+
+    savePosition()
+    {
+        if (this._savedPosition)
+            return;
+
+        console.assert(this.parent);
+        if (!this.parent)
+            return;
+
+        this._savedPosition = {
+            parent: this.parent,
+            index: this.parent.children.indexOf(this)
+        };
+    }
+
+    restorePosition()
+    {
+        if (!this._savedPosition)
+            return;
+
+        if (this.parent !== this._savedPosition.parent)
+            this._savedPosition.parent.insertChild(this, this._savedPosition.index);
+
+        this._savedPosition = null;
+    }
+
+    appendContextMenuItems(contextMenu)
+    {
+        // Subclasses may override
+        return null;
+    }
+
+    // Protected
+
+    filterableDataForColumn(columnIdentifier)
+    {
+        let value = this.data[columnIdentifier];
+        return typeof value === "string" ? value : null;
+    }
+};
+
+// Used to create a new table row when entering new data by editing cells.
+WebInspector.PlaceholderDataGridNode = class PlaceholderDataGridNode extends WebInspector.DataGridNode
+{
+    constructor(data)
+    {
+        super(data, false);
+        this.isPlaceholderNode = true;
+    }
+
+    makeNormal()
+    {
+        this.isPlaceholderNode = false;
+    }
+};

Added: trunk/Source/WebInspectorUI/UserInterface/Views/TreeElement.js (0 => 203114)


--- trunk/Source/WebInspectorUI/UserInterface/Views/TreeElement.js	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TreeElement.js	2016-07-12 13:05:13 UTC (rev 203114)
@@ -0,0 +1,612 @@
+/*
+ * 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
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.TreeElement = class TreeElement extends WebInspector.Object
+{
+    constructor(title, representedObject, hasChildren)
+    {
+        super();
+
+        this._title = title;
+        this.representedObject = (representedObject || {});
+
+        if (this.representedObject.__treeElementIdentifier)
+            this.identifier = this.representedObject.__treeElementIdentifier;
+        else {
+            this.identifier = WebInspector.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;
+    }
+
+    // Methods
+
+    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); }
+
+    get arrowToggleWidth()
+    {
+        return 10;
+    }
+
+    get selectable()
+    {
+        if (this._hidden)
+            return false;
+        return this._selectable;
+    }
+
+    set selectable(x)
+    {
+        this._selectable = x;
+    }
+
+    get listItemElement()
+    {
+        return this._listItemNode;
+    }
+
+    get title()
+    {
+        return this._title;
+    }
+
+    set title(x)
+    {
+        this._title = x;
+        this._setListItemNodeContent();
+        this.didChange();
+    }
+
+    get titleHTML()
+    {
+        return this._titleHTML;
+    }
+
+    set titleHTML(x)
+    {
+        this._titleHTML = x;
+        this._setListItemNodeContent();
+        this.didChange();
+    }
+
+    get tooltip()
+    {
+        return this._tooltip;
+    }
+
+    set tooltip(x)
+    {
+        this._tooltip = x;
+        if (this._listItemNode)
+            this._listItemNode.title = x ? x : "";
+    }
+
+    get hasChildren()
+    {
+        return this._hasChildren;
+    }
+
+    set hasChildren(x)
+    {
+        if (this._hasChildren === x)
+            return;
+
+        this._hasChildren = x;
+
+        if (!this._listItemNode)
+            return;
+
+        if (x)
+            this._listItemNode.classList.add("parent");
+        else {
+            this._listItemNode.classList.remove("parent");
+            this.collapse();
+        }
+
+        this.didChange();
+    }
+
+    get hidden()
+    {
+        return this._hidden;
+    }
+
+    set hidden(x)
+    {
+        if (this._hidden === x)
+            return;
+
+        this._hidden = x;
+
+        if (this._listItemNode)
+            this._listItemNode.hidden = this._hidden;
+        if (this._childrenListNode)
+            this._childrenListNode.hidden = this._hidden;
+
+        if (this.treeOutline)
+            this.treeOutline.dispatchEventToListeners(WebInspector.TreeOutline.Event.ElementVisibilityDidChange, {element: this});
+    }
+
+    get shouldRefreshChildren()
+    {
+        return this._shouldRefreshChildren;
+    }
+
+    set shouldRefreshChildren(x)
+    {
+        this._shouldRefreshChildren = x;
+        if (x && this.expanded)
+            this.expand();
+    }
+
+    _fireDidChange()
+    {
+        if (this.treeOutline)
+            this.treeOutline._treeElementDidChange(this);
+    }
+
+    didChange()
+    {
+        if (!this.treeOutline)
+            return;
+
+        this.onNextFrame._fireDidChange();
+    }
+
+    _setListItemNodeContent()
+    {
+        if (!this._listItemNode)
+            return;
+
+        if (!this._titleHTML && !this._title)
+            this._listItemNode.removeChildren();
+        else if (typeof this._titleHTML === "string")
+            this._listItemNode.innerHTML = this._titleHTML;
+        else if (typeof this._title === "string")
+            this._listItemNode.textContent = this._title;
+        else {
+            this._listItemNode.removeChildren();
+            if (this._title.parentNode)
+                this._title.parentNode.removeChild(this._title);
+            this._listItemNode.appendChild(this._title);
+        }
+    }
+
+    _attach()
+    {
+        if (!this._listItemNode || this.parent._shouldRefreshChildren) {
+            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 : "";
+            this._listItemNode.hidden = this.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);
+        if (this._childrenListNode && this._childrenListNode.parentNode)
+            this._childrenListNode.parentNode.removeChild(this._childrenListNode);
+    }
+
+    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.dispatchEventToListeners(WebInspector.TreeOutline.Event.ElementDisclosureDidChanged, {element: 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 dispatch an ElementAdded event,
+        // this makes sure the expanded flag is true before calling those functions. This prevents the
+        // possibility of an infinite loop if onpopulate or an event handler 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");
+            this._childrenListNode.hidden = this.hidden;
+
+            this.onpopulate();
+
+            for (var i = 0; i < this.children.length; ++i)
+                this.children[i]._attach();
+
+            this._shouldRefreshChildren = false;
+        }
+
+        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.dispatchEventToListeners(WebInspector.TreeOutline.Event.ElementDisclosureDidChanged, {element: 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(ignoreHidden)
+    {
+        if (!ignoreHidden && this.hidden)
+            return false;
+
+        var currentAncestor = this.parent;
+        while (currentAncestor && !currentAncestor.root) {
+            if (!currentAncestor.expanded)
+                return false;
+            if (!ignoreHidden && currentAncestor.hidden)
+                return false;
+            currentAncestor = currentAncestor.parent;
+        }
+
+        return true;
+    }
+
+    selectOnMouseDown(event)
+    {
+        this.select(false, true);
+    }
+
+    select(omitFocus, selectedByUser, suppressOnSelect, suppressOnDeselect)
+    {
+        if (!this.treeOutline || !this.selectable)
+            return;
+
+        if (this.selected && !this.treeOutline.allowsRepeatSelection)
+            return;
+
+        if (!omitFocus)
+            this.treeOutline._childrenListNode.focus();
+
+        // Focusing on another node may detach "this" from tree.
+        let treeOutline = this.treeOutline;
+        if (!treeOutline)
+            return;
+
+        treeOutline.processingSelectionChange = true;
+
+        // Prevent dispatching a SelectionDidChange event for the deselected element if
+        // it will be dispatched for the selected element. The event data includes both
+        // the selected and deselected elements, so one event is.
+        if (!suppressOnSelect)
+            suppressOnDeselect = true;
+
+        let deselectedElement = treeOutline.selectedTreeElement;
+        if (!this.selected) {
+            if (treeOutline.selectedTreeElement)
+                treeOutline.selectedTreeElement.deselect(suppressOnDeselect);
+
+            this.selected = true;
+            treeOutline.selectedTreeElement = this;
+
+            if (this._listItemNode)
+                this._listItemNode.classList.add("selected");
+        }
+
+        if (!suppressOnSelect) {
+            if (this.onselect)
+                this.onselect(this, selectedByUser);
+
+            treeOutline.dispatchEventToListeners(WebInspector.TreeOutline.Event.SelectionDidChange, {selectedElement: this, deselectedElement, selectedByUser});
+        }
+
+        treeOutline.processingSelectionChange = false;
+    }
+
+    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.remove("selected");
+
+        if (!suppressOnDeselect) {
+            if (this.ondeselect)
+                this.ondeselect(this);
+
+            this.treeOutline.dispatchEventToListeners(WebInspector.TreeOutline.Event.SelectionDidChange, {deselectedElement: this});
+        }
+
+        return true;
+    }
+
+    onpopulate()
+    {
+        // Overriden by subclasses.
+    }
+
+    traverseNextTreeElement(skipUnrevealed, stayWithin, dontPopulate, info)
+    {
+        function shouldSkip(element) {
+            return skipUnrevealed && !element.revealed(true);
+        }
+
+        var depthChange = 0;
+        var element = this;
+
+        if (!dontPopulate)
+            element.onpopulate();
+
+        do {
+            if (element.hasChildren && element.children[0] && (!skipUnrevealed || element.expanded)) {
+                element = element.children[0];
+                depthChange += 1;
+            } else {
+                while (element && !element.nextSibling && element.parent && !element.parent.root && element.parent !== stayWithin) {
+                    element = element.parent;
+                    depthChange -= 1;
+                }
+
+                if (element)
+                    element = element.nextSibling;
+            }
+        } while (element && shouldSkip(element));
+
+        if (info)
+            info.depthChange = depthChange;
+
+        return element;
+    }
+
+    traversePreviousTreeElement(skipUnrevealed, dontPopulate)
+    {
+        function shouldSkip(element) {
+            return skipUnrevealed && !element.revealed(true);
+        }
+
+        var element = this;
+
+        do {
+            if (element.previousSibling) {
+                element = element.previousSibling;
+
+                while (element && element.hasChildren && element.expanded && !shouldSkip(element)) {
+                    if (!dontPopulate)
+                        element.onpopulate();
+                    element = element.children.lastValue;
+                }
+            } else
+                element = element.parent && element.parent.root ? null : element.parent;
+        } while (element && shouldSkip(element));
+
+        return element;
+    }
+
+    isEventWithinDisclosureTriangle(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;
+    }
+};

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js (203113 => 203114)


--- trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js	2016-07-12 13:04:38 UTC (rev 203113)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js	2016-07-12 13:05:13 UTC (rev 203114)
@@ -643,588 +643,3 @@
 };
 
 WebInspector.TreeOutline._knownTreeElementNextIdentifier = 1;
-
-WebInspector.TreeElement = class TreeElement extends WebInspector.Object
-{
-    constructor(title, representedObject, hasChildren)
-    {
-        super();
-
-        this._title = title;
-        this.representedObject = (representedObject || {});
-
-        if (this.representedObject.__treeElementIdentifier)
-            this.identifier = this.representedObject.__treeElementIdentifier;
-        else {
-            this.identifier = WebInspector.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;
-    }
-
-    // Methods
-
-    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); }
-
-    get arrowToggleWidth()
-    {
-        return 10;
-    }
-
-    get selectable()
-    {
-        if (this._hidden)
-            return false;
-        return this._selectable;
-    }
-
-    set selectable(x)
-    {
-        this._selectable = x;
-    }
-
-    get listItemElement()
-    {
-        return this._listItemNode;
-    }
-
-    get title()
-    {
-        return this._title;
-    }
-
-    set title(x)
-    {
-        this._title = x;
-        this._setListItemNodeContent();
-        this.didChange();
-    }
-
-    get titleHTML()
-    {
-        return this._titleHTML;
-    }
-
-    set titleHTML(x)
-    {
-        this._titleHTML = x;
-        this._setListItemNodeContent();
-        this.didChange();
-    }
-
-    get tooltip()
-    {
-        return this._tooltip;
-    }
-
-    set tooltip(x)
-    {
-        this._tooltip = x;
-        if (this._listItemNode)
-            this._listItemNode.title = x ? x : "";
-    }
-
-    get hasChildren()
-    {
-        return this._hasChildren;
-    }
-
-    set hasChildren(x)
-    {
-        if (this._hasChildren === x)
-            return;
-
-        this._hasChildren = x;
-
-        if (!this._listItemNode)
-            return;
-
-        if (x)
-            this._listItemNode.classList.add("parent");
-        else {
-            this._listItemNode.classList.remove("parent");
-            this.collapse();
-        }
-
-        this.didChange();
-    }
-
-    get hidden()
-    {
-        return this._hidden;
-    }
-
-    set hidden(x)
-    {
-        if (this._hidden === x)
-            return;
-
-        this._hidden = x;
-
-        if (this._listItemNode)
-            this._listItemNode.hidden = this._hidden;
-        if (this._childrenListNode)
-            this._childrenListNode.hidden = this._hidden;
-
-        if (this.treeOutline)
-            this.treeOutline.dispatchEventToListeners(WebInspector.TreeOutline.Event.ElementVisibilityDidChange, {element: this});
-    }
-
-    get shouldRefreshChildren()
-    {
-        return this._shouldRefreshChildren;
-    }
-
-    set shouldRefreshChildren(x)
-    {
-        this._shouldRefreshChildren = x;
-        if (x && this.expanded)
-            this.expand();
-    }
-
-    _fireDidChange()
-    {
-        if (this.treeOutline)
-            this.treeOutline._treeElementDidChange(this);
-    }
-
-    didChange()
-    {
-        if (!this.treeOutline)
-            return;
-
-        this.onNextFrame._fireDidChange();
-    }
-
-    _setListItemNodeContent()
-    {
-        if (!this._listItemNode)
-            return;
-
-        if (!this._titleHTML && !this._title)
-            this._listItemNode.removeChildren();
-        else if (typeof this._titleHTML === "string")
-            this._listItemNode.innerHTML = this._titleHTML;
-        else if (typeof this._title === "string")
-            this._listItemNode.textContent = this._title;
-        else {
-            this._listItemNode.removeChildren();
-            if (this._title.parentNode)
-                this._title.parentNode.removeChild(this._title);
-            this._listItemNode.appendChild(this._title);
-        }
-    }
-
-    _attach()
-    {
-        if (!this._listItemNode || this.parent._shouldRefreshChildren) {
-            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 : "";
-            this._listItemNode.hidden = this.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);
-        if (this._childrenListNode && this._childrenListNode.parentNode)
-            this._childrenListNode.parentNode.removeChild(this._childrenListNode);
-    }
-
-    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.dispatchEventToListeners(WebInspector.TreeOutline.Event.ElementDisclosureDidChanged, {element: 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 dispatch an ElementAdded event,
-        // this makes sure the expanded flag is true before calling those functions. This prevents the
-        // possibility of an infinite loop if onpopulate or an event handler 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");
-            this._childrenListNode.hidden = this.hidden;
-
-            this.onpopulate();
-
-            for (var i = 0; i < this.children.length; ++i)
-                this.children[i]._attach();
-
-            this._shouldRefreshChildren = false;
-        }
-
-        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.dispatchEventToListeners(WebInspector.TreeOutline.Event.ElementDisclosureDidChanged, {element: 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(ignoreHidden)
-    {
-        if (!ignoreHidden && this.hidden)
-            return false;
-
-        var currentAncestor = this.parent;
-        while (currentAncestor && !currentAncestor.root) {
-            if (!currentAncestor.expanded)
-                return false;
-            if (!ignoreHidden && currentAncestor.hidden)
-                return false;
-            currentAncestor = currentAncestor.parent;
-        }
-
-        return true;
-    }
-
-    selectOnMouseDown(event)
-    {
-        this.select(false, true);
-    }
-
-    select(omitFocus, selectedByUser, suppressOnSelect, suppressOnDeselect)
-    {
-        if (!this.treeOutline || !this.selectable)
-            return;
-
-        if (this.selected && !this.treeOutline.allowsRepeatSelection)
-            return;
-
-        if (!omitFocus)
-            this.treeOutline._childrenListNode.focus();
-
-        // Focusing on another node may detach "this" from tree.
-        let treeOutline = this.treeOutline;
-        if (!treeOutline)
-            return;
-
-        treeOutline.processingSelectionChange = true;
-
-        // Prevent dispatching a SelectionDidChange event for the deselected element if
-        // it will be dispatched for the selected element. The event data includes both
-        // the selected and deselected elements, so one event is.
-        if (!suppressOnSelect)
-            suppressOnDeselect = true;
-
-        let deselectedElement = treeOutline.selectedTreeElement;
-        if (!this.selected) {
-            if (treeOutline.selectedTreeElement)
-                treeOutline.selectedTreeElement.deselect(suppressOnDeselect);
-
-            this.selected = true;
-            treeOutline.selectedTreeElement = this;
-
-            if (this._listItemNode)
-                this._listItemNode.classList.add("selected");
-        }
-
-        if (!suppressOnSelect) {
-            if (this.onselect)
-                this.onselect(this, selectedByUser);
-
-            treeOutline.dispatchEventToListeners(WebInspector.TreeOutline.Event.SelectionDidChange, {selectedElement: this, deselectedElement, selectedByUser});
-        }
-
-        treeOutline.processingSelectionChange = false;
-    }
-
-    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.remove("selected");
-
-        if (!suppressOnDeselect) {
-            if (this.ondeselect)
-                this.ondeselect(this);
-
-            this.treeOutline.dispatchEventToListeners(WebInspector.TreeOutline.Event.SelectionDidChange, {deselectedElement: this});
-        }
-
-        return true;
-    }
-
-    onpopulate()
-    {
-        // Overriden by subclasses.
-    }
-
-    traverseNextTreeElement(skipUnrevealed, stayWithin, dontPopulate, info)
-    {
-        function shouldSkip(element) {
-            return skipUnrevealed && !element.revealed(true);
-        }
-
-        var depthChange = 0;
-        var element = this;
-
-        if (!dontPopulate)
-            element.onpopulate();
-
-        do {
-            if (element.hasChildren && element.children[0] && (!skipUnrevealed || element.expanded)) {
-                element = element.children[0];
-                depthChange += 1;
-            } else {
-                while (element && !element.nextSibling && element.parent && !element.parent.root && element.parent !== stayWithin) {
-                    element = element.parent;
-                    depthChange -= 1;
-                }
-
-                if (element)
-                    element = element.nextSibling;
-            }
-        } while (element && shouldSkip(element));
-
-        if (info)
-            info.depthChange = depthChange;
-
-        return element;
-    }
-
-    traversePreviousTreeElement(skipUnrevealed, dontPopulate)
-    {
-        function shouldSkip(element) {
-            return skipUnrevealed && !element.revealed(true);
-        }
-
-        var element = this;
-
-        do {
-            if (element.previousSibling) {
-                element = element.previousSibling;
-
-                while (element && element.hasChildren && element.expanded && !shouldSkip(element)) {
-                    if (!dontPopulate)
-                        element.onpopulate();
-                    element = element.children.lastValue;
-                }
-            } else
-                element = element.parent && element.parent.root ? null : element.parent;
-        } while (element && shouldSkip(element));
-
-        return element;
-    }
-
-    isEventWithinDisclosureTriangle(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;
-    }
-};
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to