Web Inspector: Sources: allow image collections to be filtered by type
authordrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Mar 2019 21:47:38 +0000 (21:47 +0000)
committerdrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Mar 2019 21:47:38 +0000 (21:47 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195630

Reviewed by Matt Baker.

* UserInterface/Views/ResourceCollectionContentView.js:
(WI.ResourceCollectionContentView):
(WI.ResourceCollectionContentView.prototype.get navigationItems): Added.
(WI.ResourceCollectionContentView.prototype.contentViewAdded):
(WI.ResourceCollectionContentView.prototype.contentViewRemoved): Added.
(WI.ResourceCollectionContentView.prototype._updateImageTypeScopeBar): Added.
(WI.ResourceCollectionContentView.prototype._handleImageTypeSelectionChanged): Added.
* UserInterface/Views/ResourceCollectionContentView.css: Asdded.
(.resource-collection-image-type-scope-bar.default-item-selected):

* UserInterface/Views/CollectionContentView.css:
(.content-view.collection > .content-view[hidden]): Added.

* UserInterface/Views/ScopeBarItem.js:
(WI.ScopeBarItem.prototype.set hidden):
* UserInterface/Views/MultipleScopeBarItem.js:
(WI.MultipleScopeBarItem.prototype.set scopeBarItems):
(WI.MultipleScopeBarItem.prototype.set selectedScopeBarItem):
(WI.MultipleScopeBarItem.prototype.get _visibleScopeBarItems): Added.
(WI.MultipleScopeBarItem.prototype._selectElementSelectionChanged):
(WI.MultipleScopeBarItem.prototype._handleItemHiddenChanged): Added.
Dispatch an event when an item is hidden so that any owner `WI.MultipleScopeBarItem` can
rerender it's <select> without that item.

* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Main.html:

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

Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
Source/WebInspectorUI/UserInterface/Main.html
Source/WebInspectorUI/UserInterface/Views/CollectionContentView.css
Source/WebInspectorUI/UserInterface/Views/MultipleScopeBarItem.js
Source/WebInspectorUI/UserInterface/Views/ResourceCollectionContentView.css [new file with mode: 0644]
Source/WebInspectorUI/UserInterface/Views/ResourceCollectionContentView.js
Source/WebInspectorUI/UserInterface/Views/ScopeBarItem.js

index c6d89e6..c78df69 100644 (file)
@@ -1,3 +1,37 @@
+2019-03-12  Devin Rousso  <drousso@apple.com>
+
+        Web Inspector: Sources: allow image collections to be filtered by type
+        https://bugs.webkit.org/show_bug.cgi?id=195630
+
+        Reviewed by Matt Baker.
+
+        * UserInterface/Views/ResourceCollectionContentView.js:
+        (WI.ResourceCollectionContentView):
+        (WI.ResourceCollectionContentView.prototype.get navigationItems): Added.
+        (WI.ResourceCollectionContentView.prototype.contentViewAdded):
+        (WI.ResourceCollectionContentView.prototype.contentViewRemoved): Added.
+        (WI.ResourceCollectionContentView.prototype._updateImageTypeScopeBar): Added.
+        (WI.ResourceCollectionContentView.prototype._handleImageTypeSelectionChanged): Added.
+        * UserInterface/Views/ResourceCollectionContentView.css: Asdded.
+        (.resource-collection-image-type-scope-bar.default-item-selected):
+
+        * UserInterface/Views/CollectionContentView.css:
+        (.content-view.collection > .content-view[hidden]): Added.
+
+        * UserInterface/Views/ScopeBarItem.js:
+        (WI.ScopeBarItem.prototype.set hidden):
+        * UserInterface/Views/MultipleScopeBarItem.js:
+        (WI.MultipleScopeBarItem.prototype.set scopeBarItems):
+        (WI.MultipleScopeBarItem.prototype.set selectedScopeBarItem):
+        (WI.MultipleScopeBarItem.prototype.get _visibleScopeBarItems): Added.
+        (WI.MultipleScopeBarItem.prototype._selectElementSelectionChanged):
+        (WI.MultipleScopeBarItem.prototype._handleItemHiddenChanged): Added.
+        Dispatch an event when an item is hidden so that any owner `WI.MultipleScopeBarItem` can
+        rerender it's <select> without that item.
+
+        * Localizations/en.lproj/localizedStrings.js:
+        * UserInterface/Main.html:
+
 2019-03-12  Nikita Vasilyev  <nvasilyev@apple.com>
 
         Web Inspector: Keyboard shortcut for settings tab too greedy on non-US keyboards
index c155c3f..6045496 100644 (file)
@@ -148,6 +148,7 @@ localizedStrings["Available Style Sheets"] = "Available Style Sheets";
 localizedStrings["Average CPU: %s"] = "Average CPU: %s";
 localizedStrings["Average Time"] = "Average Time";
 localizedStrings["Average: %s"] = "Average: %s";
+localizedStrings["BMP"] = "BMP";
 localizedStrings["Back (%s)"] = "Back (%s)";
 localizedStrings["Backtrace"] = "Backtrace";
 localizedStrings["Basic"] = "Basic";
@@ -498,6 +499,7 @@ localizedStrings["Full-Screen"] = "Full-Screen";
 localizedStrings["Full-Screen from \u201C%s\u201D"] = "Full-Screen from \u201C%s\u201D";
 localizedStrings["Function"] = "Function";
 localizedStrings["Function Name Variable"] = "Function Name Variable";
+localizedStrings["GIF"] = "GIF";
 localizedStrings["Garbage Collection"] = "Garbage Collection";
 localizedStrings["General"] = "General";
 localizedStrings["Getter"] = "Getter";
@@ -534,6 +536,7 @@ localizedStrings["Hierarchy Level"] = "Hierarchy Level";
 localizedStrings["High"] = "High";
 localizedStrings["Highest: %s"] = "Highest: %s";
 localizedStrings["Host"] = "Host";
+localizedStrings["ICO"] = "ICO";
 localizedStrings["IP"] = "IP";
 localizedStrings["IP Address"] = "IP Address";
 localizedStrings["Identity"] = "Identity";
@@ -568,6 +571,8 @@ localizedStrings["Invalid"] = "Invalid";
 localizedStrings["Invalid characters"] = "Invalid characters";
 localizedStrings["Inverted"] = "Inverted";
 localizedStrings["Invoke getter"] = "Invoke getter";
+localizedStrings["JP2"] = "JP2";
+localizedStrings["JPEG"] = "JPEG";
 localizedStrings["JSON"] = "JSON";
 localizedStrings["JavaScript"] = "JavaScript";
 localizedStrings["JavaScript & Events"] = "JavaScript & Events";
@@ -720,6 +725,8 @@ localizedStrings["Over 1 ms"] = "Over 1 ms";
 localizedStrings["Over 15 ms"] = "Over 15 ms";
 localizedStrings["Overview"] = "Overview";
 localizedStrings["Owns"] = "Owns";
+localizedStrings["PDF"] = "PDF";
+localizedStrings["PNG"] = "PNG";
 localizedStrings["Page"] = "Page";
 localizedStrings["Page Issue"] = "Page Issue";
 localizedStrings["Page navigated at %s"] = "Page navigated at %s";
@@ -851,6 +858,7 @@ localizedStrings["Role"] = "Role";
 localizedStrings["Run %d"] = "Run %d";
 localizedStrings["Run console commands as if inside a user gesture"] = "Run console commands as if inside a user gesture";
 localizedStrings["Running the \u201C%s\u201D audit"] = "Running the \u201C%s\u201D audit";
+localizedStrings["SVG"] = "SVG";
 localizedStrings["Samples"] = "Samples";
 localizedStrings["Save %d"] = "Save %d";
 localizedStrings["Save File"] = "Save File";
@@ -1001,6 +1009,7 @@ localizedStrings["Subject"] = "Subject";
 localizedStrings["Subtree Modified"] = "Subtree Modified";
 localizedStrings["Summary"] = "Summary";
 localizedStrings["TCP"] = "TCP";
+localizedStrings["TIFF"] = "TIFF";
 localizedStrings["Tab width:"] = "Tab width:";
 localizedStrings["Tabs"] = "Tabs";
 localizedStrings["Tag"] = "Tag";
@@ -1118,6 +1127,7 @@ localizedStrings["Watch Expressions"] = "Watch Expressions";
 localizedStrings["Waterfall"] = "Waterfall";
 localizedStrings["Web Inspector"] = "Web Inspector";
 localizedStrings["WebKit Threads"] = "WebKit Threads";
+localizedStrings["WebP"] = "WebP";
 localizedStrings["WebRTC"] = "WebRTC";
 localizedStrings["WebRTC Logging:"] = "WebRTC Logging:";
 localizedStrings["WebSocket Connection Established"] = "WebSocket Connection Established";
@@ -1131,6 +1141,7 @@ localizedStrings["Worker \u2014 %s"] = "Worker \u2014 %s";
 localizedStrings["Worker: %s"] = "Worker: %s";
 localizedStrings["Working Copy"] = "Working Copy";
 localizedStrings["Wrap lines to editor width"] = "Wrap lines to editor width";
+localizedStrings["XBM"] = "XBM";
 localizedStrings["XHR"] = "XHR";
 localizedStrings["XHR Breakpoint\u2026"] = "XHR Breakpoint\u2026";
 localizedStrings["XHRs"] = "XHRs";
index bdf8af6..46131a2 100644 (file)
     <link rel="stylesheet" href="Views/RenderingFrameTimelineOverviewGraph.css">
     <link rel="stylesheet" href="Views/RenderingFrameTimelineView.css">
     <link rel="stylesheet" href="Views/Resizer.css">
+    <link rel="stylesheet" href="Views/ResourceCollectionContentView.css">
     <link rel="stylesheet" href="Views/ResourceCookiesContentView.css">
     <link rel="stylesheet" href="Views/ResourceDetailsSection.css">
     <link rel="stylesheet" href="Views/ResourceDetailsSidebarPanel.css">
index 87bb924..707ee68 100644 (file)
@@ -32,3 +32,7 @@
 .content-view.collection > .content-view {
     flex-grow: 1;
 }
+
+.content-view.collection > .content-view[hidden] {
+    display: none;
+}
index 057622e..04a8b1e 100644 (file)
@@ -82,7 +82,7 @@ WI.MultipleScopeBarItem = class MultipleScopeBarItem extends WI.Object
             return optionElement;
         }
 
-        for (var scopeBarItem of this._scopeBarItems) {
+        for (var scopeBarItem of this._visibleScopeBarItems) {
             if (scopeBarItem.selected && !this._selectedScopeBarItem)
                 this._selectedScopeBarItem = scopeBarItem;
             else if (scopeBarItem.selected) {
@@ -92,6 +92,7 @@ WI.MultipleScopeBarItem = class MultipleScopeBarItem extends WI.Object
             }
 
             scopeBarItem.addEventListener(WI.ScopeBarItem.Event.SelectionChanged, this._itemSelectionDidChange, this);
+            scopeBarItem.addEventListener(WI.ScopeBarItem.Event.HiddenChanged, this._handleItemHiddenChanged, this);
 
             this._selectElement.appendChild(createOption(scopeBarItem));
         }
@@ -130,7 +131,11 @@ WI.MultipleScopeBarItem = class MultipleScopeBarItem extends WI.Object
 
         this._element.classList.toggle("selected", !!selectedScopeBarItem);
         this._selectedScopeBarItem = selectedScopeBarItem || null;
-        this._selectElement.selectedIndex = this._scopeBarItems.indexOf(this._selectedScopeBarItem);
+
+        let selectedIndex = this._visibleScopeBarItems.indexOf(this._selectedScopeBarItem);
+        if (selectedIndex < 0)
+            selectedIndex = 0;
+        this._selectElement.selectedIndex = selectedIndex;
 
         if (this._selectedScopeBarItem) {
             this.displaySelectedItem();
@@ -165,6 +170,11 @@ WI.MultipleScopeBarItem = class MultipleScopeBarItem extends WI.Object
 
     // Private
 
+    get _visibleScopeBarItems()
+    {
+        return this._scopeBarItems.filter((item) => !item.hidden);
+    }
+
     _handleMouseDown(event)
     {
         // Only handle left mouse clicks.
@@ -191,7 +201,7 @@ WI.MultipleScopeBarItem = class MultipleScopeBarItem extends WI.Object
 
     _selectElementSelectionChanged(event)
     {
-        this.selectedScopeBarItem = this._scopeBarItems[this._selectElement.selectedIndex];
+        this.selectedScopeBarItem = this._visibleScopeBarItems[this._selectElement.selectedIndex];
     }
 
     _itemSelectionDidChange(event)
@@ -200,4 +210,10 @@ WI.MultipleScopeBarItem = class MultipleScopeBarItem extends WI.Object
             return;
         this.selectedScopeBarItem = event.target.selected ? event.target : null;
     }
+
+    _handleItemHiddenChanged(event)
+    {
+        // Regenerate the <select> with the new options.
+        this.scopeBarItems = this._scopeBarItems;
+    }
 };
diff --git a/Source/WebInspectorUI/UserInterface/Views/ResourceCollectionContentView.css b/Source/WebInspectorUI/UserInterface/Views/ResourceCollectionContentView.css
new file mode 100644 (file)
index 0000000..3a9a9ae
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.resource-collection-image-type-scope-bar.default-item-selected {
+    --scope-bar-text-color-override: var(--text-color);
+    --scope-bar-background-color-override: transparent;
+    --scope-bar-border-color-override: transparent;
+}
index 9f83719..4c546ae 100644 (file)
@@ -34,6 +34,44 @@ WI.ResourceCollectionContentView = class ResourceCollectionContentView extends W
             contentViewConstructor = WI.ImageResourceContentView;
 
         super(collection, contentViewConstructor);
+
+        if (collection.resourceType === WI.Resource.Type.Image) {
+            let allItem = new WI.ScopeBarItem("all", WI.UIString("All"));
+
+            let items = [allItem];
+            this._scopeBarItemTypeMap = {};
+
+            let addItem = (key, label) => {
+                let item = new WI.ScopeBarItem(key, label);
+                items.push(item);
+                this._scopeBarItemTypeMap[key] = item;
+            };
+            addItem("bmp", WI.UIString("BMP"));
+            addItem("gif", WI.UIString("GIF"));
+            addItem("ico", WI.UIString("ICO"));
+            addItem("jp2", WI.UIString("JP2"));
+            addItem("jpg", WI.UIString("JPEG"));
+            addItem("pdf", WI.UIString("PDF"));
+            addItem("png", WI.UIString("PNG"));
+            addItem("svg", WI.UIString("SVG"));
+            addItem("tiff", WI.UIString("TIFF"));
+            addItem("webp", WI.UIString("WebP"));
+            addItem("xbm", WI.UIString("XBM"));
+
+            const shouldGroupNonExclusiveItems = true;
+            this._imageTypeScopeBar = new WI.ScopeBar("resource-collection-image-type-scope-bar", items, allItem, shouldGroupNonExclusiveItems);
+            this._imageTypeScopeBar.addEventListener(WI.ScopeBar.Event.SelectionChanged, this._handleImageTypeSelectionChanged, this);
+        }
+    }
+
+    // Public
+
+    get navigationItems()
+    {
+        let navigationItems = super.navigationItems;
+        if (this._imageTypeScopeBar)
+            navigationItems.unshift(this._imageTypeScopeBar);
+        return navigationItems;
     }
 
     // Protected
@@ -45,12 +83,46 @@ WI.ResourceCollectionContentView = class ResourceCollectionContentView extends W
         let resource = contentView.representedObject;
         console.assert(resource instanceof WI.Resource);
 
+        this._updateImageTypeScopeBar();
+
         contentView.addEventListener(WI.ResourceContentView.Event.ContentError, this._handleContentError, this);
         contentView.element.title = WI.displayNameForURL(resource.url, resource.urlComponents);
     }
 
+    contentViewRemoved(contentView)
+    {
+        this._updateImageTypeScopeBar();
+    }
+
     // Private
 
+    _updateImageTypeScopeBar()
+    {
+        let extensions = new Set;
+
+        for (let resource of this.representedObject)
+            extensions.add(WI.fileExtensionForMIMEType(resource.mimeType));
+
+        for (let [key, item] of Object.entries(this._scopeBarItemTypeMap)) {
+            let hidden = !extensions.has(key);
+            item.hidden = hidden;
+            if (hidden && item.selected)
+                item.selected = false;
+        }
+    }
+
+    _handleImageTypeSelectionChanged()
+    {
+        let selectedTypes = this._imageTypeScopeBar.selectedItems.map((item) => item.id);
+        let allTypesAllowed = selectedTypes.length === 1 && selectedTypes[0] === "all";
+        for (let view of this.subviews) {
+            let hidden = !allTypesAllowed;
+            if (hidden && view instanceof WI.ResourceContentView)
+                hidden = !selectedTypes.includes(WI.fileExtensionForMIMEType(view.representedObject.mimeType));
+            view.element.hidden = hidden;
+        }
+    }
+
     _handleContentError(event)
     {
         if (event && event.target)
index 64ceb9d..b38bfd5 100644 (file)
@@ -101,6 +101,8 @@ WI.ScopeBarItem = class ScopeBarItem extends WI.Object
         this._hidden = flag;
 
         this._element.classList.toggle("hidden", flag);
+
+        this.dispatchEventToListeners(WI.ScopeBarItem.Event.HiddenChanged);
     }
 
     // Private
@@ -116,5 +118,6 @@ WI.ScopeBarItem = class ScopeBarItem extends WI.Object
 };
 
 WI.ScopeBarItem.Event = {
-    SelectionChanged: "scope-bar-item-selection-did-change"
+    SelectionChanged: "scope-bar-item-selection-changed",
+    HiddenChanged: "scope-bar-item-hidden-changed",
 };