Changeset 222573 in webkit


Ignore:
Timestamp:
Sep 27, 2017 1:41:03 PM (7 years ago)
Author:
Matt Baker
Message:

Web Inspector: Create ResourceCollectionContentView and make CollectionContentView easier to extend
https://bugs.webkit.org/show_bug.cgi?id=177419

Reviewed by Devin Rousso.

CollectionContentView should be generic, work with any represented object
Collection, and not perform any type checking. It should just map items
to ContentViews using the provided ContentView constructor.

The behavior when clicking a ContentView in the collection has been extended.
If selection is enabled, clicking a ContentView will cause a "selected" class
to be applied to its element, and a SupplementalRepresentedObjectsDidChange
event is dispatched.

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

New file, move CollectionContentView above subclasses.

  • UserInterface/Models/ResourceCollection.js:

(WI.ResourceCollection.prototype.get resourceType):
Make resource type publicly available.

  • UserInterface/Views/CollectionContentView.js:

Move type checking of the collection out of the base class and assert
that ContentViews are created when invoking contentViewConstructor.
(WI.CollectionContentView):
(WI.CollectionContentView.titleForCollection):
(WI.CollectionContentView.prototype.get supplementalRepresentedObjects):
(WI.CollectionContentView.prototype.get selectionEnabled):
(WI.CollectionContentView.prototype.set selectionEnabled):
(WI.CollectionContentView.prototype.addContentViewForItem):
(WI.CollectionContentView.prototype.removeContentViewForItem):
(WI.CollectionContentView.prototype.contentViewAdded):
(WI.CollectionContentView.prototype.contentViewRemoved):
(WI.CollectionContentView.prototype.initialLayout):
(WI.CollectionContentView.prototype.attached):
(WI.CollectionContentView.prototype.detached):
(WI.CollectionContentView.prototype._handleItemAdded):
(WI.CollectionContentView.prototype._handleItemRemoved):
(WI.CollectionContentView.prototype._selectItem):
(WI.CollectionContentView.prototype._addContentViewForItem): Deleted.
(WI.CollectionContentView.prototype._removeContentViewForItem): Deleted.

  • UserInterface/Views/ContentView.js:

(WI.ContentView.createFromRepresentedObject):
Create a ResourceCollectionContentView. In the future, additional
Collection types can be mapped to their associated CollectionContentView.

  • UserInterface/Views/ResourceCollectionContentView.js: Added.

New class for resource-specific logic previously in CollectionContentView.
(WI.ResourceCollectionContentView):
(WI.ResourceCollectionContentView.prototype.contentViewAdded):
(WI.ResourceCollectionContentView.prototype._handleContentError):
Remove ContentView without removing the resource from its collection.

Location:
trunk/Source/WebInspectorUI
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r222566 r222573  
     12017-09-27  Matt Baker  <mattbaker@apple.com>
     2
     3        Web Inspector: Create ResourceCollectionContentView and make CollectionContentView easier to extend
     4        https://bugs.webkit.org/show_bug.cgi?id=177419
     5
     6        Reviewed by Devin Rousso.
     7
     8        CollectionContentView should be generic, work with any represented object
     9        Collection, and not perform any type checking. It should just map items
     10        to ContentViews using the provided ContentView constructor.
     11
     12        The behavior when clicking a ContentView in the collection has been extended.
     13        If selection is enabled, clicking a ContentView will cause a "selected" class
     14        to be applied to its element, and a SupplementalRepresentedObjectsDidChange
     15        event is dispatched.
     16
     17        * Localizations/en.lproj/localizedStrings.js:
     18        * UserInterface/Main.html:
     19        New file, move CollectionContentView above subclasses.
     20
     21        * UserInterface/Models/ResourceCollection.js:
     22        (WI.ResourceCollection.prototype.get resourceType):
     23        Make resource type publicly available.
     24
     25        * UserInterface/Views/CollectionContentView.js:
     26        Move type checking of the collection out of the base class and assert
     27        that ContentViews are created when invoking `contentViewConstructor`.
     28        (WI.CollectionContentView):
     29        (WI.CollectionContentView.titleForCollection):
     30        (WI.CollectionContentView.prototype.get supplementalRepresentedObjects):
     31        (WI.CollectionContentView.prototype.get selectionEnabled):
     32        (WI.CollectionContentView.prototype.set selectionEnabled):
     33        (WI.CollectionContentView.prototype.addContentViewForItem):
     34        (WI.CollectionContentView.prototype.removeContentViewForItem):
     35        (WI.CollectionContentView.prototype.contentViewAdded):
     36        (WI.CollectionContentView.prototype.contentViewRemoved):
     37        (WI.CollectionContentView.prototype.initialLayout):
     38        (WI.CollectionContentView.prototype.attached):
     39        (WI.CollectionContentView.prototype.detached):
     40        (WI.CollectionContentView.prototype._handleItemAdded):
     41        (WI.CollectionContentView.prototype._handleItemRemoved):
     42        (WI.CollectionContentView.prototype._selectItem):
     43        (WI.CollectionContentView.prototype._addContentViewForItem): Deleted.
     44        (WI.CollectionContentView.prototype._removeContentViewForItem): Deleted.
     45
     46        * UserInterface/Views/ContentView.js:
     47        (WI.ContentView.createFromRepresentedObject):
     48        Create a ResourceCollectionContentView. In the future, additional
     49        Collection types can be mapped to their associated CollectionContentView.
     50
     51        * UserInterface/Views/ResourceCollectionContentView.js: Added.
     52        New class for resource-specific logic previously in CollectionContentView.
     53        (WI.ResourceCollectionContentView):
     54        (WI.ResourceCollectionContentView.prototype.contentViewAdded):
     55        (WI.ResourceCollectionContentView.prototype._handleContentError):
     56        Remove ContentView without removing the resource from its collection.
     57
    1582017-09-27  Ross Kirsling  <ross.kirsling@sony.com>
    259
  • trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js

    r222470 r222573  
    205205localizedStrings["Collapse columns"] = "Collapse columns";
    206206localizedStrings["Collect garbage"] = "Collect garbage";
     207localizedStrings["Collection"] = "Collection";
    207208localizedStrings["Color"] = "Color";
    208209localizedStrings["Comment"] = "Comment";
  • trunk/Source/WebInspectorUI/UserInterface/Main.html

    r222475 r222573  
    523523    <script src="Views/SettingsView.js"></script>
    524524
     525    <script src="Views/CollectionContentView.js"></script>
     526
    525527    <script src="Views/ActivateButtonNavigationItem.js"></script>
    526528    <script src="Views/ActivateButtonToolbarItem.js"></script>
     
    551553    <script src="Views/CodeMirrorRegexMode.js"></script>
    552554    <script src="Views/CodeMirrorTextMarkers.js"></script>
    553     <script src="Views/CollectionContentView.js"></script>
    554555    <script src="Views/ColorPicker.js"></script>
    555556    <script src="Views/ColorWheel.js"></script>
     
    683684    <script src="Views/Resizer.js"></script>
    684685    <script src="Views/ResourceClusterContentView.js"></script>
     686    <script src="Views/ResourceCollectionContentView.js"></script>
    685687    <script src="Views/ResourceDetailsSidebarPanel.js"></script>
    686688    <script src="Views/ResourceSidebarPanel.js"></script>
  • trunk/Source/WebInspectorUI/UserInterface/Models/ResourceCollection.js

    r221748 r222573  
    6565    // Public
    6666
     67    get resourceType() { return this._resourceType; }
     68
    6769    resourceForURL(url)
    6870    {
  • trunk/Source/WebInspectorUI/UserInterface/Views/CollectionContentView.js

    r222356 r222573  
    2626WI.CollectionContentView = class CollectionContentView extends WI.ContentView
    2727{
    28     constructor(collection)
     28    constructor(collection, contentViewConstructor, contentPlaceholderText)
    2929    {
    3030        console.assert(collection instanceof WI.Collection);
     
    3232        super(collection);
    3333
    34         this.representedObject.addEventListener(WI.Collection.Event.ItemAdded, this._handleItemAdded, this);
    35         this.representedObject.addEventListener(WI.Collection.Event.ItemRemoved, this._handleItemRemoved, this);
    36 
    37         this._contentViewMap = new WeakMap;
     34        this.element.classList.add("collection");
     35
     36        this._contentPlaceholder = new WI.TitleView(contentPlaceholderText || WI.CollectionContentView.titleForCollection(collection));
     37        this._contentViewConstructor = contentViewConstructor;
     38        this._contentViewMap = new Map;
    3839        this._handleClickMap = new WeakMap;
    39 
    40         this._contentViewConstructor = null;
    41         let title = "";
    42         switch (this.representedObject.typeVerifier) {
     40        this._selectedItem = null;
     41        this._selectionEnabled = false;
     42    }
     43
     44    static titleForCollection(collection)
     45    {
     46        switch (collection.typeVerifier) {
    4347        case WI.Collection.TypeVerifier.Frame:
    44             title = WI.UIString("Frames");
    45             break;
    46 
     48            return WI.UIString("Frames");
     49        case WI.Collection.TypeVerifier.Resource:
     50            return WI.UIString("Resources");
    4751        case WI.Collection.TypeVerifier.Script:
    48             title = WI.UIString("Extra Scripts");
    49             break;
    50 
    51         case WI.Collection.TypeVerifier.Resource:
    52             title = WI.UIString("Resource");
    53             break;
    54 
    55         case WI.ResourceCollection.TypeVerifier.Document:
    56             title = WI.Resource.displayNameForType(WI.Resource.Type.Document, true);
    57             break;
    58 
    59         case WI.ResourceCollection.TypeVerifier.Stylesheet:
    60             title = WI.Resource.displayNameForType(WI.Resource.Type.Stylesheet, true);
    61             break;
    62 
    63         case WI.ResourceCollection.TypeVerifier.Image:
    64             this._contentViewConstructor = WI.ImageResourceContentView;
    65             title = WI.Resource.displayNameForType(WI.Resource.Type.Image, true);
    66             break;
    67 
    68         case WI.ResourceCollection.TypeVerifier.Font:
    69             title = WI.Resource.displayNameForType(WI.Resource.Type.Font, true);
    70             break;
    71 
    72         case WI.ResourceCollection.TypeVerifier.Script:
    73             title = WI.Resource.displayNameForType(WI.Resource.Type.Script, true);
    74             break;
    75 
    76         case WI.ResourceCollection.TypeVerifier.XHR:
    77             title = WI.Resource.displayNameForType(WI.Resource.Type.XHR, true);
    78             break;
    79 
    80         case WI.ResourceCollection.TypeVerifier.Fetch:
    81             title = WI.Resource.displayNameForType(WI.Resource.Type.Fetch, true);
    82             break;
    83 
    84         case WI.ResourceCollection.TypeVerifier.WebSocket:
    85             title = WI.Resource.displayNameForType(WI.Resource.Type.WebSocket, true);
    86             break;
    87 
    88         case WI.ResourceCollection.TypeVerifier.Other:
    89             title = WI.Resource.displayNameForType(WI.Resource.Type.Other, true);
    90             break;
    91         }
    92 
    93         this._contentPlaceholder = new WI.TitleView(title);
    94 
    95         this.element.classList.add("collection");
    96     }
    97 
    98      // Public
    99 
    100     initialLayout()
    101     {
    102         let items = this.representedObject.items;
    103         if (this._contentViewConstructor && items.size) {
    104             for (let item of items)
    105                 this._addContentViewForItem(item);
    106         } else
    107             this.addSubview(this._contentPlaceholder);
    108     }
    109 
    110      // Private
    111 
    112     _addContentViewForItem(item)
     52            return WI.UIString("Scripts");
     53        case WI.Collection.TypeVerifier.CSSStyleSheet:
     54            return WI.UIString("Stylesheets");
     55        case WI.Collection.TypeVerifier.Canvas:
     56            return WI.UIString("Canvases");
     57        case WI.Collection.TypeVerifier.ShaderProgram:
     58            return WI.UIString("Shader Programs");
     59        }
     60
     61        console.warn("No default title for Collection type verifier.", collection.typeVerifier);
     62        return WI.UIString("Collection");
     63    }
     64
     65    // Public
     66
     67    get supplementalRepresentedObjects()
     68    {
     69        if (this._selectedItem)
     70            return [this._selectedItem];
     71        return [];
     72    }
     73
     74    get selectionEnabled()
     75    {
     76        return this._selectionEnabled;
     77    }
     78
     79    set selectionEnabled(value)
     80    {
     81        if (this._selectionEnabled === value)
     82            return;
     83
     84        this._selectionEnabled = value;
     85        if (!this._selectionEnabled)
     86            this._selectItem(null);
     87    }
     88
     89    // Protected
     90
     91    addContentViewForItem(item)
    11392    {
    11493        if (!this._contentViewConstructor)
    11594            return;
     95
     96        if (this._contentViewMap.has(item)) {
     97            console.assert(false, "Already added ContentView for item.", item);
     98            return;
     99        }
    116100
    117101        if (this._contentPlaceholder.parentView)
     
    119103
    120104        let contentView = new this._contentViewConstructor(item);
    121 
    122         contentView.addEventListener(WI.ResourceContentView.Event.ContentError, this._handleContentError, this);
     105        console.assert(contentView instanceof WI.ContentView);
    123106
    124107        let handleClick = (event) => {
     
    126109                return;
    127110
    128             WI.showRepresentedObject(item);
     111            if (this._selectionEnabled)
     112                this._selectItem(item);
     113            else
     114                WI.showRepresentedObject(item);
    129115        };
     116
     117        this._contentViewMap.set(item, contentView);
    130118        this._handleClickMap.set(item, handleClick);
    131119        contentView.element.addEventListener("click", handleClick);
    132120
    133         contentView.element.title = WI.displayNameForURL(item.url, item.urlComponents);
    134 
    135121        this.addSubview(contentView);
    136         this._contentViewMap.set(item, contentView);
    137     }
    138 
    139     _removeContentViewForItem(item)
     122        this.contentViewAdded(contentView);
     123    }
     124
     125    removeContentViewForItem(item)
    140126    {
    141127        if (!this._contentViewConstructor)
     
    149135        this.removeSubview(contentView);
    150136        this._contentViewMap.delete(item);
     137        this.contentViewRemoved(contentView);
    151138
    152139        contentView.removeEventListener(null, null, this);
     
    154141        let handleClick = this._handleClickMap.get(item);
    155142        console.assert(handleClick);
     143
    156144        if (handleClick) {
    157145            contentView.element.removeEventListener("click", handleClick);
     
    159147        }
    160148
    161         if (!this.representedObject.resources.length)
     149        if (this._selectedItem === item)
     150            this._selectItem(null);
     151
     152        if (!this.subviews.length)
    162153            this.addSubview(this._contentPlaceholder);
    163154    }
     155
     156    contentViewAdded(contentView)
     157    {
     158        // Implemented by subclasses.
     159    }
     160
     161    contentViewRemoved(contentView)
     162    {
     163        // Implemented by subclasses.
     164    }
     165
     166    initialLayout()
     167    {
     168        let items = this.representedObject.items;
     169        if (!items.size || !this._contentViewConstructor) {
     170            this.addSubview(this._contentPlaceholder);
     171            return;
     172        }
     173
     174        for (let item of items)
     175            this.addContentViewForItem(item);
     176    }
     177
     178    attached()
     179    {
     180        super.attached();
     181
     182        this.representedObject.addEventListener(WI.Collection.Event.ItemAdded, this._handleItemAdded, this);
     183        this.representedObject.addEventListener(WI.Collection.Event.ItemRemoved, this._handleItemRemoved, this);
     184
     185        for (let item of this._contentViewMap.keys()) {
     186            if (this.representedObject.items.has(item))
     187                continue;
     188
     189            this.removeContentViewForItem(item);
     190            if (this._selectedItem === item)
     191                this._selectItem(null);
     192        }
     193
     194        for (let item of this.representedObject.items) {
     195            if (!this._contentViewMap.has(item))
     196                this.addContentViewForItem(item);
     197        }
     198    }
     199
     200    detached()
     201    {
     202        this.representedObject.removeEventListener(null, null, this);
     203
     204        super.detached();
     205    }
     206
     207     // Private
    164208
    165209    _handleItemAdded(event)
     
    169213            return;
    170214
    171         this._addContentViewForItem(item);
     215        this.addContentViewForItem(item);
    172216    }
    173217
     
    178222            return;
    179223
    180         this._removeContentViewForItem(item);
     224        this.removeContentViewForItem(item);
    181225    }
    182226
     
    186230            this._removeContentViewForItem(event.target.representedObject);
    187231    }
     232
     233    _selectItem(item)
     234    {
     235        if (this._selectedItem === item)
     236            return;
     237
     238        if (this._selectedItem) {
     239            let contentView = this._contentViewMap.get(this._selectedItem);
     240            console.assert(contentView, "Missing ContentView for deselected item.", this._selectedItem);
     241            contentView.element.classList.remove("selected");
     242        }
     243
     244        this._selectedItem = item;
     245
     246        if (this._selectedItem) {
     247            let selectedContentView = this._contentViewMap.get(this._selectedItem);
     248            console.assert(selectedContentView, "Missing ContentView for selected item.", this._selectedItem);
     249            selectedContentView.element.classList.add("selected");
     250        }
     251
     252        this.dispatchEventToListeners(WI.ContentView.Event.SupplementalRepresentedObjectsDidChange);
     253    }
    188254};
  • trunk/Source/WebInspectorUI/UserInterface/Views/ContentView.js

    r222356 r222573  
    162162            return new WI.RecordingContentView(representedObject, extraArguments);
    163163
     164        if (representedObject instanceof WI.ResourceCollection)
     165            return new WI.ResourceCollectionContentView(representedObject, extraArguments);
     166
    164167        if (representedObject instanceof WI.Collection)
    165168            return new WI.CollectionContentView(representedObject, extraArguments);
Note: See TracChangeset for help on using the changeset viewer.