Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (243179 => 243180)
--- trunk/Source/WebInspectorUI/ChangeLog 2019-03-19 23:34:03 UTC (rev 243179)
+++ trunk/Source/WebInspectorUI/ChangeLog 2019-03-19 23:35:20 UTC (rev 243180)
@@ -1,5 +1,80 @@
2019-03-19 Devin Rousso <drou...@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 <drou...@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>
Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (243179 => 243180)
--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2019-03-19 23:34:03 UTC (rev 243179)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2019-03-19 23:35:20 UTC (rev 243180)
@@ -511,7 +511,10 @@
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";
Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js (243179 => 243180)
--- trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js 2019-03-19 23:34:03 UTC (rev 243179)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js 2019-03-19 23:35:20 UTC (rev 243180)
@@ -134,7 +134,7 @@
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),
Modified: trunk/Source/WebInspectorUI/UserInterface/Base/URLUtilities.js (243179 => 243180)
--- trunk/Source/WebInspectorUI/UserInterface/Base/URLUtilities.js 2019-03-19 23:34:03 UTC (rev 243179)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/URLUtilities.js 2019-03-19 23:35:20 UTC (rev 243180)
@@ -214,7 +214,7 @@
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 @@
displayName = urlComponents.lastPathComponent;
}
+ if (options.allowDirectoryAsName && (!displayName || urlComponents.path.endsWith(displayName + "/")))
+ displayName = "/";
+
return displayName || WI.displayNameForHost(urlComponents.host) || url;
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js (243179 => 243180)
--- trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js 2019-03-19 23:34:03 UTC (rev 243179)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js 2019-03-19 23:35:20 UTC (rev 243180)
@@ -1181,6 +1181,12 @@
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,
Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorFrontendAPI.js (243179 => 243180)
--- trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorFrontendAPI.js 2019-03-19 23:34:03 UTC (rev 243179)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorFrontendAPI.js 2019-03-19 23:35:20 UTC (rev 243180)
@@ -122,11 +122,7 @@
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()
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DetailsSection.css (243179 => 243180)
--- trunk/Source/WebInspectorUI/UserInterface/Views/DetailsSection.css 2019-03-19 23:34:03 UTC (rev 243179)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DetailsSection.css 2019-03-19 23:35:20 UTC (rev 243180)
@@ -140,7 +140,7 @@
.details-section > .header .go-to-arrow {
width: 10px;
- height: 12px;
+ height: 15px;
-webkit-margin-start: 3px;
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/GeneralTreeElement.js (243179 => 243180)
--- trunk/Source/WebInspectorUI/UserInterface/Views/GeneralTreeElement.js 2019-03-19 23:34:03 UTC (rev 243179)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/GeneralTreeElement.js 2019-03-19 23:35:20 UTC (rev 243180)
@@ -191,6 +191,43 @@
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)
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js (243179 => 243180)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js 2019-03-19 23:34:03 UTC (rev 243179)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js 2019-03-19 23:35:20 UTC (rev 243180)
@@ -88,10 +88,10 @@
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 @@
{
let navigationItems = [this._urlFilterNavigationItem, this._typeFilterScopeBar];
if (WI.MediaInstrument.supported())
- navigationItems.push(this._groupByDOMNodeNavigationItem);
+ navigationItems.push(this._groupMediaRequestsByDOMNodeNavigationItem);
return navigationItems;
}
@@ -643,7 +643,7 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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) {
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTreeElement.js (243179 => 243180)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTreeElement.js 2019-03-19 23:34:03 UTC (rev 243179)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTreeElement.js 2019-03-19 23:35:20 UTC (rev 243180)
@@ -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 @@
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 @@
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 @@
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]);
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTreeElement.js (243179 => 243180)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTreeElement.js 2019-03-19 23:34:03 UTC (rev 243179)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTreeElement.js 2019-03-19 23:35:20 UTC (rev 243180)
@@ -130,43 +130,6 @@
// 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.
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.css (243179 => 243180)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.css 2019-03-19 23:34:03 UTC (rev 243179)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.css 2019-03-19 23:35:20 UTC (rev 243180)
@@ -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;
@@ -82,8 +85,8 @@
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 {
@@ -90,11 +93,16 @@
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;
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js (243179 => 243180)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js 2019-03-19 23:34:03 UTC (rev 243179)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js 2019-03-19 23:35:20 UTC (rev 243180)
@@ -30,6 +30,16 @@
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 @@
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 @@
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 @@
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,24 +301,13 @@
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);
+ this._handleResourceGroupingModeChanged();
- if (script.sourceMaps.length && WI.SourcesNavigationSidebarPanel.shouldPlaceResourcesAtTopLevel())
- this._resourcesTreeOutline.disclosureButtons = true;
- }
-
if (WI.domDebuggerManager.supported) {
if (WI.settings.showAllRequestsBreakpoint.value)
WI.domDebuggerManager.addURLBreakpoint(WI.domDebuggerManager.allRequestsBreakpoint);
@@ -347,6 +356,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
_compareTreeElements(a, b)
{
- // Always sort the main frame element first.
- if (a instanceof WI.FrameTreeElement)
- return -1;
- if (b instanceof WI.FrameTreeElement)
- return 1;
+ 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,
+ ];
- console.assert(a.mainTitle);
- console.assert(b.mainTitle);
+ 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 @@
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 @@
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 @@
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 @@
_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;
- this._addBreakpointsForSourceCode(resource);
- this._addIssuesForSourceCode(resource);
+ 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}));
+ }
+
+ 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 @@
if (script.resource || script.dynamicallyAddedScriptElement)
return;
- let insertIntoTopLevel = false;
- let parentFolderTreeElement = null;
+ let scriptTreeElement = new WI.ScriptTreeElement(script);
- if (script.injected) {
- if (!this._extensionScriptsFolderTreeElement) {
- let collection = new WI.ScriptCollection;
- this._extensionScriptsFolderTreeElement = new WI.FolderTreeElement(WI.UIString("Extension Scripts"), collection);
- }
+ if (!script.injected && WI.SourcesNavigationSidebarPanel.shouldPlaceResourcesAtTopLevel()) {
+ let index = insertionIndexForObjectInListSortedByFunction(scriptTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
+ this._resourcesTreeOutline.insertChild(scriptTreeElement, index);
+ } else {
+ let parentFolderTreeElement = null;
- parentFolderTreeElement = this._extensionScriptsFolderTreeElement;
- } else {
- if (WI.SourcesNavigationSidebarPanel.shouldPlaceResourcesAtTopLevel())
- insertIntoTopLevel = true;
- else {
+ 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 @@
parentFolderTreeElement = this._extraScriptsFolderTreeElement;
}
- }
- if (parentFolderTreeElement)
- parentFolderTreeElement.representedObject.add(script);
+ if (parentFolderTreeElement)
+ parentFolderTreeElement.representedObject.add(script);
- let scriptTreeElement = new WI.ScriptTreeElement(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 @@
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 @@
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 @@
|| 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 @@
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 @@
_handleMainFrameDidChange(event)
{
- this._updateMainFrameTreeElement(WI.networkManager.mainFrame);
+ let mainFrame = WI.networkManager.mainFrame;
+ this._updateMainFrameTreeElement(mainFrame);
+ this._addResourcesRecursivelyForFrame(mainFrame);
}
_handleDebuggerBreakpointAdded(event)