<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[203254] trunk/Source/WebInspectorUI</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/203254">203254</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-07-14 16:38:13 -0700 (Thu, 14 Jul 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: Rename CCTNode to CallingContextTreeNode
https://bugs.webkit.org/show_bug.cgi?id=159782

Patch by Joseph Pecoraro &lt;pecoraro@apple.com&gt; on 2016-07-14
Reviewed by Timothy Hatcher.

* UserInterface/Models/CallingContextTree.js:
* UserInterface/Models/CallingContextTreeNode.js:
Extra to its own file and rename.

* UserInterface/Main.html:
* UserInterface/Test.html:
* UserInterface/TestStub.html:
Include the new file.

* UserInterface/Views/ProfileDataGridNode.js:
(WebInspector.ProfileDataGridNode):
* UserInterface/Views/ProfileDataGridTree.js:
(WebInspector.ProfileDataGridTree.prototype._updateCurrentFocusDetails):
Rename shorthand &quot;cctnode&quot;.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceMainhtml">trunk/Source/WebInspectorUI/UserInterface/Main.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsCallingContextTreejs">trunk/Source/WebInspectorUI/UserInterface/Models/CallingContextTree.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTesthtml">trunk/Source/WebInspectorUI/UserInterface/Test.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTestStubhtml">trunk/Source/WebInspectorUI/UserInterface/TestStub.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsProfileDataGridNodejs">trunk/Source/WebInspectorUI/UserInterface/Views/ProfileDataGridNode.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsProfileDataGridTreejs">trunk/Source/WebInspectorUI/UserInterface/Views/ProfileDataGridTree.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsCallingContextTreeNodejs">trunk/Source/WebInspectorUI/UserInterface/Models/CallingContextTreeNode.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (203253 => 203254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2016-07-14 23:37:37 UTC (rev 203253)
+++ trunk/Source/WebInspectorUI/ChangeLog        2016-07-14 23:38:13 UTC (rev 203254)
</span><span class="lines">@@ -1,3 +1,25 @@
</span><ins>+2016-07-14  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: Rename CCTNode to CallingContextTreeNode
+        https://bugs.webkit.org/show_bug.cgi?id=159782
+
+        Reviewed by Timothy Hatcher.
+
+        * UserInterface/Models/CallingContextTree.js:
+        * UserInterface/Models/CallingContextTreeNode.js:
+        Extra to its own file and rename.
+
+        * UserInterface/Main.html:
+        * UserInterface/Test.html:
+        * UserInterface/TestStub.html:
+        Include the new file.
+
+        * UserInterface/Views/ProfileDataGridNode.js:
+        (WebInspector.ProfileDataGridNode):
+        * UserInterface/Views/ProfileDataGridTree.js:
+        (WebInspector.ProfileDataGridTree.prototype._updateCurrentFocusDetails):
+        Rename shorthand &quot;cctnode&quot;.
+
</ins><span class="cx"> 2016-07-14  Matt Baker  &lt;mattbaker@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: SidebarPanel classes should use View.layout instead of &quot;refresh&quot;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceMainhtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (203253 => 203254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Main.html        2016-07-14 23:37:37 UTC (rev 203253)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html        2016-07-14 23:38:13 UTC (rev 203254)
</span><span class="lines">@@ -283,6 +283,7 @@
</span><span class="cx">     &lt;script src=&quot;Models/Branch.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/Breakpoint.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/CallingContextTree.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Models/CallingContextTreeNode.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Models/CSSCompletions.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/CSSKeywordCompletions.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/CSSMedia.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsCallingContextTreejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/CallingContextTree.js (203253 => 203254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/CallingContextTree.js        2016-07-14 23:37:37 UTC (rev 203253)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/CallingContextTree.js        2016-07-14 23:38:13 UTC (rev 203254)
</span><span class="lines">@@ -41,7 +41,7 @@
</span><span class="cx"> 
</span><span class="cx">     reset()
</span><span class="cx">     {
</span><del>-        this._root = new WebInspector.CCTNode(-1, -1, -1, &quot;&lt;root&gt;&quot;, null);
</del><ins>+        this._root = new WebInspector.CallingContextTreeNode(-1, -1, -1, &quot;&lt;root&gt;&quot;, null);
</ins><span class="cx">         this._totalNumberOfSamples = 0;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -168,226 +168,6 @@
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-WebInspector.CCTNode = class CCTNode extends WebInspector.Object
-{
-    constructor(sourceID, line, column, name, url, hash)
-    {
-        super();
-
-        this._children = {};
-        this._sourceID = sourceID;
-        this._line = line;
-        this._column = column;
-        this._name = name;
-        this._url = url;
-        this._uid = WebInspector.CCTNode.__uid++;
-
-        this._timestamps = [];
-        this._durations = [];
-        this._leafTimestamps = [];
-        this._leafDurations = [];
-        this._expressionLocations = {}; // Keys are &quot;line:column&quot; strings. Values are arrays of timestamps in sorted order.
-
-        this._hash = hash || WebInspector.CCTNode._hash(this);
-    }
-
-    // Static and Private
-
-    static _hash(stackFrame)
-    {
-        return stackFrame.name + &quot;:&quot; + stackFrame.sourceID + &quot;:&quot; + stackFrame.line + &quot;:&quot; + stackFrame.column;
-    }
-
-    // Public
-
-    get sourceID() { return this._sourceID; }
-    get line() { return this._line; }
-    get column() { return this._column; }
-    get name() { return this._name; }
-    get uid() { return this._uid; }
-    get url() { return this._url; }
-    get hash() { return this._hash; }
-
-    hasChildrenInTimeRange(startTime, endTime)
-    {
-        for (let propertyName of Object.getOwnPropertyNames(this._children)) {
-            let child = this._children[propertyName];
-            if (child.hasStackTraceInTimeRange(startTime, endTime))
-                return true;
-        }
-        return false;
-    }
-    
-    hasStackTraceInTimeRange(startTime, endTime)
-    {
-        console.assert(startTime &lt;= endTime);
-        if (startTime &gt; endTime)
-            return false;
-
-        let timestamps = this._timestamps;
-        let length = timestamps.length;
-        if (!length)
-            return false;
-
-        let index = timestamps.lowerBound(startTime);
-        if (index === length)
-            return false;
-        console.assert(startTime &lt;= timestamps[index]);
-
-        let hasTimestampInRange = timestamps[index] &lt;= endTime;
-        return hasTimestampInRange;
-    }
-
-    filteredTimestampsAndDuration(startTime, endTime)
-    {
-        let lowerIndex = this._timestamps.lowerBound(startTime);
-        let upperIndex = this._timestamps.upperBound(endTime);
-
-        let totalDuration = 0;
-        for (let i = lowerIndex; i &lt; upperIndex; ++i)
-            totalDuration += this._durations[i];
-
-        return {
-            timestamps: this._timestamps.slice(lowerIndex, upperIndex),
-            duration: totalDuration,
-        };
-    }
-
-    filteredLeafTimestampsAndDuration(startTime, endTime)
-    {
-        let lowerIndex = this._leafTimestamps.lowerBound(startTime);
-        let upperIndex = this._leafTimestamps.upperBound(endTime);
-
-        let totalDuration = 0;
-        for (let i = lowerIndex; i &lt; upperIndex; ++i)
-            totalDuration += this._leafDurations[i];
-
-        return {
-            leafTimestamps: this._leafTimestamps.slice(lowerIndex, upperIndex),
-            leafDuration: totalDuration,
-        };
-    }
-
-    hasChildren()
-    {
-        return !isEmptyObject(this._children);
-    }
-
-    findOrMakeChild(stackFrame)
-    {
-        let hash = WebInspector.CCTNode._hash(stackFrame);
-        let node = this._children[hash];
-        if (node)
-            return node;
-        node = new WebInspector.CCTNode(stackFrame.sourceID, stackFrame.line, stackFrame.column, stackFrame.name, stackFrame.url, hash);
-        this._children[hash] = node;
-        return node;
-    }
-
-    addTimestampAndExpressionLocation(timestamp, duration, expressionLocation, leaf)
-    {
-        console.assert(!this._timestamps.length || this._timestamps.lastValue &lt;= timestamp, &quot;Expected timestamps to be added in sorted, increasing, order.&quot;);
-        this._timestamps.push(timestamp);
-        this._durations.push(duration);
-
-        if (leaf) {
-            this._leafTimestamps.push(timestamp);
-            this._leafDurations.push(duration);
-        }
-
-        if (!expressionLocation)
-            return;
-
-        let {line, column} = expressionLocation;    
-        let hashCons = line + &quot;:&quot; + column;
-        let timestamps = this._expressionLocations[hashCons];
-        if (!timestamps) {
-            timestamps = [];
-            this._expressionLocations[hashCons] = timestamps;
-        }
-        console.assert(!timestamps.length || timestamps.lastValue &lt;= timestamp, &quot;Expected timestamps to be added in sorted, increasing, order.&quot;);
-        timestamps.push(timestamp);
-    }
-
-    forEachChild(callback)
-    {
-        for (let propertyName of Object.getOwnPropertyNames(this._children))
-            callback(this._children[propertyName]);
-    }
-
-    forEachNode(callback)
-    {
-        callback(this);
-        this.forEachChild(function(child) {
-            child.forEachNode(callback);
-        });
-    }
-
-    equals(other)
-    {
-        return this._hash === other.hash;
-    }
-
-    toCPUProfileNode(numSamples, startTime, endTime)
-    {
-        let children = [];
-        this.forEachChild((child) =&gt; {
-            if (child.hasStackTraceInTimeRange(startTime, endTime))
-                children.push(child.toCPUProfileNode(numSamples, startTime, endTime));
-        });
-        let cpuProfileNode = {
-            id: this._uid,
-            functionName: this._name,
-            url: this._url,
-            lineNumber: this._line,
-            columnNumber: this._column,
-            children: children
-        };
-
-        let timestamps = [];
-        let frameStartTime = Number.MAX_VALUE;
-        let frameEndTime = Number.MIN_VALUE;
-        for (let i = 0; i &lt; this._timestamps.length; i++) {
-            let timestamp = this._timestamps[i];
-            if (startTime &lt;= timestamp &amp;&amp; timestamp &lt;= endTime) {
-                timestamps.push(timestamp);
-                frameStartTime = Math.min(frameStartTime, timestamp);
-                frameEndTime = Math.max(frameEndTime, timestamp);
-            }
-        }
-
-        cpuProfileNode.callInfo = {
-            callCount: timestamps.length, // Totally not callCount, but oh well, this makes life easier because of field names.
-            startTime: frameStartTime,
-            endTime: frameEndTime,
-            totalTime: (timestamps.length / numSamples) * (endTime - startTime)
-        };
-
-        return cpuProfileNode;
-    }
-
-    // Testing.
-
-    __test_buildLeafLinkedLists(parent, result)
-    {
-        let linkedListNode = {
-            name: this._name,
-            url: this._url,
-            parent: parent
-        };
-        if (this.hasChildren()) {
-            this.forEachChild((child) =&gt; {
-                child.__test_buildLeafLinkedLists(linkedListNode, result);
-            });
-        } else {
-            // We're a leaf.
-            result.push(linkedListNode);
-        }
-    }
-};
-
-WebInspector.CCTNode.__uid = 0;
-
</del><span class="cx"> WebInspector.CallingContextTree.Type = {
</span><span class="cx">     TopDown: Symbol(&quot;TopDown&quot;),
</span><span class="cx">     BottomUp: Symbol(&quot;BottomUp&quot;),
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsCallingContextTreeNodejsfromrev203253trunkSourceWebInspectorUIUserInterfaceModelsCallingContextTreejs"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebInspectorUI/UserInterface/Models/CallingContextTreeNode.js (from rev 203253, trunk/Source/WebInspectorUI/UserInterface/Models/CallingContextTree.js) (0 => 203254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/CallingContextTreeNode.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/CallingContextTreeNode.js        2016-07-14 23:38:13 UTC (rev 203254)
</span><span class="lines">@@ -0,0 +1,244 @@
</span><ins>+/*
+ * Copyright (C) 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.CallingContextTreeNode = class CallingContextTreeNode extends WebInspector.Object
+{
+    constructor(sourceID, line, column, name, url, hash)
+    {
+        super();
+
+        this._children = {};
+        this._sourceID = sourceID;
+        this._line = line;
+        this._column = column;
+        this._name = name;
+        this._url = url;
+        this._uid = WebInspector.CallingContextTreeNode.__uid++;
+
+        this._timestamps = [];
+        this._durations = [];
+        this._leafTimestamps = [];
+        this._leafDurations = [];
+        this._expressionLocations = {}; // Keys are &quot;line:column&quot; strings. Values are arrays of timestamps in sorted order.
+
+        this._hash = hash || WebInspector.CallingContextTreeNode._hash(this);
+    }
+
+    // Static and Private
+
+    static _hash(stackFrame)
+    {
+        return stackFrame.name + &quot;:&quot; + stackFrame.sourceID + &quot;:&quot; + stackFrame.line + &quot;:&quot; + stackFrame.column;
+    }
+
+    // Public
+
+    get sourceID() { return this._sourceID; }
+    get line() { return this._line; }
+    get column() { return this._column; }
+    get name() { return this._name; }
+    get uid() { return this._uid; }
+    get url() { return this._url; }
+    get hash() { return this._hash; }
+
+    hasChildrenInTimeRange(startTime, endTime)
+    {
+        for (let propertyName of Object.getOwnPropertyNames(this._children)) {
+            let child = this._children[propertyName];
+            if (child.hasStackTraceInTimeRange(startTime, endTime))
+                return true;
+        }
+        return false;
+    }
+    
+    hasStackTraceInTimeRange(startTime, endTime)
+    {
+        console.assert(startTime &lt;= endTime);
+        if (startTime &gt; endTime)
+            return false;
+
+        let timestamps = this._timestamps;
+        let length = timestamps.length;
+        if (!length)
+            return false;
+
+        let index = timestamps.lowerBound(startTime);
+        if (index === length)
+            return false;
+        console.assert(startTime &lt;= timestamps[index]);
+
+        let hasTimestampInRange = timestamps[index] &lt;= endTime;
+        return hasTimestampInRange;
+    }
+
+    filteredTimestampsAndDuration(startTime, endTime)
+    {
+        let lowerIndex = this._timestamps.lowerBound(startTime);
+        let upperIndex = this._timestamps.upperBound(endTime);
+
+        let totalDuration = 0;
+        for (let i = lowerIndex; i &lt; upperIndex; ++i)
+            totalDuration += this._durations[i];
+
+        return {
+            timestamps: this._timestamps.slice(lowerIndex, upperIndex),
+            duration: totalDuration,
+        };
+    }
+
+    filteredLeafTimestampsAndDuration(startTime, endTime)
+    {
+        let lowerIndex = this._leafTimestamps.lowerBound(startTime);
+        let upperIndex = this._leafTimestamps.upperBound(endTime);
+
+        let totalDuration = 0;
+        for (let i = lowerIndex; i &lt; upperIndex; ++i)
+            totalDuration += this._leafDurations[i];
+
+        return {
+            leafTimestamps: this._leafTimestamps.slice(lowerIndex, upperIndex),
+            leafDuration: totalDuration,
+        };
+    }
+
+    hasChildren()
+    {
+        return !isEmptyObject(this._children);
+    }
+
+    findOrMakeChild(stackFrame)
+    {
+        let hash = WebInspector.CallingContextTreeNode._hash(stackFrame);
+        let node = this._children[hash];
+        if (node)
+            return node;
+        node = new WebInspector.CallingContextTreeNode(stackFrame.sourceID, stackFrame.line, stackFrame.column, stackFrame.name, stackFrame.url, hash);
+        this._children[hash] = node;
+        return node;
+    }
+
+    addTimestampAndExpressionLocation(timestamp, duration, expressionLocation, leaf)
+    {
+        console.assert(!this._timestamps.length || this._timestamps.lastValue &lt;= timestamp, &quot;Expected timestamps to be added in sorted, increasing, order.&quot;);
+        this._timestamps.push(timestamp);
+        this._durations.push(duration);
+
+        if (leaf) {
+            this._leafTimestamps.push(timestamp);
+            this._leafDurations.push(duration);
+        }
+
+        if (!expressionLocation)
+            return;
+
+        let {line, column} = expressionLocation;    
+        let hashCons = line + &quot;:&quot; + column;
+        let timestamps = this._expressionLocations[hashCons];
+        if (!timestamps) {
+            timestamps = [];
+            this._expressionLocations[hashCons] = timestamps;
+        }
+        console.assert(!timestamps.length || timestamps.lastValue &lt;= timestamp, &quot;Expected timestamps to be added in sorted, increasing, order.&quot;);
+        timestamps.push(timestamp);
+    }
+
+    forEachChild(callback)
+    {
+        for (let propertyName of Object.getOwnPropertyNames(this._children))
+            callback(this._children[propertyName]);
+    }
+
+    forEachNode(callback)
+    {
+        callback(this);
+        this.forEachChild(function(child) {
+            child.forEachNode(callback);
+        });
+    }
+
+    equals(other)
+    {
+        return this._hash === other.hash;
+    }
+
+    toCPUProfileNode(numSamples, startTime, endTime)
+    {
+        let children = [];
+        this.forEachChild((child) =&gt; {
+            if (child.hasStackTraceInTimeRange(startTime, endTime))
+                children.push(child.toCPUProfileNode(numSamples, startTime, endTime));
+        });
+        let cpuProfileNode = {
+            id: this._uid,
+            functionName: this._name,
+            url: this._url,
+            lineNumber: this._line,
+            columnNumber: this._column,
+            children: children
+        };
+
+        let timestamps = [];
+        let frameStartTime = Number.MAX_VALUE;
+        let frameEndTime = Number.MIN_VALUE;
+        for (let i = 0; i &lt; this._timestamps.length; i++) {
+            let timestamp = this._timestamps[i];
+            if (startTime &lt;= timestamp &amp;&amp; timestamp &lt;= endTime) {
+                timestamps.push(timestamp);
+                frameStartTime = Math.min(frameStartTime, timestamp);
+                frameEndTime = Math.max(frameEndTime, timestamp);
+            }
+        }
+
+        cpuProfileNode.callInfo = {
+            callCount: timestamps.length, // Totally not callCount, but oh well, this makes life easier because of field names.
+            startTime: frameStartTime,
+            endTime: frameEndTime,
+            totalTime: (timestamps.length / numSamples) * (endTime - startTime)
+        };
+
+        return cpuProfileNode;
+    }
+
+    // Testing.
+
+    __test_buildLeafLinkedLists(parent, result)
+    {
+        let linkedListNode = {
+            name: this._name,
+            url: this._url,
+            parent: parent
+        };
+        if (this.hasChildren()) {
+            this.forEachChild((child) =&gt; {
+                child.__test_buildLeafLinkedLists(linkedListNode, result);
+            });
+        } else {
+            // We're a leaf.
+            result.push(linkedListNode);
+        }
+    }
+};
+
+WebInspector.CallingContextTreeNode.__uid = 0;
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTesthtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Test.html (203253 => 203254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Test.html        2016-07-14 23:37:37 UTC (rev 203253)
+++ trunk/Source/WebInspectorUI/UserInterface/Test.html        2016-07-14 23:38:13 UTC (rev 203254)
</span><span class="lines">@@ -97,6 +97,7 @@
</span><span class="cx">     &lt;script src=&quot;Models/CSSStyleSheet.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/CallFrame.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/CallingContextTree.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Models/CallingContextTreeNode.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Models/CollectionEntry.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/CollectionEntryPreview.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/Color.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTestStubhtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TestStub.html (203253 => 203254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TestStub.html        2016-07-14 23:37:37 UTC (rev 203253)
+++ trunk/Source/WebInspectorUI/UserInterface/TestStub.html        2016-07-14 23:38:13 UTC (rev 203254)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx">     &lt;script src=&quot;Base/Utilities.js&quot;&gt;&lt;/script&gt;
</span><span class="cx"> 
</span><span class="cx">     &lt;script src=&quot;Models/CallingContextTree.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Models/CallingContextTreeNode.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx"> 
</span><span class="cx">     &lt;script src=&quot;Test/TestSuite.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Test/TestHarness.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsProfileDataGridNodejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ProfileDataGridNode.js (203253 => 203254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ProfileDataGridNode.js        2016-07-14 23:37:37 UTC (rev 203253)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ProfileDataGridNode.js        2016-07-14 23:38:13 UTC (rev 203254)
</span><span class="lines">@@ -25,11 +25,11 @@
</span><span class="cx"> 
</span><span class="cx"> WebInspector.ProfileDataGridNode = class ProfileDataGridNode extends WebInspector.DataGridNode
</span><span class="cx"> {
</span><del>-    constructor(cctNode, tree)
</del><ins>+    constructor(callingContextTreeNode, tree)
</ins><span class="cx">     {
</span><del>-        super(cctNode, false);
</del><ins>+        super(callingContextTreeNode, false);
</ins><span class="cx"> 
</span><del>-        this._node = cctNode;
</del><ins>+        this._node = callingContextTreeNode;
</ins><span class="cx">         this._tree = tree;
</span><span class="cx"> 
</span><span class="cx">         this._childrenToChargeToSelf = new Set;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsProfileDataGridTreejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ProfileDataGridTree.js (203253 => 203254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ProfileDataGridTree.js        2016-07-14 23:37:37 UTC (rev 203253)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ProfileDataGridTree.js        2016-07-14 23:38:13 UTC (rev 203254)
</span><span class="lines">@@ -239,8 +239,7 @@
</span><span class="cx"> 
</span><span class="cx">     _updateCurrentFocusDetails(focusDataGridNode)
</span><span class="cx">     {
</span><del>-        let cctNode = focusDataGridNode.callingContextTreeNode;
-        let {timestamps, duration} = cctNode.filteredTimestampsAndDuration(this._startTime, this._endTime);
</del><ins>+        let {timestamps, duration} = focusDataGridNode.callingContextTreeNode.filteredTimestampsAndDuration(this._startTime, this._endTime);
</ins><span class="cx"> 
</span><span class="cx">         this._currentFocusStartTime = timestamps[0];
</span><span class="cx">         this._currentFocusEndTime = timestamps.lastValue;
</span></span></pre>
</div>
</div>

</body>
</html>