Web Inspector: Sources: provide option to group by path
authordrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Mar 2019 23:35:20 +0000 (23:35 +0000)
committerdrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Mar 2019 23:35:20 +0000 (23:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195203
<rdar://problem/27340680>

Reviewed by Timothy Hatcher.

Create top-level folders for each origin and nest all resources (in a folder chain) underneath.

* UserInterface/Views/SourcesNavigationSidebarPanel.js:
(WI.SourcesNavigationSidebarPanel):
(WI.SourcesNavigationSidebarPanel.prototype.closed):
(WI.SourcesNavigationSidebarPanel.prototype.treeElementForRepresentedObject.searchTreeOutline): Added.
(WI.SourcesNavigationSidebarPanel.prototype.treeElementForRepresentedObject):
(WI.SourcesNavigationSidebarPanel.prototype._compareTreeElements):
(WI.SourcesNavigationSidebarPanel.prototype._updateMainFrameTreeElement):
(WI.SourcesNavigationSidebarPanel.prototype._addResource):
(WI.SourcesNavigationSidebarPanel.prototype._addScript):
(WI.SourcesNavigationSidebarPanel.prototype._addWorkerTargetWithMainResource):
(WI.SourcesNavigationSidebarPanel.prototype._handleResourceGroupingModeMouseDown.addOption): Added.
(WI.SourcesNavigationSidebarPanel.prototype._handleResourceGroupingModeMouseDown): Added.
(WI.SourcesNavigationSidebarPanel.prototype._handleTreeSelectionDidChange):
(WI.SourcesNavigationSidebarPanel.prototype._handleResourceGroupingModeChanged):
(WI.SourcesNavigationSidebarPanel.prototype._handleFrameMainResourceDidChange):
(WI.SourcesNavigationSidebarPanel.prototype._handleMainFrameDidChange):
* UserInterface/Views/SourcesNavigationSidebarPanel.css:
(.sidebar > .panel.navigation.sources > .content):
(.sidebar > .panel.navigation.sources > .content > .details-section.paused-reason.collapsed > .header > .options,):
(.sidebar > .panel.navigation.sources > .content > .details-section.breakpoints > .header > .options .create-breakpoint): Added.
(.sidebar > .panel.navigation.sources > .content > .resources): Added.
(.sidebar > .panel.navigation.sources > .content .tree-outline.single-thread): Added.
(.sidebar > .panel.navigation.sources > .content .tree-outline.single-thread > .item.thread): Added.
(.sidebar > .panel.navigation.sources > .content > .details-section.scripts:not(.collapsed)): Deleted.
(.sidebar > .panel.navigation.sources > .content > .tree-outline.single-thread): Deleted.
(.sidebar > .panel.navigation.sources > .content > .tree-outline.single-thread > .item.thread): Deleted.
Drive-by: fix "No Filter Results" message view to not overlap eachother.
Drive-by: try to be more smart about what tree we focus when selecting a represented object.
* UserInterface/Views/ResourceTreeElement.js:
(WI.ResourceTreeElement):
(WI.ResourceTreeElement.prototype.get mainTitleText):
(WI.ResourceTreeElement.prototype._updateTitles):
* UserInterface/Base/URLUtilities.js:
(WI.displayNameForURL):
Provide a way for the display name to use a directory "/" instead of the last path component.
This is needed in cases where the loaded resource is an implicit "index.*".

* UserInterface/Views/GeneralTreeElement.js:
(WI.GeneralTreeElement.prototype.createFoldersAsNeededForSubpath): Added.
* UserInterface/Views/SourceCodeTreeElement.js:
(WI.SourceCodeTreeElement.prototype.createFoldersAsNeededForSubpath): Deleted.

* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Models/Resource.js:

* UserInterface/Views/DetailsSection.css:
(.details-section > .header .go-to-arrow):
Drive-by: vertically center go-to-arrow.
* UserInterface/Protocol/InspectorFrontendAPI.js:
(InspectorFrontendAPI.contextMenuItemSelected):

* UserInterface/Base/Setting.js:
* UserInterface/Views/NetworkTableContentView.js:
(WI.NetworkTableContentView):
(WI.NetworkTableContentView.prototype.get filterNavigationItems):
(WI.NetworkTableContentView.prototype._populateNameCell):
(WI.NetworkTableContentView.prototype._generateSortComparator):
(WI.NetworkTableContentView.prototype._insertResourceAndReloadTable):
(WI.NetworkTableContentView.prototype._updateFilteredEntries):
(WI.NetworkTableContentView.prototype._handleGroupMediaRequestsByDOMNodeCheckedDidChange): Added.
(WI.NetworkTableContentView.prototype._handleGroupByDOMNodeCheckedDidChange): Deleted.
Rename the `groupByNode` setting to be more specific.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@243180 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
Source/WebInspectorUI/UserInterface/Base/Setting.js
Source/WebInspectorUI/UserInterface/Base/URLUtilities.js
Source/WebInspectorUI/UserInterface/Models/Resource.js
Source/WebInspectorUI/UserInterface/Protocol/InspectorFrontendAPI.js
Source/WebInspectorUI/UserInterface/Views/DetailsSection.css
Source/WebInspectorUI/UserInterface/Views/GeneralTreeElement.js
Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js
Source/WebInspectorUI/UserInterface/Views/ResourceTreeElement.js
Source/WebInspectorUI/UserInterface/Views/SourceCodeTreeElement.js
Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.css
Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js

index d7ddc8c..dadd058 100644 (file)
@@ -1,5 +1,80 @@
 2019-03-19  Devin Rousso  <drousso@apple.com>
 
+        Web Inspector: Sources: provide option to group by path
+        https://bugs.webkit.org/show_bug.cgi?id=195203
+        <rdar://problem/27340680>
+
+        Reviewed by Timothy Hatcher.
+
+        Create top-level folders for each origin and nest all resources (in a folder chain) underneath.
+
+        * UserInterface/Views/SourcesNavigationSidebarPanel.js:
+        (WI.SourcesNavigationSidebarPanel):
+        (WI.SourcesNavigationSidebarPanel.prototype.closed):
+        (WI.SourcesNavigationSidebarPanel.prototype.treeElementForRepresentedObject.searchTreeOutline): Added.
+        (WI.SourcesNavigationSidebarPanel.prototype.treeElementForRepresentedObject):
+        (WI.SourcesNavigationSidebarPanel.prototype._compareTreeElements):
+        (WI.SourcesNavigationSidebarPanel.prototype._updateMainFrameTreeElement):
+        (WI.SourcesNavigationSidebarPanel.prototype._addResource):
+        (WI.SourcesNavigationSidebarPanel.prototype._addScript):
+        (WI.SourcesNavigationSidebarPanel.prototype._addWorkerTargetWithMainResource):
+        (WI.SourcesNavigationSidebarPanel.prototype._handleResourceGroupingModeMouseDown.addOption): Added.
+        (WI.SourcesNavigationSidebarPanel.prototype._handleResourceGroupingModeMouseDown): Added.
+        (WI.SourcesNavigationSidebarPanel.prototype._handleTreeSelectionDidChange):
+        (WI.SourcesNavigationSidebarPanel.prototype._handleResourceGroupingModeChanged):
+        (WI.SourcesNavigationSidebarPanel.prototype._handleFrameMainResourceDidChange):
+        (WI.SourcesNavigationSidebarPanel.prototype._handleMainFrameDidChange):
+        * UserInterface/Views/SourcesNavigationSidebarPanel.css:
+        (.sidebar > .panel.navigation.sources > .content):
+        (.sidebar > .panel.navigation.sources > .content > .details-section.paused-reason.collapsed > .header > .options,):
+        (.sidebar > .panel.navigation.sources > .content > .details-section.breakpoints > .header > .options .create-breakpoint): Added.
+        (.sidebar > .panel.navigation.sources > .content > .resources): Added.
+        (.sidebar > .panel.navigation.sources > .content .tree-outline.single-thread): Added.
+        (.sidebar > .panel.navigation.sources > .content .tree-outline.single-thread > .item.thread): Added.
+        (.sidebar > .panel.navigation.sources > .content > .details-section.scripts:not(.collapsed)): Deleted.
+        (.sidebar > .panel.navigation.sources > .content > .tree-outline.single-thread): Deleted.
+        (.sidebar > .panel.navigation.sources > .content > .tree-outline.single-thread > .item.thread): Deleted.
+        Drive-by: fix "No Filter Results" message view to not overlap eachother.
+        Drive-by: try to be more smart about what tree we focus when selecting a represented object.
+
+        * UserInterface/Views/ResourceTreeElement.js:
+        (WI.ResourceTreeElement):
+        (WI.ResourceTreeElement.prototype.get mainTitleText):
+        (WI.ResourceTreeElement.prototype._updateTitles):
+        * UserInterface/Base/URLUtilities.js:
+        (WI.displayNameForURL):
+        Provide a way for the display name to use a directory "/" instead of the last path component.
+        This is needed in cases where the loaded resource is an implicit "index.*".
+
+        * UserInterface/Views/GeneralTreeElement.js:
+        (WI.GeneralTreeElement.prototype.createFoldersAsNeededForSubpath): Added.
+        * UserInterface/Views/SourceCodeTreeElement.js:
+        (WI.SourceCodeTreeElement.prototype.createFoldersAsNeededForSubpath): Deleted.
+
+        * Localizations/en.lproj/localizedStrings.js:
+        * UserInterface/Models/Resource.js:
+
+        * UserInterface/Views/DetailsSection.css:
+        (.details-section > .header .go-to-arrow):
+        Drive-by: vertically center go-to-arrow.
+
+        * UserInterface/Protocol/InspectorFrontendAPI.js:
+        (InspectorFrontendAPI.contextMenuItemSelected):
+
+        * UserInterface/Base/Setting.js:
+        * UserInterface/Views/NetworkTableContentView.js:
+        (WI.NetworkTableContentView):
+        (WI.NetworkTableContentView.prototype.get filterNavigationItems):
+        (WI.NetworkTableContentView.prototype._populateNameCell):
+        (WI.NetworkTableContentView.prototype._generateSortComparator):
+        (WI.NetworkTableContentView.prototype._insertResourceAndReloadTable):
+        (WI.NetworkTableContentView.prototype._updateFilteredEntries):
+        (WI.NetworkTableContentView.prototype._handleGroupMediaRequestsByDOMNodeCheckedDidChange): Added.
+        (WI.NetworkTableContentView.prototype._handleGroupByDOMNodeCheckedDidChange): Deleted.
+        Rename the `groupByNode` setting to be more specific.
+
+2019-03-19  Devin Rousso  <drousso@apple.com>
+
         Web Inspector: CPU Usage Timeline - the right edge of each column should align with a CPU measurement
         https://bugs.webkit.org/show_bug.cgi?id=195789
         <rdar://problem/48915271>
index 2d8b2d1..f1c6d0b 100644 (file)
@@ -511,7 +511,10 @@ localizedStrings["Group"] = "Group";
 localizedStrings["Group Media Requests"] = "Group Media Requests";
 localizedStrings["Group by Event"] = "Group by Event";
 localizedStrings["Group by Node"] = "Group by Node";
+localizedStrings["Group by Path"] = "Group by Path";
+localizedStrings["Group by Type"] = "Group by Type";
 localizedStrings["Grouping Method"] = "Grouping Method";
+localizedStrings["Grouping Mode"] = "Grouping Mode";
 localizedStrings["HAR Export (%s)"] = "HAR Export (%s)";
 localizedStrings["HAR Import"] = "HAR Import";
 localizedStrings["HAR Import Error: %s"] = "HAR Import Error: %s";
index 09d7750..4d54ee4 100644 (file)
@@ -134,7 +134,7 @@ WI.settings = {
     emulateInUserGesture: new WI.Setting("emulate-in-user-gesture", false),
     enableControlFlowProfiler: new WI.Setting("enable-control-flow-profiler", false),
     enableLineWrapping: new WI.Setting("enable-line-wrapping", false),
-    groupByDOMNode: new WI.Setting("group-by-dom-node", false),
+    groupMediaRequestsByDOMNode: new WI.Setting("group-media-requests-by-dom-node", WI.Setting.migrateValue("group-by-dom-node") || false),
     indentUnit: new WI.Setting("indent-unit", 4),
     indentWithTabs: new WI.Setting("indent-with-tabs", false),
     resourceCachingDisabled: new WI.Setting("disable-resource-caching", false),
index bc93298..644ac78 100644 (file)
@@ -214,7 +214,7 @@ function parseQueryString(queryString, arrayResult)
     return parameters;
 }
 
-WI.displayNameForURL = function(url, urlComponents)
+WI.displayNameForURL = function(url, urlComponents, options = {})
 {
     if (url.startsWith("data:"))
         return WI.truncateURL(url);
@@ -229,6 +229,9 @@ WI.displayNameForURL = function(url, urlComponents)
         displayName = urlComponents.lastPathComponent;
     }
 
+    if (options.allowDirectoryAsName && (!displayName || urlComponents.path.endsWith(displayName + "/")))
+        displayName = "/";
+
     return displayName || WI.displayNameForHost(urlComponents.host) || url;
 };
 
index 237c053..f2a0f52 100644 (file)
@@ -1181,6 +1181,12 @@ WI.Resource.NetworkPriority = {
     High: Symbol("high"),
 };
 
+WI.Resource.GroupingMode = {
+    Path: "group-resource-by-path",
+    Type: "group-resource-by-type",
+};
+WI.settings.resourceGroupingMode = new WI.Setting("resource-grouping-mode", WI.Resource.GroupingMode.Type);
+
 // This MIME Type map is private, use WI.Resource.typeFromMIMEType().
 WI.Resource._mimeTypeMap = {
     "text/html": WI.Resource.Type.Document,
index 6d070e6..aeba887 100644 (file)
@@ -122,11 +122,7 @@ InspectorFrontendAPI = {
 
     contextMenuItemSelected: function(id)
     {
-        try {
-            WI.ContextMenu.contextMenuItemSelected(id);
-        } catch (e) {
-            console.error("Uncaught exception in inspector page under contextMenuItemSelected", e);
-        }
+        WI.ContextMenu.contextMenuItemSelected(id);
     },
 
     contextMenuCleared: function()
index 36f4ad4..99efee8 100644 (file)
@@ -140,7 +140,7 @@ body[dir=rtl] .details-section > .header::before {
 
 .details-section > .header .go-to-arrow {
     width: 10px;
-    height: 12px;
+    height: 15px;
     -webkit-margin-start: 3px;
 }
 
index 8626e83..31f1e30 100644 (file)
@@ -191,6 +191,43 @@ WI.GeneralTreeElement = class GeneralTreeElement extends WI.TreeElement
         this._tooltipHandledSeparately = !!x;
     }
 
+    createFoldersAsNeededForSubpath(subpath)
+    {
+        if (!subpath)
+            return this;
+
+        let components = subpath.split("/");
+        if (components.length === 1)
+            return this;
+
+        if (!this._subpathFolderTreeElementMap)
+            this._subpathFolderTreeElementMap = new Map;
+
+        let currentPath = "";
+        let currentFolderTreeElement = this;
+
+        for (let component of components) {
+            if (currentPath)
+                currentPath += "/";
+            currentPath += component;
+
+            let cachedFolder = this._subpathFolderTreeElementMap.get(currentPath);
+            if (cachedFolder) {
+                currentFolderTreeElement = cachedFolder;
+                continue;
+            }
+
+            let newFolder = new WI.FolderTreeElement(component);
+            this._subpathFolderTreeElementMap.set(currentPath, newFolder);
+
+            let index = insertionIndexForObjectInListSortedByFunction(newFolder, currentFolderTreeElement.children, WI.ResourceTreeElement.compareFolderAndResourceTreeElements);
+            currentFolderTreeElement.insertChild(newFolder, index);
+            currentFolderTreeElement = newFolder;
+        }
+
+        return currentFolderTreeElement;
+    }
+
     // Overrides from TreeElement (Private)
 
     isEventWithinDisclosureTriangle(event)
index 1389197..1dd6510 100644 (file)
@@ -88,10 +88,10 @@ WI.NetworkTableContentView = class NetworkTableContentView extends WI.ContentVie
         this._typeFilterScopeBar.addEventListener(WI.ScopeBar.Event.SelectionChanged, this._typeFilterScopeBarSelectionChanged, this);
 
         if (WI.MediaInstrument.supported()) {
-            this._groupByDOMNodeNavigationItem = new WI.CheckboxNavigationItem("group-by-node", WI.UIString("Group Media Requests"), WI.settings.groupByDOMNode.value);
-            this._groupByDOMNodeNavigationItem.addEventListener(WI.CheckboxNavigationItem.Event.CheckedDidChange, this._handleGroupByDOMNodeCheckedDidChange, this);
+            this._groupMediaRequestsByDOMNodeNavigationItem = new WI.CheckboxNavigationItem("group-media-requests", WI.UIString("Group Media Requests"), WI.settings.groupMediaRequestsByDOMNode.value);
+            this._groupMediaRequestsByDOMNodeNavigationItem.addEventListener(WI.CheckboxNavigationItem.Event.CheckedDidChange, this._handleGroupMediaRequestsByDOMNodeCheckedDidChange, this);
         } else
-            WI.settings.groupByDOMNode.value = false;
+            WI.settings.groupMediaRequestsByDOMNode.value = false;
 
         this._urlFilterSearchText = null;
         this._urlFilterSearchRegex = null;
@@ -246,7 +246,7 @@ WI.NetworkTableContentView = class NetworkTableContentView extends WI.ContentVie
     {
         let navigationItems = [this._urlFilterNavigationItem, this._typeFilterScopeBar];
         if (WI.MediaInstrument.supported())
-            navigationItems.push(this._groupByDOMNodeNavigationItem);
+            navigationItems.push(this._groupMediaRequestsByDOMNodeNavigationItem);
         return navigationItems;
     }
 
@@ -643,7 +643,7 @@ WI.NetworkTableContentView = class NetworkTableContentView extends WI.ContentVie
 
         cell.classList.add(WI.ResourceTreeElement.ResourceIconStyleClassName);
 
-        if (WI.settings.groupByDOMNode.value && resource.initiatorNode) {
+        if (WI.settings.groupMediaRequestsByDOMNode.value && resource.initiatorNode) {
             let nodeEntry = this._domNodeEntries.get(resource.initiatorNode);
             if (nodeEntry.initiatedResourceEntries.length > 1 || nodeEntry.domNode.domEvents.length)
                 cell.classList.add("child");
@@ -1063,7 +1063,7 @@ WI.NetworkTableContentView = class NetworkTableContentView extends WI.ContentVie
         // This will ensure that all resource entries for a given `initiatorNode` will appear right
         // next to each other, as they will all effectively be sorted by the first resource.
         let substitute = (entry, other) => {
-            if (WI.settings.groupByDOMNode.value && entry.resource.initiatorNode) {
+            if (WI.settings.groupMediaRequestsByDOMNode.value && entry.resource.initiatorNode) {
                 let nodeEntry = this._domNodeEntries.get(entry.resource.initiatorNode);
                 if (!nodeEntry.initiatedResourceEntries.includes(other))
                     return nodeEntry.initiatedResourceEntries[0];
@@ -1710,7 +1710,7 @@ WI.NetworkTableContentView = class NetworkTableContentView extends WI.ContentVie
 
         this._tryLinkResourceToDOMNode(resourceEntry);
 
-        if (WI.settings.groupByDOMNode.value && resource.initiatorNode) {
+        if (WI.settings.groupMediaRequestsByDOMNode.value && resource.initiatorNode) {
             if (!this._entriesSortComparator)
                 this._generateSortComparator();
         } else if (this._isDefaultSort() || !this._entriesSortComparator) {
@@ -1726,7 +1726,7 @@ WI.NetworkTableContentView = class NetworkTableContentView extends WI.ContentVie
         insertObjectIntoSortedArray(resourceEntry, collection.entries, this._entriesSortComparator);
 
         if (this._passFilter(resourceEntry)) {
-            if (WI.settings.groupByDOMNode.value)
+            if (WI.settings.groupMediaRequestsByDOMNode.value)
                 this._updateFilteredEntries();
             else
                 insertObjectIntoSortedArray(resourceEntry, collection.filteredEntries, this._entriesSortComparator);
@@ -1897,7 +1897,7 @@ WI.NetworkTableContentView = class NetworkTableContentView extends WI.ContentVie
         else
             collection.filteredEntries = collection.entries.slice();
 
-        if (WI.settings.groupByDOMNode.value) {
+        if (WI.settings.groupMediaRequestsByDOMNode.value) {
             for (let nodeEntry of this._domNodeEntries.values()) {
                 if (nodeEntry.initiatedResourceEntries.length < 2 && !nodeEntry.domNode.domEvents.length)
                     continue;
@@ -2003,11 +2003,11 @@ WI.NetworkTableContentView = class NetworkTableContentView extends WI.ContentVie
         this._reloadTable();
     }
 
-    _handleGroupByDOMNodeCheckedDidChange(event)
+    _handleGroupMediaRequestsByDOMNodeCheckedDidChange(event)
     {
-        WI.settings.groupByDOMNode.value = this._groupByDOMNodeNavigationItem.checked;
+        WI.settings.groupMediaRequestsByDOMNode.value = this._groupMediaRequestsByDOMNodeNavigationItem.checked;
 
-        if (!WI.settings.groupByDOMNode.value) {
+        if (!WI.settings.groupMediaRequestsByDOMNode.value) {
             this._table.element.classList.remove("grouped");
 
             if (this._selectedObject && this._selectedObject instanceof WI.DOMNode) {
index 216233d..278c005 100644 (file)
@@ -25,7 +25,7 @@
 
 WI.ResourceTreeElement = class ResourceTreeElement extends WI.SourceCodeTreeElement
 {
-    constructor(resource, representedObject)
+    constructor(resource, representedObject, {allowDirectoryAsName, hideOrigin} = {})
     {
         console.assert(resource instanceof WI.Resource);
 
@@ -33,6 +33,11 @@ WI.ResourceTreeElement = class ResourceTreeElement extends WI.SourceCodeTreeElem
         const subtitle = null;
         super(resource, ["resource", WI.ResourceTreeElement.ResourceIconStyleClassName, WI.Resource.classNameForResource(resource)], title, subtitle, representedObject || resource);
 
+        if (allowDirectoryAsName)
+            this._allowDirectoryAsName = allowDirectoryAsName;
+        if (hideOrigin)
+            this._hideOrigin = hideOrigin;
+
         this._updateResource(resource);
     }
 
@@ -135,7 +140,9 @@ WI.ResourceTreeElement = class ResourceTreeElement extends WI.SourceCodeTreeElem
 
     get mainTitleText()
     {
-        return WI.displayNameForURL(this._resource.url, this._resource.urlComponents);
+        return WI.displayNameForURL(this._resource.url, this._resource.urlComponents, {
+            allowDirectoryAsName: this._allowDirectoryAsName,
+        });
     }
 
     _updateTitles()
@@ -158,9 +165,11 @@ WI.ResourceTreeElement = class ResourceTreeElement extends WI.SourceCodeTreeElem
         var oldMainTitle = this.mainTitle;
         this.mainTitle = this.mainTitleText;
 
-        // Show the host as the subtitle if it is different from the main resource or if this is the main frame's main resource.
-        var subtitle = parentResourceHost !== urlComponents.host || frame && frame.isMainFrame() && isMainResource ? WI.displayNameForHost(urlComponents.host) : null;
-        this.subtitle = this.mainTitle !== subtitle ? subtitle : null;
+        if (!this._hideOrigin) {
+            // Show the host as the subtitle if it is different from the main resource or if this is the main frame's main resource.
+            var subtitle = parentResourceHost !== urlComponents.host || frame && frame.isMainFrame() && isMainResource ? WI.displayNameForHost(urlComponents.host) : null;
+            this.subtitle = this.mainTitle !== subtitle ? subtitle : null;
+        }
 
         if (oldMainTitle !== this.mainTitle)
             this.callFirstAncestorFunction("descendantResourceTreeElementMainTitleDidChange", [this, oldMainTitle]);
index cde0ca0..87de40d 100644 (file)
@@ -130,43 +130,6 @@ WI.SourceCodeTreeElement = class SourceCodeTreeElement extends WI.FolderizedTree
 
     // Protected
 
-    createFoldersAsNeededForSubpath(subpath)
-    {
-        if (!subpath)
-            return this;
-
-        var components = subpath.split("/");
-        if (components.length === 1)
-            return this;
-
-        if (!this._subpathFolderTreeElementMap)
-            this._subpathFolderTreeElementMap = {};
-
-        var currentPath = "";
-        var currentFolderTreeElement = this;
-
-        for (var i = 0; i < components.length - 1; ++i) {
-            var componentName = components[i];
-            currentPath += (i ? "/" : "") + componentName;
-
-            var cachedFolder = this._subpathFolderTreeElementMap[currentPath];
-            if (cachedFolder) {
-                currentFolderTreeElement = cachedFolder;
-                continue;
-            }
-
-            var newFolder = new WI.FolderTreeElement(componentName);
-            newFolder.__path = currentPath;
-            this._subpathFolderTreeElementMap[currentPath] = newFolder;
-
-            var index = insertionIndexForObjectInListSortedByFunction(newFolder, currentFolderTreeElement.children, WI.ResourceTreeElement.compareFolderAndResourceTreeElements);
-            currentFolderTreeElement.insertChild(newFolder, index);
-            currentFolderTreeElement = newFolder;
-        }
-
-        return currentFolderTreeElement;
-    }
-
     descendantResourceTreeElementTypeDidChange(childTreeElement, oldType)
     {
         // Called by descendant SourceMapResourceTreeElements.
index a04ecb2..dd57638 100644 (file)
@@ -24,6 +24,8 @@
  */
 
 .sidebar > .panel.navigation.sources > .content {
+    display: flex;
+    flex-direction: column;
     top: var(--navigation-bar-height);
 }
 
@@ -73,6 +75,7 @@
 }
 
 .sidebar > .panel.navigation.sources > .content > .details-section.paused-reason.collapsed > .header > .options,
+.sidebar > .panel.navigation.sources > .content > .details-section.breakpoints.collapsed > .header > .options,
 .sidebar > .panel.navigation.sources > .content > .details-section > .content,
 .sidebar > .panel.navigation.sources > .content > .details-section > .content > .group {
     display: block;
     display: none;
 }
 
-.sidebar > .panel.navigation.sources > .content > .details-section.scripts:not(.collapsed) {
-    border-bottom: none;
+.sidebar > .panel.navigation.sources > .content > .details-section.breakpoints > .header > .options .create-breakpoint {
+    width: 15px;
 }
 
 .sidebar > .panel.navigation.sources > .content > .navigation-bar {
     margin-bottom: 1px;
 }
 
-.sidebar > .panel.navigation.sources > .content > .tree-outline.single-thread {
+.sidebar > .panel.navigation.sources > .content > .resources {
+    position: relative;
+    height: 100%;
+}
+
+.sidebar > .panel.navigation.sources > .content .tree-outline.single-thread {
     -webkit-margin-start: -10px;
 }
 
-.sidebar > .panel.navigation.sources > .content .tree-outline.single-thread > .item.thread {
+.sidebar > .panel.navigation.sources > .content .tree-outline.single-thread > .item.thread {
     display: none;
 }
 
index b76d76c..1187d8c 100644 (file)
@@ -30,6 +30,16 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
         const shouldAutoPruneStaleTopLevelResourceTreeElements = true;
         super("sources", WI.UIString("Sources"), shouldAutoPruneStaleTopLevelResourceTreeElements);
 
+        this._workerTargetTreeElementMap = new Map;
+        this._mainFrameTreeElement = null;
+        this._extensionScriptsFolderTreeElement = null;
+        this._extraScriptsFolderTreeElement = null;
+        this._anonymousScriptsFolderTreeElement = null;
+
+        this._originTreeElementMap = new Map;
+
+        this._boundCompareTreeElements = this._compareTreeElements.bind(this);
+
         this._debuggerNavigationBar = new WI.NavigationBar;
         this.addSubview(this._debuggerNavigationBar);
 
@@ -175,18 +185,11 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
         let breakpointsSection = new WI.DetailsSection("breakpoints", WI.UIString("Breakpoints"), [breakpointsGroup], breakpointNavigationBarWrapper);
         this.contentView.element.insertBefore(breakpointsSection.element, this.contentView.element.firstChild);
 
-        this._resourcesTreeOutline = this.contentTreeOutline;
-        this._resourcesTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._handleTreeSelectionDidChange, this);
-        this._resourcesTreeOutline.includeSourceMapResourceChildren = true;
-
         this._resourcesNavigationBar = new WI.NavigationBar;
         this.contentView.addSubview(this._resourcesNavigationBar);
-        this.contentView.element.insertBefore(this._resourcesNavigationBar.element, this._resourcesTreeOutline.element);
+        this.contentView.element.insertBefore(this._resourcesNavigationBar.element, breakpointsSection.nextSibling);
 
-        this._workerTargetTreeElementMap = new Map;
-        this._extensionScriptsFolderTreeElement = null;
-        this._extraScriptsFolderTreeElement = null;
-        this._anonymousScriptsFolderTreeElement = null;
+        this._resourcesNavigationBar.addNavigationItem(new WI.FlexibleSpaceNavigationItem);
 
         const resourceTypeScopeItemPrefix = "sources-resource-type-";
         let resourceTypeScopeBarItems = [];
@@ -202,6 +205,21 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
         this._resourceTypeScopeBar.addEventListener(WI.ScopeBar.Event.SelectionChanged, this._handleResourceTypeScopeBarSelectionChanged, this);
         this._resourcesNavigationBar.addNavigationItem(this._resourceTypeScopeBar);
 
+        this._resourcesNavigationBar.addNavigationItem(new WI.FlexibleSpaceNavigationItem);
+
+        let resourceGroupingModeNavigationItem = new WI.ButtonNavigationItem("grouping-mode", WI.UIString("Grouping Mode"), "Images/Gear.svg", 15, 15);
+        resourceGroupingModeNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
+        resourceGroupingModeNavigationItem.element.addEventListener("mousedown", this._handleResourceGroupingModeMouseDown.bind(this));
+        this._resourcesNavigationBar.addNavigationItem(resourceGroupingModeNavigationItem);
+
+        let resourcesContainer = this.contentView.element.insertBefore(document.createElement("div"), this._resourcesNavigationBar.element.nextSibling);
+        resourcesContainer.classList.add("resources");
+
+        this._resourcesTreeOutline = this.contentTreeOutline;
+        this._resourcesTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._handleTreeSelectionDidChange, this);
+        this._resourcesTreeOutline.includeSourceMapResourceChildren = true;
+        resourcesContainer.appendChild(this._resourcesTreeOutline.element);
+
         let onlyShowResourcesWithIssuesFilterFunction = (treeElement) => {
             if (treeElement.treeOutline !== this._resourcesTreeOutline)
                 return true;
@@ -220,6 +238,8 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
         const activatedByDefault = false;
         this.filterBar.addFilterBarButton("sources-only-show-resources-with-issues", onlyShowResourcesWithIssuesFilterFunction, activatedByDefault, WI.UIString("Only show resources with issues"), WI.UIString("Show all resources"), "Images/Errors.svg", 15, 15);
 
+        WI.settings.resourceGroupingMode.addEventListener(WI.Setting.Event.Changed, this._handleResourceGroupingModeChanged, this);
+
         WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._handleFrameMainResourceDidChange, this);
         WI.Frame.addEventListener(WI.Frame.Event.ResourceWasAdded, this._handleResourceAdded, this);
         WI.Target.addEventListener(WI.Target.Event.ResourceAdded, this._handleResourceAdded, this);
@@ -281,23 +301,12 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
         if (InspectorBackend.domains.Debugger.setPauseOnAssertions && WI.settings.showAssertionFailuresBreakpoint.value)
             WI.debuggerManager.addBreakpoint(WI.debuggerManager.assertionFailuresBreakpoint);
 
-        let mainFrame = WI.networkManager.mainFrame;
-        if (mainFrame) {
-            this._updateMainFrameTreeElement(mainFrame);
-            this._addResourcesRecursivelyForFrame(mainFrame);
-        }
-
         for (let target of WI.targets)
             this._addTarget(target);
 
         this._updateCallStackTreeOutline();
 
-        for (let script of WI.debuggerManager.knownNonResourceScripts) {
-            this._addScript(script);
-
-            if (script.sourceMaps.length && WI.SourcesNavigationSidebarPanel.shouldPlaceResourcesAtTopLevel())
-                this._resourcesTreeOutline.disclosureButtons = true;
-        }
+        this._handleResourceGroupingModeChanged();
 
         if (WI.domDebuggerManager.supported) {
             if (WI.settings.showAllRequestsBreakpoint.value)
@@ -347,6 +356,7 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
 
     closed()
     {
+        WI.settings.resourceGroupingMode.removeEventListener(null, null, this);
         WI.Frame.removeEventListener(null, null, this);
         WI.Target.removeEventListener(null, null, this);
         WI.networkManager.removeEventListener(null, null, this);
@@ -387,7 +397,6 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
             return null;
         }
 
-        // The Frame is used as the representedObject instead of the main resource in our tree.
         if (representedObject instanceof WI.Resource && representedObject.parentFrame && representedObject.parentFrame.mainResource === representedObject)
             representedObject = representedObject.parentFrame;
 
@@ -417,7 +426,12 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
             return resourceOrFrame.parentFrame;
         }
 
-        let treeElement = this._resourcesTreeOutline.findTreeElement(representedObject, isAncestor, getParent);
+        function searchTreeOutline(treeOutline, forceSearch) {
+            if (!treeOutline || (!treeOutline.selectedTreeElement && !forceSearch))
+                return null;
+            return treeOutline.findTreeElement(representedObject, isAncestor, getParent);
+        }
+        let treeElement = searchTreeOutline(this._pauseReasonTreeOutline) || searchTreeOutline(this._callStackTreeOutline) || searchTreeOutline(this._breakpointsTreeOutline) || searchTreeOutline(this._resourcesTreeOutline, true);
         if (treeElement)
             return treeElement;
 
@@ -441,7 +455,7 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
             this._anonymousScriptsFolderTreeElement = new WI.FolderTreeElement(WI.UIString("Anonymous Scripts"), new WI.ScriptCollection);
 
         if (!this._anonymousScriptsFolderTreeElement.parent) {
-            let index = insertionIndexForObjectInListSortedByFunction(this._anonymousScriptsFolderTreeElement, this._resourcesTreeOutline.children, this._compareTreeElements);
+            let index = insertionIndexForObjectInListSortedByFunction(this._anonymousScriptsFolderTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
             this._resourcesTreeOutline.insertChild(this._anonymousScriptsFolderTreeElement, index);
         }
 
@@ -485,6 +499,9 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
         if (treeElement instanceof WI.FolderTreeElement)
             return false;
 
+        if (treeElement instanceof WI.IssueTreeElement)
+            treeElement = treeElement.parent;
+
         function match()
         {
             if (treeElement instanceof WI.FrameTreeElement)
@@ -527,16 +544,30 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
 
     _compareTreeElements(a, b)
     {
-        // Always sort the main frame element first.
-        if (a instanceof WI.FrameTreeElement)
-            return -1;
-        if (b instanceof WI.FrameTreeElement)
-            return 1;
-
-        console.assert(a.mainTitle);
-        console.assert(b.mainTitle);
+        const rankFunctions = [
+            (treeElement) => treeElement === this._mainFrameTreeElement,
+            (treeElement) => treeElement instanceof WI.FrameTreeElement,
+            (treeElement) => {
+                return treeElement instanceof WI.FolderTreeElement
+                    && treeElement !== this._extensionScriptsFolderTreeElement
+                    && treeElement !== this._extraScriptsFolderTreeElement
+                    && treeElement !== this._anonymousScriptsFolderTreeElement;
+            },
+            (treeElement) => treeElement === this._extensionScriptsFolderTreeElement,
+            (treeElement) => treeElement === this._extraScriptsFolderTreeElement,
+            (treeElement) => treeElement === this._anonymousScriptsFolderTreeElement,
+        ];
+
+        let aRank = rankFunctions.findIndex((rankFunction) => rankFunction(a));
+        let bRank = rankFunctions.findIndex((rankFunction) => rankFunction(b));
+        if (aRank >= 0 && bRank >= 0) {
+            if (aRank < bRank)
+                return -1;
+            if (bRank < aRank)
+                return 1;
+        }
 
-        return (a.mainTitle || "").extendedLocaleCompare(b.mainTitle || "");
+        return a.mainTitle.extendedLocaleCompare(b.mainTitle) || a.subtitle.extendedLocaleCompare(b.subtitle);
     }
 
     _updateMainFrameTreeElement(mainFrame)
@@ -544,6 +575,7 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
         if (this.didInitialLayout)
             this.contentBrowser.contentViewContainer.closeAllContentViews();
 
+        let oldMainFrameTreeElement = this._mainFrameTreeElement;
         if (this._mainFrameTreeElement) {
             this._resourcesTreeOutline.removeChild(this._mainFrameTreeElement);
             this._mainFrameTreeElement = null;
@@ -552,7 +584,28 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
         if (!mainFrame)
             return;
 
-        this._mainFrameTreeElement = new WI.FrameTreeElement(mainFrame);
+        let resourceGroupingMode = WI.settings.resourceGroupingMode.value;
+        switch (resourceGroupingMode) {
+        case WI.Resource.GroupingMode.Path:
+            for (let treeElement of this._originTreeElementMap.values()) {
+                if (treeElement !== oldMainFrameTreeElement)
+                    this._resourcesTreeOutline.removeChild(treeElement);
+            }
+            this._originTreeElementMap.clear();
+
+            this._mainFrameTreeElement = new WI.FolderTreeElement(mainFrame.securityOrigin, mainFrame);
+            this._originTreeElementMap.set(mainFrame.securityOrigin, this._mainFrameTreeElement);
+            break;
+
+        default:
+            WI.reportInternalError("Unknown resource grouping mode", {"Resource Grouping Mode": WI.settings.resourceGroupingMode.value});
+            // Fallthrough for default value.
+
+        case WI.Resource.GroupingMode.Type:
+            this._mainFrameTreeElement = new WI.FrameTreeElement(mainFrame);
+            break;
+        }
+
         this._resourcesTreeOutline.insertChild(this._mainFrameTreeElement, 0);
 
         // Cookie restoration will attempt to re-select the resource we were showing.
@@ -564,7 +617,7 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
             let currentContentView = this.contentBrowser.currentContentView;
             let treeElement = currentContentView ? this.treeElementForRepresentedObject(currentContentView.representedObject) : null;
             if (!treeElement)
-                treeElement = this._mainFrameTreeElement;
+                treeElement = this.treeElementForRepresentedObject(WI.networkManager.mainFrame);
             this.showDefaultContentViewForTreeElement(treeElement);
         });
     }
@@ -600,11 +653,42 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
 
     _addResource(resource)
     {
-        if (resource.type !== WI.Resource.Type.Document && resource.type !== WI.Resource.Type.Script)
-            return;
+        if (WI.settings.resourceGroupingMode.value === WI.Resource.GroupingMode.Path) {
+            if (!this._mainFrameTreeElement || this._resourcesTreeOutline.findTreeElement(resource))
+                return;
+
+            let origin = null;
+            if (resource.urlComponents.scheme && resource.urlComponents.host) {
+                origin = resource.urlComponents.scheme + "://" + resource.urlComponents.host;
+                if (resource.urlComponents.port)
+                    origin += ":" + resource.urlComponents.port;
+            } else
+                origin = resource.parentFrame.securityOrigin;
+
+            let frameTreeElement = this._originTreeElementMap.get(origin);
+            if (!frameTreeElement) {
+                frameTreeElement = new WI.FolderTreeElement(origin, origin === resource.parentFrame.securityOrigin ? resource.parentFrame : null);
+                this._originTreeElementMap.set(origin, frameTreeElement);
+
+                let index = insertionIndexForObjectInListSortedByFunction(frameTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
+                this._resourcesTreeOutline.insertChild(frameTreeElement, index);
+            }
+
+            let subpath = resource.urlComponents.path;
+            if (subpath && subpath[0] === "/")
+                subpath = subpath.substring(1);
+
+            let parent = frameTreeElement.createFoldersAsNeededForSubpath(subpath);
+            if (resource instanceof WI.CSSStyleSheet)
+                parent.appendChild(new WI.CSSStyleSheetTreeElement(resource));
+            else
+                parent.appendChild(new WI.ResourceTreeElement(resource, resource, {allowDirectoryAsName: true, hideOrigin: true}));
+        }
 
-        this._addBreakpointsForSourceCode(resource);
-        this._addIssuesForSourceCode(resource);
+        if (resource.type === WI.Resource.Type.Document || resource.type === WI.Resource.Type.Script) {
+            this._addBreakpointsForSourceCode(resource);
+            this._addIssuesForSourceCode(resource);
+        }
     }
 
     _addResourcesRecursivelyForFrame(frame)
@@ -642,20 +726,22 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
         if (script.resource || script.dynamicallyAddedScriptElement)
             return;
 
-        let insertIntoTopLevel = false;
-        let parentFolderTreeElement = null;
-
-        if (script.injected) {
-            if (!this._extensionScriptsFolderTreeElement) {
-                let collection = new WI.ScriptCollection;
-                this._extensionScriptsFolderTreeElement = new WI.FolderTreeElement(WI.UIString("Extension Scripts"), collection);
-            }
+        let scriptTreeElement = new WI.ScriptTreeElement(script);
 
-            parentFolderTreeElement = this._extensionScriptsFolderTreeElement;
+        if (!script.injected && WI.SourcesNavigationSidebarPanel.shouldPlaceResourcesAtTopLevel()) {
+            let index = insertionIndexForObjectInListSortedByFunction(scriptTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
+            this._resourcesTreeOutline.insertChild(scriptTreeElement, index);
         } else {
-            if (WI.SourcesNavigationSidebarPanel.shouldPlaceResourcesAtTopLevel())
-                insertIntoTopLevel = true;
-            else {
+            let parentFolderTreeElement = null;
+
+            if (script.injected) {
+                if (!this._extensionScriptsFolderTreeElement) {
+                    let collection = new WI.ScriptCollection;
+                    this._extensionScriptsFolderTreeElement = new WI.FolderTreeElement(WI.UIString("Extension Scripts"), collection);
+                }
+
+                parentFolderTreeElement = this._extensionScriptsFolderTreeElement;
+            } else {
                 if (!this._extraScriptsFolderTreeElement) {
                     let collection = new WI.ScriptCollection;
                     this._extraScriptsFolderTreeElement = new WI.FolderTreeElement(WI.UIString("Extra Scripts"), collection);
@@ -663,19 +749,12 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
 
                 parentFolderTreeElement = this._extraScriptsFolderTreeElement;
             }
-        }
-
-        if (parentFolderTreeElement)
-            parentFolderTreeElement.representedObject.add(script);
 
-        let scriptTreeElement = new WI.ScriptTreeElement(script);
+            if (parentFolderTreeElement)
+                parentFolderTreeElement.representedObject.add(script);
 
-        if (insertIntoTopLevel) {
-            let index = insertionIndexForObjectInListSortedByFunction(scriptTreeElement, this._resourcesTreeOutline.children, this._compareTreeElements);
-            this._resourcesTreeOutline.insertChild(scriptTreeElement, index);
-        } else {
             if (!parentFolderTreeElement.parent) {
-                let index = insertionIndexForObjectInListSortedByFunction(parentFolderTreeElement, this._resourcesTreeOutline.children, this._compareTreeElements);
+                let index = insertionIndexForObjectInListSortedByFunction(parentFolderTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
                 this._resourcesTreeOutline.insertChild(parentFolderTreeElement, index);
             }
 
@@ -693,7 +772,7 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
         let targetTreeElement = new WI.WorkerTreeElement(target);
         this._workerTargetTreeElementMap.set(target, targetTreeElement);
 
-        let index = insertionIndexForObjectInListSortedByFunction(targetTreeElement, this._resourcesTreeOutline.children, this._compareTreeElements);
+        let index = insertionIndexForObjectInListSortedByFunction(targetTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
         this._resourcesTreeOutline.insertChild(targetTreeElement, index);
     }
 
@@ -1258,6 +1337,29 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
         this.updateFilter();
     }
 
+    _handleResourceGroupingModeMouseDown(event)
+    {
+        if (this._ignoreResourceGroupingModeMouseDown)
+            return;
+
+        this._ignoreResourceGroupingModeMouseDown = true;
+
+        let contextMenu = WI.ContextMenu.createFromEvent(event);
+        contextMenu.addBeforeShowCallback(() => {
+            this._ignoreResourceGroupingModeMouseDown = false;
+        });
+
+        function addOption(mode, label) {
+            contextMenu.appendCheckboxItem(label, () => {
+                WI.settings.resourceGroupingMode.value = mode;
+            }, WI.settings.resourceGroupingMode.value === mode);
+        }
+        addOption(WI.Resource.GroupingMode.Path, WI.UIString("Group by Path"));
+        addOption(WI.Resource.GroupingMode.Type, WI.UIString("Group by Type"));
+
+        contextMenu.show();
+    }
+
     _handleTreeSelectionDidChange(event)
     {
         if (!this.selected)
@@ -1277,7 +1379,9 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
             || treeElement instanceof WI.ResourceTreeElement
             || treeElement instanceof WI.ScriptTreeElement
             || treeElement instanceof WI.CSSStyleSheetTreeElement) {
-            WI.showRepresentedObject(treeElement.representedObject);
+            let representedObject = treeElement.representedObject;
+            if (representedObject instanceof WI.Collection || representedObject instanceof WI.SourceCode)
+                WI.showRepresentedObject(representedObject);
             return;
         }
 
@@ -1387,10 +1491,38 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
         contextMenu.show();
     }
 
+    _handleResourceGroupingModeChanged(event)
+    {
+        this._workerTargetTreeElementMap.clear();
+        this._mainFrameTreeElement = null;
+        this._extensionScriptsFolderTreeElement = null;
+        this._extraScriptsFolderTreeElement = null;
+        this._anonymousScriptsFolderTreeElement = null;
+
+        this._originTreeElementMap.clear();
+
+        this._resourcesTreeOutline.removeChildren();
+
+        let mainFrame = WI.networkManager.mainFrame;
+        if (mainFrame) {
+            this._updateMainFrameTreeElement(mainFrame);
+            this._addResourcesRecursivelyForFrame(mainFrame);
+        }
+
+        for (let script of WI.debuggerManager.knownNonResourceScripts) {
+            this._addScript(script);
+
+            if (script.sourceMaps.length && WI.SourcesNavigationSidebarPanel.shouldPlaceResourcesAtTopLevel())
+                this._resourcesTreeOutline.disclosureButtons = true;
+        }
+    }
+
     _handleFrameMainResourceDidChange(event)
     {
-        if (event.target.isMainFrame()) {
-            this._updateMainFrameTreeElement(event.target);
+        let frame = event.target;
+        if (frame.isMainFrame()) {
+            this._updateMainFrameTreeElement(frame);
+            this._addResourcesRecursivelyForFrame(frame);
 
             for (let domBreakpoint of WI.domDebuggerManager.domBreakpoints)
                 this._removeBreakpoint(domBreakpoint);
@@ -1410,7 +1542,9 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
 
     _handleMainFrameDidChange(event)
     {
-        this._updateMainFrameTreeElement(WI.networkManager.mainFrame);
+        let mainFrame = WI.networkManager.mainFrame;
+        this._updateMainFrameTreeElement(mainFrame);
+        this._addResourcesRecursivelyForFrame(mainFrame);
     }
 
     _handleDebuggerBreakpointAdded(event)