<!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>[180713] 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/180713">180713</a></dd>
<dt>Author</dt> <dd>joepeck@webkit.org</dd>
<dt>Date</dt> <dd>2015-02-26 17:15:15 -0800 (Thu, 26 Feb 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: New ObjectTree UI for Arrays / Maps / Sets
https://bugs.webkit.org/show_bug.cgi?id=142037

Reviewed by Timothy Hatcher.

* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Main.html:
Miscellaneous changes.

* UserInterface/Models/PropertyDescriptor.js:
(WebInspector.PropertyDescriptor.prototype.isIndexProperty):
Useful for quickly checking if this property is numeric and possibly
an array index.

* UserInterface/Models/PropertyPath.js:
(WebInspector.PropertyPath.prototype.appendMapKey):
(WebInspector.PropertyPath.prototype.appendMapValue):
(WebInspector.PropertyPath.prototype.appendSetIndex):
Be specific about property paths into maps / sets. Note that a map
value may be displayable if the key is simple.

* UserInterface/Protocol/RemoteObject.js:
(WebInspector.RemoteObject.prototype.hasValue):
A simple value RemoteObject may have the value &quot;undefined&quot;. So provide
a falsey proof helper that actually checks if we have a value.

(WebInspector.RemoteObject.prototype.isArray):
(WebInspector.RemoteObject.prototype.backendGetOwnPropertyDescriptor):
(WebInspector.RemoteObject.prototype.wrappedCallback):
(WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor):
Currently backend APIs exist only to get all properties. In the case
of collections, we often want to get only one property (__proto__).
This is a simple implementation on top of callFunctionOn.

* UserInterface/Views/ConsoleMessageImpl.js:
(WebInspector.ConsoleMessageImpl.prototype._formatParameterAsObject):
(WebInspector.ConsoleMessageImpl.prototype._formatParameterAsArray):
(WebInspector.ConsoleMessageImpl.prototype.appendUndefined): Deleted.
(WebInspector.ConsoleMessageImpl.prototype._printArray): Deleted.
(WebInspector.ConsoleMessageImpl.prototype._formatAsArrayEntry): Deleted.
Simplify array formatted to just use an ObjectTreeView. Add fixmes
that we should seed the ObjectTreeView with a starting property path.

* UserInterface/Views/FormattedValue.css:
(.formatted-node &gt; ol):
Sometimes, a node's display was getting overridden by various console styles.
Force a node to always display block. We may be able to remove this later.

* UserInterface/Views/FormattedValue.js:
(WebInspector.FormattedValue.createObjectTreeOrFormattedValueForRemoteObject):
Helper for formatting a node / object / value more easily. This
is used by all collection types.

* UserInterface/Views/ObjectPreviewView.js:
(WebInspector.ObjectPreviewView.prototype._appendPropertyPreviews):
We lost the nice sparse array support when switching to the new preview path,
we should add it back.

* UserInterface/Views/ObjectTreeArrayIndexTreeElement.css:
(.object-tree-array-index):
(.object-tree-array-index &gt; .titles):
(.object-tree-array-index &gt; .icon):
(.object-tree-array-index .index-name):
(.object-tree-array-index .index-value .object-tree):
(.object-tree-array-index .index-value .object-tree .object-tree-outline):
(.object-tree-property + ol .object-tree-array-index):
New styles specific to array index tree elements.

* UserInterface/Views/ObjectTreeMapEntryTreeElement.css:
(.object-tree-array-index.object-tree-map-entry &gt; .titles &gt; .title &gt; .index-name):
(.object-tree-map-entry.key):
(.object-tree-map-entry.key:first-of-type):
(.object-tree-map-entry):
New styles specific to map key/value tree elements.

* UserInterface/Views/ObjectTreeCollectionTreeElement.js: Removed.
Remove old collection implementation.

* UserInterface/Views/ObjectTreeArrayIndexTreeElement.js: Added.
(WebInspector.ObjectTreeArrayIndexTreeElement):
(WebInspector.ObjectTreeArrayIndexTreeElement.prototype.get property):
(WebInspector.ObjectTreeArrayIndexTreeElement.prototype._resolvedValue):
(WebInspector.ObjectTreeArrayIndexTreeElement.prototype._propertyPathType):
(WebInspector.ObjectTreeArrayIndexTreeElement.prototype._resolvedValuePropertyPath):
(WebInspector.ObjectTreeArrayIndexTreeElement.prototype._thisPropertyPath):
(WebInspector.ObjectTreeArrayIndexTreeElement.prototype._propertyPathString):
(WebInspector.ObjectTreeArrayIndexTreeElement.prototype._updateTitle):
(WebInspector.ObjectTreeArrayIndexTreeElement.prototype._titleFragment):
(WebInspector.ObjectTreeArrayIndexTreeElement.prototype._createInteractiveGetterElement.):
(WebInspector.ObjectTreeArrayIndexTreeElement.prototype._createReadOnlyIconElement):
Index followed by formatted value. Unfortunately a page can hack up an array
with getter properties, so also support getter values in an array. This ends
up copying a lot of ObjectTreePropertyTreeElement as a result.

* UserInterface/Views/ObjectTreeMapEntryTreeElement.js: Added.
(WebInspector.ObjectTreeMapEntryTreeElement):
(WebInspector.ObjectTreeMapEntryTreeElement.prototype.get object):
(WebInspector.ObjectTreeMapEntryTreeElement.prototype._propertyPathString):
(WebInspector.ObjectTreeMapEntryTreeElement.prototype._titleFragment):
(WebInspector.ObjectTreeMapKeyTreeElement):
(WebInspector.ObjectTreeMapKeyTreeElement.prototype.displayPropertyName):
(WebInspector.ObjectTreeMapKeyTreeElement.prototype.resolvedValuePropertyPath):
(WebInspector.ObjectTreeMapValueTreeElement):
(WebInspector.ObjectTreeMapValueTreeElement.prototype.displayPropertyName):
(WebInspector.ObjectTreeMapValueTreeElement.prototype.resolvedValuePropertyPath):
Key/value followed by formatted value.

* UserInterface/Views/ObjectTreeSetIndexTreeElement.js: Added.
(WebInspector.ObjectTreeSetIndexTreeElement):
(WebInspector.ObjectTreeSetIndexTreeElement.prototype.get object):
(WebInspector.ObjectTreeSetIndexTreeElement.prototype._resolvedValuePropertyPath):
(WebInspector.ObjectTreeSetIndexTreeElement.prototype._titleFragment):
Dot followed by formatted value.

* UserInterface/Views/ObjectTreePropertyTreeElement.css:
(.object-tree-property &gt; .titles):
Reformat.

* UserInterface/Views/ObjectTreeView.css:
(.object-tree-property :matches(.formatted-string, .formatted-regexp)):
Upgrade generic styles.

* UserInterface/Views/ObjectTreePropertyTreeElement.js:
(WebInspector.ObjectTreePropertyTreeElement.prototype._resolvedValue):
(WebInspector.ObjectTreePropertyTreeElement.prototype._resolvedValuePropertyPath):
(WebInspector.ObjectTreePropertyTreeElement.prototype._updateChildren):
(WebInspector.ObjectTreePropertyTreeElement.prototype._updateChildrenInternal):
(WebInspector.ObjectTreePropertyTreeElement.prototype._updateEntries):
(WebInspector.ObjectTreePropertyTreeElement.prototype._updateProperties):
* UserInterface/Views/ObjectTreeView.js:
(WebInspector.ObjectTreeView):
(WebInspector.ObjectTreeView.emptyMessageElement):
(WebInspector.ObjectTreeView.prototype.expand):
(WebInspector.ObjectTreeView.prototype.collapse):
(WebInspector.ObjectTreeView.prototype.update):
(WebInspector.ObjectTreeView.prototype._updateChildren):
(WebInspector.ObjectTreeView.prototype._updateEntries):
(WebInspector.ObjectTreeView.prototype._updateProperties):
(WebInspector.ObjectTreeView.prototype._handlePreviewOrTitleElementClick):
Both ObjectTreeView and ObjectTreePropertyTreeElement will fetch only collection
entries or properties depending on the type of the object being expanded.

(WebInspector.ObjectTreeView.prototype._trackWeakEntries):
(WebInspector.ObjectTreeView.prototype._untrackWeakEntries):
Allow WeakMap entries to be Garbage Collected when the ObjectTreeView
collapses or the console is cleared. FIXME for handling sub-tree WeakMaps.</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="#trunkSourceWebInspectorUIUserInterfaceModelsPropertyDescriptorjs">trunk/Source/WebInspectorUI/UserInterface/Models/PropertyDescriptor.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsPropertyPathjs">trunk/Source/WebInspectorUI/UserInterface/Models/PropertyPath.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceProtocolRemoteObjectjs">trunk/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsConsoleMessageImpljs">trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleMessageImpl.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsFormattedValuecss">trunk/Source/WebInspectorUI/UserInterface/Views/FormattedValue.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsFormattedValuejs">trunk/Source/WebInspectorUI/UserInterface/Views/FormattedValue.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsObjectPreviewViewjs">trunk/Source/WebInspectorUI/UserInterface/Views/ObjectPreviewView.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsObjectTreePropertyTreeElementcss">trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreePropertyTreeElement.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsObjectTreePropertyTreeElementjs">trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreePropertyTreeElement.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsObjectTreeViewcss">trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeView.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsObjectTreeViewjs">trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeView.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsObjectTreeArrayIndexTreeElementcss">trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeArrayIndexTreeElement.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsObjectTreeArrayIndexTreeElementjs">trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeArrayIndexTreeElement.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsObjectTreeMapEntryTreeElementcss">trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeMapEntryTreeElement.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsObjectTreeMapEntryTreeElementjs">trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeMapEntryTreeElement.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsObjectTreeSetIndexTreeElementjs">trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeSetIndexTreeElement.js</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsObjectTreeCollectionTreeElementjs">trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeCollectionTreeElement.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (180712 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2015-02-27 01:04:19 UTC (rev 180712)
+++ trunk/Source/WebInspectorUI/ChangeLog        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -1,3 +1,152 @@
</span><ins>+2015-02-26  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: New ObjectTree UI for Arrays / Maps / Sets
+        https://bugs.webkit.org/show_bug.cgi?id=142037
+
+        Reviewed by Timothy Hatcher.
+
+        * Localizations/en.lproj/localizedStrings.js:
+        * UserInterface/Main.html:
+        Miscellaneous changes.
+
+        * UserInterface/Models/PropertyDescriptor.js:
+        (WebInspector.PropertyDescriptor.prototype.isIndexProperty):
+        Useful for quickly checking if this property is numeric and possibly
+        an array index.
+
+        * UserInterface/Models/PropertyPath.js:
+        (WebInspector.PropertyPath.prototype.appendMapKey):
+        (WebInspector.PropertyPath.prototype.appendMapValue):
+        (WebInspector.PropertyPath.prototype.appendSetIndex):
+        Be specific about property paths into maps / sets. Note that a map
+        value may be displayable if the key is simple.
+
+        * UserInterface/Protocol/RemoteObject.js:
+        (WebInspector.RemoteObject.prototype.hasValue):
+        A simple value RemoteObject may have the value &quot;undefined&quot;. So provide
+        a falsey proof helper that actually checks if we have a value.
+
+        (WebInspector.RemoteObject.prototype.isArray):
+        (WebInspector.RemoteObject.prototype.backendGetOwnPropertyDescriptor):
+        (WebInspector.RemoteObject.prototype.wrappedCallback):
+        (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor):
+        Currently backend APIs exist only to get all properties. In the case
+        of collections, we often want to get only one property (__proto__).
+        This is a simple implementation on top of callFunctionOn.
+
+        * UserInterface/Views/ConsoleMessageImpl.js:
+        (WebInspector.ConsoleMessageImpl.prototype._formatParameterAsObject):
+        (WebInspector.ConsoleMessageImpl.prototype._formatParameterAsArray):
+        (WebInspector.ConsoleMessageImpl.prototype.appendUndefined): Deleted.
+        (WebInspector.ConsoleMessageImpl.prototype._printArray): Deleted.
+        (WebInspector.ConsoleMessageImpl.prototype._formatAsArrayEntry): Deleted.
+        Simplify array formatted to just use an ObjectTreeView. Add fixmes
+        that we should seed the ObjectTreeView with a starting property path.
+
+        * UserInterface/Views/FormattedValue.css:
+        (.formatted-node &gt; ol):
+        Sometimes, a node's display was getting overridden by various console styles.
+        Force a node to always display block. We may be able to remove this later.
+
+        * UserInterface/Views/FormattedValue.js:
+        (WebInspector.FormattedValue.createObjectTreeOrFormattedValueForRemoteObject):
+        Helper for formatting a node / object / value more easily. This
+        is used by all collection types.
+
+        * UserInterface/Views/ObjectPreviewView.js:
+        (WebInspector.ObjectPreviewView.prototype._appendPropertyPreviews):
+        We lost the nice sparse array support when switching to the new preview path,
+        we should add it back.
+
+        * UserInterface/Views/ObjectTreeArrayIndexTreeElement.css:
+        (.object-tree-array-index):
+        (.object-tree-array-index &gt; .titles):
+        (.object-tree-array-index &gt; .icon):
+        (.object-tree-array-index .index-name):
+        (.object-tree-array-index .index-value .object-tree):
+        (.object-tree-array-index .index-value .object-tree .object-tree-outline):
+        (.object-tree-property + ol .object-tree-array-index):
+        New styles specific to array index tree elements.
+
+        * UserInterface/Views/ObjectTreeMapEntryTreeElement.css:
+        (.object-tree-array-index.object-tree-map-entry &gt; .titles &gt; .title &gt; .index-name):
+        (.object-tree-map-entry.key):
+        (.object-tree-map-entry.key:first-of-type):
+        (.object-tree-map-entry):
+        New styles specific to map key/value tree elements.
+
+        * UserInterface/Views/ObjectTreeCollectionTreeElement.js: Removed.
+        Remove old collection implementation.
+
+        * UserInterface/Views/ObjectTreeArrayIndexTreeElement.js: Added.
+        (WebInspector.ObjectTreeArrayIndexTreeElement):
+        (WebInspector.ObjectTreeArrayIndexTreeElement.prototype.get property):
+        (WebInspector.ObjectTreeArrayIndexTreeElement.prototype._resolvedValue):
+        (WebInspector.ObjectTreeArrayIndexTreeElement.prototype._propertyPathType):
+        (WebInspector.ObjectTreeArrayIndexTreeElement.prototype._resolvedValuePropertyPath):
+        (WebInspector.ObjectTreeArrayIndexTreeElement.prototype._thisPropertyPath):
+        (WebInspector.ObjectTreeArrayIndexTreeElement.prototype._propertyPathString):
+        (WebInspector.ObjectTreeArrayIndexTreeElement.prototype._updateTitle):
+        (WebInspector.ObjectTreeArrayIndexTreeElement.prototype._titleFragment):
+        (WebInspector.ObjectTreeArrayIndexTreeElement.prototype._createInteractiveGetterElement.):
+        (WebInspector.ObjectTreeArrayIndexTreeElement.prototype._createReadOnlyIconElement):
+        Index followed by formatted value. Unfortunately a page can hack up an array
+        with getter properties, so also support getter values in an array. This ends
+        up copying a lot of ObjectTreePropertyTreeElement as a result.
+
+        * UserInterface/Views/ObjectTreeMapEntryTreeElement.js: Added.
+        (WebInspector.ObjectTreeMapEntryTreeElement):
+        (WebInspector.ObjectTreeMapEntryTreeElement.prototype.get object):
+        (WebInspector.ObjectTreeMapEntryTreeElement.prototype._propertyPathString):
+        (WebInspector.ObjectTreeMapEntryTreeElement.prototype._titleFragment):
+        (WebInspector.ObjectTreeMapKeyTreeElement):
+        (WebInspector.ObjectTreeMapKeyTreeElement.prototype.displayPropertyName):
+        (WebInspector.ObjectTreeMapKeyTreeElement.prototype.resolvedValuePropertyPath):
+        (WebInspector.ObjectTreeMapValueTreeElement):
+        (WebInspector.ObjectTreeMapValueTreeElement.prototype.displayPropertyName):
+        (WebInspector.ObjectTreeMapValueTreeElement.prototype.resolvedValuePropertyPath):
+        Key/value followed by formatted value.
+
+        * UserInterface/Views/ObjectTreeSetIndexTreeElement.js: Added.
+        (WebInspector.ObjectTreeSetIndexTreeElement):
+        (WebInspector.ObjectTreeSetIndexTreeElement.prototype.get object):
+        (WebInspector.ObjectTreeSetIndexTreeElement.prototype._resolvedValuePropertyPath):
+        (WebInspector.ObjectTreeSetIndexTreeElement.prototype._titleFragment):
+        Dot followed by formatted value.
+
+        * UserInterface/Views/ObjectTreePropertyTreeElement.css:
+        (.object-tree-property &gt; .titles):
+        Reformat.
+
+        * UserInterface/Views/ObjectTreeView.css:
+        (.object-tree-property :matches(.formatted-string, .formatted-regexp)):
+        Upgrade generic styles.
+
+        * UserInterface/Views/ObjectTreePropertyTreeElement.js:
+        (WebInspector.ObjectTreePropertyTreeElement.prototype._resolvedValue):
+        (WebInspector.ObjectTreePropertyTreeElement.prototype._resolvedValuePropertyPath):
+        (WebInspector.ObjectTreePropertyTreeElement.prototype._updateChildren):
+        (WebInspector.ObjectTreePropertyTreeElement.prototype._updateChildrenInternal):
+        (WebInspector.ObjectTreePropertyTreeElement.prototype._updateEntries):
+        (WebInspector.ObjectTreePropertyTreeElement.prototype._updateProperties):
+        * UserInterface/Views/ObjectTreeView.js:
+        (WebInspector.ObjectTreeView):
+        (WebInspector.ObjectTreeView.emptyMessageElement):
+        (WebInspector.ObjectTreeView.prototype.expand):
+        (WebInspector.ObjectTreeView.prototype.collapse):
+        (WebInspector.ObjectTreeView.prototype.update):
+        (WebInspector.ObjectTreeView.prototype._updateChildren):
+        (WebInspector.ObjectTreeView.prototype._updateEntries):
+        (WebInspector.ObjectTreeView.prototype._updateProperties):
+        (WebInspector.ObjectTreeView.prototype._handlePreviewOrTitleElementClick):
+        Both ObjectTreeView and ObjectTreePropertyTreeElement will fetch only collection
+        entries or properties depending on the type of the object being expanded.
+
+        (WebInspector.ObjectTreeView.prototype._trackWeakEntries):
+        (WebInspector.ObjectTreeView.prototype._untrackWeakEntries):
+        Allow WeakMap entries to be Garbage Collected when the ObjectTreeView
+        collapses or the console is cleared. FIXME for handling sub-tree WeakMaps.
+
</ins><span class="cx"> 2015-02-26  Brent Fulgham  &lt;bfulgham@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Win] Make build logs more legible by reducing noise
</span></span></pre></div>
<a id="trunkSourceWebInspectorUILocalizationsenlprojlocalizedStringsjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (180712 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js        2015-02-27 01:04:19 UTC (rev 180712)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -307,12 +307,14 @@
</span><span class="cx"> localizedStrings[&quot;No Box Model Information&quot;] = &quot;No Box Model Information&quot;;
</span><span class="cx"> localizedStrings[&quot;No Call Frames&quot;] = &quot;No Call Frames&quot;;
</span><span class="cx"> localizedStrings[&quot;No Child Layers&quot;] = &quot;No Child Layers&quot;;
</span><ins>+localizedStrings[&quot;No Entries.&quot;] = &quot;No Entries.&quot;;
</ins><span class="cx"> localizedStrings[&quot;No Event Listeners&quot;] = &quot;No Event Listeners&quot;;
</span><span class="cx"> localizedStrings[&quot;No Filter Results&quot;] = &quot;No Filter Results&quot;;
</span><span class="cx"> localizedStrings[&quot;No Layer Available&quot;] = &quot;No Layer Available&quot;;
</span><span class="cx"> localizedStrings[&quot;No Parameters&quot;] = &quot;No Parameters&quot;;
</span><span class="cx"> localizedStrings[&quot;No Properties&quot;] = &quot;No Properties&quot;;
</span><span class="cx"> localizedStrings[&quot;No Properties \u2014 Click to Edit&quot;] = &quot;No Properties \u2014 Click to Edit&quot;;
</span><ins>+localizedStrings[&quot;No Properties.&quot;] = &quot;No Properties.&quot;;
</ins><span class="cx"> localizedStrings[&quot;No Query Parameters&quot;] = &quot;No Query Parameters&quot;;
</span><span class="cx"> localizedStrings[&quot;No Request Headers&quot;] = &quot;No Request Headers&quot;;
</span><span class="cx"> localizedStrings[&quot;No Response Headers&quot;] = &quot;No Response Headers&quot;;
</span><span class="lines">@@ -481,7 +483,8 @@
</span><span class="cx"> localizedStrings[&quot;XHR&quot;] = &quot;XHR&quot;;
</span><span class="cx"> localizedStrings[&quot;XHRs&quot;] = &quot;XHRs&quot;;
</span><span class="cx"> localizedStrings[&quot;Yes&quot;] = &quot;Yes&quot;;
</span><ins>+localizedStrings[&quot;key&quot;] = &quot;key&quot;;
</ins><span class="cx"> localizedStrings[&quot;line &quot;] = &quot;line &quot;;
</span><span class="cx"> localizedStrings[&quot;originally %s&quot;] = &quot;originally %s&quot;;
</span><del>-localizedStrings[&quot;undefined \xD7 %d&quot;] = &quot;undefined \xD7 %d&quot;;
</del><ins>+localizedStrings[&quot;value&quot;] = &quot;value&quot;;
</ins><span class="cx"> localizedStrings[&quot; %s  Profile Recorded&quot;] = &quot; %s  Profile Recorded&quot;;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceMainhtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (180712 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Main.html        2015-02-27 01:04:19 UTC (rev 180712)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -99,6 +99,8 @@
</span><span class="cx">     &lt;link rel=&quot;stylesheet&quot; href=&quot;Views/NetworkTimelineView.css&quot;&gt;
</span><span class="cx">     &lt;link rel=&quot;stylesheet&quot; href=&quot;Views/ObjectPreviewView.css&quot;&gt;
</span><span class="cx">     &lt;link rel=&quot;stylesheet&quot; href=&quot;Views/ObjectTreeView.css&quot;&gt;
</span><ins>+    &lt;link rel=&quot;stylesheet&quot; href=&quot;Views/ObjectTreeArrayIndexTreeElement.css&quot;&gt;
+    &lt;link rel=&quot;stylesheet&quot; href=&quot;Views/ObjectTreeMapEntryTreeElement.css&quot;&gt;
</ins><span class="cx">     &lt;link rel=&quot;stylesheet&quot; href=&quot;Views/ObjectTreePropertyTreeElement.css&quot;&gt;
</span><span class="cx">     &lt;link rel=&quot;stylesheet&quot; href=&quot;Views/OverviewTimelineView.css&quot;&gt;
</span><span class="cx">     &lt;link rel=&quot;stylesheet&quot; href=&quot;Views/PathComponentIcons.css&quot;&gt;
</span><span class="lines">@@ -420,8 +422,10 @@
</span><span class="cx">     &lt;script src=&quot;Views/NetworkTimelineView.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/ObjectPreviewView.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/ObjectPropertiesSection.js&quot;&gt;&lt;/script&gt;
</span><del>-    &lt;script src=&quot;Views/ObjectTreeCollectionTreeElement.js&quot;&gt;&lt;/script&gt;
</del><ins>+    &lt;script src=&quot;Views/ObjectTreeArrayIndexTreeElement.js&quot;&gt;&lt;/script&gt;
+    &lt;script src=&quot;Views/ObjectTreeMapEntryTreeElement.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Views/ObjectTreePropertyTreeElement.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Views/ObjectTreeSetIndexTreeElement.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Views/ObjectTreeView.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/OverviewTimelineView.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/Popover.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsPropertyDescriptorjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/PropertyDescriptor.js (180712 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/PropertyDescriptor.js        2015-02-27 01:04:19 UTC (rev 180712)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/PropertyDescriptor.js        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -142,5 +142,10 @@
</span><span class="cx">     hasSetter: function()
</span><span class="cx">     {
</span><span class="cx">         return this._set &amp;&amp; this._set.type === &quot;function&quot;;
</span><del>-    }
</del><ins>+    },
+
+    isIndexProperty: function()
+    {
+        return !isNaN(Number(this._name));
+    },
</ins><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsPropertyPathjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/PropertyPath.js (180712 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/PropertyPath.js        2015-02-27 01:04:19 UTC (rev 180712)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/PropertyPath.js        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -44,10 +44,11 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> WebInspector.PropertyPath.SpecialPathComponent = {
</span><del>-    CollectionIndex: &quot;@collection[?]&quot;,
</del><span class="cx">     InternalPropertyName: &quot;@internal&quot;,
</span><span class="cx">     SymbolPropertyName: &quot;@symbol&quot;,
</span><del>-    GetterPropertyName: &quot;@getter&quot;,
</del><ins>+    MapKey: &quot;@mapkey&quot;,
+    MapValue: &quot;@mapvalue&quot;,
+    SetIndex: &quot;@setindex&quot;,
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> WebInspector.PropertyPath.Type = {
</span><span class="lines">@@ -200,12 +201,36 @@
</span><span class="cx">         return new WebInspector.PropertyPath(object, component, this);
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    appendCollectionIndex: function(object)
</del><ins>+    appendMapKey: function(object)
</ins><span class="cx">     {
</span><del>-        var component = WebInspector.PropertyPath.SpecialPathComponent.CollectionIndex;
</del><ins>+        var component = WebInspector.PropertyPath.SpecialPathComponent.MapKey;
</ins><span class="cx">         return new WebInspector.PropertyPath(object, component, this);
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    appendMapValue: function(object, keyObject)
+    {
+        console.assert(!keyObject || keyObject instanceof WebInspector.RemoteObject);
+
+        if (keyObject &amp;&amp; keyObject.hasValue()) {
+            if (keyObject.type === &quot;string&quot;) {
+                var component = &quot;.get(&quot; + doubleQuotedString(keyObject.description) + &quot;)&quot;;
+                return new WebInspector.PropertyPath(object, component, this);                
+            }
+
+            var component = &quot;.get(&quot; + keyObject.description + &quot;)&quot;;
+            return new WebInspector.PropertyPath(object, component, this);                
+        }
+            
+        var component = WebInspector.PropertyPath.SpecialPathComponent.MapValue;
+        return new WebInspector.PropertyPath(object, component, this);
+    },
+
+    appendSetIndex: function(object)
+    {
+        var component = WebInspector.PropertyPath.SpecialPathComponent.SetIndex;
+        return new WebInspector.PropertyPath(object, component, this);
+    },
+    
</ins><span class="cx">     appendPropertyDescriptor: function(object, descriptor, type)
</span><span class="cx">     {
</span><span class="cx">         if (descriptor.isInternalProperty)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceProtocolRemoteObjectjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js (180712 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js        2015-02-27 01:04:19 UTC (rev 180712)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -145,6 +145,11 @@
</span><span class="cx">         return this._preview;
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    hasValue: function()
+    {
+        return &quot;_value&quot; in this;
+    },
+
</ins><span class="cx">     getOwnPropertyDescriptors: function(callback)
</span><span class="cx">     {
</span><span class="cx">         this._getPropertyDescriptors(true, callback);
</span><span class="lines">@@ -350,6 +355,11 @@
</span><span class="cx">         return this._type === &quot;symbol&quot;;
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    isArray: function()
+    {
+        return this._subtype === &quot;array&quot;;
+    },
+
</ins><span class="cx">     isCollectionType: function()
</span><span class="cx">     {
</span><span class="cx">         return this._subtype === &quot;map&quot; || this._subtype === &quot;set&quot; || this._subtype === &quot;weakmap&quot;;
</span><span class="lines">@@ -439,6 +449,32 @@
</span><span class="cx">         this.callFunction(backendInvokeGetter, [getterRemoteObject], true, callback);
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    getOwnPropertyDescriptor: function(propertyName, callback)
+    {
+        if (!RuntimeAgent.getOwnPropertyDescriptor) {
+            function backendGetOwnPropertyDescriptor(propertyName)
+            {
+                return this[propertyName];
+            }
+
+            function wrappedCallback(error, result, wasThrown)
+            {
+                if (error || wasThrown || !(result instanceof WebInspector.RemoteObject)) {
+                    callback(null);
+                    return;
+                }
+
+                var fakeDescriptor = {name: propertyName, value: result, writable: true, configurable: true, enumerable: false};
+                var fakePropertyDescriptor = new WebInspector.PropertyDescriptor(fakeDescriptor, true, false, false, false);
+                callback(fakePropertyDescriptor);
+            }
+
+            this.callFunction(backendGetOwnPropertyDescriptor, [propertyName], false, wrappedCallback);
+        }
+
+        // FIXME: Implement a real getOwnPropertyDescriptor?
+    },
+
</ins><span class="cx">     release: function()
</span><span class="cx">     {
</span><span class="cx">         RuntimeAgent.releaseObject(this._objectId);
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsConsoleMessageImpljs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleMessageImpl.js (180712 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleMessageImpl.js        2015-02-27 01:04:19 UTC (rev 180712)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleMessageImpl.js        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -296,7 +296,8 @@
</span><span class="cx"> 
</span><span class="cx">     _formatParameterAsObject: function(obj, elem, forceExpansion)
</span><span class="cx">     {
</span><del>-        var objectTree = new WebInspector.ObjectTreeView(obj, WebInspector.ObjectTreeView.Mode.Properties, forceExpansion);
</del><ins>+        // FIXME: Intialize component with &quot;$n&quot; instead of &quot;obj&quot;. Or, an existing property path.
+        var objectTree = new WebInspector.ObjectTreeView(obj, WebInspector.ObjectTreeView.Mode.Properties, null, forceExpansion);
</ins><span class="cx">         elem.appendChild(objectTree.element);
</span><span class="cx">     },
</span><span class="cx"> 
</span><span class="lines">@@ -314,8 +315,9 @@
</span><span class="cx"> 
</span><span class="cx">     _formatParameterAsArray: function(arr, elem)
</span><span class="cx">     {
</span><del>-        // FIXME: Array previews look poor. Keep doing what we currently do for arrays.
-        arr.deprecatedGetOwnProperties(this._printArray.bind(this, arr, elem));
</del><ins>+        // FIXME: Intialize component with &quot;$n&quot; instead of &quot;obj&quot;. Or, an existing property path.
+        var objectTree = new WebInspector.ObjectTreeView(arr, WebInspector.ObjectTreeView.Mode.Properties);
+        elem.appendChild(objectTree.element);
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     _userProvidedColumnNames: function(columnNamesArgument)
</span><span class="lines">@@ -439,57 +441,6 @@
</span><span class="cx">         return element;
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    _printArray: function(array, elem, properties)
-    {
-        if (!properties)
-            return;
-
-        var elements = [];
-        for (var i = 0; i &lt; properties.length; ++i) {
-            var property = properties[i];
-            var name = property.name;
-            if (!isNaN(name))
-                elements[name] = this._formatAsArrayEntry(property.value);
-        }
-
-        elem.appendChild(document.createTextNode(&quot;[&quot;));
-        var lastNonEmptyIndex = -1;
-
-        function appendUndefined(elem, index)
-        {
-            if (index - lastNonEmptyIndex &lt;= 1)
-                return;
-            var span = elem.createChild(&quot;span&quot;, &quot;formatted-undefined&quot;);
-            span.textContent = WebInspector.UIString(&quot;undefined Ã— %d&quot;).format(index - lastNonEmptyIndex - 1);
-        }
-
-        var length = array.arrayLength();
-        for (var i = 0; i &lt; length; ++i) {
-            var element = elements[i];
-            if (!element)
-                continue;
-
-            if (i - lastNonEmptyIndex &gt; 1) {
-                appendUndefined(elem, i);
-                elem.appendChild(document.createTextNode(&quot;, &quot;));
-            }
-
-            elem.appendChild(element);
-            lastNonEmptyIndex = i;
-            if (i &lt; length - 1)
-                elem.appendChild(document.createTextNode(&quot;, &quot;));
-        }
-        appendUndefined(elem, length);
-
-        elem.appendChild(document.createTextNode(&quot;]&quot;));
-    },
-
-    _formatAsArrayEntry: function(output)
-    {
-        // Prevent infinite expansion of cross-referencing arrays.
-        return this._formatParameter(output, output.subtype &amp;&amp; output.subtype === &quot;array&quot;);
-    },
-
</del><span class="cx">     _formatWithSubstitutionString: function(parameters, formattedResult)
</span><span class="cx">     {
</span><span class="cx">         var formatters = {};
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsFormattedValuecss"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/FormattedValue.css (180712 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/FormattedValue.css        2015-02-27 01:04:19 UTC (rev 180712)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/FormattedValue.css        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -30,6 +30,10 @@
</span><span class="cx">     color: black;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+.formatted-node &gt; ol {
+    display: block !important;
+}
+
</ins><span class="cx"> .formatted-number {
</span><span class="cx">     color: rgb(28, 0, 207);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsFormattedValuejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/FormattedValue.js (180712 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/FormattedValue.js        2015-02-27 01:04:19 UTC (rev 180712)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/FormattedValue.js        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -111,3 +111,16 @@
</span><span class="cx"> {
</span><span class="cx">     return WebInspector.FormattedValue.createElementForTypesAndValue(propertyPreview.type, propertyPreview.subtype, propertyPreview.value, true, false);
</span><span class="cx"> };
</span><ins>+
+WebInspector.FormattedValue.createObjectTreeOrFormattedValueForRemoteObject = function(object, propertyPath)
+{
+    if (object.subtype === &quot;node&quot;)
+        return WebInspector.FormattedValue.createElementForNode(object);
+
+    if (object.type === &quot;object&quot;) {
+        var objectTree = new WebInspector.ObjectTreeView(object, WebInspector.ObjectTreeView.Mode.Properties, propertyPath);
+        return objectTree.element;
+    }
+
+    return WebInspector.FormattedValue.createElementForRemoteObject(object);
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsObjectPreviewViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectPreviewView.js (180712 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectPreviewView.js        2015-02-27 01:04:19 UTC (rev 180712)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectPreviewView.js        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -171,6 +171,7 @@
</span><span class="cx">         if (preview.subtype === &quot;date&quot;)
</span><span class="cx">             return !preview.propertyPreviews.length;
</span><span class="cx"> 
</span><ins>+        // FIXME: Array previews should have better sparse support: (undefined Ã— 10).
</ins><span class="cx">         var isArray = preview.subtype === &quot;array&quot;;
</span><span class="cx"> 
</span><span class="cx">         element.appendChild(document.createTextNode(isArray ? &quot;[&quot; : &quot;{&quot;));
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsObjectTreeArrayIndexTreeElementcssfromrev180712trunkSourceWebInspectorUIUserInterfaceViewsFormattedValuecss"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeArrayIndexTreeElement.css (from rev 180712, trunk/Source/WebInspectorUI/UserInterface/Views/FormattedValue.css) (0 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeArrayIndexTreeElement.css                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeArrayIndexTreeElement.css        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -0,0 +1,65 @@
</span><ins>+/*
+ * Copyright (C) 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.
+ *
+ * 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.
+ */
+
+.object-tree-array-index {
+    position: relative;
+    left: -12px;
+    margin-top: 2px;
+    margin-bottom: 1px;
+}
+
+.object-tree-array-index &gt; .disclosure-button,
+.object-tree-array-index &gt; .icon {
+    display: none;
+}
+
+.object-tree-array-index .index-name {
+    font-family: -webkit-system-font, sans-serif;
+    font-size: 11px;
+    vertical-align: top;
+    color: hsla(0, 0%, 0%, 0.33);
+
+    position:relative;
+    top: -1px;
+
+    display: inline-block;
+    width: 22px;
+    text-align: center;
+}
+
+/* FIXME: Should this be all the time? */
+.object-tree-array-index .index-value .object-tree {
+    display: inline-block;
+}
+
+/* An array inside an array we should reduce the padding-start. */
+.object-tree-array-index .index-value .object-tree .object-tree-outline {
+    -webkit-padding-start: 6px;
+}
+
+/* An array inside an ObjectTreePropertyTreeElement needs more left shift */
+.object-tree-property + ol .object-tree-array-index {
+    left: -18px;
+}
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsObjectTreeArrayIndexTreeElementjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeArrayIndexTreeElement.js (0 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeArrayIndexTreeElement.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeArrayIndexTreeElement.js        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -0,0 +1,174 @@
</span><ins>+/*
+ * Copyright (C) 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.
+ *
+ * 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.
+ */
+
+// FIXME: This should share more code with ObjectTreePropertyTreeElement.
+
+WebInspector.ObjectTreeArrayIndexTreeElement = function(property, propertyPath)
+{
+    console.assert(property instanceof WebInspector.PropertyDescriptor);
+    console.assert(propertyPath instanceof WebInspector.PropertyPath);
+    console.assert(property.isIndexProperty(), &quot;ArrayIndexTreeElement expects numeric property names&quot;);
+
+    this._property = property;
+    this._propertyPath = propertyPath;
+
+    var classNames = [&quot;object-tree-property&quot;, &quot;object-tree-array-index&quot;];
+    if (!this._property.hasValue())
+        classNames.push(&quot;accessor&quot;);
+
+    WebInspector.GeneralTreeElement.call(this, classNames, this._titleFragment(), null, this._property, false);
+
+    this.small = true;
+    this.toggleOnClick = false;
+    this.selectable = false;
+    this.tooltipHandledSeparately = true;
+    this.hasChildren = false;
+};
+
+WebInspector.ObjectTreeArrayIndexTreeElement.prototype = {
+    constructor: WebInspector.ObjectTreeArrayIndexTreeElement,
+    __proto__: WebInspector.GeneralTreeElement.prototype,
+
+    // Public
+
+    get property()
+    {
+        return this._property;
+    },
+
+    // Private
+
+    _resolvedValue: function()
+    {
+        if (this._getterValue)
+            return this._getterValue;
+        if (this._property.hasValue())
+            return this._property.value;
+        return null;
+    },
+
+    _propertyPathType: function()
+    {
+        if (this._getterValue || this._property.hasValue())
+            return WebInspector.PropertyPath.Type.Value;
+        if (this._property.hasGetter())
+            return WebInspector.PropertyPath.Type.Getter;
+        if (this._property.hasSetter())
+            return WebInspector.PropertyPath.Type.Setter;
+        return WebInspector.PropertyPath.Type.Value;
+    },
+
+    _resolvedValuePropertyPath: function()
+    {
+        if (this._getterValue)
+            return this._propertyPath.appendPropertyDescriptor(this._getterValue, this._property, WebInspector.PropertyPath.Type.Value);
+        if (this._property.hasValue())
+            return this._propertyPath.appendPropertyDescriptor(this._property.value, this._property, WebInspector.PropertyPath.Type.Value);
+        return null;
+    },
+
+    _thisPropertyPath: function()
+    {
+        return this._propertyPath.appendPropertyDescriptor(null, this._property, this._propertyPathType());
+    },
+
+    _propertyPathString: function(propertyPath)
+    {
+        if (propertyPath.isFullPathImpossible())
+            return WebInspector.UIString(&quot;Unable to determine path to property from root&quot;);
+
+        return propertyPath.displayPath(this._propertyPathType());
+    },
+
+    _updateTitle: function()
+    {
+        this.mainTitle = this._titleFragment();
+
+        if (this._getterValue)
+            this.removeClassName(&quot;accessor&quot;);
+
+        this._updateHasChildren();
+    },
+
+    _titleFragment: function()
+    {
+        var container = document.createDocumentFragment();
+
+        // Array index name.
+        var nameElement = container.appendChild(document.createElement(&quot;span&quot;));
+        nameElement.className = &quot;index-name&quot;;
+        nameElement.textContent = this._property.name;
+        nameElement.title = this._propertyPathString(this._thisPropertyPath());
+
+        // Value.
+        var valueElement = container.appendChild(document.createElement(&quot;span&quot;));
+        valueElement.className = &quot;index-value&quot;;
+
+        var resolvedValue = this._resolvedValue();
+        if (resolvedValue)
+            valueElement.appendChild(WebInspector.FormattedValue.createObjectTreeOrFormattedValueForRemoteObject(resolvedValue, this._resolvedValuePropertyPath()));
+        else {
+            if (this._property.hasGetter())
+                container.appendChild(this._createInteractiveGetterElement());
+            if (!this._property.hasSetter())
+                container.appendChild(this._createReadOnlyIconElement());
+            // FIXME: What if just a setter?
+        }
+
+        valueElement.classList.add(&quot;value&quot;);
+        if (this._property.wasThrown || this._getterHadError)
+            valueElement.classList.add(&quot;error&quot;);
+
+        return container;
+    },
+
+    _createInteractiveGetterElement: function()
+    {
+        var getterElement = document.createElement(&quot;img&quot;);
+        getterElement.className = &quot;getter&quot;;
+        getterElement.title = WebInspector.UIString(&quot;Invoke getter&quot;);
+
+        getterElement.addEventListener(&quot;click&quot;, function(event) {
+            event.stopPropagation();
+            var lastNonPrototypeObject = this._propertyPath.lastNonPrototypeObject;
+            var getterObject = this._property.get;
+            lastNonPrototypeObject.invokeGetter(getterObject, function(error, result, wasThrown) {
+                this._getterHadError = !!(error || wasThrown);
+                this._getterValue = result;
+                this._updateTitle();
+            }.bind(this));
+        }.bind(this));
+
+        return getterElement;
+    },
+
+    _createReadOnlyIconElement: function()
+    {
+        var readOnlyElement = document.createElement(&quot;img&quot;);
+        readOnlyElement.className = &quot;read-only&quot;;
+        readOnlyElement.title = WebInspector.UIString(&quot;Read only&quot;);
+        return readOnlyElement;
+    },
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsObjectTreeCollectionTreeElementjs"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeCollectionTreeElement.js (180712 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeCollectionTreeElement.js        2015-02-27 01:04:19 UTC (rev 180712)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeCollectionTreeElement.js        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -1,215 +0,0 @@
</span><del>-/*
- * Copyright (C) 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.
- *
- * 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.ObjectTreeCollectionTreeElement = function(remoteObject)
-{
-    console.assert(remoteObject instanceof WebInspector.RemoteObject);
-
-    this._remoteObject = remoteObject;
-    this._requestingEntries = false;
-    this._trackingEntries = false;
-
-    TreeElement.call(this, &quot;&lt;entries&gt;&quot;, null, false);
-    this.toggleOnClick = true;
-    this.selectable = false;
-    this.hasChildren = true;
-    this.expand();
-
-    // FIXME: When a parent TreeElement is collapsed, we do not get a chance
-    // to releaseWeakCollectionEntries. We should.
-};
-
-WebInspector.ObjectTreeCollectionTreeElement.propertyDescriptorForEntry = function(name, value)
-{
-    var descriptor = {name: name, value: value, enumerable: true, writable: false};
-    return new WebInspector.PropertyDescriptor(descriptor, true, false, false);
-}
-
-WebInspector.ObjectTreeCollectionTreeElement.prototype = {
-    constructor: WebInspector.ObjectTreeCollectionTreeElement,
-    __proto__: TreeElement.prototype,
-
-    // Public
-
-    get remoteObject()
-    {
-        return this._remoteObject;
-    },
-
-    // Protected
-
-    onexpand: function()
-    {
-        if (this.children.length &amp;&amp; !this.shouldRefreshChildren)
-            return;
-
-        if (this._requestingEntries)
-            return;
-
-        this._requestingEntries = true;
-
-        function callback(entries) {
-            this._requestingEntries = false;
-
-            this.removeChildren();
-
-            if (!entries || !entries.length) {
-                this.appendChild(new WebInspector.ObjectTreeEmptyCollectionTreeElement);
-                return;
-            }
-
-            this._trackWeakEntries();
-
-            for (var i = 0; i &lt; entries.length; ++i) {
-                var entry = entries[i];
-                if (entry.key)
-                    this.appendChild(new WebInspector.ObjectTreeCollectionEntryTreeElement(entry, i));
-                else {
-                    var propertyDescriptor = WebInspector.ObjectTreeCollectionTreeElement.propertyDescriptorForEntry(&quot;&quot; + i, entry.value);
-                    this.appendChild(new WebInspector.ObjectTreePropertyTreeElement(propertyDescriptor));
-                }
-            }
-        }
-
-        this._remoteObject.getCollectionEntries(0, 100, callback.bind(this));
-    },
-
-    oncollapse: function()
-    {
-        this._untrackWeakEntries();
-    },
-
-    ondetach: function()
-    {
-        this._untrackWeakEntries();
-    },
-
-    // Private.
-
-    _trackWeakEntries: function()
-    {
-        if (!this._remoteObject.isWeakCollection())
-            return;
-
-        if (this._trackingEntries)
-            return;
-
-        this._trackingEntries = true;
-
-        WebInspector.logManager.addEventListener(WebInspector.LogManager.Event.Cleared, this._untrackWeakEntries, this);
-        WebInspector.logManager.addEventListener(WebInspector.LogManager.Event.ActiveLogCleared, this._untrackWeakEntries, this);
-        WebInspector.logManager.addEventListener(WebInspector.LogManager.Event.SessionStarted, this._untrackWeakEntries, this);
-    },
-
-    _untrackWeakEntries: function()
-    {
-        if (!this._remoteObject.isWeakCollection())
-            return;
-
-        if (!this._trackingEntries)
-            return;
-
-        this._trackingEntries = false;
-
-        this._remoteObject.releaseWeakCollectionEntries();
-
-        WebInspector.logManager.removeEventListener(WebInspector.LogManager.Event.Cleared, this._untrackWeakEntries, this);
-        WebInspector.logManager.removeEventListener(WebInspector.LogManager.Event.ActiveLogCleared, this._untrackWeakEntries, this);
-        WebInspector.logManager.removeEventListener(WebInspector.LogManager.Event.SessionStarted, this._untrackWeakEntries, this);
-
-        this.removeChildren();
-
-        if (this.expanded)
-            this.collapse();
-    },
-};
-
-WebInspector.ObjectTreeCollectionEntryTreeElement = function(entry, index)
-{
-    console.assert(entry instanceof WebInspector.CollectionEntry);
-    console.assert(entry.key instanceof WebInspector.RemoteObject);
-    console.assert(entry.value instanceof WebInspector.RemoteObject);
-
-    this._name = &quot;&quot; + index;
-    this._key = entry.key;
-    this._value = entry.value;
-
-    TreeElement.call(this, &quot;&quot;, null, false);
-    this.toggleOnClick = true;
-    this.selectable = false;
-    this.hasChildren = true;
-}
-
-WebInspector.ObjectTreeCollectionEntryTreeElement.prototype = {
-    constructor: WebInspector.ObjectTreeCollectionEntryTreeElement,
-    __proto__: TreeElement.prototype,
-
-    // Protected
-
-    onpopulate: function()
-    {
-        if (this.children.length &amp;&amp; !this.shouldRefreshChildren)
-            return;
-
-        var keyPropertyDescriptor = WebInspector.ObjectTreeCollectionTreeElement.propertyDescriptorForEntry(&quot;key&quot;, this._key);
-        this.appendChild(new WebInspector.ObjectTreePropertyTreeElement(keyPropertyDescriptor));
-
-        var valuePropertyDescriptor = WebInspector.ObjectTreeCollectionTreeElement.propertyDescriptorForEntry(&quot;value&quot;, this._value);
-        this.appendChild(new WebInspector.ObjectTreePropertyTreeElement(valuePropertyDescriptor));
-    },
-
-    onattach: function()
-    {
-        var nameElement = document.createElement(&quot;span&quot;);
-        nameElement.className = &quot;name&quot;;
-        nameElement.textContent = &quot;&quot; + this._name;
-
-        var separatorElement = document.createElement(&quot;span&quot;);
-        separatorElement.className = &quot;separator&quot;;
-        separatorElement.textContent = &quot;: &quot;;
-
-        var valueElement = document.createElement(&quot;span&quot;);
-        valueElement.className = &quot;value&quot;;
-        valueElement.textContent = &quot;{&quot; + this._key.description + &quot; =&gt; &quot; + this._value.description + &quot;}&quot;;
-
-        this.listItemElement.classList.add(&quot;object-tree-property&quot;);
-
-        this.listItemElement.removeChildren();
-        this.listItemElement.appendChild(nameElement);
-        this.listItemElement.appendChild(separatorElement);
-        this.listItemElement.appendChild(valueElement);
-    }
-};
-
-WebInspector.ObjectTreeEmptyCollectionTreeElement = function()
-{
-    TreeElement.call(this, WebInspector.UIString(&quot;Empty Collection&quot;), null, false);
-    this.selectable = false;
-}
-
-WebInspector.ObjectTreeEmptyCollectionTreeElement.prototype = {
-    constructor: WebInspector.ObjectTreeEmptyCollectionTreeElement,
-    __proto__: TreeElement.prototype
-};
</del></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsObjectTreeMapEntryTreeElementcssfromrev180712trunkSourceWebInspectorUIUserInterfaceViewsFormattedValuecss"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeMapEntryTreeElement.css (from rev 180712, trunk/Source/WebInspectorUI/UserInterface/Views/FormattedValue.css) (0 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeMapEntryTreeElement.css                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeMapEntryTreeElement.css        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+/*
+ * Copyright (C) 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.
+ *
+ * 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.
+ */
+
+.object-tree-array-index.object-tree-map-entry &gt; .titles &gt; .title &gt; .index-name {
+    width: 37px;
+    text-align: right;
+    margin-right: 5px;
+}
+
+.object-tree-map-entry.key {
+    border-top: 1px solid hsl(0, 0%, 96%);
+}
+
+.object-tree-map-entry.key:first-of-type {
+    border-top: none;
+}
+
+.object-tree-map-entry {
+    padding-top: 2px;
+    padding-bottom: 2px;
+}
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsObjectTreeMapEntryTreeElementjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeMapEntryTreeElement.js (0 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeMapEntryTreeElement.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeMapEntryTreeElement.js        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -0,0 +1,133 @@
</span><ins>+/*
+ * Copyright (C) 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.
+ *
+ * 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.ObjectTreeMapEntryTreeElement = function(object, propertyPath)
+{
+    console.assert(object instanceof WebInspector.RemoteObject);
+    console.assert(propertyPath instanceof WebInspector.PropertyPath);
+
+    this._object = object;
+    this._propertyPath = propertyPath;
+
+    // Treat the same as an array-index just with different strings and widths.
+    WebInspector.GeneralTreeElement.call(this, [&quot;object-tree-array-index&quot;, &quot;object-tree-map-entry&quot;], this._titleFragment(), null, this._object, false);
+
+    this.small = true;
+    this.toggleOnClick = false;
+    this.selectable = false;
+    this.tooltipHandledSeparately = true;
+    this.hasChildren = false;
+};
+
+WebInspector.ObjectTreeMapEntryTreeElement.prototype = {
+    constructor: WebInspector.ObjectTreeMapEntryTreeElement,
+    __proto__: WebInspector.GeneralTreeElement.prototype,
+
+    // Public
+
+    get object()
+    {
+        return this._object;
+    },
+
+    // Private
+
+    _propertyPathString: function(propertyPath)
+    {
+        if (propertyPath.isFullPathImpossible())
+            return WebInspector.UIString(&quot;Unable to determine path to property from root&quot;);
+
+        return propertyPath.displayPath(WebInspector.PropertyPath.Type.Value);
+    },
+
+    _titleFragment: function()
+    {
+        var container = document.createDocumentFragment();
+
+        var propertyPath = this.resolvedValuePropertyPath();
+
+        // Index name.
+        var nameElement = container.appendChild(document.createElement(&quot;span&quot;));
+        nameElement.className = &quot;index-name&quot;;
+        nameElement.textContent = this.displayPropertyName();
+        nameElement.title = this._propertyPathString(propertyPath);
+
+        // Value.
+        var valueElement = container.appendChild(document.createElement(&quot;span&quot;));
+        valueElement.className = &quot;index-value&quot;;
+        valueElement.appendChild(WebInspector.FormattedValue.createObjectTreeOrFormattedValueForRemoteObject(this._object, propertyPath));
+
+        return container;
+    }
+};
+
+
+WebInspector.ObjectTreeMapKeyTreeElement = function(object, propertyPath)
+{
+    WebInspector.ObjectTreeMapEntryTreeElement.call(this, object, propertyPath);
+    this.addClassName(&quot;key&quot;);
+}
+
+WebInspector.ObjectTreeMapKeyTreeElement.prototype = {
+    constructor: WebInspector.ObjectTreeMapKeyTreeElement,
+    __proto__: WebInspector.ObjectTreeMapEntryTreeElement.prototype,
+
+    // Protected
+
+    displayPropertyName: function()
+    {
+        return WebInspector.UIString(&quot;key&quot;);
+    },
+
+    resolvedValuePropertyPath: function()
+    {
+        return this._propertyPath.appendMapKey(this._object);
+    }
+};
+
+
+WebInspector.ObjectTreeMapValueTreeElement = function(object, propertyPath, key)
+{
+    this._key = key;
+    WebInspector.ObjectTreeMapEntryTreeElement.call(this, object, propertyPath);
+    this.addClassName(&quot;value&quot;);
+}
+
+WebInspector.ObjectTreeMapValueTreeElement.prototype = {
+    constructor: WebInspector.ObjectTreeMapValueTreeElement,
+    __proto__: WebInspector.ObjectTreeMapEntryTreeElement.prototype,
+
+    // Protected
+
+    displayPropertyName: function()
+    {
+        return WebInspector.UIString(&quot;value&quot;);
+    },
+
+    resolvedValuePropertyPath: function()
+    {
+        return this._propertyPath.appendMapValue(this._object, this._key);
+    }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsObjectTreePropertyTreeElementcss"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreePropertyTreeElement.css (180712 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreePropertyTreeElement.css        2015-02-27 01:04:19 UTC (rev 180712)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreePropertyTreeElement.css        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -27,6 +27,16 @@
</span><span class="cx">     margin-top: 1px;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+.object-tree-property &gt; .titles {
+    position: relative;
+    top: 2px;
+    line-height: normal;
+    padding-bottom: 1px;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    white-space: nowrap;
+}
+
</ins><span class="cx"> .object-tree-property &gt; .disclosure-button {
</span><span class="cx">     float: left;
</span><span class="cx"> 
</span><span class="lines">@@ -160,20 +170,6 @@
</span><span class="cx">     margin-left: 3px;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-.object-tree-property :matches(.formatted-string, .formatted-regexp) {
-    white-space: nowrap;
-}
-
</del><span class="cx"> .object-tree-property .value.error {
</span><span class="cx">     color: red;
</span><span class="cx"> }
</span><del>-
-.object-tree-property &gt; .titles {
-    position: relative;
-    top: 2px;
-    line-height: normal;
-    padding-bottom: 1px;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    white-space: nowrap;
-}
</del></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsObjectTreePropertyTreeElementjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreePropertyTreeElement.js (180712 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreePropertyTreeElement.js        2015-02-27 01:04:19 UTC (rev 180712)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreePropertyTreeElement.js        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -94,10 +94,8 @@
</span><span class="cx">     {
</span><span class="cx">         if (this._getterValue)
</span><span class="cx">             return this._getterValue;
</span><del>-
</del><span class="cx">         if (this._property.hasValue())
</span><span class="cx">             return this._property.value;
</span><del>-
</del><span class="cx">         return null;
</span><span class="cx">     },
</span><span class="cx"> 
</span><span class="lines">@@ -116,10 +114,8 @@
</span><span class="cx">     {
</span><span class="cx">         if (this._getterValue)
</span><span class="cx">             return this._propertyPath.appendPropertyDescriptor(this._getterValue, this._property, WebInspector.PropertyPath.Type.Value);
</span><del>-
</del><span class="cx">         if (this._property.hasValue())
</span><span class="cx">             return this._propertyPath.appendPropertyDescriptor(this._property.value, this._property, WebInspector.PropertyPath.Type.Value);
</span><del>-
</del><span class="cx">         return null;
</span><span class="cx">     },
</span><span class="cx"> 
</span><span class="lines">@@ -391,48 +387,84 @@
</span><span class="cx">             return;
</span><span class="cx"> 
</span><span class="cx">         var resolvedValue = this._resolvedValue();
</span><del>-        var resolvedValuePropertyPath = this._resolvedValuePropertyPath();
</del><ins>+        if (resolvedValue.isCollectionType() &amp;&amp; this._mode === WebInspector.ObjectTreeView.Mode.Properties)
+            resolvedValue.getCollectionEntries(0, 100, this._updateChildrenInternal.bind(this, this._updateEntries, this._mode));
+        else if (this._property.name === &quot;__proto__&quot;)
+            resolvedValue.getOwnPropertyDescriptors(this._updateChildrenInternal.bind(this, this._updateProperties, WebInspector.ObjectTreeView.Mode.API));
+        else
+            resolvedValue.getDisplayablePropertyDescriptors(this._updateChildrenInternal.bind(this, this._updateProperties, this._mode));
+    },
</ins><span class="cx"> 
</span><del>-        function callback(mode, properties)
-        {
-            this.removeChildren();
</del><ins>+    _updateChildrenInternal: function(handler, mode, list)
+    {
+        this.removeChildren();
</ins><span class="cx"> 
</span><del>-            if (!properties) {
-                var errorMessageElement = document.createElement(&quot;div&quot;);
-                errorMessageElement.className = &quot;empty-message&quot;;
-                errorMessageElement.textContent = WebInspector.UIString(&quot;Could not fetch properties. Object may no longer exist.&quot;);;
-                this.appendChild(new TreeElement(errorMessageElement, null, false));
-                return;
-            }
</del><ins>+        if (!list) {
+            var errorMessageElement = WebInspector.ObjectTreeView.emptyMessageElement(WebInspector.UIString(&quot;Could not fetch properties. Object may no longer exist.&quot;));
+            this.appendChild(new TreeElement(errorMessageElement, null, false));
+            return;
+        }
</ins><span class="cx"> 
</span><del>-            var prototypeName = undefined;
-            if (this._property.name === &quot;__proto__&quot;) {
-                if (resolvedValue.description)
-                    prototypeName = this._sanitizedPrototypeString(resolvedValue);
-            }
</del><ins>+        handler.call(this, list, this._resolvedValuePropertyPath(), mode);
+    },
</ins><span class="cx"> 
</span><del>-            var isAPI = mode === WebInspector.ObjectTreeView.Mode.API;
</del><ins>+    _updateEntries: function(entries, propertyPath, mode)
+    {
+        for (var entry of entries) {
+            if (entry.key) {
+                this.appendChild(new WebInspector.ObjectTreeMapKeyTreeElement(entry.key, propertyPath));
+                this.appendChild(new WebInspector.ObjectTreeMapValueTreeElement(entry.value, propertyPath, entry.key));
+            } else
+                this.appendChild(new WebInspector.ObjectTreeSetIndexTreeElement(entry.value, propertyPath));
+        }
</ins><span class="cx"> 
</span><del>-            properties.sort(WebInspector.ObjectTreeView.ComparePropertyDescriptors);
-            for (var propertyDescriptor of properties) {
-                // FIXME: If this is a pure API ObjectTree, we should show the native getters.
-                // For now, just skip native binding getters in API mode, since we likely
-                // already showed them in the Properties section.
-                if (isAPI &amp;&amp; propertyDescriptor.nativeGetter)
-                    continue;
-                this.appendChild(new WebInspector.ObjectTreePropertyTreeElement(propertyDescriptor, resolvedValuePropertyPath, mode, prototypeName));
-            }
</del><ins>+        if (!this.children.length) {
+            var emptyMessageElement = WebInspector.ObjectTreeView.emptyMessageElement(WebInspector.UIString(&quot;No Entries.&quot;));
+            this.appendChild(new TreeElement(emptyMessageElement, null, false));
+        }
</ins><span class="cx"> 
</span><del>-            // FIXME: Re-enable Collection Entries with new UI.
-            // if (mode === WebInspector.ObjectTreeView.Mode.Properties) {
-            //     if (resolvedValue.isCollectionType())
-            //         this.appendChild(new WebInspector.ObjectTreeCollectionTreeElement(resolvedValue));
-            // }
-        };
</del><ins>+        // Show the prototype so users can see the API.
+        var resolvedValue = this._resolvedValue();
+        resolvedValue.getOwnPropertyDescriptor(&quot;__proto__&quot;, function(propertyDescriptor) {
+            if (propertyDescriptor)
+                this.appendChild(new WebInspector.ObjectTreePropertyTreeElement(propertyDescriptor, propertyPath, mode));
+        }.bind(this));
+    },
</ins><span class="cx"> 
</span><del>-        if (this._property.name === &quot;__proto__&quot;)
-            resolvedValue.getOwnPropertyDescriptors(callback.bind(this, WebInspector.ObjectTreeView.Mode.API));
-        else
-            resolvedValue.getDisplayablePropertyDescriptors(callback.bind(this, this._mode));
-    },
</del><ins>+    _updateProperties: function(properties, propertyPath, mode)
+    {
+        properties.sort(WebInspector.ObjectTreeView.ComparePropertyDescriptors);
+
+        var resolvedValue = this._resolvedValue();
+        var isArray = resolvedValue.isArray();
+        var isPropertyMode = mode === WebInspector.ObjectTreeView.Mode.Properties || this._getterValue;
+        var isAPI = mode === WebInspector.ObjectTreeView.Mode.API;
+
+        var prototypeName = undefined;
+        if (this._property.name === &quot;__proto__&quot;) {
+            if (resolvedValue.description)
+                prototypeName = this._sanitizedPrototypeString(resolvedValue);
+        }
+
+        for (var propertyDescriptor of properties) {
+            // FIXME: If this is a pure API ObjectTree, we should show the native getters.
+            // For now, just skip native binding getters in API mode, since we likely
+            // already showed them in the Properties section.
+            if (isAPI &amp;&amp; propertyDescriptor.nativeGetter)
+                continue;
+            
+            if (isArray &amp;&amp; isPropertyMode) {
+                if (propertyDescriptor.isIndexProperty())
+                    this.appendChild(new WebInspector.ObjectTreeArrayIndexTreeElement(propertyDescriptor, propertyPath));
+                else if (propertyDescriptor.name === &quot;__proto__&quot;)
+                    this.appendChild(new WebInspector.ObjectTreePropertyTreeElement(propertyDescriptor, propertyPath, mode, prototypeName));
+            } else
+                this.appendChild(new WebInspector.ObjectTreePropertyTreeElement(propertyDescriptor, propertyPath, mode, prototypeName));
+        }
+
+        if (!this.children.length) {
+            var emptyMessageElement = WebInspector.ObjectTreeView.emptyMessageElement(WebInspector.UIString(&quot;No Properties.&quot;));
+            this.appendChild(new TreeElement(emptyMessageElement, null, false));
+        }
+    }
</ins><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsObjectTreeSetIndexTreeElementjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeSetIndexTreeElement.js (0 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeSetIndexTreeElement.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeSetIndexTreeElement.js        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+/*
+ * Copyright (C) 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.
+ *
+ * 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.ObjectTreeSetIndexTreeElement = function(object, propertyPath)
+{
+    console.assert(object instanceof WebInspector.RemoteObject);
+
+    this._object = object;
+    this._propertyPath = propertyPath;
+
+    // Treat the same as an array-index just with a different character.
+    WebInspector.GeneralTreeElement.call(this, [&quot;object-tree-array-index&quot;], this._titleFragment(), null, this._object, false);
+
+    this.small = true;
+    this.toggleOnClick = false;
+    this.selectable = false;
+    this.tooltipHandledSeparately = true;
+    this.hasChildren = false;
+};
+
+WebInspector.ObjectTreeSetIndexTreeElement.prototype = {
+    constructor: WebInspector.ObjectTreeSetIndexTreeElement,
+    __proto__: WebInspector.GeneralTreeElement.prototype,
+
+    // Public
+
+    get object()
+    {
+        return this._object;
+    },
+
+    // Private
+
+    _resolvedValuePropertyPath: function()
+    {
+        return this._propertyPath.appendSetIndex(this._object);
+    },
+
+    _titleFragment: function()
+    {
+        var container = document.createDocumentFragment();
+
+        // Set bullet.
+        var nameElement = container.appendChild(document.createElement(&quot;span&quot;));
+        nameElement.className = &quot;index-name&quot;;
+        nameElement.textContent = &quot;\u2022&quot;;
+        nameElement.title = WebInspector.UIString(&quot;Unable to determine path to property from root&quot;);
+
+        // Value.
+        var valueElement = container.appendChild(document.createElement(&quot;span&quot;));
+        valueElement.className = &quot;index-value&quot;;
+        valueElement.appendChild(WebInspector.FormattedValue.createObjectTreeOrFormattedValueForRemoteObject(this._object, this._resolvedValuePropertyPath()));
+
+        return container;
+    }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsObjectTreeViewcss"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeView.css (180712 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeView.css        2015-02-27 01:04:19 UTC (rev 180712)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeView.css        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -105,3 +105,7 @@
</span><span class="cx">     font-family: sans-serif;
</span><span class="cx">     font-size: 12px;
</span><span class="cx"> }
</span><ins>+
+.object-tree-property :matches(.formatted-string, .formatted-regexp) {
+    white-space: nowrap;
+}
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsObjectTreeViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeView.js (180712 => 180713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeView.js        2015-02-27 01:04:19 UTC (rev 180712)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeView.js        2015-02-27 01:15:15 UTC (rev 180713)
</span><span class="lines">@@ -23,17 +23,24 @@
</span><span class="cx">  * THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><span class="cx"> 
</span><del>-WebInspector.ObjectTreeView = function(object, mode, forceExpanding)
</del><ins>+WebInspector.ObjectTreeView = function(object, mode, propertyPath, forceExpanding)
</ins><span class="cx"> {
</span><span class="cx">     WebInspector.Object.call(this);
</span><span class="cx"> 
</span><span class="cx">     console.assert(object instanceof WebInspector.RemoteObject);
</span><ins>+    console.assert(!propertyPath || propertyPath instanceof WebInspector.PropertyPath);
</ins><span class="cx"> 
</span><span class="cx">     this._object = object;
</span><span class="cx">     this._mode = mode || WebInspector.ObjectTreeView.Mode.Properties;
</span><ins>+    this._propertyPath = propertyPath || new WebInspector.PropertyPath(this._object, &quot;obj&quot;);
</ins><span class="cx">     this._expanded = false;
</span><span class="cx">     this._hasLosslessPreview = false;
</span><span class="cx"> 
</span><ins>+    // If ObjectTree is used outside of the console, we do not know when to release
+    // WeakMap entries. Currently collapse would work. For the console, we can just
+    // listen for console clear events. Currently all ObjectTrees are in the console.
+    this._inConsole = true;
+
</ins><span class="cx">     this._element = document.createElement(&quot;div&quot;);
</span><span class="cx">     this._element.className = &quot;object-tree&quot;;
</span><span class="cx"> 
</span><span class="lines">@@ -62,6 +69,14 @@
</span><span class="cx">     // FIXME: Support editable ObjectTrees.
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+WebInspector.ObjectTreeView.emptyMessageElement = function(message)
+{
+    var emptyMessageElement = document.createElement(&quot;div&quot;);
+    emptyMessageElement.className = &quot;empty-message&quot;;
+    emptyMessageElement.textContent = message;
+    return emptyMessageElement;
+};
+
</ins><span class="cx"> WebInspector.ObjectTreeView.Mode = {
</span><span class="cx">     Properties: Symbol(&quot;object-tree-properties&quot;),
</span><span class="cx">     API: Symbol(&quot;object-tree-api&quot;),
</span><span class="lines">@@ -152,6 +167,8 @@
</span><span class="cx">         if (this._previewView)
</span><span class="cx">             this._previewView.showTitle();
</span><span class="cx"> 
</span><ins>+        this._trackWeakEntries();
+
</ins><span class="cx">         this.update();
</span><span class="cx">     },
</span><span class="cx"> 
</span><span class="lines">@@ -165,47 +182,76 @@
</span><span class="cx"> 
</span><span class="cx">         if (this._previewView)
</span><span class="cx">             this._previewView.showPreview();
</span><ins>+
+        this._untrackWeakEntries();
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // Protected
</span><span class="cx"> 
</span><span class="cx">     update: function()
</span><span class="cx">     {
</span><del>-        this._object.getDisplayablePropertyDescriptors(this._updateProperties.bind(this));
</del><ins>+        if (this._object.isCollectionType() &amp;&amp; this._mode === WebInspector.ObjectTreeView.Mode.Properties)
+            this._object.getCollectionEntries(0, 100, this._updateChildren.bind(this, this._updateEntries));
+        else
+            this._object.getDisplayablePropertyDescriptors(this._updateChildren.bind(this, this._updateProperties));
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     // Private
</span><span class="cx"> 
</span><del>-    _updateProperties: function(properties)
</del><ins>+    _updateChildren: function(handler, list)
</ins><span class="cx">     {
</span><span class="cx">         this._outline.removeChildren();
</span><span class="cx"> 
</span><del>-        if (!properties) {
-            var errorMessageElement = document.createElement(&quot;div&quot;);
-            errorMessageElement.className = &quot;empty-message&quot;;
-            errorMessageElement.textContent = WebInspector.UIString(&quot;Could not fetch properties. Object may no longer exist.&quot;);;
</del><ins>+        if (!list) {
+            var errorMessageElement = WebInspector.ObjectTreeView.emptyMessageElement(WebInspector.UIString(&quot;Could not fetch properties. Object may no longer exist.&quot;));
</ins><span class="cx">             this._outline.appendChild(new TreeElement(errorMessageElement, null, false));
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        handler.call(this, list, this._propertyPath);
+    },
+
+    _updateEntries: function(entries, propertyPath)
+    {
+        for (var entry of entries) {
+            if (entry.key) {
+                this._outline.appendChild(new WebInspector.ObjectTreeMapKeyTreeElement(entry.key, propertyPath));
+                this._outline.appendChild(new WebInspector.ObjectTreeMapValueTreeElement(entry.value, propertyPath, entry.key));
+            } else
+                this._outline.appendChild(new WebInspector.ObjectTreeSetIndexTreeElement(entry.value, propertyPath));
+        }
+
+        if (!this._outline.children.length) {
+            var emptyMessageElement = WebInspector.ObjectTreeView.emptyMessageElement(WebInspector.UIString(&quot;No Entries.&quot;));
+            this._outline.appendChild(new TreeElement(emptyMessageElement, null, false));
+        }
+
+        // Show the prototype so users can see the API.
+        this._object.getOwnPropertyDescriptor(&quot;__proto__&quot;, function(propertyDescriptor) {
+            if (propertyDescriptor)
+                this._outline.appendChild(new WebInspector.ObjectTreePropertyTreeElement(propertyDescriptor, propertyPath, this._mode));
+        }.bind(this));
+    },
+
+    _updateProperties: function(properties, propertyPath)
+    {
</ins><span class="cx">         properties.sort(WebInspector.ObjectTreeView.ComparePropertyDescriptors);
</span><span class="cx"> 
</span><del>-        // FIXME: Intialize component with &quot;$n&quot; instead of &quot;obj&quot;.
-        var rootPropertyPath = new WebInspector.PropertyPath(this._object, &quot;obj&quot;);
</del><ins>+        var isArray = this._object.isArray();
+        var isPropertyMode = this._mode === WebInspector.ObjectTreeView.Mode.Properties;
</ins><span class="cx"> 
</span><del>-        for (var propertyDescriptor of properties)
-            this._outline.appendChild(new WebInspector.ObjectTreePropertyTreeElement(propertyDescriptor, rootPropertyPath, this._mode));
</del><ins>+        for (var propertyDescriptor of properties) {
+            if (isArray &amp;&amp; isPropertyMode) {
+                if (propertyDescriptor.isIndexProperty())
+                    this._outline.appendChild(new WebInspector.ObjectTreeArrayIndexTreeElement(propertyDescriptor, propertyPath));
+                else if (propertyDescriptor.name === &quot;__proto__&quot;)
+                    this._outline.appendChild(new WebInspector.ObjectTreePropertyTreeElement(propertyDescriptor, propertyPath, this._mode));
+            } else
+                this._outline.appendChild(new WebInspector.ObjectTreePropertyTreeElement(propertyDescriptor, propertyPath, this._mode));
+        }
</ins><span class="cx"> 
</span><del>-        // FIXME: Re-enable Collection Entries with new UI.
-        // if (this._mode === WebInspector.ObjectTreeView.Mode.Properties) {
-        //     if (this._object.isCollectionType())
-        //         this._outline.appendChild(new WebInspector.ObjectTreeCollectionTreeElement(this._object));
-        // }
-
</del><span class="cx">         if (!this._outline.children.length) {
</span><del>-            var emptyMessageElement = document.createElement(&quot;div&quot;);
-            emptyMessageElement.className = &quot;empty-message&quot;;
-            emptyMessageElement.textContent = WebInspector.UIString(&quot;No Properties&quot;);;
</del><ins>+            var emptyMessageElement = WebInspector.ObjectTreeView.emptyMessageElement(WebInspector.UIString(&quot;No Properties.&quot;));
</ins><span class="cx">             this._outline.appendChild(new TreeElement(emptyMessageElement, null, false));
</span><span class="cx">         }
</span><span class="cx">     },
</span><span class="lines">@@ -221,5 +267,45 @@
</span><span class="cx">             this.collapse();
</span><span class="cx"> 
</span><span class="cx">         event.stopPropagation();
</span><del>-    }
</del><ins>+    },
+
+    _trackWeakEntries: function()
+    {
+        if (this._trackingEntries)
+            return;
+
+        if (!this._object.isWeakCollection())
+            return;
+
+        this._trackingEntries = true;
+
+        if (this._inConsole) {
+            WebInspector.logManager.addEventListener(WebInspector.LogManager.Event.Cleared, this._untrackWeakEntries, this);
+            WebInspector.logManager.addEventListener(WebInspector.LogManager.Event.ActiveLogCleared, this._untrackWeakEntries, this);
+            WebInspector.logManager.addEventListener(WebInspector.LogManager.Event.SessionStarted, this._untrackWeakEntries, this);
+        }
+    },
+
+    _untrackWeakEntries: function()
+    {
+        if (!this._trackingEntries)
+            return;
+
+        if (!this._object.isWeakCollection())
+            return;
+
+        this._trackingEntries = false;
+
+        this._object.releaseWeakCollectionEntries();
+
+        if (this._inConsole) {
+            WebInspector.logManager.removeEventListener(WebInspector.LogManager.Event.Cleared, this._untrackWeakEntries, this);
+            WebInspector.logManager.removeEventListener(WebInspector.LogManager.Event.ActiveLogCleared, this._untrackWeakEntries, this);
+            WebInspector.logManager.removeEventListener(WebInspector.LogManager.Event.SessionStarted, this._untrackWeakEntries, this);
+        }
+
+        // FIXME: This only tries to release weak entries if this object was a WeakMap.
+        // If there was a WeakMap expanded in a sub-object, we will never release those values.
+        // Should we attempt walking the entire tree and release weak collections?
+    },
</ins><span class="cx"> };
</span></span></pre>
</div>
</div>

</body>
</html>