Changeset 224067 in webkit


Ignore:
Timestamp:
Oct 26, 2017 4:41:23 PM (7 years ago)
Author:
webkit@devinrousso.com
Message:

Web Inspector: Canvas Tab: canvases overview should support navigation via keyboard
https://bugs.webkit.org/show_bug.cgi?id=178800
<rdar://problem/35175856>

Reviewed by Brian Burg.

Create a KeyboardShorcut for each of the following:

  • Up: selects the previous canvas in the selected column
  • Down: selects the next canvas in the selected column
  • Right: selects the next canvas in the selected row
  • Left: selects the previous canvas in the selected row
  • Space: toggle recording of the selected canvas
  • Shift+Space: toggle single-frame recording of the selected canvas

The calculation for selected row/colum is based on the offsetWidth of the parent element
and the selected item's content view element. Since this view uses a flexbox, all of the
items are expected to have the same dimensions, meaning that this value is uniform. The
intended functionality is that of a spreadsheet, where pressing pressing left/right will
never change the selected row and up/down will never change the selected column.

  • UserInterface/Views/CanvasOverviewContentView.css:

(.content-view.canvas-overview):
(.content-view.canvas-overview .content-view.canvas):
Move margin value to a CSS variable so that it can be easily retrieved via JavaScript.

  • UserInterface/Views/CanvasOverviewContentView.js:

(WI.CanvasOverviewContentView):
(WI.CanvasOverviewContentView.prototype.contentViewAdded):
(WI.CanvasOverviewContentView.prototype.contentViewRemoved):
(WI.CanvasOverviewContentView.prototype.attached):
(WI.CanvasOverviewContentView.prototype.detached):
(WI.CanvasOverviewContentView.prototype.get _itemMargin):
(WI.CanvasOverviewContentView.prototype._changeSelectedItemVertically):
(WI.CanvasOverviewContentView.prototype._changeSelectedItemHorizontally):
(WI.CanvasOverviewContentView.prototype._updateNavigationItems):
(WI.CanvasOverviewContentView.prototype._handleUp):
(WI.CanvasOverviewContentView.prototype._handleRight):
(WI.CanvasOverviewContentView.prototype._handleDown):
(WI.CanvasOverviewContentView.prototype._handleLeft):
(WI.CanvasOverviewContentView.prototype._handleSpace):
(WI.CanvasOverviewContentView.prototype._supplementalRepresentedObjectsDidChange):
Drive-by: call _updateNavigationItems whenever an item is added/removed so that if there
are no items the navigation items cannot be clicked.

Location:
trunk/Source/WebInspectorUI
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r224064 r224067  
     12017-10-26  Devin Rousso  <webkit@devinrousso.com>
     2
     3        Web Inspector: Canvas Tab: canvases overview should support navigation via keyboard
     4        https://bugs.webkit.org/show_bug.cgi?id=178800
     5        <rdar://problem/35175856>
     6
     7        Reviewed by Brian Burg.
     8
     9        Create a KeyboardShorcut for each of the following:
     10         - Up: selects the previous canvas in the selected column
     11         - Down: selects the next canvas in the selected column
     12         - Right: selects the next canvas in the selected row
     13         - Left: selects the previous canvas in the selected row
     14         - Space: toggle recording of the selected canvas
     15         - Shift+Space: toggle single-frame recording of the selected canvas
     16
     17        The calculation for selected row/colum is based on the `offsetWidth` of the parent element
     18        and the selected item's content view element. Since this view uses a flexbox, all of the
     19        items are expected to have the same dimensions, meaning that this value is uniform. The
     20        intended functionality is that of a spreadsheet, where pressing pressing left/right will
     21        never change the selected row and up/down will never change the selected column.
     22
     23        * UserInterface/Views/CanvasOverviewContentView.css:
     24        (.content-view.canvas-overview):
     25        (.content-view.canvas-overview .content-view.canvas):
     26        Move margin value to a CSS variable so that it can be easily retrieved via JavaScript.
     27
     28        * UserInterface/Views/CanvasOverviewContentView.js:
     29        (WI.CanvasOverviewContentView):
     30        (WI.CanvasOverviewContentView.prototype.contentViewAdded):
     31        (WI.CanvasOverviewContentView.prototype.contentViewRemoved):
     32        (WI.CanvasOverviewContentView.prototype.attached):
     33        (WI.CanvasOverviewContentView.prototype.detached):
     34        (WI.CanvasOverviewContentView.prototype.get _itemMargin):
     35        (WI.CanvasOverviewContentView.prototype._changeSelectedItemVertically):
     36        (WI.CanvasOverviewContentView.prototype._changeSelectedItemHorizontally):
     37        (WI.CanvasOverviewContentView.prototype._updateNavigationItems):
     38        (WI.CanvasOverviewContentView.prototype._handleUp):
     39        (WI.CanvasOverviewContentView.prototype._handleRight):
     40        (WI.CanvasOverviewContentView.prototype._handleDown):
     41        (WI.CanvasOverviewContentView.prototype._handleLeft):
     42        (WI.CanvasOverviewContentView.prototype._handleSpace):
     43        (WI.CanvasOverviewContentView.prototype._supplementalRepresentedObjectsDidChange):
     44        Drive-by: call `_updateNavigationItems` whenever an item is added/removed so that if there
     45        are no items the navigation items cannot be clicked.
     46
    1472017-10-26  Nikita Vasilyev  <nvasilyev@apple.com>
    248
  • trunk/Source/WebInspectorUI/UserInterface/Views/CanvasOverviewContentView.css

    r223979 r224067  
    2828    align-items: flex-start;
    2929    background-color: hsl(0, 0%, 90%);
     30
     31    --item-margin: 10px;
    3032}
    3133
    3234.content-view.canvas-overview .content-view.canvas {
    3335    flex-grow: 0;
    34     margin: 10px;
     36    margin: var(--item-margin);
    3537    width: 400px;
    3638    background-color: white;
  • trunk/Source/WebInspectorUI/UserInterface/Views/CanvasOverviewContentView.js

    r223918 r224067  
    3535
    3636        this._refreshButtonNavigationItem = new WI.ButtonNavigationItem("refresh-all", WI.UIString("Refresh all"), "Images/ReloadFull.svg", 13, 13);
    37         this._refreshButtonNavigationItem.disabled = true;
     37        this._refreshButtonNavigationItem.enabled = false;
    3838        this._refreshButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._refreshPreviews, this);
    3939
    4040        this._showGridButtonNavigationItem = new WI.ActivateButtonNavigationItem("show-grid", WI.UIString("Show transparency grid"), WI.UIString("Hide Grid"), "Images/NavigationItemCheckers.svg", 13, 13);
    4141        this._showGridButtonNavigationItem.activated = !!WI.settings.showImageGrid.value;
    42         this._showGridButtonNavigationItem.disabled = true;
     42        this._showGridButtonNavigationItem.enabled = false;
    4343        this._showGridButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._showGridButtonClicked, this);
    4444
    4545        this.selectionEnabled = true;
     46
     47        this._keyboardShortcuts = [
     48            new WI.KeyboardShortcut(null, WI.KeyboardShortcut.Key.Up, this._handleUp.bind(this)),
     49            new WI.KeyboardShortcut(null, WI.KeyboardShortcut.Key.Right, this._handleRight.bind(this)),
     50            new WI.KeyboardShortcut(null, WI.KeyboardShortcut.Key.Down, this._handleDown.bind(this)),
     51            new WI.KeyboardShortcut(null, WI.KeyboardShortcut.Key.Left, this._handleLeft.bind(this)),
     52            new WI.KeyboardShortcut(null, WI.KeyboardShortcut.Key.Space, this._handleSpace.bind(this)),
     53            new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.Shift, WI.KeyboardShortcut.Key.Space, this._handleSpace.bind(this)),
     54        ];
     55
     56        for (let shortcut of this._keyboardShortcuts)
     57            shortcut.disabled = true;
    4658    }
    4759
     
    8799        contentView.element.addEventListener("mouseenter", this._contentViewMouseEnter);
    88100        contentView.element.addEventListener("mouseleave", this._contentViewMouseLeave);
     101
     102        this._updateNavigationItems();
    89103    }
    90104
     
    93107        contentView.element.removeEventListener("mouseenter", this._contentViewMouseEnter);
    94108        contentView.element.removeEventListener("mouseleave", this._contentViewMouseLeave);
     109
     110        this._updateNavigationItems();
    95111    }
    96112
     
    102118
    103119        this.addEventListener(WI.ContentView.Event.SupplementalRepresentedObjectsDidChange, this._supplementalRepresentedObjectsDidChange, this);
     120
     121        for (let shortcut of this._keyboardShortcuts)
     122            shortcut.disabled = false;
    104123    }
    105124
     
    110129        this.removeEventListener(null, null, this);
    111130
     131        for (let shortcut of this._keyboardShortcuts)
     132            shortcut.disabled = true;
     133
    112134        super.detached();
    113135    }
    114136
    115137    // Private
     138
     139    get _itemMargin()
     140    {
     141        return parseInt(window.getComputedStyle(this.element).getPropertyValue("--item-margin"));
     142    }
    116143
    117144    _refreshPreviews()
     
    119146        for (let canvasContentView of this.subviews)
    120147            canvasContentView.refresh();
     148    }
     149
     150    _changeSelectedItemVertically(shift)
     151    {
     152        let itemElementWidth = this.element.firstElementChild.offsetWidth + (2 * this._itemMargin);
     153        let itemsPerRow = Math.floor(this.element.offsetWidth / itemElementWidth);
     154
     155        let items = Array.from(this.representedObject.items);
     156        let index = items.indexOf(this._selectedItem);
     157        if (index === -1)
     158            index = shift < 0 ? items.length + 1 : itemsPerRow;
     159
     160        index += shift * itemsPerRow;
     161        if (index < 0)
     162            index = items.length + index;
     163
     164        this.setSelectedItem(items[index % items.length]);
     165    }
     166
     167    _changeSelectedItemHorizontally(shift)
     168    {
     169        let itemElementWidth = this.element.firstElementChild.offsetWidth + (2 * this._itemMargin);
     170        let itemsPerRow = Math.floor(this.element.offsetWidth / itemElementWidth);
     171
     172        let items = Array.from(this.representedObject.items);
     173        let index = items.indexOf(this._selectedItem);
     174        if (index === -1)
     175            index = shift >= 0 ? itemsPerRow - 1 : 0;
     176
     177        let selectedRow = Math.floor(index / itemsPerRow);
     178        index += shift;
     179        if (index < selectedRow * itemsPerRow)
     180            index += itemsPerRow;
     181        else if (index >= (selectedRow + 1) * itemsPerRow)
     182            index -= itemsPerRow;
     183
     184        this.setSelectedItem(items[index]);
     185    }
     186
     187    _updateNavigationItems()
     188    {
     189        let hasItems = !!this.representedObject.items.size;
     190        this._refreshButtonNavigationItem.enabled = hasItems;
     191        this._showGridButtonNavigationItem.enabled = hasItems;
    121192    }
    122193
     
    133204    }
    134205
     206    _handleUp(event)
     207    {
     208        this._changeSelectedItemVertically(-1);
     209    }
     210
     211    _handleRight(event)
     212    {
     213        let shift = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? -1 : 1;
     214        this._changeSelectedItemHorizontally(shift);
     215    }
     216
     217    _handleDown(event)
     218    {
     219        this._changeSelectedItemVertically(1);
     220    }
     221
     222    _handleLeft(event)
     223    {
     224        let shift = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? 1 : -1;
     225        this._changeSelectedItemHorizontally(shift);
     226    }
     227
     228    _handleSpace(event)
     229    {
     230        if (!this._selectedItem)
     231            return;
     232
     233        if (this._selectedItem.isRecording)
     234            WI.canvasManager.stopRecording();
     235        else if (!WI.canvasManager.recordingCanvas) {
     236            let singleFrame = !!event.shiftKey;
     237            WI.canvasManager.startRecording(this._selectedItem, singleFrame);
     238        }
     239    }
     240
     241    _updateShowImageGrid()
     242    {
     243        this._showGridButtonNavigationItem.activated = !!WI.settings.showImageGrid.value;
     244    }
     245
    135246    _supplementalRepresentedObjectsDidChange()
    136247    {
    137248        this.dispatchEventToListeners(WI.ContentView.Event.SelectionPathComponentsDidChange);
    138     }
    139 
    140     _updateNavigationItems()
    141     {
    142         let disabled = !this.representedObject.items.size;
    143         this._refreshButtonNavigationItem.disabled = disabled;
    144         this._showGridButtonNavigationItem.disabled = disabled;
    145     }
    146 
    147     _updateShowImageGrid()
    148     {
    149         this._showGridButtonNavigationItem.activated = !!WI.settings.showImageGrid.value;
    150249    }
    151250
Note: See TracChangeset for help on using the changeset viewer.