<!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>[160025] 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/160025">160025</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2013-12-03 11:51:08 -0800 (Tue, 03 Dec 2013)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: restore navigation panel state across reloads and reopens
https://bugs.webkit.org/show_bug.cgi?id=122125

Patch by Brian J. Burg &lt;burg@cs.washington.edu&gt; on 2013-12-03
Reviewed by Timothy Hatcher.

The previous strategy for restoring content views after inspector
re-open did not consider the active sidebar and its selection, and
tried to recreate the appropriate selection from the saved content
view. However, doesn't work for tree elements in the sidebar panel
that don't change views when selected, such as script breakpoints,
special breakpoints, call stack, timeline sections, etc.

This patch implements a new strategy that saves the navigation
sidebar panel's view state by serializing the identity of the
selected element's represented object. Relevant represented
object classes implement the saveIdentityToCookie() method. Each
represented object class also adds a TypeIdentifier property to
its constructor, to aid inexact matching based on represented
object type, rather than its complete identity.

When restoring, the navigation sidebar attempts to match added
tree elements against the pending cookie, and selects the element
if it matches. A represented object matches if its serialized
identity matches the previously saved serialized identity.

The inspector view state is now only saved on the page hide event
(for saving across reopen) and when the main frame commits its
provisional load (for saving across same-page reloads). It
consolidates similar view state settings into a single setting.

* UserInterface/ApplicationCacheFrame.js:
(WebInspector.ApplicationCacheFrame): Add cookie keys and type identifier.
(WebInspector.ApplicationCacheFrame.prototype.saveIdentityToCookie): Added.
* UserInterface/ApplicationCacheManager.js: remove objectForCookie().
* UserInterface/Breakpoint.js:
(WebInspector.Breakpoint): Add cookie keys and type identifier.
(WebInspector.Breakpoint.prototype.saveIdentityToCookie):
* UserInterface/CookieStorageObject.js:
(WebInspector.CookieStorageObject.prototype.saveIdentityToCookie): Added.
* UserInterface/DOMStorageObject.js:
(WebInspector.DOMStorageObject): Add cookie keys and type identifier.
(WebInspector.DOMStorageObject.prototype.saveIdentityToCookie): Added.
* UserInterface/DatabaseObject.js:
(WebInspector.DatabaseObject): Add cookie keys and type identifier.
(WebInspector.DatabaseObject.prototype.saveIdentityToCookie): Added.
* UserInterface/DatabaseTableObject.js:
(WebInspector.DatabaseTableObject): Add cookie keys and type identifier.
(WebInspector.DatabaseTableObject.prototype.saveIdentityToCookie): Added.
* UserInterface/DebuggerSidebarPanel.js:
(WebInspector.DebuggerSidebarPanel.prototype.saveStateToCookie): Added.
(WebInspector.DebuggerSidebarPanel.prototype.restoreStateFromCookie): Added.
* UserInterface/Frame.js:
(WebInspector.Frame): Add cookie keys and type identifier.
(WebInspector.Frame.prototype.saveIdentityToCookie): Added.
* UserInterface/FrameResourceManager.js: remove objectForCookie().
* UserInterface/InstrumentSidebarPanel.js:
(WebInspector.InstrumentSidebarPanel.prototype.showTimelineForRecordType):
Return the shown timeline, if any.

(WebInspector.InstrumentSidebarPanel.prototype.saveStateToCookie): Added.
(WebInspector.InstrumentSidebarPanel.prototype.restoreStateFromCookie): Added.
(WebInspector.InstrumentSidebarPanel.prototype.showProfile):
Return the shown profile, if any.

* UserInterface/Main.js:
(WebInspector): Added cookie keys for the selected sidebar and
typeidentifier of the sidebar's selected tree element.

(WebInspector.contentLoaded): Remove callbacks for
resolveAndShowPendingContentViewCookie(). Consolidate all saved
inspector view state into one Setting. Move special-cased
restoring of the console to the restoration method. Move saving
of last opened navigation panel to the saving method.

(WebInspector._mainResourceDidChange): Try to restore saved view
state when the main resource changes.

(WebInspector._provisionalLoadCommitted): Update the saved view
state when the navigation commits. This is the last chance to save
it before the main resource changes and the navigation panel view
state is discarded and rebuilt.

(WebInspector._pageHidden): Update the saved view state when the
inspector page is hidden, but before state is discarded.

(WebInspector._navigationSidebarPanelSelected): Don't save last
navigation sidebar panel.
(WebInspector._updateCookieForInspectorViewState): Renamed from
_updateCurrentContentViewCookie. It delegates view state
serialization to the currently open navigation sidebar, rather
than the current content view.

(WebInspector._contentBrowserRepresentedObjectsDidChange): Don't
spuriously serialize the current view state cookie on every
ContentView change.

(WebInspector._restoreInspectorViewStateFromCookie): Renamed from
_showContentViewForCookie. It now restores a specific navigation
panel and delegates remaining view state restoration to the panel
itself. Last-resort selection of any tree element with the same
type identifier was moved to the navigation panel's restore method.

* UserInterface/NavigationSidebarPanel.js:
(WebInspector.NavigationSidebarPanel):
(WebInspector.NavigationSidebarPanel.prototype.set contentTreeOutline):
(WebInspector.NavigationSidebarPanel.prototype.createContentTreeOutline):
Save references to all created TreeOutlines in a Set, so we can
restore any tree's selection.

(WebInspector.NavigationSidebarPanel.prototype.saveStateToCookie):
Added. Find the selected tree element from all tree outlines and
ask it to serialize its identity.

(WebInspector.NavigationSidebarPanel.prototype.restoreStateFromCookie):
Added. Eagerly search existing tree elements for a matching
representedObject. If none exists, save the pending cookie and
schedule last-resort matching using the provided timeout interval.

(WebInspector.NavigationSidebarPanel.prototype._treeElementAddedOrChanged):
Check if the added tree element matches a pending view state
cookie, if one exists.

(WebInspector.NavigationSidebarPanel.prototype.treeElementMatchesCookie):
Added. Check if the tree element's representedObject matches the
pending view state cookie.

(WebInspector.NavigationSidebarPanel.prototype._checkElementsForPendingViewStateCookie):
Added. For each provided tree element, check if the tree
element's represented object produces the same serialized identity
as the pending view state cookie that we are trying to resolve.
If a match is found (possibly by relaxing to matching anything
with the same type), select the tree element and clear both the
pending view state cookie and last-resort selection timer.

* UserInterface/Resource.js:
(WebInspector.Resource): Add cookie keys and type identifier.
(WebInspector.Resource.prototype.saveIdentityToCookie): Added.

* UserInterface/ResourceClusterContentView.js:
(WebInspector.ResourceClusterContentView.prototype.saveToCookie):
(WebInspector.ResourceClusterContentView.prototype.restoreFromCookie):
Since identity state is serialized by the representedObject, these
methods only need to save view-specific state, such as the visible
subview. Remove extraneous state.

* UserInterface/Script.js:
(WebInspector.Script): Add cookie keys and type identifier.
(WebInspector.Script.prototype.saveIdentityToCookie): Added.
* UserInterface/StorageManager.js: remove objectForCookie().
* UserInterface/TimelineManager.js: remove objectForCookie().
* UserInterface/TimelinesContentView.js:
(WebInspector.TimelinesContentView.prototype.saveToCookie):
(WebInspector.TimelinesContentView.prototype.restoreFromCookie):
Since identity state is serialized by the representedObject, these
methods only need to save view-specific state, such as the visible
subview. Remove extraneous state.

* UserInterface/TreeOutline.js: Add TreeOutline.prototype.constructor
so other code can assume the constructor property exists.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceApplicationCacheFramejs">trunk/Source/WebInspectorUI/UserInterface/ApplicationCacheFrame.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceApplicationCacheManagerjs">trunk/Source/WebInspectorUI/UserInterface/ApplicationCacheManager.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceBreakpointjs">trunk/Source/WebInspectorUI/UserInterface/Breakpoint.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceCookieStorageObjectjs">trunk/Source/WebInspectorUI/UserInterface/CookieStorageObject.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceDOMStorageObjectjs">trunk/Source/WebInspectorUI/UserInterface/DOMStorageObject.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceDatabaseObjectjs">trunk/Source/WebInspectorUI/UserInterface/DatabaseObject.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceDatabaseTableObjectjs">trunk/Source/WebInspectorUI/UserInterface/DatabaseTableObject.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceDebuggerSidebarPaneljs">trunk/Source/WebInspectorUI/UserInterface/DebuggerSidebarPanel.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceFramejs">trunk/Source/WebInspectorUI/UserInterface/Frame.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceFrameResourceManagerjs">trunk/Source/WebInspectorUI/UserInterface/FrameResourceManager.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceInstrumentSidebarPaneljs">trunk/Source/WebInspectorUI/UserInterface/InstrumentSidebarPanel.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceMainjs">trunk/Source/WebInspectorUI/UserInterface/Main.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceNavigationSidebarPaneljs">trunk/Source/WebInspectorUI/UserInterface/NavigationSidebarPanel.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceResourcejs">trunk/Source/WebInspectorUI/UserInterface/Resource.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceResourceClusterContentViewjs">trunk/Source/WebInspectorUI/UserInterface/ResourceClusterContentView.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceScriptjs">trunk/Source/WebInspectorUI/UserInterface/Script.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceStorageManagerjs">trunk/Source/WebInspectorUI/UserInterface/StorageManager.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelineManagerjs">trunk/Source/WebInspectorUI/UserInterface/TimelineManager.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTimelinesContentViewjs">trunk/Source/WebInspectorUI/UserInterface/TimelinesContentView.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTreeOutlinejs">trunk/Source/WebInspectorUI/UserInterface/TreeOutline.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/ChangeLog        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -1,3 +1,165 @@
</span><ins>+2013-12-03  Brian J. Burg  &lt;burg@cs.washington.edu&gt;
+
+        Web Inspector: restore navigation panel state across reloads and reopens
+        https://bugs.webkit.org/show_bug.cgi?id=122125
+
+        Reviewed by Timothy Hatcher.
+
+        The previous strategy for restoring content views after inspector
+        re-open did not consider the active sidebar and its selection, and
+        tried to recreate the appropriate selection from the saved content
+        view. However, doesn't work for tree elements in the sidebar panel
+        that don't change views when selected, such as script breakpoints,
+        special breakpoints, call stack, timeline sections, etc.
+
+        This patch implements a new strategy that saves the navigation
+        sidebar panel's view state by serializing the identity of the
+        selected element's represented object. Relevant represented
+        object classes implement the saveIdentityToCookie() method. Each
+        represented object class also adds a TypeIdentifier property to
+        its constructor, to aid inexact matching based on represented
+        object type, rather than its complete identity.
+
+        When restoring, the navigation sidebar attempts to match added
+        tree elements against the pending cookie, and selects the element
+        if it matches. A represented object matches if its serialized
+        identity matches the previously saved serialized identity.
+
+        The inspector view state is now only saved on the page hide event
+        (for saving across reopen) and when the main frame commits its
+        provisional load (for saving across same-page reloads). It
+        consolidates similar view state settings into a single setting.
+
+        * UserInterface/ApplicationCacheFrame.js:
+        (WebInspector.ApplicationCacheFrame): Add cookie keys and type identifier.
+        (WebInspector.ApplicationCacheFrame.prototype.saveIdentityToCookie): Added.
+        * UserInterface/ApplicationCacheManager.js: remove objectForCookie().
+        * UserInterface/Breakpoint.js:
+        (WebInspector.Breakpoint): Add cookie keys and type identifier.
+        (WebInspector.Breakpoint.prototype.saveIdentityToCookie):
+        * UserInterface/CookieStorageObject.js:
+        (WebInspector.CookieStorageObject.prototype.saveIdentityToCookie): Added.
+        * UserInterface/DOMStorageObject.js:
+        (WebInspector.DOMStorageObject): Add cookie keys and type identifier.
+        (WebInspector.DOMStorageObject.prototype.saveIdentityToCookie): Added.
+        * UserInterface/DatabaseObject.js:
+        (WebInspector.DatabaseObject): Add cookie keys and type identifier.
+        (WebInspector.DatabaseObject.prototype.saveIdentityToCookie): Added.
+        * UserInterface/DatabaseTableObject.js:
+        (WebInspector.DatabaseTableObject): Add cookie keys and type identifier.
+        (WebInspector.DatabaseTableObject.prototype.saveIdentityToCookie): Added.
+        * UserInterface/DebuggerSidebarPanel.js:
+        (WebInspector.DebuggerSidebarPanel.prototype.saveStateToCookie): Added.
+        (WebInspector.DebuggerSidebarPanel.prototype.restoreStateFromCookie): Added.
+        * UserInterface/Frame.js:
+        (WebInspector.Frame): Add cookie keys and type identifier.
+        (WebInspector.Frame.prototype.saveIdentityToCookie): Added.
+        * UserInterface/FrameResourceManager.js: remove objectForCookie().
+        * UserInterface/InstrumentSidebarPanel.js:
+        (WebInspector.InstrumentSidebarPanel.prototype.showTimelineForRecordType):
+        Return the shown timeline, if any.
+
+        (WebInspector.InstrumentSidebarPanel.prototype.saveStateToCookie): Added.
+        (WebInspector.InstrumentSidebarPanel.prototype.restoreStateFromCookie): Added.
+        (WebInspector.InstrumentSidebarPanel.prototype.showProfile):
+        Return the shown profile, if any.
+
+        * UserInterface/Main.js:
+        (WebInspector): Added cookie keys for the selected sidebar and
+        typeidentifier of the sidebar's selected tree element.
+
+        (WebInspector.contentLoaded): Remove callbacks for
+        resolveAndShowPendingContentViewCookie(). Consolidate all saved
+        inspector view state into one Setting. Move special-cased
+        restoring of the console to the restoration method. Move saving
+        of last opened navigation panel to the saving method.
+
+        (WebInspector._mainResourceDidChange): Try to restore saved view
+        state when the main resource changes.
+
+        (WebInspector._provisionalLoadCommitted): Update the saved view
+        state when the navigation commits. This is the last chance to save
+        it before the main resource changes and the navigation panel view
+        state is discarded and rebuilt.
+
+        (WebInspector._pageHidden): Update the saved view state when the
+        inspector page is hidden, but before state is discarded.
+
+        (WebInspector._navigationSidebarPanelSelected): Don't save last
+        navigation sidebar panel.
+        (WebInspector._updateCookieForInspectorViewState): Renamed from
+        _updateCurrentContentViewCookie. It delegates view state
+        serialization to the currently open navigation sidebar, rather
+        than the current content view.
+
+        (WebInspector._contentBrowserRepresentedObjectsDidChange): Don't
+        spuriously serialize the current view state cookie on every
+        ContentView change.
+
+        (WebInspector._restoreInspectorViewStateFromCookie): Renamed from
+        _showContentViewForCookie. It now restores a specific navigation
+        panel and delegates remaining view state restoration to the panel
+        itself. Last-resort selection of any tree element with the same
+        type identifier was moved to the navigation panel's restore method.
+
+        * UserInterface/NavigationSidebarPanel.js:
+        (WebInspector.NavigationSidebarPanel):
+        (WebInspector.NavigationSidebarPanel.prototype.set contentTreeOutline):
+        (WebInspector.NavigationSidebarPanel.prototype.createContentTreeOutline):
+        Save references to all created TreeOutlines in a Set, so we can
+        restore any tree's selection.
+
+        (WebInspector.NavigationSidebarPanel.prototype.saveStateToCookie):
+        Added. Find the selected tree element from all tree outlines and
+        ask it to serialize its identity.
+
+        (WebInspector.NavigationSidebarPanel.prototype.restoreStateFromCookie):
+        Added. Eagerly search existing tree elements for a matching
+        representedObject. If none exists, save the pending cookie and
+        schedule last-resort matching using the provided timeout interval.
+
+        (WebInspector.NavigationSidebarPanel.prototype._treeElementAddedOrChanged):
+        Check if the added tree element matches a pending view state
+        cookie, if one exists.
+
+        (WebInspector.NavigationSidebarPanel.prototype.treeElementMatchesCookie):
+        Added. Check if the tree element's representedObject matches the
+        pending view state cookie.
+
+        (WebInspector.NavigationSidebarPanel.prototype._checkElementsForPendingViewStateCookie):
+        Added. For each provided tree element, check if the tree
+        element's represented object produces the same serialized identity
+        as the pending view state cookie that we are trying to resolve.
+        If a match is found (possibly by relaxing to matching anything
+        with the same type), select the tree element and clear both the
+        pending view state cookie and last-resort selection timer.
+
+        * UserInterface/Resource.js:
+        (WebInspector.Resource): Add cookie keys and type identifier.
+        (WebInspector.Resource.prototype.saveIdentityToCookie): Added.
+
+        * UserInterface/ResourceClusterContentView.js:
+        (WebInspector.ResourceClusterContentView.prototype.saveToCookie):
+        (WebInspector.ResourceClusterContentView.prototype.restoreFromCookie):
+        Since identity state is serialized by the representedObject, these
+        methods only need to save view-specific state, such as the visible
+        subview. Remove extraneous state.
+
+        * UserInterface/Script.js:
+        (WebInspector.Script): Add cookie keys and type identifier.
+        (WebInspector.Script.prototype.saveIdentityToCookie): Added.
+        * UserInterface/StorageManager.js: remove objectForCookie().
+        * UserInterface/TimelineManager.js: remove objectForCookie().
+        * UserInterface/TimelinesContentView.js:
+        (WebInspector.TimelinesContentView.prototype.saveToCookie):
+        (WebInspector.TimelinesContentView.prototype.restoreFromCookie):
+        Since identity state is serialized by the representedObject, these
+        methods only need to save view-specific state, such as the visible
+        subview. Remove extraneous state.
+
+        * UserInterface/TreeOutline.js: Add TreeOutline.prototype.constructor
+        so other code can assume the constructor property exists.
+
</ins><span class="cx"> 2013-12-02  Antoine Quint  &lt;graouts@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: popover can overlap target frame
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceApplicationCacheFramejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/ApplicationCacheFrame.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/ApplicationCacheFrame.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/ApplicationCacheFrame.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -35,9 +35,15 @@
</span><span class="cx">     this._status = status;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+WebInspector.ApplicationCacheFrame.TypeIdentifier = &quot;application-cache-frame&quot;;
+WebInspector.ApplicationCacheFrame.FrameURLCookieKey = &quot;application-cache-frame-url&quot;;
+WebInspector.ApplicationCacheFrame.ManifestURLCookieKey = &quot;application-cache-frame-manifest-url&quot;;
+
</ins><span class="cx"> WebInspector.ApplicationCacheFrame.prototype = {
</span><span class="cx">     constructor: WebInspector.ApplicationCacheFrame,
</span><span class="cx">     
</span><ins>+    // Public
+
</ins><span class="cx">     get frame()
</span><span class="cx">     {
</span><span class="cx">         return this._frame;
</span><span class="lines">@@ -56,6 +62,12 @@
</span><span class="cx">     set status(status)
</span><span class="cx">     {
</span><span class="cx">         this._status = status;
</span><ins>+    },
+
+    saveIdentityToCookie: function(cookie)
+    {
+        cookie[WebInspector.ApplicationCacheFrame.FrameURLCookieKey] = this.frame.url;
+        cookie[WebInspector.ApplicationCacheFrame.ManifestURLCookieKey] = this.manifest.manifestURL;
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceApplicationCacheManagerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/ApplicationCacheManager.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/ApplicationCacheManager.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/ApplicationCacheManager.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -102,19 +102,6 @@
</span><span class="cx">         ApplicationCacheAgent.getApplicationCacheForFrame(frame.id, callbackWrapper);
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    objectForCookie: function(cookie, matchOnTypeAlone)
-    {
-        console.assert(cookie.type &amp;&amp; cookie.type === WebInspector.ContentViewCookieType.ApplicationCache);
-
-        for (var i = 0; i &lt; this._applicationCacheObjects.length; ++i) {
-            var object = this._applicationCacheObjects[i];
-            if (object.frame.url === cookie.frame &amp;&amp; object.manifest.manifestURL === cookie.manifest)
-                return object;
-        }
-
-        return matchOnTypeAlone &amp;&amp; this._applicationCacheObjects.length ? this._applicationCacheObjects[0] : null;
-    },
-
</del><span class="cx">     // Private
</span><span class="cx"> 
</span><span class="cx">     _mainResourceDidChange: function(event)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceBreakpointjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Breakpoint.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Breakpoint.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/Breakpoint.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -69,6 +69,11 @@
</span><span class="cx"> 
</span><span class="cx"> WebInspector.Breakpoint.DefaultBreakpointActionType = WebInspector.BreakpointAction.Type.Log;
</span><span class="cx"> 
</span><ins>+WebInspector.Breakpoint.TypeIdentifier = &quot;breakpoint&quot;;
+WebInspector.Breakpoint.URLCookieKey = &quot;breakpoint-url&quot;;
+WebInspector.Breakpoint.LineNumberCookieKey = &quot;breakpoint-line-number&quot;;
+WebInspector.Breakpoint.ColumnNumberCookieKey = &quot;breakpoint-column-number&quot;;
+
</ins><span class="cx"> WebInspector.Breakpoint.Event = {
</span><span class="cx">     DisabledStateDidChange: &quot;breakpoint-disabled-state-did-change&quot;,
</span><span class="cx">     ResolvedStateDidChange: &quot;breakpoint-resolved-state-did-change&quot;,
</span><span class="lines">@@ -290,6 +295,13 @@
</span><span class="cx">         this.dispatchEventToListeners(WebInspector.Breakpoint.Event.ActionsDidChange);
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    saveIdentityToCookie: function(cookie)
+    {
+        cookie[WebInspector.Breakpoint.URLCookieKey] = this.url;
+        cookie[WebInspector.Breakpoint.LineNumberCookieKey] = this.sourceCodeLocation.lineNumber;
+        cookie[WebInspector.Breakpoint.ColumnNumberCookieKey] = this.sourceCodeLocation.columnNumber;
+    },
+
</ins><span class="cx">     // Protected (Called by BreakpointAction)
</span><span class="cx"> 
</span><span class="cx">     breakpointActionDidChange: function(action)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceCookieStorageObjectjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/CookieStorageObject.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/CookieStorageObject.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/CookieStorageObject.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -28,6 +28,9 @@
</span><span class="cx">     this._host = host;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+WebInspector.CookieStorageObject.TypeIdentifier = &quot;cookie-storage&quot;;
+WebInspector.CookieStorageObject.CookieHostCookieKey = &quot;cookie-storage-host&quot;;
+
</ins><span class="cx"> WebInspector.CookieStorageObject.prototype = {
</span><span class="cx">     constructor: WebInspector.CookieStorageObject,
</span><span class="cx"> 
</span><span class="lines">@@ -36,5 +39,9 @@
</span><span class="cx">         return this._host;
</span><span class="cx">     },
</span><span class="cx">     
</span><ins>+    saveIdentityToCookie: function(cookie)
+    {
+        cookie[WebInspector.CookieStorageObject.CookieHostCookieKey] = this.host;
+    }
</ins><span class="cx">     // FIXME: This class will need to look up cookies that are set for this host.
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceDOMStorageObjectjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/DOMStorageObject.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/DOMStorageObject.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/DOMStorageObject.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -30,6 +30,10 @@
</span><span class="cx">     this._isLocalStorage = isLocalStorage;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+WebInspector.DOMStorageObject.TypeIdentifier = &quot;dom-storage&quot;;
+WebInspector.DOMStorageObject.HostCookieKey = &quot;dom-storage-object-host&quot;;
+WebInspector.DOMStorageObject.LocalStorageCookieKey = &quot;dom-storage-object-local-storage&quot;;
+
</ins><span class="cx"> WebInspector.DOMStorageObject.prototype = {
</span><span class="cx">     constructor: WebInspector.DOMStorageObject,
</span><span class="cx">     
</span><span class="lines">@@ -43,6 +47,12 @@
</span><span class="cx">         return this._host;
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    saveIdentityToCookie: function(cookie)
+    {
+        cookie[WebInspector.DOMStorageObject.HostCookieKey] = this.host;
+        cookie[WebInspector.DOMStorageObject.LocalStorageCookieKey] = this.isLocalStorage();
+    },
+
</ins><span class="cx">     isLocalStorage: function()
</span><span class="cx">     {
</span><span class="cx">         return this._isLocalStorage;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceDatabaseObjectjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/DatabaseObject.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/DatabaseObject.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/DatabaseObject.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -31,9 +31,15 @@
</span><span class="cx">     this._version = version;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+WebInspector.DatabaseObject.TypeIdentifier = &quot;database&quot;;
+WebInspector.DatabaseObject.HostCookieKey = &quot;database-object-host&quot;;
+WebInspector.DatabaseObject.NameCookieKey = &quot;database-object-name&quot;;
+
</ins><span class="cx"> WebInspector.DatabaseObject.prototype = {
</span><span class="cx">     constructor: WebInspector.DatabaseObject,
</span><span class="cx">     
</span><ins>+    // Public
+
</ins><span class="cx">     get id()
</span><span class="cx">     {
</span><span class="cx">         return this._id;
</span><span class="lines">@@ -54,6 +60,12 @@
</span><span class="cx">         return this._version;
</span><span class="cx">     },
</span><span class="cx">     
</span><ins>+    saveIdentityToCookie: function(cookie)
+    {
+        cookie[WebInspector.DatabaseObject.HostCookieKey] = this.host;
+        cookie[WebInspector.DatabaseObject.NameCookieKey] = this.name;
+    },
+
</ins><span class="cx">     getTableNames: function(callback)
</span><span class="cx">     {
</span><span class="cx">         function sortingCallback(error, names)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceDatabaseTableObjectjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/DatabaseTableObject.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/DatabaseTableObject.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/DatabaseTableObject.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -31,6 +31,9 @@
</span><span class="cx">     this._database = database;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+WebInspector.DatabaseTableObject.TypeIdentifier = &quot;database-table&quot;;
+WebInspector.DatabaseTableObject.NameCookieKey = &quot;database-table-object-name&quot;;
+
</ins><span class="cx"> WebInspector.DatabaseTableObject.prototype = {
</span><span class="cx">     constructor: WebInspector.DatabaseTableObject,
</span><span class="cx">     
</span><span class="lines">@@ -42,7 +45,12 @@
</span><span class="cx">     get database()
</span><span class="cx">     {
</span><span class="cx">         return this._database;
</span><del>-    }
</del><ins>+    },
+
+    saveIdentityToCookie: function(cookie)
+    {
+        cookie[WebInspector.DatabaseTableObject.NameCookieKey] = this.name;
+    },
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> WebInspector.DatabaseTableObject.prototype.__proto__ = WebInspector.Object.prototype;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceDebuggerSidebarPaneljs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/DebuggerSidebarPanel.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/DebuggerSidebarPanel.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/DebuggerSidebarPanel.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -120,6 +120,9 @@
</span><span class="cx"> WebInspector.DebuggerSidebarPanel.OffsetSectionsStyleClassName = &quot;offset-sections&quot;;
</span><span class="cx"> WebInspector.DebuggerSidebarPanel.ExceptionIconStyleClassName = &quot;breakpoint-exception-icon&quot;;
</span><span class="cx"> 
</span><ins>+WebInspector.DebuggerSidebarPanel.SelectedAllExceptionsCookieKey = &quot;debugger-sidebar-panel-all-exceptions-breakpoint&quot;;
+WebInspector.DebuggerSidebarPanel.SelectedAllUncaughtExceptionsCookieKey = &quot;debugger-sidebar-panel-all-uncaught-exceptions-breakpoint&quot;;
+
</ins><span class="cx"> WebInspector.DebuggerSidebarPanel.prototype = {
</span><span class="cx">     constructor: WebInspector.DebuggerSidebarPanel,
</span><span class="cx"> 
</span><span class="lines">@@ -134,6 +137,40 @@
</span><span class="cx">         return this.contentTreeOutline.getCachedTreeElement(representedObject);
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    // Protected
+
+    saveStateToCookie: function(cookie)
+    {
+        console.assert(cookie);
+
+        var selectedTreeElement = this._breakpointsContentTreeOutline.selectedTreeElement;
+        if (!selectedTreeElement)
+            return;
+
+        var representedObject = selectedTreeElement.representedObject;
+
+        if (representedObject === WebInspector.debuggerManager.allExceptionsBreakpoint)
+            cookie[WebInspector.DebuggerSidebarPanel.SelectedAllExceptionsCookieKey] = true;
+
+        if (representedObject === WebInspector.debuggerManager.allUncaughtExceptionsBreakpoint)
+            cookie[WebInspector.DebuggerSidebarPanel.SelectedAllUncaughtExceptionsCookieKey] = true;
+
+        WebInspector.NavigationSidebarPanel.prototype.saveStateToCookie.call(this, cookie);
+    },
+
+    restoreStateFromCookie: function(cookie)
+    {
+        console.assert(cookie);
+
+        // Eagerly resolve the special breakpoints; otherwise, use the default behavior.
+        if (cookie[WebInspector.DebuggerSidebarPanel.SelectedAllExceptionsCookieKey])
+            this._allExceptionsBreakpointTreeElement.revealAndSelect();
+        else if (cookie[WebInspector.DebuggerSidebarPanel.SelectedAllUncaughtExceptionsCookieKey])
+            this._allUncaughtExceptionsBreakpointTreeElement.revealAndSelect();
+        else
+            WebInspector.NavigationSidebarPanel.prototype.restoreStateFromCookie.call(this, cookie);
+    },
+
</ins><span class="cx">     // Private
</span><span class="cx"> 
</span><span class="cx">     _debuggerPauseResumeButtonClicked: function(event)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceFramejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Frame.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Frame.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/Frame.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -67,6 +67,9 @@
</span><span class="cx">     ExecutionContextsCleared: &quot;frame-execution-contexts-cleared&quot;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+WebInspector.Frame.TypeIdentifier = &quot;Frame&quot;;
+WebInspector.Frame.MainResourceURLCookieKey = &quot;frame-main-resource-url&quot;;
+
</ins><span class="cx"> WebInspector.Frame.prototype = {
</span><span class="cx">     constructor: WebInspector.Frame,
</span><span class="cx"> 
</span><span class="lines">@@ -432,6 +435,11 @@
</span><span class="cx">         this.dispatchEventToListeners(WebInspector.Frame.Event.AllResourcesRemoved);
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    saveIdentityToCookie: function(cookie)
+    {
+        cookie[WebInspector.Frame.MainResourceURLCookieKey] = this.mainResource.url;
+    },
+
</ins><span class="cx">     // Private
</span><span class="cx"> 
</span><span class="cx">     _isProvisionalResource: function(resource)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceFrameResourceManagerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/FrameResourceManager.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/FrameResourceManager.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/FrameResourceManager.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -80,20 +80,6 @@
</span><span class="cx">         return this._frameIdentifierMap[frameId] || null;
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-
-    objectForCookie: function(cookie)
-    {
-        var representedObject = cookie.url ? this.resourceForURL(cookie.url) : this.mainFrame;
-
-        if (!representedObject)
-            representedObject = this.mainFrame;
-
-        if (representedObject instanceof WebInspector.Resource &amp;&amp; representedObject.isMainResource())
-            representedObject = representedObject.parentFrame;
-
-        return representedObject;
-    },
-
</del><span class="cx">     frameDidNavigate: function(framePayload)
</span><span class="cx">     {
</span><span class="cx">         // Called from WebInspector.PageObserver.
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceInstrumentSidebarPaneljs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/InstrumentSidebarPanel.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/InstrumentSidebarPanel.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/InstrumentSidebarPanel.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -158,6 +158,10 @@
</span><span class="cx"> WebInspector.InstrumentSidebarPanel.StartCSSSelectorProfileValue = &quot;start-css-selector-profile&quot;;
</span><span class="cx"> WebInspector.InstrumentSidebarPanel.StartCanvasProfileValue = &quot;start-canvas-profile&quot;;
</span><span class="cx"> 
</span><ins>+WebInspector.InstrumentSidebarPanel.SelectedTimelineCookieKey = &quot;instrument-sidebar-panel-selected-timeline&quot;;
+WebInspector.InstrumentSidebarPanel.SelectedProfileTypeCookieKey = &quot;instrument-sidebar-panel-selected-profile-type&quot;;
+WebInspector.InstrumentSidebarPanel.SelectedProfileTitleCookieKey = &quot;instrument-sidebar-panel-selected-profile-title&quot;;
+
</ins><span class="cx"> WebInspector.InstrumentSidebarPanel.prototype = {
</span><span class="cx">     constructor: WebInspector.InstrumentSidebarPanel,
</span><span class="cx"> 
</span><span class="lines">@@ -179,11 +183,50 @@
</span><span class="cx">     {
</span><span class="cx">         var treeElementToSelect = this._timelineTreeElementMap[type];
</span><span class="cx">         if (!treeElementToSelect)
</span><del>-            return;
</del><ins>+            return null;
</ins><span class="cx"> 
</span><span class="cx">         treeElementToSelect.select(true, true);
</span><ins>+        return treeElementToSelect.representedObject;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    saveStateToCookie: function(cookie)
+    {
+        console.assert(cookie);
+
+        // This sidebar has two separate tree outlines, but only one selected tree element between them.
+        var selectedTreeElement = this._timelinesTreeOutline.selectedTreeElement || this.contentTreeOutline.selectedTreeElement;
+        if (!selectedTreeElement)
+            return;
+
+        var representedObject = selectedTreeElement.representedObject;
+        if (representedObject === WebInspector.TimelineRecord.Type.Script || representedObject === WebInspector.TimelineRecord.Type.Layout || representedObject === WebInspector.TimelineRecord.Type.Network)
+            cookie[WebInspector.InstrumentSidebarPanel.SelectedTimelineCookieKey] = representedObject;
+        else if (representedObject instanceof WebInspector.ProfileObject) {
+            cookie[WebInspector.InstrumentSidebarPanel.SelectedProfileTypeCookieKey] = representedObject.type;
+            cookie[WebInspector.InstrumentSidebarPanel.SelectedProfileTitleCookieKey] = representedObject.title;
+        }
+    },
+
+    restoreStateFromCookie: function(cookie)
+    {
+        // Eagerly restore the sidebar's selection, since its elements are persistent or permanent.
+        console.assert(cookie);
+        var selectedTimelineType = cookie[WebInspector.InstrumentSidebarPanel.SelectedTimelineCookieKey];
+        if (selectedTimelineType) {
+            return this.showTimelineForRecordType(selectedTimelineType);
+            return WebInspector.timelineManager.timelines;
+        }
+
+        // Profiles are persisted across page reloads, but not across inspector open/close.
+        var selectedProfileType = cookie[WebInspector.InstrumentSidebarPanel.SelectedProfileTypeCookieKey];
+        var selectedProfileTitle = cookie[WebInspector.InstrumentSidebarPanel.SelectedProfileTitleCookieKey];
+        // Profile titles are optional, but profile types are mandatory.
+        if (!selectedProfileType)
+            return null;
+
+        return this.showProfile(selectedProfileType, selectedProfileTitle);
+    },
+
</ins><span class="cx">     showProfile: function(type, title)
</span><span class="cx">     {
</span><span class="cx">         var profileTreeElements = this.contentTreeOutline.children;
</span><span class="lines">@@ -192,7 +235,7 @@
</span><span class="cx">             var profile = treeElement.representedObject;
</span><span class="cx">             if (profile.type === type &amp;&amp; profile.title === title) {
</span><span class="cx">                 treeElement.revealAndSelect();
</span><del>-                return;
</del><ins>+                return profile;
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">     },
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceMainjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Main.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Main.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -40,6 +40,9 @@
</span><span class="cx"> 
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+WebInspector.SelectedSidebarPanelCookieKey = &quot;selected-sidebar-panel&quot;;
+WebInspector.TypeIdentifierCookieKey = &quot;represented-object-type&quot;;
+
</ins><span class="cx"> WebInspector.loaded = function()
</span><span class="cx"> {
</span><span class="cx">     // Tell the InspectorFrontendHost we loaded first to establish communication with InspectorBackend.
</span><span class="lines">@@ -103,14 +106,8 @@
</span><span class="cx">     this.frameResourceManager.addEventListener(WebInspector.FrameResourceManager.Event.MainFrameDidChange, this._mainFrameDidChange, this);
</span><span class="cx"> 
</span><span class="cx">     WebInspector.Frame.addEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
</span><ins>+    WebInspector.Frame.addEventListener(WebInspector.Frame.Event.ProvisionalLoadCommitted, this._provisionalLoadCommitted, this);
</ins><span class="cx"> 
</span><del>-    // These listeners are for events that could resolve a pending content view cookie.
-    this.applicationCacheManager.addEventListener(WebInspector.ApplicationCacheManager.Event.FrameManifestAdded, this._resolveAndShowPendingContentViewCookie, this);
-    this.frameResourceManager.addEventListener(WebInspector.FrameResourceManager.Event.MainFrameDidChange, this._resolveAndShowPendingContentViewCookie, this);
-    this.storageManager.addEventListener(WebInspector.StorageManager.Event.DatabaseWasAdded, this._resolveAndShowPendingContentViewCookie, this);
-    this.storageManager.addEventListener(WebInspector.StorageManager.Event.CookieStorageObjectWasAdded, this._resolveAndShowPendingContentViewCookie, this);
-    this.storageManager.addEventListener(WebInspector.StorageManager.Event.DOMStorageObjectWasAdded, this._resolveAndShowPendingContentViewCookie, this);
-
</del><span class="cx">     document.addEventListener(&quot;DOMContentLoaded&quot;, this.contentLoaded.bind(this));
</span><span class="cx"> 
</span><span class="cx">     document.addEventListener(&quot;beforecopy&quot;, this._beforecopy.bind(this));
</span><span class="lines">@@ -126,9 +123,11 @@
</span><span class="cx">     window.addEventListener(&quot;keydown&quot;, this._windowKeyDown.bind(this));
</span><span class="cx">     window.addEventListener(&quot;keyup&quot;, this._windowKeyUp.bind(this));
</span><span class="cx">     window.addEventListener(&quot;mousemove&quot;, this._mouseMoved.bind(this), true);
</span><ins>+    window.addEventListener(&quot;pagehide&quot;, this._pageHidden.bind(this));
</ins><span class="cx"> 
</span><span class="cx">     // Create settings.
</span><del>-    this._lastSelectedNavigationSidebarPanelSetting = new WebInspector.Setting(&quot;last-selected-navigation-sidebar-panel&quot;, &quot;resource&quot;);
</del><ins>+    this._lastInspectorViewStateCookieSetting = new WebInspector.Setting(&quot;last-content-view-state-cookie&quot;, {});
+
</ins><span class="cx">     this._navigationSidebarCollapsedSetting = new WebInspector.Setting(&quot;navigation-sidebar-collapsed&quot;, false);
</span><span class="cx">     this._navigationSidebarWidthSetting = new WebInspector.Setting(&quot;navigation-sidebar-width&quot;, null);
</span><span class="cx"> 
</span><span class="lines">@@ -136,9 +135,6 @@
</span><span class="cx">     this._detailsSidebarCollapsedSetting = new WebInspector.Setting(&quot;details-sidebar-collapsed&quot;, true);
</span><span class="cx">     this._detailsSidebarWidthSetting = new WebInspector.Setting(&quot;details-sidebar-width&quot;, null);
</span><span class="cx"> 
</span><del>-    this._lastContentViewResponsibleSidebarPanelSetting = new WebInspector.Setting(&quot;last-content-view-responsible-sidebar-panel&quot;, &quot;resource&quot;);
-    this._lastContentCookieSetting = new WebInspector.Setting(&quot;last-content-view-cookie&quot;, {});
-
</del><span class="cx">     this._toolbarDockedRightDisplayModeSetting = new WebInspector.Setting(&quot;toolbar-docked-right-display-mode&quot;, WebInspector.Toolbar.DisplayMode.IconAndLabelVertical);
</span><span class="cx">     this._toolbarDockedRightSizeModeSetting = new WebInspector.Setting(&quot;toolbar-docked-right-size-mode&quot;,WebInspector.Toolbar.SizeMode.Normal);
</span><span class="cx"> 
</span><span class="lines">@@ -278,8 +274,6 @@
</span><span class="cx"> 
</span><span class="cx">     this._updateToolbarHeight();
</span><span class="cx"> 
</span><del>-    this.navigationSidebar.selectedSidebarPanel = this._lastSelectedNavigationSidebarPanelSetting.value;
-
</del><span class="cx">     if (this._navigationSidebarWidthSetting.value)
</span><span class="cx">         this.navigationSidebar.width = this._navigationSidebarWidthSetting.value;
</span><span class="cx"> 
</span><span class="lines">@@ -296,14 +290,9 @@
</span><span class="cx">     // selected sidebar panel gets shown and has a say in what content view gets shown.
</span><span class="cx">     this.navigationSidebar.collapsed = this._navigationSidebarCollapsedSetting.value;
</span><span class="cx"> 
</span><del>-    // If InspectorFrontendAPI didn't show a content view, then try to show the last content view.
-    if (!this.contentBrowser.currentContentView &amp;&amp; !this.ignoreLastContentCookie) {
-        if (this._lastContentCookieSetting.value === &quot;console&quot;) {
-            // The console does not have a sidebar, so handle its special cookie here.
-            this.showFullHeightConsole();
-        } else
-            this._showContentViewForCookie(this._lastContentCookieSetting.value);
-    }
</del><ins>+    // If InspectorFrontendAPI didn't show a content view, then try to restore the last saved view state.
+    if (!this.contentBrowser.currentContentView &amp;&amp; !this.ignoreLastContentCookie)
+        this._restoreInspectorViewStateFromCookie(this._lastInspectorViewStateCookieSetting.value);
</ins><span class="cx"> 
</span><span class="cx">     this._updateSplitConsoleHeight(this._splitConsoleHeightSetting.value);
</span><span class="cx"> 
</span><span class="lines">@@ -726,9 +715,20 @@
</span><span class="cx"> {
</span><span class="cx">     if (!event.target.isMainFrame())
</span><span class="cx">         return;
</span><ins>+
+    this._restoreInspectorViewStateFromCookie(this._lastInspectorViewStateCookieSetting.value, true);
+
</ins><span class="cx">     this.updateWindowTitle();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+WebInspector._provisionalLoadCommitted = function(event)
+{
+    if (!event.target.isMainFrame())
+        return;
+
+    this._updateCookieForInspectorViewState();
+}
+
</ins><span class="cx"> WebInspector._windowFocused = function(event)
</span><span class="cx"> {
</span><span class="cx">     if (event.target.document.nodeType !== Node.DOCUMENT_NODE || this.docked)
</span><span class="lines">@@ -789,6 +789,11 @@
</span><span class="cx">     };
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+WebInspector._pageHidden = function(event)
+{
+    this._updateCookieForInspectorViewState();
+}
+
</ins><span class="cx"> WebInspector._undock = function(event)
</span><span class="cx"> {
</span><span class="cx">     this._dockButtonToggledSetting.value = this.undockButtonNavigationItem.toggled;
</span><span class="lines">@@ -890,8 +895,6 @@
</span><span class="cx">     if (!selectedSidebarPanel)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    this._lastSelectedNavigationSidebarPanelSetting.value = selectedSidebarPanel.identifier;
-
</del><span class="cx">     this._updateNavigationSidebarForCurrentContentView();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -965,27 +968,28 @@
</span><span class="cx">     this._updateToolbarHeight();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-WebInspector._updateCurrentContentViewCookie = function()
</del><ins>+WebInspector._updateCookieForInspectorViewState = function()
</ins><span class="cx"> {
</span><ins>+    var cookie = {};
</ins><span class="cx">     var currentContentView = this.contentBrowser.currentContentView;
</span><del>-    if (!currentContentView)
-        return;
</del><span class="cx"> 
</span><span class="cx">     // The console does not have a sidebar, so create a cookie here.
</span><del>-    if (currentContentView.representedObject instanceof WebInspector.LogObject) {
-        this._lastContentViewResponsibleSidebarPanelSetting.value = null;
-        this._lastContentCookieSetting.value = &quot;console&quot;;
</del><ins>+    if (currentContentView &amp;&amp; currentContentView.representedObject instanceof WebInspector.LogObject) {
+        cookie[WebInspector.SelectedSidebarPanelCookieKey] = &quot;console&quot;;
+        this._lastInspectorViewStateCookieSetting.value = cookie;
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    var responsibleSidebarPanel = this.sidebarPanelForRepresentedObject(currentContentView.representedObject);
-    if (!responsibleSidebarPanel)
</del><ins>+    var selectedSidebarPanel = this.navigationSidebar.selectedSidebarPanel;
+    if (!selectedSidebarPanel)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    var cookie = {};
-    currentContentView.saveToCookie(cookie);
-    this._lastContentViewResponsibleSidebarPanelSetting.value = responsibleSidebarPanel.identifier;
-    this._lastContentCookieSetting.value = cookie;
</del><ins>+    // Restoring view state after inspector re-open or page reload is delegated to navigation sidebars.
+    // This is because some navigation sidebar state (such as breakpoint selections) cannot be inferred
+    // solely based on which content view is visible, or multiple navigation sidebars could be shown.
+    cookie[WebInspector.SelectedSidebarPanelCookieKey] = selectedSidebarPanel.identifier;
+    selectedSidebarPanel.saveStateToCookie(cookie);
+    this._lastInspectorViewStateCookieSetting.value = cookie;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> WebInspector._contentBrowserCurrentContentViewDidChange = function(event)
</span><span class="lines">@@ -1079,75 +1083,30 @@
</span><span class="cx"> 
</span><span class="cx">     // Stop ignoring the sidebar panel selected event.
</span><span class="cx">     delete this._ignoreDetailsSidebarPanelSelectedEvent;
</span><del>-
-    this._updateCurrentContentViewCookie(event);
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-WebInspector._showContentViewForCookie = function(cookie)
</del><ins>+WebInspector._restoreInspectorViewStateFromCookie = function(cookie, causedByReload)
</ins><span class="cx"> {
</span><del>-    if (!cookie || !cookie.type)
-        return null;
</del><ins>+    if (!cookie)
+        return;
</ins><span class="cx"> 
</span><del>-    this._pendingContentViewCookie = cookie;
-    var shownContentView = this._resolveAndShowPendingContentViewCookie();
-
-    // At this point, we assume no storage objects or views have been created yet.
-    // If the cookie requests these views, they will be shown when the storage object
-    // is added (if it matches exactly), or any view of the same type (after a timeout).
-    if (!shownContentView) {
-        if (this._lastAttemptCookieCheckingTimeout)
-            clearTimeout(this._lastAttemptCookieCheckingTimeout);
-
-        var lastAttemptToRestoreFromCookie = function() {
-            delete this._lastAttemptCookieCheckingTimeout;
-            this._resolveAndShowPendingContentViewCookie(true);
-        };
-
-        // When the specific storage item wasn't found we want to relax the check to show the first item with the
-        // same type. There is no good time to naturally declare the cookie wasn't found, so we do that on a timeout.
-        this._lastAttemptCookieCheckingTimeout = setTimeout(lastAttemptToRestoreFromCookie.bind(this), 500);
</del><ins>+    // The console does not have a sidebar, so handle its special cookie here.
+    if (cookie[WebInspector.SelectedSidebarPanelCookieKey] === &quot;console&quot;) {
+        this.showFullHeightConsole();
+        return;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return shownContentView;
-}
</del><ins>+    const matchTypeOnlyDelayForReload = 2000;
+    const matchTypeOnlyDelayForReopen = 1000;
+    var sidebarPanelIdentifier = cookie[WebInspector.SelectedSidebarPanelCookieKey];
+    var sidebarPanel = WebInspector.navigationSidebar.findSidebarPanel(sidebarPanelIdentifier);
+    if (!sidebarPanel)
+        return;
</ins><span class="cx"> 
</span><del>-WebInspector._resolveAndShowPendingContentViewCookie = function(matchOnTypeAlone)
-{
-    var cookie = this._pendingContentViewCookie;
-    if (!cookie)
-        return false;
</del><ins>+    WebInspector.navigationSidebar.selectedSidebarPanel = sidebarPanel;
</ins><span class="cx"> 
</span><del>-    var representedObject = null;
-
-    if (cookie.type === WebInspector.ContentViewCookieType.Resource)
-        representedObject = this.frameResourceManager.objectForCookie(cookie);
-
-    if (cookie.type === WebInspector.ContentViewCookieType.Timelines)
-        representedObject = this.timelineManager.objectForCookie(cookie);
-
-    if (cookie.type === WebInspector.ContentViewCookieType.CookieStorage || cookie.type === WebInspector.ContentViewCookieType.Database  || cookie.type === WebInspector.ContentViewCookieType.DatabaseTable || cookie.type === WebInspector.ContentViewCookieType.DOMStorage)
-        representedObject = this.storageManager.objectForCookie(cookie, matchOnTypeAlone);
-
-    if (cookie.type === WebInspector.ContentViewCookieType.ApplicationCache)
-        representedObject = this.applicationCacheManager.objectForCookie(cookie, matchOnTypeAlone);
-
-    if (!representedObject)
-        return false;
-
-    // If we reached this point, then we should be able to create and/or display a content view based on the cookie.
-    delete this._pendingContentViewCookie;
-    if (this._lastAttemptCookieCheckingTimeout)
-        clearTimeout(this._lastAttemptCookieCheckingTimeout);
-
-    // Delay this work because other listeners of the originating event might not have fired yet.
-    // So displaying the content view before those listeners do their work might cause the
-    // dependent view states (navigation sidebar tree elements, path components) to be wrong.
-    function delayedWork()
-    {
-        this.contentBrowser.showContentViewForRepresentedObject(representedObject, cookie);
-    }
-    setTimeout(delayedWork.bind(this), 0);
-    return true;
</del><ins>+    var relaxMatchDelay = causedByReload ? matchTypeOnlyDelayForReload : matchTypeOnlyDelayForReopen;
+    sidebarPanel.restoreStateFromCookie(cookie, relaxMatchDelay);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> WebInspector._initializeWebSocketIfNeeded = function()
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceNavigationSidebarPaneljs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/NavigationSidebarPanel.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/NavigationSidebarPanel.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/NavigationSidebarPanel.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -44,6 +44,8 @@
</span><span class="cx">     if (autoHideToolbarItemWhenEmpty)
</span><span class="cx">         this.toolbarItem.hidden = true;
</span><span class="cx"> 
</span><ins>+    this._visibleContentTreeOutlines = new Set;
+
</ins><span class="cx">     this._contentElement = document.createElement(&quot;div&quot;);
</span><span class="cx">     this._contentElement.className = WebInspector.NavigationSidebarPanel.ContentElementStyleClassName;
</span><span class="cx">     this._contentElement.addEventListener(&quot;scroll&quot;, this._updateContentOverflowShadowVisibility.bind(this));
</span><span class="lines">@@ -135,6 +137,9 @@
</span><span class="cx">         this._contentTreeOutline = newTreeOutline;
</span><span class="cx">         this._contentTreeOutline.element.classList.remove(WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementHiddenStyleClassName);
</span><span class="cx"> 
</span><ins>+        this._visibleContentTreeOutlines.delete(this._contentTreeOutline);
+        this._visibleContentTreeOutlines.add(newTreeOutline);
+
</ins><span class="cx">         this._updateFilter();
</span><span class="cx">     },
</span><span class="cx"> 
</span><span class="lines">@@ -163,6 +168,9 @@
</span><span class="cx">         contentTreeOutline.oncollapse = this._treeElementExpandedOrCollapsed.bind(this);
</span><span class="cx">         contentTreeOutline.allowsRepeatSelection = true;
</span><span class="cx"> 
</span><ins>+        if (dontHideByDefault)
+            this._visibleContentTreeOutlines.add(contentTreeOutline);
+
</ins><span class="cx">         return contentTreeOutline;
</span><span class="cx">     },
</span><span class="cx"> 
</span><span class="lines">@@ -179,6 +187,46 @@
</span><span class="cx">             selectedTreeElement.select();
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    saveStateToCookie: function(cookie)
+    {
+        console.assert(cookie);
+
+        // This does not save folder selections, which lack a represented object and content view.
+        var selectedTreeElement = null;
+        this._visibleContentTreeOutlines.forEach(function(outline) {
+            if (outline.selectedTreeElement)
+                selectedTreeElement = outline.selectedTreeElement;
+        });
+
+        if (!selectedTreeElement)
+            return;
+
+        var representedObject = selectedTreeElement.representedObject;
+        cookie[WebInspector.TypeIdentifierCookieKey] = representedObject.constructor.TypeIdentifier;
+        representedObject.saveIdentityToCookie(cookie);
+    },
+
+    // This can be supplemented by subclasses that admit a simpler strategy for static tree elements.
+    restoreStateFromCookie: function(cookie, relaxedMatchDelay)
+    {
+        this._pendingViewStateCookie = cookie;
+
+        // Check if any existing tree elements in any outline match the cookie.
+        this._checkOutlinesForPendingViewStateCookie();
+
+        if (this._finalAttemptToRestoreViewStateTimeout)
+            clearTimeout(this._finalAttemptToRestoreViewStateTimeout);
+
+        var finalAttemptToRestoreViewStateFromCookie = function() {
+            delete this._finalAttemptToRestoreViewStateTimeout;
+            this._checkOutlinesForPendingViewStateCookie(true);
+        };
+
+        // If the specific tree element wasn't found, we may need to wait for the resources
+        // to be registered. We try one last time (match type only) after an arbitrary amount of timeout.
+        this._finalAttemptToRestoreViewStateTimeout = setTimeout(finalAttemptToRestoreViewStateFromCookie.bind(this), relaxedMatchDelay);
+    },
+
</ins><span class="cx">     showEmptyContentPlaceholder: function(message, hideToolbarItem)
</span><span class="cx">     {
</span><span class="cx">         console.assert(message);
</span><span class="lines">@@ -399,6 +447,7 @@
</span><span class="cx"> 
</span><span class="cx">         this._checkForEmptyFilterResults();
</span><span class="cx">         this._updateContentOverflowShadowVisibility();
</span><ins>+        this._checkElementsForPendingViewStateCookie(treeElement);
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     _treeElementExpandedOrCollapsed: function(treeElement)
</span><span class="lines">@@ -490,6 +539,70 @@
</span><span class="cx"> 
</span><span class="cx">         // Check on a delay to coalesce multiple calls to _checkForOldResources.
</span><span class="cx">         this._checkForOldResourcesTimeoutIdentifier = setTimeout(delayedWork.bind(this), 0);
</span><ins>+    },
+
+    _checkOutlinesForPendingViewStateCookie: function(matchTypeOnly)
+    {
+        if (!this._pendingViewStateCookie)
+            return;
+
+        var visibleTreeElements = [];
+        this._visibleContentTreeOutlines.forEach(function(outline) {
+            var currentTreeElement = outline.hasChildren ? outline.children[0] : null;
+            while (currentTreeElement) {
+                visibleTreeElements.push(currentTreeElement);
+                currentTreeElement = currentTreeElement.traverseNextTreeElement(false, null, false);
+            }
+        });
+
+        return this._checkElementsForPendingViewStateCookie(visibleTreeElements, matchTypeOnly);
+    },
+
+    _checkElementsForPendingViewStateCookie: function(treeElements, matchTypeOnly)
+    {
+        if (!this._pendingViewStateCookie)
+            return;
+
+        var cookie = this._pendingViewStateCookie;
+
+        function treeElementMatchesCookie(treeElement)
+        {
+            var representedObject = treeElement.representedObject;
+            if (!representedObject)
+                return false;
+
+            var typeIdentifier = cookie[WebInspector.TypeIdentifierCookieKey];
+            if (typeIdentifier !== representedObject.constructor.TypeIdentifier)
+                return false;
+
+            if (matchTypeOnly)
+                return true;
+
+            var candidateObjectCookie = {};
+            representedObject.saveIdentityToCookie(candidateObjectCookie);
+
+            return Object.keys(candidateObjectCookie).every(function valuesMatchForKey(key) {
+                return candidateObjectCookie[key] === cookie[key];
+            });
+        }
+
+        if (!(treeElements instanceof Array))
+            treeElements = [treeElements];
+
+        var matchedElement = null;
+        treeElements.some(function(element) {
+            if (treeElementMatchesCookie(element)) {
+                matchedElement = element;
+                return true;
+            }
+        });
+
+        if (matchedElement) {
+            matchedElement.revealAndSelect();
+            delete this._pendingViewStateCookie;
+            if (this._finalAttemptToRestoreViewStateTimeout)
+                clearTimeout(this._finalAttemptToRestoreViewStateTimeout);
+        }
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceResourcejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Resource.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Resource.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/Resource.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -55,6 +55,10 @@
</span><span class="cx"> 
</span><span class="cx"> WebInspector.Object.addConstructorFunctions(WebInspector.Resource);
</span><span class="cx"> 
</span><ins>+WebInspector.Resource.TypeIdentifier = &quot;resource&quot;;
+WebInspector.Resource.URLCookieKey = &quot;resource-url&quot;;
+WebInspector.Resource.MainResourceCookieKey = &quot;resource-is-main-resource&quot;;
+
</ins><span class="cx"> WebInspector.Resource.Event = {
</span><span class="cx">     URLDidChange: &quot;resource-url-did-change&quot;,
</span><span class="cx">     MIMETypeDidChange: &quot;resource-mime-type-did-change&quot;,
</span><span class="lines">@@ -691,6 +695,12 @@
</span><span class="cx">             this._type = WebInspector.Resource.Type.Script;
</span><span class="cx">             this.dispatchEventToListeners(WebInspector.Resource.Event.TypeDidChange, {oldType: oldType});
</span><span class="cx">         }
</span><ins>+    },
+
+    saveIdentityToCookie: function(cookie)
+    {
+        cookie[WebInspector.Resource.URLCookieKey] = this.url;
+        cookie[WebInspector.Resource.MainResourceCookieKey] = this.isMainResource();
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceResourceClusterContentViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/ResourceClusterContentView.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/ResourceClusterContentView.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/ResourceClusterContentView.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -47,6 +47,8 @@
</span><span class="cx">     this._currentContentViewSetting = new WebInspector.Setting(&quot;resource-current-view-&quot; + this._resource.url.hash, WebInspector.ResourceClusterContentView.ResponseIdentifier);
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+WebInspector.ResourceClusterContentView.ContentViewIdentifierCookieKey = &quot;resource-cluster-content-view-identifier&quot;;
+
</ins><span class="cx"> WebInspector.ResourceClusterContentView.RequestIconStyleClassName = &quot;request-icon&quot;;
</span><span class="cx"> WebInspector.ResourceClusterContentView.ResponseIconStyleClassName = &quot;response-icon&quot;;
</span><span class="cx"> WebInspector.ResourceClusterContentView.RequestIdentifier = &quot;request&quot;;
</span><span class="lines">@@ -142,17 +144,13 @@
</span><span class="cx"> 
</span><span class="cx">     saveToCookie: function(cookie)
</span><span class="cx">     {
</span><del>-        cookie.type = WebInspector.ContentViewCookieType.Resource;
-        cookie.url = this.representedObject.url;
-        cookie.subview = this._currentContentViewSetting.value;
</del><ins>+        cookie[WebInspector.ResourceClusterContentView.ContentViewIdentifierCookieKey] = this._currentContentViewSetting.value;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     restoreFromCookie: function(cookie)
</span><span class="cx">     {
</span><del>-        if (&quot;lineNumber&quot; in cookie &amp;&amp; &quot;columnNumber&quot; in cookie)
-            return this.showResponse(new WebInspector.SourceCodePosition(cookie.lineNumber, cookie.columnNumber));
-
-        this._showContentViewForIdentifier(cookie.subview);
</del><ins>+        var viewIdentifier = cookie[WebInspector.ResourceClusterContentView.ContentViewIdentifierCookieKey];
+        this._showContentViewForIdentifier(viewIdentifier);
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     showRequest: function()
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceScriptjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Script.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Script.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/Script.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -43,6 +43,10 @@
</span><span class="cx">         WebInspector.sourceMapManager.downloadSourceMap(sourceMapURL, this._url, this);
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+WebInspector.Script.TypeIdentifier = &quot;script&quot;;
+WebInspector.Script.URLCookieKey = &quot;script-url&quot;;
+WebInspector.Script.DisplayNameCookieKey = &quot;script-display-name&quot;;
+
</ins><span class="cx"> WebInspector.Script.resetUniqueDisplayNameNumbers = function()
</span><span class="cx"> {
</span><span class="cx">     WebInspector.Script._nextUniqueDisplayNameNumber = 1;
</span><span class="lines">@@ -117,6 +121,12 @@
</span><span class="cx">         return true;
</span><span class="cx">     },
</span><span class="cx"> 
</span><ins>+    saveIdentityToCookie: function(cookie)
+    {
+        cookie[WebInspector.Script.URLCookieKey] = this.url;
+        cookie[WebInspector.Script.DisplayNameCookieKey] = this.displayName;
+    },
+
</ins><span class="cx">     // Private
</span><span class="cx"> 
</span><span class="cx">     _resolveResource: function()
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceStorageManagerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/StorageManager.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/StorageManager.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/StorageManager.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -147,57 +147,6 @@
</span><span class="cx">         this.dispatchEventToListeners(WebInspector.StorageManager.Event.DOMStorageObjectWasInspected, {domStorage: domStorage});
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    objectForCookie: function(cookie, matchOnTypeAlone)
-    {
-        console.assert(cookie.type);
-
-        var findMatchingObjectInArray = function (array, matchesFunction) {
-            for (var i = 0; i &lt; array.length; ++i)
-                if (matchesFunction.call(null, array[i]))
-                    return array[i];
-
-            return matchOnTypeAlone &amp;&amp; array.length ? array[0] : null;
-        };
-
-        if (cookie.type === WebInspector.ContentViewCookieType.CookieStorage) {
-            if (this._cookieStorageObjects[cookie.host])
-                return this._cookieStorageObjects[cookie.host];
-
-            if (!matchOnTypeAlone)
-                return null;
-
-            // If we just want any cookie storage object, use the first one.
-            for (var key in this._cookieStorageObjects)
-                return this._cookieStorageObjects[key];
-
-            return null;
-        }
-
-        if (cookie.type === WebInspector.ContentViewCookieType.DOMStorage) {
-            return findMatchingObjectInArray(this._domStorageObjects, function(object) {
-                return object.host === cookie.host &amp;&amp; object.isLocalStorage() === cookie.isLocalStorage;
-            });
-        }
-
-        if (cookie.type === WebInspector.ContentViewCookieType.Database) {
-            return findMatchingObjectInArray(this._databaseObjects, function(object) {
-                return object.host === cookie.host &amp;&amp; object.name === cookie.name;
-            });
-        }
-
-        // FIXME: This isn't easy to implement like the others since DatabaseTreeElement
-        // creates database table objects, and they aren't known by StorageManager. Just
-        // display the database instead.
-        if (cookie.type === WebInspector.ContentViewCookieType.DatabaseTable) {
-            return findMatchingObjectInArray(this._databaseObjects, function(object) {
-                return object.host === cookie.host &amp;&amp; object.database === cookie.name;
-            });
-        }
-
-        console.assert(&quot;Unknown content view cookie: &quot;, cookie);
-        return null;
-    },
-
</del><span class="cx">     // Private
</span><span class="cx"> 
</span><span class="cx">     _mainResourceDidChange: function(event)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelineManagerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelineManager.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelineManager.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelineManager.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -299,11 +299,6 @@
</span><span class="cx">             this._loadEventTime = timestamp;
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    objectForCookie: function(cookie)
-    {
-        return this.timelines;
-    },
-
</del><span class="cx">     // Private
</span><span class="cx"> 
</span><span class="cx">     _clear: function()
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTimelinesContentViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TimelinesContentView.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TimelinesContentView.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/TimelinesContentView.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -209,6 +209,8 @@
</span><span class="cx"> WebInspector.TimelinesContentView.CollapseButton.States.Normal = &quot;normal&quot;;
</span><span class="cx"> WebInspector.TimelinesContentView.CollapseButton.States.Active = &quot;active&quot;;
</span><span class="cx"> 
</span><ins>+WebInspector.TimelinesContentView.SelectedTimelineCookieKey = &quot;timelines-content-view-selected-timeline&quot;;
+
</ins><span class="cx"> WebInspector.TimelinesContentView.generateEmbossedCollapseImages = function()
</span><span class="cx"> {
</span><span class="cx">     if (WebInspector.TimelinesContentView._generatedImages)
</span><span class="lines">@@ -337,13 +339,13 @@
</span><span class="cx"> 
</span><span class="cx">     saveToCookie: function(cookie)
</span><span class="cx">     {
</span><del>-        cookie.type = WebInspector.ContentViewCookieType.Timelines;
-        cookie.timeline = this._currentRecordTypeSetting.value;
</del><ins>+        cookie[WebInspector.TimelinesContentView.SelectedTimelineCookieKey] = this._currentRecordTypeSetting.value;
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     restoreFromCookie: function(cookie)
</span><span class="cx">     {
</span><del>-        this.showTimelineForRecordType(cookie.timeline);
</del><ins>+        var timeline = cookie[WebInspector.TimelinesContentView.SelectedTimelineCookieKey];
+        this.showTimelineForRecordType(timeline);
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     timelineOverviewRecordsWithType: function(type)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTreeOutlinejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TreeOutline.js (160024 => 160025)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TreeOutline.js        2013-12-03 19:44:55 UTC (rev 160024)
+++ trunk/Source/WebInspectorUI/UserInterface/TreeOutline.js        2013-12-03 19:51:08 UTC (rev 160025)
</span><span class="lines">@@ -57,6 +57,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> TreeOutline._knownTreeElementNextIdentifier = 1;
</span><ins>+TreeOutline.prototype.constructor = TreeOutline;
</ins><span class="cx"> 
</span><span class="cx"> TreeOutline.prototype.appendChild = function(child)
</span><span class="cx"> {
</span></span></pre>
</div>
</div>

</body>
</html>