⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 243180 in webkit


Ignore:
Timestamp:
Mar 19, 2019, 4:35:20 PM (7 years ago)
Author:
Devin Rousso
Message:

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.

Location:
trunk/Source/WebInspectorUI
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r243166 r243180  
     12019-03-19  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Sources: provide option to group by path
     4        https://bugs.webkit.org/show_bug.cgi?id=195203
     5        <rdar://problem/27340680>
     6
     7        Reviewed by Timothy Hatcher.
     8
     9        Create top-level folders for each origin and nest all resources (in a folder chain) underneath.
     10
     11        * UserInterface/Views/SourcesNavigationSidebarPanel.js:
     12        (WI.SourcesNavigationSidebarPanel):
     13        (WI.SourcesNavigationSidebarPanel.prototype.closed):
     14        (WI.SourcesNavigationSidebarPanel.prototype.treeElementForRepresentedObject.searchTreeOutline): Added.
     15        (WI.SourcesNavigationSidebarPanel.prototype.treeElementForRepresentedObject):
     16        (WI.SourcesNavigationSidebarPanel.prototype._compareTreeElements):
     17        (WI.SourcesNavigationSidebarPanel.prototype._updateMainFrameTreeElement):
     18        (WI.SourcesNavigationSidebarPanel.prototype._addResource):
     19        (WI.SourcesNavigationSidebarPanel.prototype._addScript):
     20        (WI.SourcesNavigationSidebarPanel.prototype._addWorkerTargetWithMainResource):
     21        (WI.SourcesNavigationSidebarPanel.prototype._handleResourceGroupingModeMouseDown.addOption): Added.
     22        (WI.SourcesNavigationSidebarPanel.prototype._handleResourceGroupingModeMouseDown): Added.
     23        (WI.SourcesNavigationSidebarPanel.prototype._handleTreeSelectionDidChange):
     24        (WI.SourcesNavigationSidebarPanel.prototype._handleResourceGroupingModeChanged):
     25        (WI.SourcesNavigationSidebarPanel.prototype._handleFrameMainResourceDidChange):
     26        (WI.SourcesNavigationSidebarPanel.prototype._handleMainFrameDidChange):
     27        * UserInterface/Views/SourcesNavigationSidebarPanel.css:
     28        (.sidebar > .panel.navigation.sources > .content):
     29        (.sidebar > .panel.navigation.sources > .content > .details-section.paused-reason.collapsed > .header > .options,):
     30        (.sidebar > .panel.navigation.sources > .content > .details-section.breakpoints > .header > .options .create-breakpoint): Added.
     31        (.sidebar > .panel.navigation.sources > .content > .resources): Added.
     32        (.sidebar > .panel.navigation.sources > .content .tree-outline.single-thread): Added.
     33        (.sidebar > .panel.navigation.sources > .content .tree-outline.single-thread > .item.thread): Added.
     34        (.sidebar > .panel.navigation.sources > .content > .details-section.scripts:not(.collapsed)): Deleted.
     35        (.sidebar > .panel.navigation.sources > .content > .tree-outline.single-thread): Deleted.
     36        (.sidebar > .panel.navigation.sources > .content > .tree-outline.single-thread > .item.thread): Deleted.
     37        Drive-by: fix "No Filter Results" message view to not overlap eachother.
     38        Drive-by: try to be more smart about what tree we focus when selecting a represented object.
     39
     40        * UserInterface/Views/ResourceTreeElement.js:
     41        (WI.ResourceTreeElement):
     42        (WI.ResourceTreeElement.prototype.get mainTitleText):
     43        (WI.ResourceTreeElement.prototype._updateTitles):
     44        * UserInterface/Base/URLUtilities.js:
     45        (WI.displayNameForURL):
     46        Provide a way for the display name to use a directory "/" instead of the last path component.
     47        This is needed in cases where the loaded resource is an implicit "index.*".
     48
     49        * UserInterface/Views/GeneralTreeElement.js:
     50        (WI.GeneralTreeElement.prototype.createFoldersAsNeededForSubpath): Added.
     51        * UserInterface/Views/SourceCodeTreeElement.js:
     52        (WI.SourceCodeTreeElement.prototype.createFoldersAsNeededForSubpath): Deleted.
     53
     54        * Localizations/en.lproj/localizedStrings.js:
     55        * UserInterface/Models/Resource.js:
     56
     57        * UserInterface/Views/DetailsSection.css:
     58        (.details-section > .header .go-to-arrow):
     59        Drive-by: vertically center go-to-arrow.
     60
     61        * UserInterface/Protocol/InspectorFrontendAPI.js:
     62        (InspectorFrontendAPI.contextMenuItemSelected):
     63
     64        * UserInterface/Base/Setting.js:
     65        * UserInterface/Views/NetworkTableContentView.js:
     66        (WI.NetworkTableContentView):
     67        (WI.NetworkTableContentView.prototype.get filterNavigationItems):
     68        (WI.NetworkTableContentView.prototype._populateNameCell):
     69        (WI.NetworkTableContentView.prototype._generateSortComparator):
     70        (WI.NetworkTableContentView.prototype._insertResourceAndReloadTable):
     71        (WI.NetworkTableContentView.prototype._updateFilteredEntries):
     72        (WI.NetworkTableContentView.prototype._handleGroupMediaRequestsByDOMNodeCheckedDidChange): Added.
     73        (WI.NetworkTableContentView.prototype._handleGroupByDOMNodeCheckedDidChange): Deleted.
     74        Rename the `groupByNode` setting to be more specific.
     75
    1762019-03-19  Devin Rousso  <drousso@apple.com>
    277
  • trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js

    r243024 r243180  
    512512localizedStrings["Group by Event"] = "Group by Event";
    513513localizedStrings["Group by Node"] = "Group by Node";
     514localizedStrings["Group by Path"] = "Group by Path";
     515localizedStrings["Group by Type"] = "Group by Type";
    514516localizedStrings["Grouping Method"] = "Grouping Method";
     517localizedStrings["Grouping Mode"] = "Grouping Mode";
    515518localizedStrings["HAR Export (%s)"] = "HAR Export (%s)";
    516519localizedStrings["HAR Import"] = "HAR Import";
  • trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js

    r242741 r243180  
    135135    enableControlFlowProfiler: new WI.Setting("enable-control-flow-profiler", false),
    136136    enableLineWrapping: new WI.Setting("enable-line-wrapping", false),
    137     groupByDOMNode: new WI.Setting("group-by-dom-node", false),
     137    groupMediaRequestsByDOMNode: new WI.Setting("group-media-requests-by-dom-node", WI.Setting.migrateValue("group-by-dom-node") || false),
    138138    indentUnit: new WI.Setting("indent-unit", 4),
    139139    indentWithTabs: new WI.Setting("indent-with-tabs", false),
  • trunk/Source/WebInspectorUI/UserInterface/Base/URLUtilities.js

    r223856 r243180  
    215215}
    216216
    217 WI.displayNameForURL = function(url, urlComponents)
     217WI.displayNameForURL = function(url, urlComponents, options = {})
    218218{
    219219    if (url.startsWith("data:"))
     
    229229        displayName = urlComponents.lastPathComponent;
    230230    }
     231
     232    if (options.allowDirectoryAsName && (!displayName || urlComponents.path.endsWith(displayName + "/")))
     233        displayName = "/";
    231234
    232235    return displayName || WI.displayNameForHost(urlComponents.host) || url;
  • trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js

    r243024 r243180  
    11821182};
    11831183
     1184WI.Resource.GroupingMode = {
     1185    Path: "group-resource-by-path",
     1186    Type: "group-resource-by-type",
     1187};
     1188WI.settings.resourceGroupingMode = new WI.Setting("resource-grouping-mode", WI.Resource.GroupingMode.Type);
     1189
    11841190// This MIME Type map is private, use WI.Resource.typeFromMIMEType().
    11851191WI.Resource._mimeTypeMap = {
  • trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorFrontendAPI.js

    r242049 r243180  
    123123    contextMenuItemSelected: function(id)
    124124    {
    125         try {
    126             WI.ContextMenu.contextMenuItemSelected(id);
    127         } catch (e) {
    128             console.error("Uncaught exception in inspector page under contextMenuItemSelected", e);
    129         }
     125        WI.ContextMenu.contextMenuItemSelected(id);
    130126    },
    131127
  • trunk/Source/WebInspectorUI/UserInterface/Views/DetailsSection.css

    r242768 r243180  
    141141.details-section > .header .go-to-arrow {
    142142    width: 10px;
    143     height: 12px;
     143    height: 15px;
    144144    -webkit-margin-start: 3px;
    145145}
  • trunk/Source/WebInspectorUI/UserInterface/Views/GeneralTreeElement.js

    r235095 r243180  
    192192    }
    193193
     194    createFoldersAsNeededForSubpath(subpath)
     195    {
     196        if (!subpath)
     197            return this;
     198
     199        let components = subpath.split("/");
     200        if (components.length === 1)
     201            return this;
     202
     203        if (!this._subpathFolderTreeElementMap)
     204            this._subpathFolderTreeElementMap = new Map;
     205
     206        let currentPath = "";
     207        let currentFolderTreeElement = this;
     208
     209        for (let component of components) {
     210            if (currentPath)
     211                currentPath += "/";
     212            currentPath += component;
     213
     214            let cachedFolder = this._subpathFolderTreeElementMap.get(currentPath);
     215            if (cachedFolder) {
     216                currentFolderTreeElement = cachedFolder;
     217                continue;
     218            }
     219
     220            let newFolder = new WI.FolderTreeElement(component);
     221            this._subpathFolderTreeElementMap.set(currentPath, newFolder);
     222
     223            let index = insertionIndexForObjectInListSortedByFunction(newFolder, currentFolderTreeElement.children, WI.ResourceTreeElement.compareFolderAndResourceTreeElements);
     224            currentFolderTreeElement.insertChild(newFolder, index);
     225            currentFolderTreeElement = newFolder;
     226        }
     227
     228        return currentFolderTreeElement;
     229    }
     230
    194231    // Overrides from TreeElement (Private)
    195232
  • trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js

    r243004 r243180  
    8989
    9090        if (WI.MediaInstrument.supported()) {
    91             this._groupByDOMNodeNavigationItem = new WI.CheckboxNavigationItem("group-by-node", WI.UIString("Group Media Requests"), WI.settings.groupByDOMNode.value);
    92             this._groupByDOMNodeNavigationItem.addEventListener(WI.CheckboxNavigationItem.Event.CheckedDidChange, this._handleGroupByDOMNodeCheckedDidChange, this);
     91            this._groupMediaRequestsByDOMNodeNavigationItem = new WI.CheckboxNavigationItem("group-media-requests", WI.UIString("Group Media Requests"), WI.settings.groupMediaRequestsByDOMNode.value);
     92            this._groupMediaRequestsByDOMNodeNavigationItem.addEventListener(WI.CheckboxNavigationItem.Event.CheckedDidChange, this._handleGroupMediaRequestsByDOMNodeCheckedDidChange, this);
    9393        } else
    94             WI.settings.groupByDOMNode.value = false;
     94            WI.settings.groupMediaRequestsByDOMNode.value = false;
    9595
    9696        this._urlFilterSearchText = null;
     
    247247        let navigationItems = [this._urlFilterNavigationItem, this._typeFilterScopeBar];
    248248        if (WI.MediaInstrument.supported())
    249             navigationItems.push(this._groupByDOMNodeNavigationItem);
     249            navigationItems.push(this._groupMediaRequestsByDOMNodeNavigationItem);
    250250        return navigationItems;
    251251    }
     
    644644        cell.classList.add(WI.ResourceTreeElement.ResourceIconStyleClassName);
    645645
    646         if (WI.settings.groupByDOMNode.value && resource.initiatorNode) {
     646        if (WI.settings.groupMediaRequestsByDOMNode.value && resource.initiatorNode) {
    647647            let nodeEntry = this._domNodeEntries.get(resource.initiatorNode);
    648648            if (nodeEntry.initiatedResourceEntries.length > 1 || nodeEntry.domNode.domEvents.length)
     
    10641064        // next to each other, as they will all effectively be sorted by the first resource.
    10651065        let substitute = (entry, other) => {
    1066             if (WI.settings.groupByDOMNode.value && entry.resource.initiatorNode) {
     1066            if (WI.settings.groupMediaRequestsByDOMNode.value && entry.resource.initiatorNode) {
    10671067                let nodeEntry = this._domNodeEntries.get(entry.resource.initiatorNode);
    10681068                if (!nodeEntry.initiatedResourceEntries.includes(other))
     
    17111711        this._tryLinkResourceToDOMNode(resourceEntry);
    17121712
    1713         if (WI.settings.groupByDOMNode.value && resource.initiatorNode) {
     1713        if (WI.settings.groupMediaRequestsByDOMNode.value && resource.initiatorNode) {
    17141714            if (!this._entriesSortComparator)
    17151715                this._generateSortComparator();
     
    17271727
    17281728        if (this._passFilter(resourceEntry)) {
    1729             if (WI.settings.groupByDOMNode.value)
     1729            if (WI.settings.groupMediaRequestsByDOMNode.value)
    17301730                this._updateFilteredEntries();
    17311731            else
     
    18981898            collection.filteredEntries = collection.entries.slice();
    18991899
    1900         if (WI.settings.groupByDOMNode.value) {
     1900        if (WI.settings.groupMediaRequestsByDOMNode.value) {
    19011901            for (let nodeEntry of this._domNodeEntries.values()) {
    19021902                if (nodeEntry.initiatedResourceEntries.length < 2 && !nodeEntry.domNode.domEvents.length)
     
    20042004    }
    20052005
    2006     _handleGroupByDOMNodeCheckedDidChange(event)
    2007     {
    2008         WI.settings.groupByDOMNode.value = this._groupByDOMNodeNavigationItem.checked;
    2009 
    2010         if (!WI.settings.groupByDOMNode.value) {
     2006    _handleGroupMediaRequestsByDOMNodeCheckedDidChange(event)
     2007    {
     2008        WI.settings.groupMediaRequestsByDOMNode.value = this._groupMediaRequestsByDOMNodeNavigationItem.checked;
     2009
     2010        if (!WI.settings.groupMediaRequestsByDOMNode.value) {
    20112011            this._table.element.classList.remove("grouped");
    20122012
  • trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTreeElement.js

    r236950 r243180  
    2626WI.ResourceTreeElement = class ResourceTreeElement extends WI.SourceCodeTreeElement
    2727{
    28     constructor(resource, representedObject)
     28    constructor(resource, representedObject, {allowDirectoryAsName, hideOrigin} = {})
    2929    {
    3030        console.assert(resource instanceof WI.Resource);
     
    3333        const subtitle = null;
    3434        super(resource, ["resource", WI.ResourceTreeElement.ResourceIconStyleClassName, WI.Resource.classNameForResource(resource)], title, subtitle, representedObject || resource);
     35
     36        if (allowDirectoryAsName)
     37            this._allowDirectoryAsName = allowDirectoryAsName;
     38        if (hideOrigin)
     39            this._hideOrigin = hideOrigin;
    3540
    3641        this._updateResource(resource);
     
    136141    get mainTitleText()
    137142    {
    138         return WI.displayNameForURL(this._resource.url, this._resource.urlComponents);
     143        return WI.displayNameForURL(this._resource.url, this._resource.urlComponents, {
     144            allowDirectoryAsName: this._allowDirectoryAsName,
     145        });
    139146    }
    140147
     
    159166        this.mainTitle = this.mainTitleText;
    160167
    161         // Show the host as the subtitle if it is different from the main resource or if this is the main frame's main resource.
    162         var subtitle = parentResourceHost !== urlComponents.host || frame && frame.isMainFrame() && isMainResource ? WI.displayNameForHost(urlComponents.host) : null;
    163         this.subtitle = this.mainTitle !== subtitle ? subtitle : null;
     168        if (!this._hideOrigin) {
     169            // Show the host as the subtitle if it is different from the main resource or if this is the main frame's main resource.
     170            var subtitle = parentResourceHost !== urlComponents.host || frame && frame.isMainFrame() && isMainResource ? WI.displayNameForHost(urlComponents.host) : null;
     171            this.subtitle = this.mainTitle !== subtitle ? subtitle : null;
     172        }
    164173
    165174        if (oldMainTitle !== this.mainTitle)
  • trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTreeElement.js

    r238859 r243180  
    131131    // Protected
    132132
    133     createFoldersAsNeededForSubpath(subpath)
    134     {
    135         if (!subpath)
    136             return this;
    137 
    138         var components = subpath.split("/");
    139         if (components.length === 1)
    140             return this;
    141 
    142         if (!this._subpathFolderTreeElementMap)
    143             this._subpathFolderTreeElementMap = {};
    144 
    145         var currentPath = "";
    146         var currentFolderTreeElement = this;
    147 
    148         for (var i = 0; i < components.length - 1; ++i) {
    149             var componentName = components[i];
    150             currentPath += (i ? "/" : "") + componentName;
    151 
    152             var cachedFolder = this._subpathFolderTreeElementMap[currentPath];
    153             if (cachedFolder) {
    154                 currentFolderTreeElement = cachedFolder;
    155                 continue;
    156             }
    157 
    158             var newFolder = new WI.FolderTreeElement(componentName);
    159             newFolder.__path = currentPath;
    160             this._subpathFolderTreeElementMap[currentPath] = newFolder;
    161 
    162             var index = insertionIndexForObjectInListSortedByFunction(newFolder, currentFolderTreeElement.children, WI.ResourceTreeElement.compareFolderAndResourceTreeElements);
    163             currentFolderTreeElement.insertChild(newFolder, index);
    164             currentFolderTreeElement = newFolder;
    165         }
    166 
    167         return currentFolderTreeElement;
    168     }
    169 
    170133    descendantResourceTreeElementTypeDidChange(childTreeElement, oldType)
    171134    {
  • trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.css

    r242315 r243180  
    2525
    2626.sidebar > .panel.navigation.sources > .content {
     27    display: flex;
     28    flex-direction: column;
    2729    top: var(--navigation-bar-height);
    2830}
     
    7476
    7577.sidebar > .panel.navigation.sources > .content > .details-section.paused-reason.collapsed > .header > .options,
     78.sidebar > .panel.navigation.sources > .content > .details-section.breakpoints.collapsed > .header > .options,
    7679.sidebar > .panel.navigation.sources > .content > .details-section > .content,
    7780.sidebar > .panel.navigation.sources > .content > .details-section > .content > .group {
     
    8386}
    8487
    85 .sidebar > .panel.navigation.sources > .content > .details-section.scripts:not(.collapsed) {
    86     border-bottom: none;
     88.sidebar > .panel.navigation.sources > .content > .details-section.breakpoints > .header > .options .create-breakpoint {
     89    width: 15px;
    8790}
    8891
     
    9194}
    9295
    93 .sidebar > .panel.navigation.sources > .content > .tree-outline.single-thread {
     96.sidebar > .panel.navigation.sources > .content > .resources {
     97    position: relative;
     98    height: 100%;
     99}
     100
     101.sidebar > .panel.navigation.sources > .content .tree-outline.single-thread {
    94102    -webkit-margin-start: -10px;
    95103}
    96104
    97 .sidebar > .panel.navigation.sources > .content > .tree-outline.single-thread > .item.thread {
     105.sidebar > .panel.navigation.sources > .content .tree-outline.single-thread > .item.thread {
    98106    display: none;
    99107}
  • trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js

    r242937 r243180  
    3131        super("sources", WI.UIString("Sources"), shouldAutoPruneStaleTopLevelResourceTreeElements);
    3232
     33        this._workerTargetTreeElementMap = new Map;
     34        this._mainFrameTreeElement = null;
     35        this._extensionScriptsFolderTreeElement = null;
     36        this._extraScriptsFolderTreeElement = null;
     37        this._anonymousScriptsFolderTreeElement = null;
     38
     39        this._originTreeElementMap = new Map;
     40
     41        this._boundCompareTreeElements = this._compareTreeElements.bind(this);
     42
    3343        this._debuggerNavigationBar = new WI.NavigationBar;
    3444        this.addSubview(this._debuggerNavigationBar);
     
    176186        this.contentView.element.insertBefore(breakpointsSection.element, this.contentView.element.firstChild);
    177187
    178         this._resourcesTreeOutline = this.contentTreeOutline;
    179         this._resourcesTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._handleTreeSelectionDidChange, this);
    180         this._resourcesTreeOutline.includeSourceMapResourceChildren = true;
    181 
    182188        this._resourcesNavigationBar = new WI.NavigationBar;
    183189        this.contentView.addSubview(this._resourcesNavigationBar);
    184         this.contentView.element.insertBefore(this._resourcesNavigationBar.element, this._resourcesTreeOutline.element);
    185 
    186         this._workerTargetTreeElementMap = new Map;
    187         this._extensionScriptsFolderTreeElement = null;
    188         this._extraScriptsFolderTreeElement = null;
    189         this._anonymousScriptsFolderTreeElement = null;
     190        this.contentView.element.insertBefore(this._resourcesNavigationBar.element, breakpointsSection.nextSibling);
     191
     192        this._resourcesNavigationBar.addNavigationItem(new WI.FlexibleSpaceNavigationItem);
    190193
    191194        const resourceTypeScopeItemPrefix = "sources-resource-type-";
     
    203206        this._resourcesNavigationBar.addNavigationItem(this._resourceTypeScopeBar);
    204207
     208        this._resourcesNavigationBar.addNavigationItem(new WI.FlexibleSpaceNavigationItem);
     209
     210        let resourceGroupingModeNavigationItem = new WI.ButtonNavigationItem("grouping-mode", WI.UIString("Grouping Mode"), "Images/Gear.svg", 15, 15);
     211        resourceGroupingModeNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
     212        resourceGroupingModeNavigationItem.element.addEventListener("mousedown", this._handleResourceGroupingModeMouseDown.bind(this));
     213        this._resourcesNavigationBar.addNavigationItem(resourceGroupingModeNavigationItem);
     214
     215        let resourcesContainer = this.contentView.element.insertBefore(document.createElement("div"), this._resourcesNavigationBar.element.nextSibling);
     216        resourcesContainer.classList.add("resources");
     217
     218        this._resourcesTreeOutline = this.contentTreeOutline;
     219        this._resourcesTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._handleTreeSelectionDidChange, this);
     220        this._resourcesTreeOutline.includeSourceMapResourceChildren = true;
     221        resourcesContainer.appendChild(this._resourcesTreeOutline.element);
     222
    205223        let onlyShowResourcesWithIssuesFilterFunction = (treeElement) => {
    206224            if (treeElement.treeOutline !== this._resourcesTreeOutline)
     
    220238        const activatedByDefault = false;
    221239        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);
     240
     241        WI.settings.resourceGroupingMode.addEventListener(WI.Setting.Event.Changed, this._handleResourceGroupingModeChanged, this);
    222242
    223243        WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._handleFrameMainResourceDidChange, this);
     
    282302            WI.debuggerManager.addBreakpoint(WI.debuggerManager.assertionFailuresBreakpoint);
    283303
    284         let mainFrame = WI.networkManager.mainFrame;
    285         if (mainFrame) {
    286             this._updateMainFrameTreeElement(mainFrame);
    287             this._addResourcesRecursivelyForFrame(mainFrame);
    288         }
    289 
    290304        for (let target of WI.targets)
    291305            this._addTarget(target);
     
    293307        this._updateCallStackTreeOutline();
    294308
    295         for (let script of WI.debuggerManager.knownNonResourceScripts) {
    296             this._addScript(script);
    297 
    298             if (script.sourceMaps.length && WI.SourcesNavigationSidebarPanel.shouldPlaceResourcesAtTopLevel())
    299                 this._resourcesTreeOutline.disclosureButtons = true;
    300         }
     309        this._handleResourceGroupingModeChanged();
    301310
    302311        if (WI.domDebuggerManager.supported) {
     
    348357    closed()
    349358    {
     359        WI.settings.resourceGroupingMode.removeEventListener(null, null, this);
    350360        WI.Frame.removeEventListener(null, null, this);
    351361        WI.Target.removeEventListener(null, null, this);
     
    388398        }
    389399
    390         // The Frame is used as the representedObject instead of the main resource in our tree.
    391400        if (representedObject instanceof WI.Resource && representedObject.parentFrame && representedObject.parentFrame.mainResource === representedObject)
    392401            representedObject = representedObject.parentFrame;
     
    418427        }
    419428
    420         let treeElement = this._resourcesTreeOutline.findTreeElement(representedObject, isAncestor, getParent);
     429        function searchTreeOutline(treeOutline, forceSearch) {
     430            if (!treeOutline || (!treeOutline.selectedTreeElement && !forceSearch))
     431                return null;
     432            return treeOutline.findTreeElement(representedObject, isAncestor, getParent);
     433        }
     434        let treeElement = searchTreeOutline(this._pauseReasonTreeOutline) || searchTreeOutline(this._callStackTreeOutline) || searchTreeOutline(this._breakpointsTreeOutline) || searchTreeOutline(this._resourcesTreeOutline, true);
    421435        if (treeElement)
    422436            return treeElement;
     
    442456
    443457        if (!this._anonymousScriptsFolderTreeElement.parent) {
    444             let index = insertionIndexForObjectInListSortedByFunction(this._anonymousScriptsFolderTreeElement, this._resourcesTreeOutline.children, this._compareTreeElements);
     458            let index = insertionIndexForObjectInListSortedByFunction(this._anonymousScriptsFolderTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
    445459            this._resourcesTreeOutline.insertChild(this._anonymousScriptsFolderTreeElement, index);
    446460        }
     
    485499        if (treeElement instanceof WI.FolderTreeElement)
    486500            return false;
     501
     502        if (treeElement instanceof WI.IssueTreeElement)
     503            treeElement = treeElement.parent;
    487504
    488505        function match()
     
    528545    _compareTreeElements(a, b)
    529546    {
    530         // Always sort the main frame element first.
    531         if (a instanceof WI.FrameTreeElement)
    532             return -1;
    533         if (b instanceof WI.FrameTreeElement)
    534             return 1;
    535 
    536         console.assert(a.mainTitle);
    537         console.assert(b.mainTitle);
    538 
    539         return (a.mainTitle || "").extendedLocaleCompare(b.mainTitle || "");
     547        const rankFunctions = [
     548            (treeElement) => treeElement === this._mainFrameTreeElement,
     549            (treeElement) => treeElement instanceof WI.FrameTreeElement,
     550            (treeElement) => {
     551                return treeElement instanceof WI.FolderTreeElement
     552                    && treeElement !== this._extensionScriptsFolderTreeElement
     553                    && treeElement !== this._extraScriptsFolderTreeElement
     554                    && treeElement !== this._anonymousScriptsFolderTreeElement;
     555            },
     556            (treeElement) => treeElement === this._extensionScriptsFolderTreeElement,
     557            (treeElement) => treeElement === this._extraScriptsFolderTreeElement,
     558            (treeElement) => treeElement === this._anonymousScriptsFolderTreeElement,
     559        ];
     560
     561        let aRank = rankFunctions.findIndex((rankFunction) => rankFunction(a));
     562        let bRank = rankFunctions.findIndex((rankFunction) => rankFunction(b));
     563        if (aRank >= 0 && bRank >= 0) {
     564            if (aRank < bRank)
     565                return -1;
     566            if (bRank < aRank)
     567                return 1;
     568        }
     569
     570        return a.mainTitle.extendedLocaleCompare(b.mainTitle) || a.subtitle.extendedLocaleCompare(b.subtitle);
    540571    }
    541572
     
    545576            this.contentBrowser.contentViewContainer.closeAllContentViews();
    546577
     578        let oldMainFrameTreeElement = this._mainFrameTreeElement;
    547579        if (this._mainFrameTreeElement) {
    548580            this._resourcesTreeOutline.removeChild(this._mainFrameTreeElement);
     
    553585            return;
    554586
    555         this._mainFrameTreeElement = new WI.FrameTreeElement(mainFrame);
     587        let resourceGroupingMode = WI.settings.resourceGroupingMode.value;
     588        switch (resourceGroupingMode) {
     589        case WI.Resource.GroupingMode.Path:
     590            for (let treeElement of this._originTreeElementMap.values()) {
     591                if (treeElement !== oldMainFrameTreeElement)
     592                    this._resourcesTreeOutline.removeChild(treeElement);
     593            }
     594            this._originTreeElementMap.clear();
     595
     596            this._mainFrameTreeElement = new WI.FolderTreeElement(mainFrame.securityOrigin, mainFrame);
     597            this._originTreeElementMap.set(mainFrame.securityOrigin, this._mainFrameTreeElement);
     598            break;
     599
     600        default:
     601            WI.reportInternalError("Unknown resource grouping mode", {"Resource Grouping Mode": WI.settings.resourceGroupingMode.value});
     602            // Fallthrough for default value.
     603
     604        case WI.Resource.GroupingMode.Type:
     605            this._mainFrameTreeElement = new WI.FrameTreeElement(mainFrame);
     606            break;
     607        }
     608
    556609        this._resourcesTreeOutline.insertChild(this._mainFrameTreeElement, 0);
    557610
     
    565618            let treeElement = currentContentView ? this.treeElementForRepresentedObject(currentContentView.representedObject) : null;
    566619            if (!treeElement)
    567                 treeElement = this._mainFrameTreeElement;
     620                treeElement = this.treeElementForRepresentedObject(WI.networkManager.mainFrame);
    568621            this.showDefaultContentViewForTreeElement(treeElement);
    569622        });
     
    601654    _addResource(resource)
    602655    {
    603         if (resource.type !== WI.Resource.Type.Document && resource.type !== WI.Resource.Type.Script)
    604             return;
    605 
    606         this._addBreakpointsForSourceCode(resource);
    607         this._addIssuesForSourceCode(resource);
     656        if (WI.settings.resourceGroupingMode.value === WI.Resource.GroupingMode.Path) {
     657            if (!this._mainFrameTreeElement || this._resourcesTreeOutline.findTreeElement(resource))
     658                return;
     659
     660            let origin = null;
     661            if (resource.urlComponents.scheme && resource.urlComponents.host) {
     662                origin = resource.urlComponents.scheme + "://" + resource.urlComponents.host;
     663                if (resource.urlComponents.port)
     664                    origin += ":" + resource.urlComponents.port;
     665            } else
     666                origin = resource.parentFrame.securityOrigin;
     667
     668            let frameTreeElement = this._originTreeElementMap.get(origin);
     669            if (!frameTreeElement) {
     670                frameTreeElement = new WI.FolderTreeElement(origin, origin === resource.parentFrame.securityOrigin ? resource.parentFrame : null);
     671                this._originTreeElementMap.set(origin, frameTreeElement);
     672
     673                let index = insertionIndexForObjectInListSortedByFunction(frameTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
     674                this._resourcesTreeOutline.insertChild(frameTreeElement, index);
     675            }
     676
     677            let subpath = resource.urlComponents.path;
     678            if (subpath && subpath[0] === "/")
     679                subpath = subpath.substring(1);
     680
     681            let parent = frameTreeElement.createFoldersAsNeededForSubpath(subpath);
     682            if (resource instanceof WI.CSSStyleSheet)
     683                parent.appendChild(new WI.CSSStyleSheetTreeElement(resource));
     684            else
     685                parent.appendChild(new WI.ResourceTreeElement(resource, resource, {allowDirectoryAsName: true, hideOrigin: true}));
     686        }
     687
     688        if (resource.type === WI.Resource.Type.Document || resource.type === WI.Resource.Type.Script) {
     689            this._addBreakpointsForSourceCode(resource);
     690            this._addIssuesForSourceCode(resource);
     691        }
    608692    }
    609693
     
    643727            return;
    644728
    645         let insertIntoTopLevel = false;
    646         let parentFolderTreeElement = null;
    647 
    648         if (script.injected) {
    649             if (!this._extensionScriptsFolderTreeElement) {
    650                 let collection = new WI.ScriptCollection;
    651                 this._extensionScriptsFolderTreeElement = new WI.FolderTreeElement(WI.UIString("Extension Scripts"), collection);
    652             }
    653 
    654             parentFolderTreeElement = this._extensionScriptsFolderTreeElement;
     729        let scriptTreeElement = new WI.ScriptTreeElement(script);
     730
     731        if (!script.injected && WI.SourcesNavigationSidebarPanel.shouldPlaceResourcesAtTopLevel()) {
     732            let index = insertionIndexForObjectInListSortedByFunction(scriptTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
     733            this._resourcesTreeOutline.insertChild(scriptTreeElement, index);
    655734        } else {
    656             if (WI.SourcesNavigationSidebarPanel.shouldPlaceResourcesAtTopLevel())
    657                 insertIntoTopLevel = true;
    658             else {
     735            let parentFolderTreeElement = null;
     736
     737            if (script.injected) {
     738                if (!this._extensionScriptsFolderTreeElement) {
     739                    let collection = new WI.ScriptCollection;
     740                    this._extensionScriptsFolderTreeElement = new WI.FolderTreeElement(WI.UIString("Extension Scripts"), collection);
     741                }
     742
     743                parentFolderTreeElement = this._extensionScriptsFolderTreeElement;
     744            } else {
    659745                if (!this._extraScriptsFolderTreeElement) {
    660746                    let collection = new WI.ScriptCollection;
     
    664750                parentFolderTreeElement = this._extraScriptsFolderTreeElement;
    665751            }
    666         }
    667 
    668         if (parentFolderTreeElement)
    669             parentFolderTreeElement.representedObject.add(script);
    670 
    671         let scriptTreeElement = new WI.ScriptTreeElement(script);
    672 
    673         if (insertIntoTopLevel) {
    674             let index = insertionIndexForObjectInListSortedByFunction(scriptTreeElement, this._resourcesTreeOutline.children, this._compareTreeElements);
    675             this._resourcesTreeOutline.insertChild(scriptTreeElement, index);
    676         } else {
     752
     753            if (parentFolderTreeElement)
     754                parentFolderTreeElement.representedObject.add(script);
     755
    677756            if (!parentFolderTreeElement.parent) {
    678                 let index = insertionIndexForObjectInListSortedByFunction(parentFolderTreeElement, this._resourcesTreeOutline.children, this._compareTreeElements);
     757                let index = insertionIndexForObjectInListSortedByFunction(parentFolderTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
    679758                this._resourcesTreeOutline.insertChild(parentFolderTreeElement, index);
    680759            }
     
    694773        this._workerTargetTreeElementMap.set(target, targetTreeElement);
    695774
    696         let index = insertionIndexForObjectInListSortedByFunction(targetTreeElement, this._resourcesTreeOutline.children, this._compareTreeElements);
     775        let index = insertionIndexForObjectInListSortedByFunction(targetTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
    697776        this._resourcesTreeOutline.insertChild(targetTreeElement, index);
    698777    }
     
    12591338    }
    12601339
     1340    _handleResourceGroupingModeMouseDown(event)
     1341    {
     1342        if (this._ignoreResourceGroupingModeMouseDown)
     1343            return;
     1344
     1345        this._ignoreResourceGroupingModeMouseDown = true;
     1346
     1347        let contextMenu = WI.ContextMenu.createFromEvent(event);
     1348        contextMenu.addBeforeShowCallback(() => {
     1349            this._ignoreResourceGroupingModeMouseDown = false;
     1350        });
     1351
     1352        function addOption(mode, label) {
     1353            contextMenu.appendCheckboxItem(label, () => {
     1354                WI.settings.resourceGroupingMode.value = mode;
     1355            }, WI.settings.resourceGroupingMode.value === mode);
     1356        }
     1357        addOption(WI.Resource.GroupingMode.Path, WI.UIString("Group by Path"));
     1358        addOption(WI.Resource.GroupingMode.Type, WI.UIString("Group by Type"));
     1359
     1360        contextMenu.show();
     1361    }
     1362
    12611363    _handleTreeSelectionDidChange(event)
    12621364    {
     
    12781380            || treeElement instanceof WI.ScriptTreeElement
    12791381            || treeElement instanceof WI.CSSStyleSheetTreeElement) {
    1280             WI.showRepresentedObject(treeElement.representedObject);
     1382            let representedObject = treeElement.representedObject;
     1383            if (representedObject instanceof WI.Collection || representedObject instanceof WI.SourceCode)
     1384                WI.showRepresentedObject(representedObject);
    12811385            return;
    12821386        }
     
    13881492    }
    13891493
     1494    _handleResourceGroupingModeChanged(event)
     1495    {
     1496        this._workerTargetTreeElementMap.clear();
     1497        this._mainFrameTreeElement = null;
     1498        this._extensionScriptsFolderTreeElement = null;
     1499        this._extraScriptsFolderTreeElement = null;
     1500        this._anonymousScriptsFolderTreeElement = null;
     1501
     1502        this._originTreeElementMap.clear();
     1503
     1504        this._resourcesTreeOutline.removeChildren();
     1505
     1506        let mainFrame = WI.networkManager.mainFrame;
     1507        if (mainFrame) {
     1508            this._updateMainFrameTreeElement(mainFrame);
     1509            this._addResourcesRecursivelyForFrame(mainFrame);
     1510        }
     1511
     1512        for (let script of WI.debuggerManager.knownNonResourceScripts) {
     1513            this._addScript(script);
     1514
     1515            if (script.sourceMaps.length && WI.SourcesNavigationSidebarPanel.shouldPlaceResourcesAtTopLevel())
     1516                this._resourcesTreeOutline.disclosureButtons = true;
     1517        }
     1518    }
     1519
    13901520    _handleFrameMainResourceDidChange(event)
    13911521    {
    1392         if (event.target.isMainFrame()) {
    1393             this._updateMainFrameTreeElement(event.target);
     1522        let frame = event.target;
     1523        if (frame.isMainFrame()) {
     1524            this._updateMainFrameTreeElement(frame);
     1525            this._addResourcesRecursivelyForFrame(frame);
    13941526
    13951527            for (let domBreakpoint of WI.domDebuggerManager.domBreakpoints)
     
    14111543    _handleMainFrameDidChange(event)
    14121544    {
    1413         this._updateMainFrameTreeElement(WI.networkManager.mainFrame);
     1545        let mainFrame = WI.networkManager.mainFrame;
     1546        this._updateMainFrameTreeElement(mainFrame);
     1547        this._addResourcesRecursivelyForFrame(mainFrame);
    14141548    }
    14151549
Note: See TracChangeset for help on using the changeset viewer.