Changeset 160025 in webkit
- Timestamp:
- Dec 3, 2013 11:51:08 AM (10 years ago)
- Location:
- trunk/Source/WebInspectorUI
- Files:
-
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebInspectorUI/ChangeLog
r159952 r160025 1 2013-12-03 Brian J. Burg <burg@cs.washington.edu> 2 3 Web Inspector: restore navigation panel state across reloads and reopens 4 https://bugs.webkit.org/show_bug.cgi?id=122125 5 6 Reviewed by Timothy Hatcher. 7 8 The previous strategy for restoring content views after inspector 9 re-open did not consider the active sidebar and its selection, and 10 tried to recreate the appropriate selection from the saved content 11 view. However, doesn't work for tree elements in the sidebar panel 12 that don't change views when selected, such as script breakpoints, 13 special breakpoints, call stack, timeline sections, etc. 14 15 This patch implements a new strategy that saves the navigation 16 sidebar panel's view state by serializing the identity of the 17 selected element's represented object. Relevant represented 18 object classes implement the saveIdentityToCookie() method. Each 19 represented object class also adds a TypeIdentifier property to 20 its constructor, to aid inexact matching based on represented 21 object type, rather than its complete identity. 22 23 When restoring, the navigation sidebar attempts to match added 24 tree elements against the pending cookie, and selects the element 25 if it matches. A represented object matches if its serialized 26 identity matches the previously saved serialized identity. 27 28 The inspector view state is now only saved on the page hide event 29 (for saving across reopen) and when the main frame commits its 30 provisional load (for saving across same-page reloads). It 31 consolidates similar view state settings into a single setting. 32 33 * UserInterface/ApplicationCacheFrame.js: 34 (WebInspector.ApplicationCacheFrame): Add cookie keys and type identifier. 35 (WebInspector.ApplicationCacheFrame.prototype.saveIdentityToCookie): Added. 36 * UserInterface/ApplicationCacheManager.js: remove objectForCookie(). 37 * UserInterface/Breakpoint.js: 38 (WebInspector.Breakpoint): Add cookie keys and type identifier. 39 (WebInspector.Breakpoint.prototype.saveIdentityToCookie): 40 * UserInterface/CookieStorageObject.js: 41 (WebInspector.CookieStorageObject.prototype.saveIdentityToCookie): Added. 42 * UserInterface/DOMStorageObject.js: 43 (WebInspector.DOMStorageObject): Add cookie keys and type identifier. 44 (WebInspector.DOMStorageObject.prototype.saveIdentityToCookie): Added. 45 * UserInterface/DatabaseObject.js: 46 (WebInspector.DatabaseObject): Add cookie keys and type identifier. 47 (WebInspector.DatabaseObject.prototype.saveIdentityToCookie): Added. 48 * UserInterface/DatabaseTableObject.js: 49 (WebInspector.DatabaseTableObject): Add cookie keys and type identifier. 50 (WebInspector.DatabaseTableObject.prototype.saveIdentityToCookie): Added. 51 * UserInterface/DebuggerSidebarPanel.js: 52 (WebInspector.DebuggerSidebarPanel.prototype.saveStateToCookie): Added. 53 (WebInspector.DebuggerSidebarPanel.prototype.restoreStateFromCookie): Added. 54 * UserInterface/Frame.js: 55 (WebInspector.Frame): Add cookie keys and type identifier. 56 (WebInspector.Frame.prototype.saveIdentityToCookie): Added. 57 * UserInterface/FrameResourceManager.js: remove objectForCookie(). 58 * UserInterface/InstrumentSidebarPanel.js: 59 (WebInspector.InstrumentSidebarPanel.prototype.showTimelineForRecordType): 60 Return the shown timeline, if any. 61 62 (WebInspector.InstrumentSidebarPanel.prototype.saveStateToCookie): Added. 63 (WebInspector.InstrumentSidebarPanel.prototype.restoreStateFromCookie): Added. 64 (WebInspector.InstrumentSidebarPanel.prototype.showProfile): 65 Return the shown profile, if any. 66 67 * UserInterface/Main.js: 68 (WebInspector): Added cookie keys for the selected sidebar and 69 typeidentifier of the sidebar's selected tree element. 70 71 (WebInspector.contentLoaded): Remove callbacks for 72 resolveAndShowPendingContentViewCookie(). Consolidate all saved 73 inspector view state into one Setting. Move special-cased 74 restoring of the console to the restoration method. Move saving 75 of last opened navigation panel to the saving method. 76 77 (WebInspector._mainResourceDidChange): Try to restore saved view 78 state when the main resource changes. 79 80 (WebInspector._provisionalLoadCommitted): Update the saved view 81 state when the navigation commits. This is the last chance to save 82 it before the main resource changes and the navigation panel view 83 state is discarded and rebuilt. 84 85 (WebInspector._pageHidden): Update the saved view state when the 86 inspector page is hidden, but before state is discarded. 87 88 (WebInspector._navigationSidebarPanelSelected): Don't save last 89 navigation sidebar panel. 90 (WebInspector._updateCookieForInspectorViewState): Renamed from 91 _updateCurrentContentViewCookie. It delegates view state 92 serialization to the currently open navigation sidebar, rather 93 than the current content view. 94 95 (WebInspector._contentBrowserRepresentedObjectsDidChange): Don't 96 spuriously serialize the current view state cookie on every 97 ContentView change. 98 99 (WebInspector._restoreInspectorViewStateFromCookie): Renamed from 100 _showContentViewForCookie. It now restores a specific navigation 101 panel and delegates remaining view state restoration to the panel 102 itself. Last-resort selection of any tree element with the same 103 type identifier was moved to the navigation panel's restore method. 104 105 * UserInterface/NavigationSidebarPanel.js: 106 (WebInspector.NavigationSidebarPanel): 107 (WebInspector.NavigationSidebarPanel.prototype.set contentTreeOutline): 108 (WebInspector.NavigationSidebarPanel.prototype.createContentTreeOutline): 109 Save references to all created TreeOutlines in a Set, so we can 110 restore any tree's selection. 111 112 (WebInspector.NavigationSidebarPanel.prototype.saveStateToCookie): 113 Added. Find the selected tree element from all tree outlines and 114 ask it to serialize its identity. 115 116 (WebInspector.NavigationSidebarPanel.prototype.restoreStateFromCookie): 117 Added. Eagerly search existing tree elements for a matching 118 representedObject. If none exists, save the pending cookie and 119 schedule last-resort matching using the provided timeout interval. 120 121 (WebInspector.NavigationSidebarPanel.prototype._treeElementAddedOrChanged): 122 Check if the added tree element matches a pending view state 123 cookie, if one exists. 124 125 (WebInspector.NavigationSidebarPanel.prototype.treeElementMatchesCookie): 126 Added. Check if the tree element's representedObject matches the 127 pending view state cookie. 128 129 (WebInspector.NavigationSidebarPanel.prototype._checkElementsForPendingViewStateCookie): 130 Added. For each provided tree element, check if the tree 131 element's represented object produces the same serialized identity 132 as the pending view state cookie that we are trying to resolve. 133 If a match is found (possibly by relaxing to matching anything 134 with the same type), select the tree element and clear both the 135 pending view state cookie and last-resort selection timer. 136 137 * UserInterface/Resource.js: 138 (WebInspector.Resource): Add cookie keys and type identifier. 139 (WebInspector.Resource.prototype.saveIdentityToCookie): Added. 140 141 * UserInterface/ResourceClusterContentView.js: 142 (WebInspector.ResourceClusterContentView.prototype.saveToCookie): 143 (WebInspector.ResourceClusterContentView.prototype.restoreFromCookie): 144 Since identity state is serialized by the representedObject, these 145 methods only need to save view-specific state, such as the visible 146 subview. Remove extraneous state. 147 148 * UserInterface/Script.js: 149 (WebInspector.Script): Add cookie keys and type identifier. 150 (WebInspector.Script.prototype.saveIdentityToCookie): Added. 151 * UserInterface/StorageManager.js: remove objectForCookie(). 152 * UserInterface/TimelineManager.js: remove objectForCookie(). 153 * UserInterface/TimelinesContentView.js: 154 (WebInspector.TimelinesContentView.prototype.saveToCookie): 155 (WebInspector.TimelinesContentView.prototype.restoreFromCookie): 156 Since identity state is serialized by the representedObject, these 157 methods only need to save view-specific state, such as the visible 158 subview. Remove extraneous state. 159 160 * UserInterface/TreeOutline.js: Add TreeOutline.prototype.constructor 161 so other code can assume the constructor property exists. 162 1 163 2013-12-02 Antoine Quint <graouts@apple.com> 2 164 -
trunk/Source/WebInspectorUI/UserInterface/ApplicationCacheFrame.js
r151453 r160025 36 36 }; 37 37 38 WebInspector.ApplicationCacheFrame.TypeIdentifier = "application-cache-frame"; 39 WebInspector.ApplicationCacheFrame.FrameURLCookieKey = "application-cache-frame-url"; 40 WebInspector.ApplicationCacheFrame.ManifestURLCookieKey = "application-cache-frame-manifest-url"; 41 38 42 WebInspector.ApplicationCacheFrame.prototype = { 39 43 constructor: WebInspector.ApplicationCacheFrame, 40 44 45 // Public 46 41 47 get frame() 42 48 { … … 57 63 { 58 64 this._status = status; 65 }, 66 67 saveIdentityToCookie: function(cookie) 68 { 69 cookie[WebInspector.ApplicationCacheFrame.FrameURLCookieKey] = this.frame.url; 70 cookie[WebInspector.ApplicationCacheFrame.ManifestURLCookieKey] = this.manifest.manifestURL; 59 71 } 60 72 }; -
trunk/Source/WebInspectorUI/UserInterface/ApplicationCacheManager.js
r157269 r160025 103 103 }, 104 104 105 objectForCookie: function(cookie, matchOnTypeAlone)106 {107 console.assert(cookie.type && cookie.type === WebInspector.ContentViewCookieType.ApplicationCache);108 109 for (var i = 0; i < this._applicationCacheObjects.length; ++i) {110 var object = this._applicationCacheObjects[i];111 if (object.frame.url === cookie.frame && object.manifest.manifestURL === cookie.manifest)112 return object;113 }114 115 return matchOnTypeAlone && this._applicationCacheObjects.length ? this._applicationCacheObjects[0] : null;116 },117 118 105 // Private 119 106 -
trunk/Source/WebInspectorUI/UserInterface/Breakpoint.js
r159946 r160025 70 70 WebInspector.Breakpoint.DefaultBreakpointActionType = WebInspector.BreakpointAction.Type.Log; 71 71 72 WebInspector.Breakpoint.TypeIdentifier = "breakpoint"; 73 WebInspector.Breakpoint.URLCookieKey = "breakpoint-url"; 74 WebInspector.Breakpoint.LineNumberCookieKey = "breakpoint-line-number"; 75 WebInspector.Breakpoint.ColumnNumberCookieKey = "breakpoint-column-number"; 76 72 77 WebInspector.Breakpoint.Event = { 73 78 DisabledStateDidChange: "breakpoint-disabled-state-did-change", … … 289 294 290 295 this.dispatchEventToListeners(WebInspector.Breakpoint.Event.ActionsDidChange); 296 }, 297 298 saveIdentityToCookie: function(cookie) 299 { 300 cookie[WebInspector.Breakpoint.URLCookieKey] = this.url; 301 cookie[WebInspector.Breakpoint.LineNumberCookieKey] = this.sourceCodeLocation.lineNumber; 302 cookie[WebInspector.Breakpoint.ColumnNumberCookieKey] = this.sourceCodeLocation.columnNumber; 291 303 }, 292 304 -
trunk/Source/WebInspectorUI/UserInterface/CookieStorageObject.js
r151453 r160025 29 29 }; 30 30 31 WebInspector.CookieStorageObject.TypeIdentifier = "cookie-storage"; 32 WebInspector.CookieStorageObject.CookieHostCookieKey = "cookie-storage-host"; 33 31 34 WebInspector.CookieStorageObject.prototype = { 32 35 constructor: WebInspector.CookieStorageObject, … … 37 40 }, 38 41 42 saveIdentityToCookie: function(cookie) 43 { 44 cookie[WebInspector.CookieStorageObject.CookieHostCookieKey] = this.host; 45 } 39 46 // FIXME: This class will need to look up cookies that are set for this host. 40 47 }; -
trunk/Source/WebInspectorUI/UserInterface/DOMStorageObject.js
r151453 r160025 31 31 }; 32 32 33 WebInspector.DOMStorageObject.TypeIdentifier = "dom-storage"; 34 WebInspector.DOMStorageObject.HostCookieKey = "dom-storage-object-host"; 35 WebInspector.DOMStorageObject.LocalStorageCookieKey = "dom-storage-object-local-storage"; 36 33 37 WebInspector.DOMStorageObject.prototype = { 34 38 constructor: WebInspector.DOMStorageObject, … … 42 46 { 43 47 return this._host; 48 }, 49 50 saveIdentityToCookie: function(cookie) 51 { 52 cookie[WebInspector.DOMStorageObject.HostCookieKey] = this.host; 53 cookie[WebInspector.DOMStorageObject.LocalStorageCookieKey] = this.isLocalStorage(); 44 54 }, 45 55 -
trunk/Source/WebInspectorUI/UserInterface/DatabaseObject.js
r151453 r160025 32 32 }; 33 33 34 WebInspector.DatabaseObject.TypeIdentifier = "database"; 35 WebInspector.DatabaseObject.HostCookieKey = "database-object-host"; 36 WebInspector.DatabaseObject.NameCookieKey = "database-object-name"; 37 34 38 WebInspector.DatabaseObject.prototype = { 35 39 constructor: WebInspector.DatabaseObject, 36 40 41 // Public 42 37 43 get id() 38 44 { … … 55 61 }, 56 62 63 saveIdentityToCookie: function(cookie) 64 { 65 cookie[WebInspector.DatabaseObject.HostCookieKey] = this.host; 66 cookie[WebInspector.DatabaseObject.NameCookieKey] = this.name; 67 }, 68 57 69 getTableNames: function(callback) 58 70 { -
trunk/Source/WebInspectorUI/UserInterface/DatabaseTableObject.js
r151453 r160025 32 32 }; 33 33 34 WebInspector.DatabaseTableObject.TypeIdentifier = "database-table"; 35 WebInspector.DatabaseTableObject.NameCookieKey = "database-table-object-name"; 36 34 37 WebInspector.DatabaseTableObject.prototype = { 35 38 constructor: WebInspector.DatabaseTableObject, … … 43 46 { 44 47 return this._database; 45 } 48 }, 49 50 saveIdentityToCookie: function(cookie) 51 { 52 cookie[WebInspector.DatabaseTableObject.NameCookieKey] = this.name; 53 }, 46 54 }; 47 55 -
trunk/Source/WebInspectorUI/UserInterface/DebuggerSidebarPanel.js
r158879 r160025 121 121 WebInspector.DebuggerSidebarPanel.ExceptionIconStyleClassName = "breakpoint-exception-icon"; 122 122 123 WebInspector.DebuggerSidebarPanel.SelectedAllExceptionsCookieKey = "debugger-sidebar-panel-all-exceptions-breakpoint"; 124 WebInspector.DebuggerSidebarPanel.SelectedAllUncaughtExceptionsCookieKey = "debugger-sidebar-panel-all-uncaught-exceptions-breakpoint"; 125 123 126 WebInspector.DebuggerSidebarPanel.prototype = { 124 127 constructor: WebInspector.DebuggerSidebarPanel, … … 133 136 134 137 return this.contentTreeOutline.getCachedTreeElement(representedObject); 138 }, 139 140 // Protected 141 142 saveStateToCookie: function(cookie) 143 { 144 console.assert(cookie); 145 146 var selectedTreeElement = this._breakpointsContentTreeOutline.selectedTreeElement; 147 if (!selectedTreeElement) 148 return; 149 150 var representedObject = selectedTreeElement.representedObject; 151 152 if (representedObject === WebInspector.debuggerManager.allExceptionsBreakpoint) 153 cookie[WebInspector.DebuggerSidebarPanel.SelectedAllExceptionsCookieKey] = true; 154 155 if (representedObject === WebInspector.debuggerManager.allUncaughtExceptionsBreakpoint) 156 cookie[WebInspector.DebuggerSidebarPanel.SelectedAllUncaughtExceptionsCookieKey] = true; 157 158 WebInspector.NavigationSidebarPanel.prototype.saveStateToCookie.call(this, cookie); 159 }, 160 161 restoreStateFromCookie: function(cookie) 162 { 163 console.assert(cookie); 164 165 // Eagerly resolve the special breakpoints; otherwise, use the default behavior. 166 if (cookie[WebInspector.DebuggerSidebarPanel.SelectedAllExceptionsCookieKey]) 167 this._allExceptionsBreakpointTreeElement.revealAndSelect(); 168 else if (cookie[WebInspector.DebuggerSidebarPanel.SelectedAllUncaughtExceptionsCookieKey]) 169 this._allUncaughtExceptionsBreakpointTreeElement.revealAndSelect(); 170 else 171 WebInspector.NavigationSidebarPanel.prototype.restoreStateFromCookie.call(this, cookie); 135 172 }, 136 173 -
trunk/Source/WebInspectorUI/UserInterface/Frame.js
r151453 r160025 68 68 }; 69 69 70 WebInspector.Frame.TypeIdentifier = "Frame"; 71 WebInspector.Frame.MainResourceURLCookieKey = "frame-main-resource-url"; 72 70 73 WebInspector.Frame.prototype = { 71 74 constructor: WebInspector.Frame, … … 433 436 }, 434 437 438 saveIdentityToCookie: function(cookie) 439 { 440 cookie[WebInspector.Frame.MainResourceURLCookieKey] = this.mainResource.url; 441 }, 442 435 443 // Private 436 444 -
trunk/Source/WebInspectorUI/UserInterface/FrameResourceManager.js
r157269 r160025 81 81 }, 82 82 83 84 objectForCookie: function(cookie)85 {86 var representedObject = cookie.url ? this.resourceForURL(cookie.url) : this.mainFrame;87 88 if (!representedObject)89 representedObject = this.mainFrame;90 91 if (representedObject instanceof WebInspector.Resource && representedObject.isMainResource())92 representedObject = representedObject.parentFrame;93 94 return representedObject;95 },96 97 83 frameDidNavigate: function(framePayload) 98 84 { -
trunk/Source/WebInspectorUI/UserInterface/InstrumentSidebarPanel.js
r157269 r160025 159 159 WebInspector.InstrumentSidebarPanel.StartCanvasProfileValue = "start-canvas-profile"; 160 160 161 WebInspector.InstrumentSidebarPanel.SelectedTimelineCookieKey = "instrument-sidebar-panel-selected-timeline"; 162 WebInspector.InstrumentSidebarPanel.SelectedProfileTypeCookieKey = "instrument-sidebar-panel-selected-profile-type"; 163 WebInspector.InstrumentSidebarPanel.SelectedProfileTitleCookieKey = "instrument-sidebar-panel-selected-profile-title"; 164 161 165 WebInspector.InstrumentSidebarPanel.prototype = { 162 166 constructor: WebInspector.InstrumentSidebarPanel, … … 180 184 var treeElementToSelect = this._timelineTreeElementMap[type]; 181 185 if (!treeElementToSelect) 182 return ;186 return null; 183 187 184 188 treeElementToSelect.select(true, true); 189 return treeElementToSelect.representedObject; 190 }, 191 192 saveStateToCookie: function(cookie) 193 { 194 console.assert(cookie); 195 196 // This sidebar has two separate tree outlines, but only one selected tree element between them. 197 var selectedTreeElement = this._timelinesTreeOutline.selectedTreeElement || this.contentTreeOutline.selectedTreeElement; 198 if (!selectedTreeElement) 199 return; 200 201 var representedObject = selectedTreeElement.representedObject; 202 if (representedObject === WebInspector.TimelineRecord.Type.Script || representedObject === WebInspector.TimelineRecord.Type.Layout || representedObject === WebInspector.TimelineRecord.Type.Network) 203 cookie[WebInspector.InstrumentSidebarPanel.SelectedTimelineCookieKey] = representedObject; 204 else if (representedObject instanceof WebInspector.ProfileObject) { 205 cookie[WebInspector.InstrumentSidebarPanel.SelectedProfileTypeCookieKey] = representedObject.type; 206 cookie[WebInspector.InstrumentSidebarPanel.SelectedProfileTitleCookieKey] = representedObject.title; 207 } 208 }, 209 210 restoreStateFromCookie: function(cookie) 211 { 212 // Eagerly restore the sidebar's selection, since its elements are persistent or permanent. 213 console.assert(cookie); 214 var selectedTimelineType = cookie[WebInspector.InstrumentSidebarPanel.SelectedTimelineCookieKey]; 215 if (selectedTimelineType) { 216 return this.showTimelineForRecordType(selectedTimelineType); 217 return WebInspector.timelineManager.timelines; 218 } 219 220 // Profiles are persisted across page reloads, but not across inspector open/close. 221 var selectedProfileType = cookie[WebInspector.InstrumentSidebarPanel.SelectedProfileTypeCookieKey]; 222 var selectedProfileTitle = cookie[WebInspector.InstrumentSidebarPanel.SelectedProfileTitleCookieKey]; 223 // Profile titles are optional, but profile types are mandatory. 224 if (!selectedProfileType) 225 return null; 226 227 return this.showProfile(selectedProfileType, selectedProfileTitle); 185 228 }, 186 229 … … 193 236 if (profile.type === type && profile.title === title) { 194 237 treeElement.revealAndSelect(); 195 return ;238 return profile; 196 239 } 197 240 } -
trunk/Source/WebInspectorUI/UserInterface/Main.js
r158879 r160025 41 41 }; 42 42 43 WebInspector.SelectedSidebarPanelCookieKey = "selected-sidebar-panel"; 44 WebInspector.TypeIdentifierCookieKey = "represented-object-type"; 45 43 46 WebInspector.loaded = function() 44 47 { … … 104 107 105 108 WebInspector.Frame.addEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this); 106 107 // These listeners are for events that could resolve a pending content view cookie. 108 this.applicationCacheManager.addEventListener(WebInspector.ApplicationCacheManager.Event.FrameManifestAdded, this._resolveAndShowPendingContentViewCookie, this); 109 this.frameResourceManager.addEventListener(WebInspector.FrameResourceManager.Event.MainFrameDidChange, this._resolveAndShowPendingContentViewCookie, this); 110 this.storageManager.addEventListener(WebInspector.StorageManager.Event.DatabaseWasAdded, this._resolveAndShowPendingContentViewCookie, this); 111 this.storageManager.addEventListener(WebInspector.StorageManager.Event.CookieStorageObjectWasAdded, this._resolveAndShowPendingContentViewCookie, this); 112 this.storageManager.addEventListener(WebInspector.StorageManager.Event.DOMStorageObjectWasAdded, this._resolveAndShowPendingContentViewCookie, this); 109 WebInspector.Frame.addEventListener(WebInspector.Frame.Event.ProvisionalLoadCommitted, this._provisionalLoadCommitted, this); 113 110 114 111 document.addEventListener("DOMContentLoaded", this.contentLoaded.bind(this)); … … 127 124 window.addEventListener("keyup", this._windowKeyUp.bind(this)); 128 125 window.addEventListener("mousemove", this._mouseMoved.bind(this), true); 126 window.addEventListener("pagehide", this._pageHidden.bind(this)); 129 127 130 128 // Create settings. 131 this._lastSelectedNavigationSidebarPanelSetting = new WebInspector.Setting("last-selected-navigation-sidebar-panel", "resource"); 129 this._lastInspectorViewStateCookieSetting = new WebInspector.Setting("last-content-view-state-cookie", {}); 130 132 131 this._navigationSidebarCollapsedSetting = new WebInspector.Setting("navigation-sidebar-collapsed", false); 133 132 this._navigationSidebarWidthSetting = new WebInspector.Setting("navigation-sidebar-width", null); … … 136 135 this._detailsSidebarCollapsedSetting = new WebInspector.Setting("details-sidebar-collapsed", true); 137 136 this._detailsSidebarWidthSetting = new WebInspector.Setting("details-sidebar-width", null); 138 139 this._lastContentViewResponsibleSidebarPanelSetting = new WebInspector.Setting("last-content-view-responsible-sidebar-panel", "resource");140 this._lastContentCookieSetting = new WebInspector.Setting("last-content-view-cookie", {});141 137 142 138 this._toolbarDockedRightDisplayModeSetting = new WebInspector.Setting("toolbar-docked-right-display-mode", WebInspector.Toolbar.DisplayMode.IconAndLabelVertical); … … 279 275 this._updateToolbarHeight(); 280 276 281 this.navigationSidebar.selectedSidebarPanel = this._lastSelectedNavigationSidebarPanelSetting.value;282 283 277 if (this._navigationSidebarWidthSetting.value) 284 278 this.navigationSidebar.width = this._navigationSidebarWidthSetting.value; … … 297 291 this.navigationSidebar.collapsed = this._navigationSidebarCollapsedSetting.value; 298 292 299 // If InspectorFrontendAPI didn't show a content view, then try to show the last content view. 300 if (!this.contentBrowser.currentContentView && !this.ignoreLastContentCookie) { 301 if (this._lastContentCookieSetting.value === "console") { 302 // The console does not have a sidebar, so handle its special cookie here. 303 this.showFullHeightConsole(); 304 } else 305 this._showContentViewForCookie(this._lastContentCookieSetting.value); 306 } 293 // If InspectorFrontendAPI didn't show a content view, then try to restore the last saved view state. 294 if (!this.contentBrowser.currentContentView && !this.ignoreLastContentCookie) 295 this._restoreInspectorViewStateFromCookie(this._lastInspectorViewStateCookieSetting.value); 307 296 308 297 this._updateSplitConsoleHeight(this._splitConsoleHeightSetting.value); … … 727 716 if (!event.target.isMainFrame()) 728 717 return; 718 719 this._restoreInspectorViewStateFromCookie(this._lastInspectorViewStateCookieSetting.value, true); 720 729 721 this.updateWindowTitle(); 722 } 723 724 WebInspector._provisionalLoadCommitted = function(event) 725 { 726 if (!event.target.isMainFrame()) 727 return; 728 729 this._updateCookieForInspectorViewState(); 730 730 } 731 731 … … 788 788 y: event.pageY 789 789 }; 790 } 791 792 WebInspector._pageHidden = function(event) 793 { 794 this._updateCookieForInspectorViewState(); 790 795 } 791 796 … … 891 896 return; 892 897 893 this._lastSelectedNavigationSidebarPanelSetting.value = selectedSidebarPanel.identifier;894 895 898 this._updateNavigationSidebarForCurrentContentView(); 896 899 } … … 966 969 } 967 970 968 WebInspector._updateCurrentContentViewCookie = function() 969 { 971 WebInspector._updateCookieForInspectorViewState = function() 972 { 973 var cookie = {}; 970 974 var currentContentView = this.contentBrowser.currentContentView; 971 if (!currentContentView)972 return;973 975 974 976 // The console does not have a sidebar, so create a cookie here. 975 if (currentContentView.representedObject instanceof WebInspector.LogObject) { 976 this._lastContentViewResponsibleSidebarPanelSetting.value = null; 977 this._lastContentCookieSetting.value = "console"; 978 return; 979 } 980 981 var responsibleSidebarPanel = this.sidebarPanelForRepresentedObject(currentContentView.representedObject); 982 if (!responsibleSidebarPanel) 983 return; 984 985 var cookie = {}; 986 currentContentView.saveToCookie(cookie); 987 this._lastContentViewResponsibleSidebarPanelSetting.value = responsibleSidebarPanel.identifier; 988 this._lastContentCookieSetting.value = cookie; 977 if (currentContentView && currentContentView.representedObject instanceof WebInspector.LogObject) { 978 cookie[WebInspector.SelectedSidebarPanelCookieKey] = "console"; 979 this._lastInspectorViewStateCookieSetting.value = cookie; 980 return; 981 } 982 983 var selectedSidebarPanel = this.navigationSidebar.selectedSidebarPanel; 984 if (!selectedSidebarPanel) 985 return; 986 987 // Restoring view state after inspector re-open or page reload is delegated to navigation sidebars. 988 // This is because some navigation sidebar state (such as breakpoint selections) cannot be inferred 989 // solely based on which content view is visible, or multiple navigation sidebars could be shown. 990 cookie[WebInspector.SelectedSidebarPanelCookieKey] = selectedSidebarPanel.identifier; 991 selectedSidebarPanel.saveStateToCookie(cookie); 992 this._lastInspectorViewStateCookieSetting.value = cookie; 989 993 } 990 994 … … 1080 1084 // Stop ignoring the sidebar panel selected event. 1081 1085 delete this._ignoreDetailsSidebarPanelSelectedEvent; 1082 1083 this._updateCurrentContentViewCookie(event); 1084 } 1085 1086 WebInspector._showContentViewForCookie = function(cookie) 1087 { 1088 if (!cookie || !cookie.type) 1089 return null; 1090 1091 this._pendingContentViewCookie = cookie; 1092 var shownContentView = this._resolveAndShowPendingContentViewCookie(); 1093 1094 // At this point, we assume no storage objects or views have been created yet. 1095 // If the cookie requests these views, they will be shown when the storage object 1096 // is added (if it matches exactly), or any view of the same type (after a timeout). 1097 if (!shownContentView) { 1098 if (this._lastAttemptCookieCheckingTimeout) 1099 clearTimeout(this._lastAttemptCookieCheckingTimeout); 1100 1101 var lastAttemptToRestoreFromCookie = function() { 1102 delete this._lastAttemptCookieCheckingTimeout; 1103 this._resolveAndShowPendingContentViewCookie(true); 1104 }; 1105 1106 // When the specific storage item wasn't found we want to relax the check to show the first item with the 1107 // same type. There is no good time to naturally declare the cookie wasn't found, so we do that on a timeout. 1108 this._lastAttemptCookieCheckingTimeout = setTimeout(lastAttemptToRestoreFromCookie.bind(this), 500); 1109 } 1110 1111 return shownContentView; 1112 } 1113 1114 WebInspector._resolveAndShowPendingContentViewCookie = function(matchOnTypeAlone) 1115 { 1116 var cookie = this._pendingContentViewCookie; 1086 } 1087 1088 WebInspector._restoreInspectorViewStateFromCookie = function(cookie, causedByReload) 1089 { 1117 1090 if (!cookie) 1118 return false; 1119 1120 var representedObject = null; 1121 1122 if (cookie.type === WebInspector.ContentViewCookieType.Resource) 1123 representedObject = this.frameResourceManager.objectForCookie(cookie); 1124 1125 if (cookie.type === WebInspector.ContentViewCookieType.Timelines) 1126 representedObject = this.timelineManager.objectForCookie(cookie); 1127 1128 if (cookie.type === WebInspector.ContentViewCookieType.CookieStorage || cookie.type === WebInspector.ContentViewCookieType.Database || cookie.type === WebInspector.ContentViewCookieType.DatabaseTable || cookie.type === WebInspector.ContentViewCookieType.DOMStorage) 1129 representedObject = this.storageManager.objectForCookie(cookie, matchOnTypeAlone); 1130 1131 if (cookie.type === WebInspector.ContentViewCookieType.ApplicationCache) 1132 representedObject = this.applicationCacheManager.objectForCookie(cookie, matchOnTypeAlone); 1133 1134 if (!representedObject) 1135 return false; 1136 1137 // If we reached this point, then we should be able to create and/or display a content view based on the cookie. 1138 delete this._pendingContentViewCookie; 1139 if (this._lastAttemptCookieCheckingTimeout) 1140 clearTimeout(this._lastAttemptCookieCheckingTimeout); 1141 1142 // Delay this work because other listeners of the originating event might not have fired yet. 1143 // So displaying the content view before those listeners do their work might cause the 1144 // dependent view states (navigation sidebar tree elements, path components) to be wrong. 1145 function delayedWork() 1146 { 1147 this.contentBrowser.showContentViewForRepresentedObject(representedObject, cookie); 1148 } 1149 setTimeout(delayedWork.bind(this), 0); 1150 return true; 1091 return; 1092 1093 // The console does not have a sidebar, so handle its special cookie here. 1094 if (cookie[WebInspector.SelectedSidebarPanelCookieKey] === "console") { 1095 this.showFullHeightConsole(); 1096 return; 1097 } 1098 1099 const matchTypeOnlyDelayForReload = 2000; 1100 const matchTypeOnlyDelayForReopen = 1000; 1101 var sidebarPanelIdentifier = cookie[WebInspector.SelectedSidebarPanelCookieKey]; 1102 var sidebarPanel = WebInspector.navigationSidebar.findSidebarPanel(sidebarPanelIdentifier); 1103 if (!sidebarPanel) 1104 return; 1105 1106 WebInspector.navigationSidebar.selectedSidebarPanel = sidebarPanel; 1107 1108 var relaxMatchDelay = causedByReload ? matchTypeOnlyDelayForReload : matchTypeOnlyDelayForReopen; 1109 sidebarPanel.restoreStateFromCookie(cookie, relaxMatchDelay); 1151 1110 } 1152 1111 -
trunk/Source/WebInspectorUI/UserInterface/NavigationSidebarPanel.js
r157269 r160025 45 45 this.toolbarItem.hidden = true; 46 46 47 this._visibleContentTreeOutlines = new Set; 48 47 49 this._contentElement = document.createElement("div"); 48 50 this._contentElement.className = WebInspector.NavigationSidebarPanel.ContentElementStyleClassName; … … 136 138 this._contentTreeOutline.element.classList.remove(WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementHiddenStyleClassName); 137 139 140 this._visibleContentTreeOutlines.delete(this._contentTreeOutline); 141 this._visibleContentTreeOutlines.add(newTreeOutline); 142 138 143 this._updateFilter(); 139 144 }, … … 164 169 contentTreeOutline.allowsRepeatSelection = true; 165 170 171 if (dontHideByDefault) 172 this._visibleContentTreeOutlines.add(contentTreeOutline); 173 166 174 return contentTreeOutline; 167 175 }, … … 178 186 if (selectedTreeElement) 179 187 selectedTreeElement.select(); 188 }, 189 190 saveStateToCookie: function(cookie) 191 { 192 console.assert(cookie); 193 194 // This does not save folder selections, which lack a represented object and content view. 195 var selectedTreeElement = null; 196 this._visibleContentTreeOutlines.forEach(function(outline) { 197 if (outline.selectedTreeElement) 198 selectedTreeElement = outline.selectedTreeElement; 199 }); 200 201 if (!selectedTreeElement) 202 return; 203 204 var representedObject = selectedTreeElement.representedObject; 205 cookie[WebInspector.TypeIdentifierCookieKey] = representedObject.constructor.TypeIdentifier; 206 representedObject.saveIdentityToCookie(cookie); 207 }, 208 209 // This can be supplemented by subclasses that admit a simpler strategy for static tree elements. 210 restoreStateFromCookie: function(cookie, relaxedMatchDelay) 211 { 212 this._pendingViewStateCookie = cookie; 213 214 // Check if any existing tree elements in any outline match the cookie. 215 this._checkOutlinesForPendingViewStateCookie(); 216 217 if (this._finalAttemptToRestoreViewStateTimeout) 218 clearTimeout(this._finalAttemptToRestoreViewStateTimeout); 219 220 var finalAttemptToRestoreViewStateFromCookie = function() { 221 delete this._finalAttemptToRestoreViewStateTimeout; 222 this._checkOutlinesForPendingViewStateCookie(true); 223 }; 224 225 // If the specific tree element wasn't found, we may need to wait for the resources 226 // to be registered. We try one last time (match type only) after an arbitrary amount of timeout. 227 this._finalAttemptToRestoreViewStateTimeout = setTimeout(finalAttemptToRestoreViewStateFromCookie.bind(this), relaxedMatchDelay); 180 228 }, 181 229 … … 400 448 this._checkForEmptyFilterResults(); 401 449 this._updateContentOverflowShadowVisibility(); 450 this._checkElementsForPendingViewStateCookie(treeElement); 402 451 }, 403 452 … … 491 540 // Check on a delay to coalesce multiple calls to _checkForOldResources. 492 541 this._checkForOldResourcesTimeoutIdentifier = setTimeout(delayedWork.bind(this), 0); 542 }, 543 544 _checkOutlinesForPendingViewStateCookie: function(matchTypeOnly) 545 { 546 if (!this._pendingViewStateCookie) 547 return; 548 549 var visibleTreeElements = []; 550 this._visibleContentTreeOutlines.forEach(function(outline) { 551 var currentTreeElement = outline.hasChildren ? outline.children[0] : null; 552 while (currentTreeElement) { 553 visibleTreeElements.push(currentTreeElement); 554 currentTreeElement = currentTreeElement.traverseNextTreeElement(false, null, false); 555 } 556 }); 557 558 return this._checkElementsForPendingViewStateCookie(visibleTreeElements, matchTypeOnly); 559 }, 560 561 _checkElementsForPendingViewStateCookie: function(treeElements, matchTypeOnly) 562 { 563 if (!this._pendingViewStateCookie) 564 return; 565 566 var cookie = this._pendingViewStateCookie; 567 568 function treeElementMatchesCookie(treeElement) 569 { 570 var representedObject = treeElement.representedObject; 571 if (!representedObject) 572 return false; 573 574 var typeIdentifier = cookie[WebInspector.TypeIdentifierCookieKey]; 575 if (typeIdentifier !== representedObject.constructor.TypeIdentifier) 576 return false; 577 578 if (matchTypeOnly) 579 return true; 580 581 var candidateObjectCookie = {}; 582 representedObject.saveIdentityToCookie(candidateObjectCookie); 583 584 return Object.keys(candidateObjectCookie).every(function valuesMatchForKey(key) { 585 return candidateObjectCookie[key] === cookie[key]; 586 }); 587 } 588 589 if (!(treeElements instanceof Array)) 590 treeElements = [treeElements]; 591 592 var matchedElement = null; 593 treeElements.some(function(element) { 594 if (treeElementMatchesCookie(element)) { 595 matchedElement = element; 596 return true; 597 } 598 }); 599 600 if (matchedElement) { 601 matchedElement.revealAndSelect(); 602 delete this._pendingViewStateCookie; 603 if (this._finalAttemptToRestoreViewStateTimeout) 604 clearTimeout(this._finalAttemptToRestoreViewStateTimeout); 605 } 493 606 } 494 607 }; -
trunk/Source/WebInspectorUI/UserInterface/Resource.js
r159233 r160025 55 55 56 56 WebInspector.Object.addConstructorFunctions(WebInspector.Resource); 57 58 WebInspector.Resource.TypeIdentifier = "resource"; 59 WebInspector.Resource.URLCookieKey = "resource-url"; 60 WebInspector.Resource.MainResourceCookieKey = "resource-is-main-resource"; 57 61 58 62 WebInspector.Resource.Event = { … … 692 696 this.dispatchEventToListeners(WebInspector.Resource.Event.TypeDidChange, {oldType: oldType}); 693 697 } 698 }, 699 700 saveIdentityToCookie: function(cookie) 701 { 702 cookie[WebInspector.Resource.URLCookieKey] = this.url; 703 cookie[WebInspector.Resource.MainResourceCookieKey] = this.isMainResource(); 694 704 } 695 705 }; -
trunk/Source/WebInspectorUI/UserInterface/ResourceClusterContentView.js
r157269 r160025 48 48 }; 49 49 50 WebInspector.ResourceClusterContentView.ContentViewIdentifierCookieKey = "resource-cluster-content-view-identifier"; 51 50 52 WebInspector.ResourceClusterContentView.RequestIconStyleClassName = "request-icon"; 51 53 WebInspector.ResourceClusterContentView.ResponseIconStyleClassName = "response-icon"; … … 143 145 saveToCookie: function(cookie) 144 146 { 145 cookie.type = WebInspector.ContentViewCookieType.Resource; 146 cookie.url = this.representedObject.url; 147 cookie.subview = this._currentContentViewSetting.value; 147 cookie[WebInspector.ResourceClusterContentView.ContentViewIdentifierCookieKey] = this._currentContentViewSetting.value; 148 148 }, 149 149 150 150 restoreFromCookie: function(cookie) 151 151 { 152 if ("lineNumber" in cookie && "columnNumber" in cookie) 153 return this.showResponse(new WebInspector.SourceCodePosition(cookie.lineNumber, cookie.columnNumber)); 154 155 this._showContentViewForIdentifier(cookie.subview); 152 var viewIdentifier = cookie[WebInspector.ResourceClusterContentView.ContentViewIdentifierCookieKey]; 153 this._showContentViewForIdentifier(viewIdentifier); 156 154 }, 157 155 -
trunk/Source/WebInspectorUI/UserInterface/Script.js
r151453 r160025 43 43 WebInspector.sourceMapManager.downloadSourceMap(sourceMapURL, this._url, this); 44 44 }; 45 46 WebInspector.Script.TypeIdentifier = "script"; 47 WebInspector.Script.URLCookieKey = "script-url"; 48 WebInspector.Script.DisplayNameCookieKey = "script-display-name"; 45 49 46 50 WebInspector.Script.resetUniqueDisplayNameNumbers = function() … … 118 122 }, 119 123 124 saveIdentityToCookie: function(cookie) 125 { 126 cookie[WebInspector.Script.URLCookieKey] = this.url; 127 cookie[WebInspector.Script.DisplayNameCookieKey] = this.displayName; 128 }, 129 120 130 // Private 121 131 -
trunk/Source/WebInspectorUI/UserInterface/StorageManager.js
r157269 r160025 148 148 }, 149 149 150 objectForCookie: function(cookie, matchOnTypeAlone)151 {152 console.assert(cookie.type);153 154 var findMatchingObjectInArray = function (array, matchesFunction) {155 for (var i = 0; i < array.length; ++i)156 if (matchesFunction.call(null, array[i]))157 return array[i];158 159 return matchOnTypeAlone && array.length ? array[0] : null;160 };161 162 if (cookie.type === WebInspector.ContentViewCookieType.CookieStorage) {163 if (this._cookieStorageObjects[cookie.host])164 return this._cookieStorageObjects[cookie.host];165 166 if (!matchOnTypeAlone)167 return null;168 169 // If we just want any cookie storage object, use the first one.170 for (var key in this._cookieStorageObjects)171 return this._cookieStorageObjects[key];172 173 return null;174 }175 176 if (cookie.type === WebInspector.ContentViewCookieType.DOMStorage) {177 return findMatchingObjectInArray(this._domStorageObjects, function(object) {178 return object.host === cookie.host && object.isLocalStorage() === cookie.isLocalStorage;179 });180 }181 182 if (cookie.type === WebInspector.ContentViewCookieType.Database) {183 return findMatchingObjectInArray(this._databaseObjects, function(object) {184 return object.host === cookie.host && object.name === cookie.name;185 });186 }187 188 // FIXME: This isn't easy to implement like the others since DatabaseTreeElement189 // creates database table objects, and they aren't known by StorageManager. Just190 // display the database instead.191 if (cookie.type === WebInspector.ContentViewCookieType.DatabaseTable) {192 return findMatchingObjectInArray(this._databaseObjects, function(object) {193 return object.host === cookie.host && object.database === cookie.name;194 });195 }196 197 console.assert("Unknown content view cookie: ", cookie);198 return null;199 },200 201 150 // Private 202 151 -
trunk/Source/WebInspectorUI/UserInterface/TimelineManager.js
r157269 r160025 300 300 }, 301 301 302 objectForCookie: function(cookie)303 {304 return this.timelines;305 },306 307 302 // Private 308 303 -
trunk/Source/WebInspectorUI/UserInterface/TimelinesContentView.js
r157269 r160025 210 210 WebInspector.TimelinesContentView.CollapseButton.States.Active = "active"; 211 211 212 WebInspector.TimelinesContentView.SelectedTimelineCookieKey = "timelines-content-view-selected-timeline"; 213 212 214 WebInspector.TimelinesContentView.generateEmbossedCollapseImages = function() 213 215 { … … 338 340 saveToCookie: function(cookie) 339 341 { 340 cookie.type = WebInspector.ContentViewCookieType.Timelines; 341 cookie.timeline = this._currentRecordTypeSetting.value; 342 cookie[WebInspector.TimelinesContentView.SelectedTimelineCookieKey] = this._currentRecordTypeSetting.value; 342 343 }, 343 344 344 345 restoreFromCookie: function(cookie) 345 346 { 346 this.showTimelineForRecordType(cookie.timeline); 347 var timeline = cookie[WebInspector.TimelinesContentView.SelectedTimelineCookieKey]; 348 this.showTimelineForRecordType(timeline); 347 349 }, 348 350 -
trunk/Source/WebInspectorUI/UserInterface/TreeOutline.js
r151688 r160025 58 58 59 59 TreeOutline._knownTreeElementNextIdentifier = 1; 60 TreeOutline.prototype.constructor = TreeOutline; 60 61 61 62 TreeOutline.prototype.appendChild = function(child)
Note: See TracChangeset
for help on using the changeset viewer.