<!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>[198196] 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/198196">198196</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-03-14 22:02:28 -0700 (Mon, 14 Mar 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Web Inspector: Show path from root to instances in the Heap Snapshot content view
https://bugs.webkit.org/show_bug.cgi?id=155478
<rdar://problem/25157408>
Patch by Joseph Pecoraro <pecoraro@apple.com> on 2016-03-14
Reviewed by Timothy Hatcher.
* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Main.html:
New strings and resources.
* UserInterface/Models/HeapSnapshotNode.js:
(WebInspector.HeapSnapshotNode.prototype.get shortestGCRootPath):
(WebInspector.HeapSnapshotNode.prototype._gcRootPaths.visitNode):
(WebInspector.HeapSnapshotNode.prototype._gcRootPaths):
Helper to get the shortest path from a GC root to the node.
* UserInterface/Models/HeapSnapshotRootPath.js: Added.
(WebInspector.HeapSnapshotRootPath):
(WebInspector.HeapSnapshotRootPath.emptyPath):
(WebInspector.HeapSnapshotRootPath.prototype.get node):
(WebInspector.HeapSnapshotRootPath.prototype.get parent):
(WebInspector.HeapSnapshotRootPath.prototype.get pathComponent):
(WebInspector.HeapSnapshotRootPath.prototype.get rootNode):
(WebInspector.HeapSnapshotRootPath.prototype.get fullPath):
(WebInspector.HeapSnapshotRootPath.prototype.isRoot):
(WebInspector.HeapSnapshotRootPath.prototype.isEmpty):
(WebInspector.HeapSnapshotRootPath.prototype.isGlobalScope):
(WebInspector.HeapSnapshotRootPath.prototype.isPathComponentImpossible):
(WebInspector.HeapSnapshotRootPath.prototype.isFullPathImpossible):
(WebInspector.HeapSnapshotRootPath.prototype.appendInternal):
(WebInspector.HeapSnapshotRootPath.prototype.appendArrayIndex):
(WebInspector.HeapSnapshotRootPath.prototype.appendPropertyName):
(WebInspector.HeapSnapshotRootPath.prototype.appendVariableName):
(WebInspector.HeapSnapshotRootPath.prototype.appendGlobalScopeName):
(WebInspector.HeapSnapshotRootPath.prototype.appendEdge):
(WebInspector.HeapSnapshotRootPath.prototype._canPropertyNameBeDotAccess):
Helper class, like PropertyPath, for building a string path to
a HeapSnapshotNode. Typically the path is built up with
HeapSnapshotEdges and so you can build a string such as:
`window.foo[0]["prop erty"]._foo`.
* UserInterface/Views/HeapAllocationsTimelineView.js:
(WebInspector.HeapAllocationsTimelineView.prototype.showHeapSnapshotList):
(WebInspector.HeapAllocationsTimelineView.prototype.showHeapSnapshotTimelineRecord):
(WebInspector.HeapAllocationsTimelineView.prototype.showHeapSnapshotDiff):
(WebInspector.HeapAllocationsTimelineView.prototype.shown):
(WebInspector.HeapAllocationsTimelineView.prototype.hidden):
(WebInspector.HeapAllocationsTimelineView.prototype.closed):
Propogate shown/hidden to the contentViewContainer.
Cleanup the contentViewContainer when closing.
* UserInterface/Views/HeapSnapshotInstanceDataGridNode.js:
(WebInspector.HeapSnapshotInstanceDataGridNode.logHeapSnapshotNode):
Helper for logging a HeapSnapshotNode value to the console. If the
path is possible from the root, just output the path in the console
otherwise use a synthetic "Heap Snapshot Object (@1234)" like string.
For strings, just get the preview as we won't get a real RemoteObject.
(WebInspector.HeapSnapshotInstanceDataGridNode.prototype.createCellContent):
(WebInspector.HeapSnapshotInstanceDataGridNode.prototype._mouseoverHandler.appendPath):
(WebInspector.HeapSnapshotInstanceDataGridNode.prototype._mouseoverHandler.appendPathRow):
(WebInspector.HeapSnapshotInstanceDataGridNode.prototype._mouseoverHandler.sanitizeClassName):
(WebInspector.HeapSnapshotInstanceDataGridNode.prototype._mouseoverHandler.stringifyEdge):
(WebInspector.HeapSnapshotInstanceDataGridNode.prototype._mouseoverHandler):
Give the @1234 id element a mouseover handler to display a popover
with the path from a root. Stop the path at "Window" if possible
to avoid displaying internals like "JSDOMWindowShell".
* UserInterface/Views/HeapSnapshotInstancesContentView.css:
(.heap-snapshot .object-id):
(.heap-snapshot .object-id:hover):
(.heap-snapshot > .data-grid tr:not(.selected) td .object-id): Deleted.
(.heap-snapshot .icon):
(.heap-snapshot-instance-popover-content):
(.heap-snapshot-instance-popover-content table):
(.heap-snapshot-instance-popover-content tr):
(.heap-snapshot-instance-popover-content td):
(.heap-snapshot-instance-popover-content td.edge-name):
(.heap-snapshot-instance-popover-content td.object-data):
(.heap-snapshot-instance-popover-content .node):
(.heap-snapshot-instance-popover-content .node *):
Styles for contents of the popover.
* UserInterface/Views/HeapSnapshotInstancesContentView.js:
(WebInspector.HeapSnapshotInstancesContentView.prototype.hidden):
* UserInterface/Views/HeapSnapshotInstancesDataGridTree.js:
(WebInspector.HeapSnapshotInstancesDataGridTree):
(WebInspector.HeapSnapshotInstancesDataGridTree.prototype.get popover):
(WebInspector.HeapSnapshotInstancesDataGridTree.prototype.get popoverNode):
(WebInspector.HeapSnapshotInstancesDataGridTree.prototype.set popoverNode):
(WebInspector.HeapSnapshotInstancesDataGridTree.prototype.hidden):
(WebInspector.HeapSnapshotInstancesDataGridTree.prototype.willDismissPopover):
Have a single popover for the entire tree. Cache and clear
contents of the popover when appropriate.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUILocalizationsenlprojlocalizedStringsjs">trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceMainhtml">trunk/Source/WebInspectorUI/UserInterface/Main.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsHeapSnapshotNodejs">trunk/Source/WebInspectorUI/UserInterface/Models/HeapSnapshotNode.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsHeapAllocationsTimelineViewjs">trunk/Source/WebInspectorUI/UserInterface/Views/HeapAllocationsTimelineView.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsHeapSnapshotInstanceDataGridNodejs">trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstanceDataGridNode.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsHeapSnapshotInstancesContentViewcss">trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstancesContentView.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsHeapSnapshotInstancesContentViewjs">trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstancesContentView.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsHeapSnapshotInstancesDataGridTreejs">trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstancesDataGridTree.js</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsHeapSnapshotRootPathjs">trunk/Source/WebInspectorUI/UserInterface/Models/HeapSnapshotRootPath.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (198195 => 198196)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2016-03-15 04:59:39 UTC (rev 198195)
+++ trunk/Source/WebInspectorUI/ChangeLog        2016-03-15 05:02:28 UTC (rev 198196)
</span><span class="lines">@@ -1,3 +1,100 @@
</span><ins>+2016-03-14 Joseph Pecoraro <pecoraro@apple.com>
+
+ Web Inspector: Show path from root to instances in the Heap Snapshot content view
+ https://bugs.webkit.org/show_bug.cgi?id=155478
+ <rdar://problem/25157408>
+
+ Reviewed by Timothy Hatcher.
+
+ * Localizations/en.lproj/localizedStrings.js:
+ * UserInterface/Main.html:
+ New strings and resources.
+
+ * UserInterface/Models/HeapSnapshotNode.js:
+ (WebInspector.HeapSnapshotNode.prototype.get shortestGCRootPath):
+ (WebInspector.HeapSnapshotNode.prototype._gcRootPaths.visitNode):
+ (WebInspector.HeapSnapshotNode.prototype._gcRootPaths):
+ Helper to get the shortest path from a GC root to the node.
+
+ * UserInterface/Models/HeapSnapshotRootPath.js: Added.
+ (WebInspector.HeapSnapshotRootPath):
+ (WebInspector.HeapSnapshotRootPath.emptyPath):
+ (WebInspector.HeapSnapshotRootPath.prototype.get node):
+ (WebInspector.HeapSnapshotRootPath.prototype.get parent):
+ (WebInspector.HeapSnapshotRootPath.prototype.get pathComponent):
+ (WebInspector.HeapSnapshotRootPath.prototype.get rootNode):
+ (WebInspector.HeapSnapshotRootPath.prototype.get fullPath):
+ (WebInspector.HeapSnapshotRootPath.prototype.isRoot):
+ (WebInspector.HeapSnapshotRootPath.prototype.isEmpty):
+ (WebInspector.HeapSnapshotRootPath.prototype.isGlobalScope):
+ (WebInspector.HeapSnapshotRootPath.prototype.isPathComponentImpossible):
+ (WebInspector.HeapSnapshotRootPath.prototype.isFullPathImpossible):
+ (WebInspector.HeapSnapshotRootPath.prototype.appendInternal):
+ (WebInspector.HeapSnapshotRootPath.prototype.appendArrayIndex):
+ (WebInspector.HeapSnapshotRootPath.prototype.appendPropertyName):
+ (WebInspector.HeapSnapshotRootPath.prototype.appendVariableName):
+ (WebInspector.HeapSnapshotRootPath.prototype.appendGlobalScopeName):
+ (WebInspector.HeapSnapshotRootPath.prototype.appendEdge):
+ (WebInspector.HeapSnapshotRootPath.prototype._canPropertyNameBeDotAccess):
+ Helper class, like PropertyPath, for building a string path to
+ a HeapSnapshotNode. Typically the path is built up with
+ HeapSnapshotEdges and so you can build a string such as:
+ `window.foo[0]["prop erty"]._foo`.
+
+ * UserInterface/Views/HeapAllocationsTimelineView.js:
+ (WebInspector.HeapAllocationsTimelineView.prototype.showHeapSnapshotList):
+ (WebInspector.HeapAllocationsTimelineView.prototype.showHeapSnapshotTimelineRecord):
+ (WebInspector.HeapAllocationsTimelineView.prototype.showHeapSnapshotDiff):
+ (WebInspector.HeapAllocationsTimelineView.prototype.shown):
+ (WebInspector.HeapAllocationsTimelineView.prototype.hidden):
+ (WebInspector.HeapAllocationsTimelineView.prototype.closed):
+ Propogate shown/hidden to the contentViewContainer.
+ Cleanup the contentViewContainer when closing.
+
+ * UserInterface/Views/HeapSnapshotInstanceDataGridNode.js:
+ (WebInspector.HeapSnapshotInstanceDataGridNode.logHeapSnapshotNode):
+ Helper for logging a HeapSnapshotNode value to the console. If the
+ path is possible from the root, just output the path in the console
+ otherwise use a synthetic "Heap Snapshot Object (@1234)" like string.
+ For strings, just get the preview as we won't get a real RemoteObject.
+
+ (WebInspector.HeapSnapshotInstanceDataGridNode.prototype.createCellContent):
+ (WebInspector.HeapSnapshotInstanceDataGridNode.prototype._mouseoverHandler.appendPath):
+ (WebInspector.HeapSnapshotInstanceDataGridNode.prototype._mouseoverHandler.appendPathRow):
+ (WebInspector.HeapSnapshotInstanceDataGridNode.prototype._mouseoverHandler.sanitizeClassName):
+ (WebInspector.HeapSnapshotInstanceDataGridNode.prototype._mouseoverHandler.stringifyEdge):
+ (WebInspector.HeapSnapshotInstanceDataGridNode.prototype._mouseoverHandler):
+ Give the @1234 id element a mouseover handler to display a popover
+ with the path from a root. Stop the path at "Window" if possible
+ to avoid displaying internals like "JSDOMWindowShell".
+
+ * UserInterface/Views/HeapSnapshotInstancesContentView.css:
+ (.heap-snapshot .object-id):
+ (.heap-snapshot .object-id:hover):
+ (.heap-snapshot > .data-grid tr:not(.selected) td .object-id): Deleted.
+ (.heap-snapshot .icon):
+ (.heap-snapshot-instance-popover-content):
+ (.heap-snapshot-instance-popover-content table):
+ (.heap-snapshot-instance-popover-content tr):
+ (.heap-snapshot-instance-popover-content td):
+ (.heap-snapshot-instance-popover-content td.edge-name):
+ (.heap-snapshot-instance-popover-content td.object-data):
+ (.heap-snapshot-instance-popover-content .node):
+ (.heap-snapshot-instance-popover-content .node *):
+ Styles for contents of the popover.
+
+ * UserInterface/Views/HeapSnapshotInstancesContentView.js:
+ (WebInspector.HeapSnapshotInstancesContentView.prototype.hidden):
+ * UserInterface/Views/HeapSnapshotInstancesDataGridTree.js:
+ (WebInspector.HeapSnapshotInstancesDataGridTree):
+ (WebInspector.HeapSnapshotInstancesDataGridTree.prototype.get popover):
+ (WebInspector.HeapSnapshotInstancesDataGridTree.prototype.get popoverNode):
+ (WebInspector.HeapSnapshotInstancesDataGridTree.prototype.set popoverNode):
+ (WebInspector.HeapSnapshotInstancesDataGridTree.prototype.hidden):
+ (WebInspector.HeapSnapshotInstancesDataGridTree.prototype.willDismissPopover):
+ Have a single popover for the entire tree. Cache and clear
+ contents of the popover when appropriate.
+
</ins><span class="cx"> 2016-03-14 Daniel Bates <dabates@apple.com>
</span><span class="cx">
</span><span class="cx"> Web Inspector: Display Content Security Policy hash in details sidebar for script and style elements
</span></span></pre></div>
<a id="trunkSourceWebInspectorUILocalizationsenlprojlocalizedStringsjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (198195 => 198196)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js        2016-03-15 04:59:39 UTC (rev 198195)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js        2016-03-15 05:02:28 UTC (rev 198196)
</span><span class="lines">@@ -20,7 +20,6 @@
</span><span class="cx"> localizedStrings["%d Errors, %d Warnings"] = "%d Errors, %d Warnings";
</span><span class="cx"> localizedStrings["%d More\u2026"] = "%d More\u2026";
</span><span class="cx"> localizedStrings["%d Warnings"] = "%d Warnings";
</span><del>-localizedStrings["%d \u2A09 %d"] = "%d \u2A09 %d";
</del><span class="cx"> localizedStrings["%d \xd7 %d pixels"] = "%d \xd7 %d pixels";
</span><span class="cx"> localizedStrings["%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)"] = "%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)";
</span><span class="cx"> localizedStrings["%d matches"] = "%d matches";
</span><span class="lines">@@ -118,6 +117,7 @@
</span><span class="cx"> localizedStrings["Breakdown of total allocation size by class"] = "Breakdown of total allocation size by class";
</span><span class="cx"> localizedStrings["Bubbling"] = "Bubbling";
</span><span class="cx"> localizedStrings["Busy"] = "Busy";
</span><ins>+localizedStrings["CSP Hash"] = "CSP Hash";
</ins><span class="cx"> localizedStrings["Cached"] = "Cached";
</span><span class="cx"> localizedStrings["Call Stack"] = "Call Stack";
</span><span class="cx"> localizedStrings["Call Trees"] = "Call Trees";
</span><span class="lines">@@ -188,7 +188,6 @@
</span><span class="cx"> localizedStrings["Container Regions"] = "Container Regions";
</span><span class="cx"> localizedStrings["Content"] = "Content";
</span><span class="cx"> localizedStrings["Content Flow"] = "Content Flow";
</span><del>-localizedStrings["CSP Hash"] = "CSP Hash";
</del><span class="cx"> localizedStrings["Content Security Policy violation of directive: %s"] = "Content Security Policy violation of directive: %s";
</span><span class="cx"> localizedStrings["Continue script execution (%s or %s)"] = "Continue script execution (%s or %s)";
</span><span class="cx"> localizedStrings["Continue to Here"] = "Continue to Here";
</span><span class="lines">@@ -566,7 +565,6 @@
</span><span class="cx"> localizedStrings["Readonly"] = "Readonly";
</span><span class="cx"> localizedStrings["Reasons for compositing:"] = "Reasons for compositing:";
</span><span class="cx"> localizedStrings["Recording"] = "Recording";
</span><del>-localizedStrings["Records"] = "Records";
</del><span class="cx"> localizedStrings["Reference Issue"] = "Reference Issue";
</span><span class="cx"> localizedStrings["Reflection"] = "Reflection";
</span><span class="cx"> localizedStrings["Refresh"] = "Refresh";
</span><span class="lines">@@ -603,6 +601,7 @@
</span><span class="cx"> localizedStrings["Role"] = "Role";
</span><span class="cx"> localizedStrings["Samples"] = "Samples";
</span><span class="cx"> localizedStrings["Scheme"] = "Scheme";
</span><ins>+localizedStrings["Scope"] = "Scope";
</ins><span class="cx"> localizedStrings["Scope Chain"] = "Scope Chain";
</span><span class="cx"> localizedStrings["Script"] = "Script";
</span><span class="cx"> localizedStrings["Script Evaluated"] = "Script Evaluated";
</span><span class="lines">@@ -657,7 +656,6 @@
</span><span class="cx"> localizedStrings["Snapshot %d"] = "Snapshot %d";
</span><span class="cx"> localizedStrings["Snapshot Comparison (%d and %d)"] = "Snapshot Comparison (%d and %d)";
</span><span class="cx"> localizedStrings["Snapshot List"] = "Snapshot List";
</span><del>-localizedStrings["Snapshots"] = "Snapshots";
</del><span class="cx"> localizedStrings["Socket"] = "Socket";
</span><span class="cx"> localizedStrings["Sockets"] = "Sockets";
</span><span class="cx"> localizedStrings["Sort Ascending"] = "Sort Ascending";
</span><span class="lines">@@ -705,6 +703,8 @@
</span><span class="cx"> localizedStrings["The webkit prefix is needed for this property.\nClick to insert a duplicate with the prefix."] = "The webkit prefix is needed for this property.\nClick to insert a duplicate with the prefix.";
</span><span class="cx"> localizedStrings["The webkit prefix is not necessary.\nClick to insert a duplicate without the prefix."] = "The webkit prefix is not necessary.\nClick to insert a duplicate without the prefix.";
</span><span class="cx"> localizedStrings["This Element"] = "This Element";
</span><ins>+localizedStrings["This object is a root"] = "This object is a root";
+localizedStrings["This object is referenced by internal objects"] = "This object is referenced by internal objects";
</ins><span class="cx"> localizedStrings["This property needs a value.\nClick to open autocomplete."] = "This property needs a value.\nClick to open autocomplete.";
</span><span class="cx"> localizedStrings["Time"] = "Time";
</span><span class="cx"> localizedStrings["Time until the load event fired, click to show the Network Requests timeline"] = "Time until the load event fired, click to show the Network Requests timeline";
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceMainhtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (198195 => 198196)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Main.html        2016-03-15 04:59:39 UTC (rev 198195)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html        2016-03-15 05:02:28 UTC (rev 198196)
</span><span class="lines">@@ -308,8 +308,8 @@
</span><span class="cx"> <script src="Models/DefaultDashboard.js"></script>
</span><span class="cx"> <script src="Models/ExecutionContext.js"></script>
</span><span class="cx"> <script src="Models/ExecutionContextList.js"></script>
</span><ins>+ <script src="Models/FPSInstrument.js"></script>
</ins><span class="cx"> <script src="Models/Frame.js"></script>
</span><del>- <script src="Models/FPSInstrument.js"></script>
</del><span class="cx"> <script src="Models/GarbageCollection.js"></script>
</span><span class="cx"> <script src="Models/Geometry.js"></script>
</span><span class="cx"> <script src="Models/Gradient.js"></script>
</span><span class="lines">@@ -319,6 +319,7 @@
</span><span class="cx"> <script src="Models/HeapSnapshotDiff.js"></script>
</span><span class="cx"> <script src="Models/HeapSnapshotEdge.js"></script>
</span><span class="cx"> <script src="Models/HeapSnapshotNode.js"></script>
</span><ins>+ <script src="Models/HeapSnapshotRootPath.js"></script>
</ins><span class="cx"> <script src="Models/IndexedDatabase.js"></script>
</span><span class="cx"> <script src="Models/IndexedDatabaseObjectStore.js"></script>
</span><span class="cx"> <script src="Models/IndexedDatabaseObjectStoreIndex.js"></script>
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsHeapSnapshotNodejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/HeapSnapshotNode.js (198195 => 198196)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/HeapSnapshotNode.js        2016-03-15 04:59:39 UTC (rev 198195)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/HeapSnapshotNode.js        2016-03-15 05:02:28 UTC (rev 198196)
</span><span class="lines">@@ -35,4 +35,62 @@
</span><span class="cx"> this.outgoingEdges = [];
</span><span class="cx"> this.incomingEdges = [];
</span><span class="cx"> }
</span><ins>+
+ // Public
+
+ get shortestGCRootPath()
+ {
+ // Returns an array from this node to a gcRoot node.
+ // E.g. [Node, Edge, Node, Edge, Node].
+ // Internal nodes are avoided, so if the path is empty this
+ // node is either a gcRoot or only reachable via Internal nodes.
+
+ if (this._shortestGCRootPath !== undefined)
+ return this._shortestGCRootPath;
+
+ let paths = this._gcRootPaths();
+ paths.sort((a, b) => a.length - b.length);
+ this._shortestGCRootPath = paths[0] || null;
+
+ return this._shortestGCRootPath;
+ }
+
+ // Private
+
+ _gcRootPaths()
+ {
+ if (this.gcRoot)
+ return [];
+
+ let paths = [];
+ let currentPath = [];
+ let visitedSet = new Set;
+
+ function visitNode(node) {
+ if (node.gcRoot) {
+ let fullPath = currentPath.slice();
+ fullPath.push(node);
+ paths.push(fullPath);
+ return;
+ }
+
+ if (visitedSet.has(node))
+ return;
+ visitedSet.add(node);
+
+ currentPath.push(node);
+ for (let parentEdge of node.incomingEdges) {
+ if (parentEdge.from.internal)
+ continue;
+ currentPath.push(parentEdge);
+ visitNode(parentEdge.from);
+ currentPath.pop();
+ }
+ currentPath.pop();
+ }
+
+ visitNode(this);
+
+ return paths;
+ }
</ins><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsHeapSnapshotRootPathjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Models/HeapSnapshotRootPath.js (0 => 198196)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/HeapSnapshotRootPath.js         (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/HeapSnapshotRootPath.js        2016-03-15 05:02:28 UTC (rev 198196)
</span><span class="lines">@@ -0,0 +1,165 @@
</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.HeapSnapshotRootPath = class HeapSnapshotRootPath extends WebInspector.Object
+{
+ constructor(node, pathComponent, parent, isGlobalScope)
+ {
+ super();
+
+ console.assert(!node || node instanceof WebInspector.HeapSnapshotNode);
+ console.assert(!pathComponent || typeof pathComponent === "string");
+ console.assert(!parent || parent instanceof WebInspector.HeapSnapshotRootPath);
+
+ this._node = node || null;
+ this._parent = parent || null;
+ this._pathComponent = typeof pathComponent === "string" ? pathComponent : null;
+ this._isGlobalScope = isGlobalScope || false;
+
+ // Become the new root when appended to an empty path.
+ if (this._parent && this._parent.isEmpty())
+ this._parent = null;
+ }
+
+ // Static
+
+ static emptyPath()
+ {
+ return new WebInspector.HeapSnapshotRootPath(null);
+ }
+
+ // Public
+
+ get node() { return this._node; }
+ get parent() { return this._parent; }
+ get pathComponent() { return this._pathComponent; }
+
+ get rootNode()
+ {
+ return this._parent ? this._parent.rootNode : this._node;
+ }
+
+ get fullPath()
+ {
+ let components = [];
+ for (let p = this; p && p.pathComponent; p = p.parent)
+ components.push(p.pathComponent);
+ components.reverse();
+ return components.join("");
+ }
+
+ isRoot()
+ {
+ return !this._parent;
+ }
+
+ isEmpty()
+ {
+ return !this._node;
+ }
+
+ isGlobalScope()
+ {
+ return this._isGlobalScope;
+ }
+
+ isPathComponentImpossible()
+ {
+ return this._pathComponent && this._pathComponent.startsWith("@");
+ }
+
+ isFullPathImpossible()
+ {
+ if (this.isEmpty())
+ return true;
+
+ if (this.isPathComponentImpossible())
+ return true;
+
+ if (this._parent)
+ return this._parent.isFullPathImpossible();
+
+ return false;
+ }
+
+ appendInternal(node)
+ {
+ return new WebInspector.HeapSnapshotRootPath(node, WebInspector.HeapSnapshotRootPath.SpecialPathComponent.InternalPropertyName, this);
+ }
+
+ appendArrayIndex(node, index)
+ {
+ let component = "[" + index + "]";
+ return new WebInspector.HeapSnapshotRootPath(node, component, this);
+ }
+
+ appendPropertyName(node, propertyName)
+ {
+ let component = this._canPropertyNameBeDotAccess(propertyName) ? "." + propertyName : "[" + doubleQuotedString(propertyName) + "]";
+ return new WebInspector.HeapSnapshotRootPath(node, component, this);
+ }
+
+ appendVariableName(node, variableName)
+ {
+ // Treat as a property of the global object, e.g. "window.foo".
+ if (this._isGlobalScope)
+ return this.appendPropertyName(node, variableName);
+ return new WebInspector.HeapSnapshotRootPath(node, variableName, this);
+ }
+
+ appendGlobalScopeName(node, globalScopeName)
+ {
+ return new WebInspector.HeapSnapshotRootPath(node, globalScopeName, this, true);
+ }
+
+ appendEdge(edge)
+ {
+ console.assert(edge instanceof WebInspector.HeapSnapshotEdge);
+
+ switch (edge.type) {
+ case WebInspector.HeapSnapshotEdge.EdgeType.Internal:
+ return this.appendInternal(edge.to);
+ case WebInspector.HeapSnapshotEdge.EdgeType.Index:
+ return this.appendArrayIndex(edge.to, edge.data);
+ case WebInspector.HeapSnapshotEdge.EdgeType.Property:
+ return this.appendPropertyName(edge.to, edge.data);
+ case WebInspector.HeapSnapshotEdge.EdgeType.Variable:
+ return this.appendVariableName(edge.to, edge.data);
+ }
+
+ console.error("Unexpected edge type", edge.type);
+ }
+
+ // Private
+
+ _canPropertyNameBeDotAccess(propertyName)
+ {
+ return /^(?![0-9])\w+$/.test(propertyName);
+ }
+};
+
+WebInspector.HeapSnapshotRootPath.SpecialPathComponent = {
+ InternalPropertyName: "@internal",
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsHeapAllocationsTimelineViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/HeapAllocationsTimelineView.js (198195 => 198196)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/HeapAllocationsTimelineView.js        2016-03-15 04:59:39 UTC (rev 198195)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/HeapAllocationsTimelineView.js        2016-03-15 05:02:28 UTC (rev 198196)
</span><span class="lines">@@ -101,6 +101,7 @@
</span><span class="cx"> this._heapSnapshotDiff = null;
</span><span class="cx"> this._cancelSelectComparisonHeapSnapshots();
</span><span class="cx">
</span><ins>+ this._contentViewContainer.hidden();
</ins><span class="cx"> this.removeSubview(this._contentViewContainer);
</span><span class="cx"> this.addSubview(this._dataGrid);
</span><span class="cx">
</span><span class="lines">@@ -113,6 +114,7 @@
</span><span class="cx"> if (this._showingSnapshotList) {
</span><span class="cx"> this.removeSubview(this._dataGrid);
</span><span class="cx"> this.addSubview(this._contentViewContainer);
</span><ins>+ this._contentViewContainer.shown();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> this._showingSnapshotList = false;
</span><span class="lines">@@ -139,6 +141,7 @@
</span><span class="cx"> if (this._showingSnapshotList) {
</span><span class="cx"> this.removeSubview(this._dataGrid);
</span><span class="cx"> this.addSubview(this._contentViewContainer);
</span><ins>+ this._contentViewContainer.shown();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> this._showingSnapshotList = false;
</span><span class="lines">@@ -189,10 +192,28 @@
</span><span class="cx"> this.showHeapSnapshotTimelineRecord(timelineRecord);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ shown()
+ {
+ super.shown();
+
+ if (!this._showingSnapshotList)
+ this._contentViewContainer.shown();
+ }
+
+ hidden()
+ {
+ super.hidden();
+
+ if (!this._showingSnapshotList)
+ this._contentViewContainer.hidden();
+ }
+
</ins><span class="cx"> closed()
</span><span class="cx"> {
</span><span class="cx"> console.assert(this.representedObject instanceof WebInspector.Timeline);
</span><span class="cx"> this.representedObject.removeEventListener(null, null, this);
</span><ins>+
+ this._contentViewContainer.closeAllContentViews();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> layout()
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsHeapSnapshotInstanceDataGridNodejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstanceDataGridNode.js (198195 => 198196)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstanceDataGridNode.js        2016-03-15 04:59:39 UTC (rev 198195)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstanceDataGridNode.js        2016-03-15 05:02:28 UTC (rev 198196)
</span><span class="lines">@@ -40,6 +40,51 @@
</span><span class="cx"> this._percent = (this._node.size / this._tree._heapSnapshot.totalSize) * 100;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ // Static
+
+ static logHeapSnapshotNode(node)
+ {
+ let heapObjectIdentifier = node.id;
+
+ let synthetic = true;
+ let text = WebInspector.UIString("Heap Snapshot Object (@%d)").format(heapObjectIdentifier);
+
+ let gcRootPath = node.shortestGCRootPath;
+ if (gcRootPath) {
+ gcRootPath = gcRootPath.slice().reverse();
+ let windowIndex = gcRootPath.findIndex((x) => {
+ return x instanceof WebInspector.HeapSnapshotNode && x.className === "Window";
+ });
+
+ let heapSnapshotRootPath = WebInspector.HeapSnapshotRootPath.emptyPath();
+ for (let i = windowIndex === -1 ? 0 : windowIndex; i < gcRootPath.length; ++i) {
+ let component = gcRootPath[i];
+ if (component instanceof WebInspector.HeapSnapshotNode) {
+ if (component.className === "Window")
+ heapSnapshotRootPath = heapSnapshotRootPath.appendGlobalScopeName(component, "window");
+ } else if (component instanceof WebInspector.HeapSnapshotEdge)
+ heapSnapshotRootPath = heapSnapshotRootPath.appendEdge(component);
+ }
+
+ if (!heapSnapshotRootPath.isFullPathImpossible()) {
+ synthetic = false;
+ text = heapSnapshotRootPath.fullPath;
+ }
+ }
+
+ if (node.className === "string") {
+ HeapAgent.getPreview(heapObjectIdentifier, function(error, string, functionDetails, objectPreviewPayload) {
+ let remoteObject = error ? WebInspector.RemoteObject.fromPrimitiveValue(undefined) : WebInspector.RemoteObject.fromPrimitiveValue(string);
+ WebInspector.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, synthetic);
+ });
+ } else {
+ HeapAgent.getRemoteObject(heapObjectIdentifier, WebInspector.RuntimeManager.ConsoleObjectGroup, function(error, remoteObjectPayload) {
+ let remoteObject = error ? WebInspector.RemoteObject.fromPrimitiveValue(undefined) : WebInspector.RemoteObject.fromPayload(remoteObjectPayload);
+ WebInspector.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, synthetic);
+ });
+ }
+ }
+
</ins><span class="cx"> // Protected
</span><span class="cx">
</span><span class="cx"> get data() { return this._node; }
</span><span class="lines">@@ -77,8 +122,13 @@
</span><span class="cx">
</span><span class="cx"> let idElement = containerElement.appendChild(document.createElement("span"));
</span><span class="cx"> idElement.classList.add("object-id");
</span><del>- idElement.textContent = "@" + id + " ";
</del><ins>+ idElement.textContent = "@" + id;
+ idElement.addEventListener("click", WebInspector.HeapSnapshotInstanceDataGridNode.logHeapSnapshotNode.bind(null, this._node));
+ idElement.addEventListener("mouseover", this._mouseoverHandler.bind(this));
</ins><span class="cx">
</span><ins>+ let spacerElement = containerElement.appendChild(document.createElement("span"));
+ spacerElement.textContent = " ";
+
</ins><span class="cx"> HeapAgent.getPreview(id, (error, string, functionDetails, objectPreviewPayload) => {
</span><span class="cx"> if (error) {
</span><span class="cx"> let previewErrorElement = containerElement.appendChild(document.createElement("span"));
</span><span class="lines">@@ -137,17 +187,116 @@
</span><span class="cx"> _contextMenuHandler(event)
</span><span class="cx"> {
</span><span class="cx"> let contextMenu = WebInspector.ContextMenu.createFromEvent(event);
</span><del>-
</del><span class="cx"> contextMenu.appendSeparator();
</span><ins>+ contextMenu.appendItem(WebInspector.UIString("Log Value"), WebInspector.HeapSnapshotInstanceDataGridNode.logHeapSnapshotNode.bind(null, this._node));
+ }
</ins><span class="cx">
</span><del>- contextMenu.appendItem(WebInspector.UIString("Log Value"), () => {
- let heapObjectIdentifier = this._node.id;
- HeapAgent.getRemoteObject(heapObjectIdentifier, WebInspector.RuntimeManager.ConsoleObjectGroup, function(error, remoteObjectPayload) {
- const synthetic = true;
- let remoteObject = error ? WebInspector.RemoteObject.fromPrimitive(undefined) : WebInspector.RemoteObject.fromPayload(remoteObjectPayload);
- let text = WebInspector.UIString("Heap Snapshot Object (@%d)").format(heapObjectIdentifier);
- WebInspector.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, synthetic);
</del><ins>+ _mouseoverHandler(event)
+ {
+ let targetFrame = WebInspector.Rect.rectFromClientRect(event.target.getBoundingClientRect());
+ if (!targetFrame.size.width && !targetFrame.size.height)
+ return;
+
+ if (this._tree.popoverNode === this._node)
+ return;
+
+ this._tree.popoverNode = this._node;
+
+ let popoverContentElement = document.createElement("div");
+ popoverContentElement.classList.add("heap-snapshot", "heap-snapshot-instance-popover-content");
+
+ function appendPath(path) {
+ let tableElement = popoverContentElement.appendChild(document.createElement("table"));
+ tableElement.classList.add("table");
+
+ path = path.slice().reverse();
+ let windowIndex = path.findIndex((x) => {
+ return x instanceof WebInspector.HeapSnapshotNode && x.className === "Window";
</ins><span class="cx"> });
</span><del>- });
</del><ins>+
+ let edge = null;
+ for (let i = windowIndex === -1 ? 0 : windowIndex; i < path.length; ++i) {
+ let component = path[i];
+ if (component instanceof WebInspector.HeapSnapshotEdge) {
+ edge = component;
+ continue;
+ }
+ appendPathRow(tableElement, edge, component);
+ edge = null;
+ }
+ }
+
+ function appendPathRow(tableElement, edge, node) {
+ let tableRow = tableElement.appendChild(document.createElement("tr"));
+
+ // Edge name.
+ let pathDataElement = tableRow.appendChild(document.createElement("td"));
+ pathDataElement.classList.add("edge-name");
+
+ if (node.className === "Window")
+ pathDataElement.textContent = "window";
+ else if (edge) {
+ let edgeString = stringifyEdge(edge);
+ pathDataElement.textContent = typeof edgeString === "string" ? edgeString : emDash;
+ } else
+ pathDataElement.textContent = emDash;
+
+ if (pathDataElement.textContent.length > 10)
+ pathDataElement.title = pathDataElement.textContent;
+
+ // Object.
+ let objectDataElement = tableRow.appendChild(document.createElement("td"));
+ objectDataElement.classList.add("object-data");
+
+ let containerElement = objectDataElement.appendChild(document.createElement("div"));
+ containerElement.classList.add("node");
+
+ let iconElement = containerElement.appendChild(document.createElement("img"));
+ iconElement.classList.add("icon", WebInspector.HeapSnapshotClusterContentView.iconStyleClassNameForClassName(node.className, node.internal));
+
+ let classNameElement = containerElement.appendChild(document.createElement("span"));
+ classNameElement.textContent = sanitizeClassName(node.className);
+
+ let idElement = containerElement.appendChild(document.createElement("span"));
+ idElement.classList.add("object-id");
+ idElement.textContent = " @" + node.id;
+ idElement.addEventListener("click", WebInspector.HeapSnapshotInstanceDataGridNode.logHeapSnapshotNode.bind(null, node));
+ }
+
+ function sanitizeClassName(className) {
+ if (className.endsWith("LexicalEnvironment"))
+ return WebInspector.UIString("Scope");
+ return className;
+ }
+
+ function stringifyEdge(edge) {
+ switch(edge.type) {
+ case WebInspector.HeapSnapshotEdge.EdgeType.Property:
+ case WebInspector.HeapSnapshotEdge.EdgeType.Variable:
+ if (/^(?![0-9])\w+$/.test(edge.data))
+ return edge.data;
+ return "[" + doubleQuotedString(edge.data) + "]";
+ case WebInspector.HeapSnapshotEdge.EdgeType.Index:
+ return "[" + edge.data + "]";
+ case WebInspector.HeapSnapshotEdge.EdgeType.Internal:
+ default:
+ return null;
+ }
+ }
+
+ if (this._node.gcRoot) {
+ let textElement = popoverContentElement.appendChild(document.createElement("div"));
+ textElement.textContent = WebInspector.UIString("This object is a root");
+ } else {
+ let path = this._node.shortestGCRootPath;
+ if (path)
+ appendPath(path);
+ else {
+ let emptyElement = popoverContentElement.appendChild(document.createElement("div"));
+ emptyElement.textContent = WebInspector.UIString("This object is referenced by internal objects");
+ }
+ }
+
+ this._tree.popover.presentNewContentWithFrame(popoverContentElement, targetFrame.pad(2), [WebInspector.RectEdge.MAX_Y, WebInspector.RectEdge.MIN_Y, WebInspector.RectEdge.MAX_X]);
</ins><span class="cx"> }
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsHeapSnapshotInstancesContentViewcss"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstancesContentView.css (198195 => 198196)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstancesContentView.css        2016-03-15 04:59:39 UTC (rev 198195)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstancesContentView.css        2016-03-15 05:02:28 UTC (rev 198196)
</span><span class="lines">@@ -37,10 +37,14 @@
</span><span class="cx"> display: inline-block;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-.heap-snapshot > .data-grid tr:not(.selected) td .object-id {
</del><ins>+.heap-snapshot .object-id {
</ins><span class="cx"> color: gray;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+.heap-snapshot .object-id:hover {
+ text-decoration: underline;
+}
+
</ins><span class="cx"> .heap-snapshot > .data-grid tr:not(.selected) td .preview-error {
</span><span class="cx"> color: red;
</span><span class="cx"> }
</span><span class="lines">@@ -75,7 +79,7 @@
</span><span class="cx"> width: 16px;
</span><span class="cx"> height: 16px;
</span><span class="cx"> margin-top: 1px;
</span><del>- margin-right: 3px;
</del><ins>+ margin-right: 4px;
</ins><span class="cx"> content: url(../Images/TypeUndefined.svg);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -121,3 +125,46 @@
</span><span class="cx"> display: inline-block;
</span><span class="cx"> height: 16px;
</span><span class="cx"> }
</span><ins>+
+.heap-snapshot-instance-popover-content {
+ white-space: pre;
+ padding: 5px 10px;
+}
+
+.heap-snapshot-instance-popover-content table {
+ border-collapse: collapse;
+}
+
+.heap-snapshot-instance-popover-content tr {
+ margin: 0;
+ padding: 1px 0;
+}
+
+.heap-snapshot-instance-popover-content td {
+ margin: 0;
+ padding: 0;
+}
+
+.heap-snapshot-instance-popover-content td.edge-name {
+ text-align: right;
+ max-width: 110px;
+ text-overflow: ellipsis;
+ overflow: hidden;
+
+ border-right: 1px solid var(--border-color);
+ padding-right: 5px;
+}
+
+.heap-snapshot-instance-popover-content td.object-data {
+ padding-left: 5px;
+}
+
+.heap-snapshot-instance-popover-content .node {
+ height: 17px;
+ line-height: 17px;
+}
+
+.heap-snapshot-instance-popover-content .node * {
+ display: inline-block;
+ vertical-align: top;
+}
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsHeapSnapshotInstancesContentViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstancesContentView.js (198195 => 198196)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstancesContentView.js        2016-03-15 04:59:39 UTC (rev 198195)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstancesContentView.js        2016-03-15 05:02:28 UTC (rev 198196)
</span><span class="lines">@@ -87,6 +87,15 @@
</span><span class="cx"> this._sortDataGrid();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ // Protected
+
+ hidden()
+ {
+ super.hidden();
+
+ this._heapSnapshotDataGridTree.hidden();
+ }
+
</ins><span class="cx"> // Private
</span><span class="cx">
</span><span class="cx"> _sortDataGrid()
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsHeapSnapshotInstancesDataGridTreejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstancesDataGridTree.js (198195 => 198196)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstancesDataGridTree.js        2016-03-15 04:59:39 UTC (rev 198195)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstancesDataGridTree.js        2016-03-15 05:02:28 UTC (rev 198196)
</span><span class="lines">@@ -37,6 +37,9 @@
</span><span class="cx"> this._sortComparator = sortComparator;
</span><span class="cx"> this._includeInternalObjects = includeInternalObjects;
</span><span class="cx">
</span><ins>+ this._popover = null;
+ this._popoverNode = null;
+
</ins><span class="cx"> this._populateTopLevel();
</span><span class="cx"> this.sort();
</span><span class="cx"> }
</span><span class="lines">@@ -80,6 +83,24 @@
</span><span class="cx"> this.sort();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ get popover()
+ {
+ if (!this._popover)
+ this._popover = new WebInspector.Popover(this);
+
+ return this._popover;
+ }
+
+ get popoverNode()
+ {
+ return this._popoverNode;
+ }
+
+ set popoverNode(x)
+ {
+ this._popoverNode = x;
+ }
+
</ins><span class="cx"> get children()
</span><span class="cx"> {
</span><span class="cx"> return this._children;
</span><span class="lines">@@ -117,6 +138,19 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ hidden()
+ {
+ if (this._popover && this._popover.visible)
+ this._popover.dismiss();
+ }
+
+ // Popover delegate
+
+ willDismissPopover(popover)
+ {
+ this._popoverNode = null;
+ }
+
</ins><span class="cx"> // Private
</span><span class="cx">
</span><span class="cx"> _populateTopLevel()
</span></span></pre>
</div>
</div>
</body>
</html>