Changeset 221338 in webkit


Ignore:
Timestamp:
Aug 29, 2017 9:04:02 PM (7 years ago)
Author:
Matt Baker
Message:

Web Inspector: Critical content browser toolbar buttons are hidden at narrow widths
https://bugs.webkit.org/show_bug.cgi?id=175999

Reviewed by Devin Rousso.

This patch adds a VisibilityPriority concept to NavigationItems. If a
NavigationBar cannot fit all of its items in the available space, items
are hidden to make room, starting with the lowest priority item. Consecutive
dividers are then collapsed, as well as leading and trailing dividers.

  • UserInterface/Main.html:

New file.

  • UserInterface/Views/CanvasContentView.js:

(WI.CanvasContentView):

  • UserInterface/Views/ConsoleDrawer.js:

(WI.ConsoleDrawer):

  • UserInterface/Views/ContentBrowser.js:

(WI.ContentBrowser):

  • UserInterface/Views/ContentBrowserTabContentView.js:

(WI.ContentBrowserTabContentView):

  • UserInterface/Views/DOMTreeContentView.js:

(WI.DOMTreeContentView):
Set High and Low priorities, and group the back/forward buttons.

  • UserInterface/Views/GroupNavigationItem.js: Added.

(WI.GroupNavigationItem):
(WI.GroupNavigationItem.prototype.get navigationItems):
(WI.GroupNavigationItem.prototype.get minimumWidth):
(WI.GroupNavigationItem.prototype.updateLayout):
(WI.GroupNavigationItem.prototype.didAttach):
(WI.GroupNavigationItem.prototype.didDetach):
NavigationItem groups. Grouped items are shown/hidden together.

  • UserInterface/Views/HierarchicalPathNavigationItem.js:

(WI.HierarchicalPathNavigationItem.prototype.updateLayout):

  • UserInterface/Views/ImageResourceContentView.js:

(WI.ImageResourceContentView):

  • UserInterface/Views/IndexedDatabaseObjectStoreContentView.js:

(WI.IndexedDatabaseObjectStoreContentView):

  • UserInterface/Views/LogContentView.js:

(WI.LogContentView):
Set High and Low priorities.

  • UserInterface/Views/NavigationBar.css:

(.navigation-bar .item.force-hidden):
New hidden class, which must be tracked separately from ".hidden".
The former is an implementation detail of NavigationBar, while the
latter is set by the client.

  • UserInterface/Views/NavigationBar.js:

(WI.NavigationBar.prototype.insertNavigationItem):
(WI.NavigationBar.prototype.removeNavigationItem):
(WI.NavigationBar.prototype.findNavigationItem.matchingSelfOrChild):
(WI.NavigationBar.prototype.findNavigationItem):
(WI.NavigationBar.prototype.layout.forceItemHidden):
(WI.NavigationBar.prototype.layout.isDivider):
(WI.NavigationBar.prototype.layout.calculateVisibleItemWidth):
(WI.NavigationBar.prototype.layout):
(WI.NavigationBar.prototype._calculateMinimumWidth):
(WI.NavigationBar.prototype.get _visibleNavigationItems):
(WI.NavigationBar):

  • UserInterface/Views/NavigationItem.js:

Add support for visibility priority, an integer value that determines the
order in which items are hidden when the NavigationBar becomes too narrow
to fit all of items child items. NavigationIte3m defines constants for
Low, Normal (the default), and High priority.

(WI.NavigationItem):
(WI.NavigationItem.prototype.get minimumWidth):
(WI.NavigationItem.prototype.get width):
(WI.NavigationItem.prototype.get visibilityPriority):
(WI.NavigationItem.prototype.set visibilityPriority):
(WI.NavigationItem.prototype.updateLayout):
(WI.NavigationItem.prototype.didAttach):
(WI.NavigationItem.prototype.didDetach):
Encapsulate the setting of the parent NavigationBar. Needed so that
GroupNavigationItem can forward this action to its children.

  • UserInterface/Views/NetworkGridContentView.js:

(WI.NetworkGridContentView):

  • UserInterface/Views/RadioButtonNavigationItem.js:

(WI.RadioButtonNavigationItem.prototype.updateLayout):

  • UserInterface/Views/RecordingContentView.js:

(WI.RecordingContentView):

  • UserInterface/Views/ScriptContentView.js:

(WI.ScriptContentView):

  • UserInterface/Views/TextContentView.js:

(WI.TextContentView):

  • UserInterface/Views/TextResourceContentView.js:

(WI.TextResourceContentView):

  • UserInterface/Views/TimelineRecordingContentView.js:

(WI.TimelineRecordingContentView):

  • UserInterface/Views/TimelineTabContentView.js:

(WI.TimelineTabContentView):
Set High and Low priorities, and group Timeline view mode buttons.

Location:
trunk/Source/WebInspectorUI
Files:
22 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r221332 r221338  
     12017-08-29  Matt Baker  <mattbaker@apple.com>
     2
     3        Web Inspector: Critical content browser toolbar buttons are hidden at narrow widths
     4        https://bugs.webkit.org/show_bug.cgi?id=175999
     5
     6        Reviewed by Devin Rousso.
     7
     8        This patch adds a VisibilityPriority concept to NavigationItems. If a
     9        NavigationBar cannot fit all of its items in the available space, items
     10        are hidden to make room, starting with the lowest priority item. Consecutive
     11        dividers are then collapsed, as well as leading and trailing dividers.
     12
     13        * UserInterface/Main.html:
     14        New file.
     15
     16        * UserInterface/Views/CanvasContentView.js:
     17        (WI.CanvasContentView):
     18        * UserInterface/Views/ConsoleDrawer.js:
     19        (WI.ConsoleDrawer):
     20        * UserInterface/Views/ContentBrowser.js:
     21        (WI.ContentBrowser):
     22        * UserInterface/Views/ContentBrowserTabContentView.js:
     23        (WI.ContentBrowserTabContentView):
     24        * UserInterface/Views/DOMTreeContentView.js:
     25        (WI.DOMTreeContentView):
     26        Set `High` and `Low` priorities, and group the back/forward buttons.
     27
     28        * UserInterface/Views/GroupNavigationItem.js: Added.
     29        (WI.GroupNavigationItem):
     30        (WI.GroupNavigationItem.prototype.get navigationItems):
     31        (WI.GroupNavigationItem.prototype.get minimumWidth):
     32        (WI.GroupNavigationItem.prototype.updateLayout):
     33        (WI.GroupNavigationItem.prototype.didAttach):
     34        (WI.GroupNavigationItem.prototype.didDetach):
     35        NavigationItem groups. Grouped items are shown/hidden together.
     36
     37        * UserInterface/Views/HierarchicalPathNavigationItem.js:
     38        (WI.HierarchicalPathNavigationItem.prototype.updateLayout):
     39        * UserInterface/Views/ImageResourceContentView.js:
     40        (WI.ImageResourceContentView):
     41        * UserInterface/Views/IndexedDatabaseObjectStoreContentView.js:
     42        (WI.IndexedDatabaseObjectStoreContentView):
     43        * UserInterface/Views/LogContentView.js:
     44        (WI.LogContentView):
     45        Set `High` and `Low` priorities.
     46
     47        * UserInterface/Views/NavigationBar.css:
     48        (.navigation-bar .item.force-hidden):
     49        New hidden class, which must be tracked separately from ".hidden".
     50        The former is an implementation detail of NavigationBar, while the
     51        latter is set by the client.
     52
     53        * UserInterface/Views/NavigationBar.js:
     54        (WI.NavigationBar.prototype.insertNavigationItem):
     55        (WI.NavigationBar.prototype.removeNavigationItem):
     56        (WI.NavigationBar.prototype.findNavigationItem.matchingSelfOrChild):
     57        (WI.NavigationBar.prototype.findNavigationItem):
     58        (WI.NavigationBar.prototype.layout.forceItemHidden):
     59        (WI.NavigationBar.prototype.layout.isDivider):
     60        (WI.NavigationBar.prototype.layout.calculateVisibleItemWidth):
     61        (WI.NavigationBar.prototype.layout):
     62        (WI.NavigationBar.prototype._calculateMinimumWidth):
     63        (WI.NavigationBar.prototype.get _visibleNavigationItems):
     64        (WI.NavigationBar):
     65
     66        * UserInterface/Views/NavigationItem.js:
     67        Add support for visibility priority, an integer value that determines the
     68        order in which items are hidden when the NavigationBar becomes too narrow
     69        to fit all of items child items. NavigationIte3m defines constants for
     70        Low, Normal (the default), and High priority.
     71
     72        (WI.NavigationItem):
     73        (WI.NavigationItem.prototype.get minimumWidth):
     74        (WI.NavigationItem.prototype.get width):
     75        (WI.NavigationItem.prototype.get visibilityPriority):
     76        (WI.NavigationItem.prototype.set visibilityPriority):
     77        (WI.NavigationItem.prototype.updateLayout):
     78        (WI.NavigationItem.prototype.didAttach):
     79        (WI.NavigationItem.prototype.didDetach):
     80        Encapsulate the setting of the parent NavigationBar. Needed so that
     81        GroupNavigationItem can forward this action to its children.
     82
     83        * UserInterface/Views/NetworkGridContentView.js:
     84        (WI.NetworkGridContentView):
     85        * UserInterface/Views/RadioButtonNavigationItem.js:
     86        (WI.RadioButtonNavigationItem.prototype.updateLayout):
     87        * UserInterface/Views/RecordingContentView.js:
     88        (WI.RecordingContentView):
     89        * UserInterface/Views/ScriptContentView.js:
     90        (WI.ScriptContentView):
     91        * UserInterface/Views/TextContentView.js:
     92        (WI.TextContentView):
     93        * UserInterface/Views/TextResourceContentView.js:
     94        (WI.TextResourceContentView):
     95        * UserInterface/Views/TimelineRecordingContentView.js:
     96        (WI.TimelineRecordingContentView):
     97        * UserInterface/Views/TimelineTabContentView.js:
     98        (WI.TimelineTabContentView):
     99        Set `High` and `Low` priorities, and group Timeline view mode buttons.
     100
    11012017-08-29  Joseph Pecoraro  <pecoraro@apple.com>
    2102
  • trunk/Source/WebInspectorUI/UserInterface/Main.html

    r221166 r221338  
    468468    <script src="Views/GeneralTabBarItem.js"></script>
    469469    <script src="Views/GeneralTreeElement.js"></script>
     470    <script src="Views/GroupNavigationItem.js"></script>
    470471    <script src="Views/NavigationSidebarPanel.js"></script>
    471472    <script src="Views/PinnedTabBarItem.js"></script>
  • trunk/Source/WebInspectorUI/UserInterface/Views/CanvasContentView.js

    r221232 r221338  
    4242            const altToolTip = WI.UIString("Cancel recording");
    4343            this._recordButtonNavigationItem = new WI.ToggleButtonNavigationItem("canvas-record", toolTip, altToolTip, "Images/Record.svg", "Images/Stop.svg", 13, 13);
     44            this._recordButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.High;
    4445            this._recordButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._toggleRecording, this);
    4546        }
    4647
    4748        this._refreshButtonNavigationItem = new WI.ButtonNavigationItem("canvas-refresh", WI.UIString("Refresh"), "Images/ReloadFull.svg", 13, 13);
     49        this._refreshButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    4850        this._refreshButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._showPreview, this);
    4951
    5052        this._showGridButtonNavigationItem = new WI.ActivateButtonNavigationItem("show-grid", WI.UIString("Show Grid"), WI.UIString("Hide Grid"), "Images/NavigationItemCheckers.svg", 13, 13);
    5153        this._showGridButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._showGridButtonClicked, this);
     54        this._showGridButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    5255        this._showGridButtonNavigationItem.activated = !!WI.settings.showImageGrid.value;
    5356    }
  • trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleDrawer.js

    r220119 r221338  
    4040
    4141        this._toggleDrawerButton = new WI.ToggleButtonNavigationItem("toggle-drawer", WI.UIString("Hide Console"), WI.UIString("Show Console"), "Images/HideConsoleDrawer.svg", "Images/ShowConsoleDrawer.svg");
     42        this._toggleDrawerButton.visibilityPriority = WI.NavigationItem.VisibilityPriority.High;
    4243        this._toggleDrawerButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, () => { WI.toggleSplitConsole(); });
    4344        this.navigationBar.insertNavigationItem(this._toggleDrawerButton, 0);
  • trunk/Source/WebInspectorUI/UserInterface/Views/ContentBrowser.js

    r220119 r221338  
    5858            this._backNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, goBack);
    5959            this._backNavigationItem.enabled = false;
    60             this._navigationBar.addNavigationItem(this._backNavigationItem);
    6160
    6261            this._forwardNavigationItem = new WI.ButtonNavigationItem("forward", WI.UIString("Forward (%s)").format(this._forwardKeyboardShortcut.displayName), forwardButtonImage, 8, 13);
    6362            this._forwardNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, goForward);
    6463            this._forwardNavigationItem.enabled = false;
    65             this._navigationBar.addNavigationItem(this._forwardNavigationItem);
     64
     65            let navigationButtonsGroup = new WI.GroupNavigationItem([this._backNavigationItem, this._forwardNavigationItem]);
     66            this._navigationBar.addNavigationItem(navigationButtonsGroup);
    6667
    6768            this._navigationBar.addNavigationItem(new WI.DividerNavigationItem);
  • trunk/Source/WebInspectorUI/UserInterface/Views/ContentBrowserTabContentView.js

    r220119 r221338  
    5757            this._showNavigationSidebarItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI.toggleNavigationSidebar, WI);
    5858            this._showNavigationSidebarItem.activated = !WI.navigationSidebar.collapsed;
     59            this._showNavigationSidebarItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.High;
    5960
    6061            this._contentBrowser.navigationBar.insertNavigationItem(this._showNavigationSidebarItem, 0);
     
    7374            this._showDetailsSidebarItem.activated = !WI.detailsSidebar.collapsed;
    7475            this._showDetailsSidebarItem.enabled = false;
     76            this._showDetailsSidebarItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.High;
    7577
    7678            this._contentBrowser.navigationBar.addNavigationItem(new WI.DividerNavigationItem);
  • trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeContentView.js

    r221174 r221338  
    3535        this._compositingBordersButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._toggleCompositingBorders, this);
    3636        this._compositingBordersButtonNavigationItem.enabled = !!PageAgent.getCompositingBordersVisible;
     37        this._compositingBordersButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    3738
    3839        WI.showPaintRectsSetting.addEventListener(WI.Setting.Event.Changed, this._showPaintRectsSettingChanged, this);
     
    4142        this._paintFlashingButtonNavigationItem.enabled = !!PageAgent.setShowPaintRects;
    4243        this._paintFlashingButtonNavigationItem.activated = PageAgent.setShowPaintRects && WI.showPaintRectsSetting.value;
     44        this._paintFlashingButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    4345
    4446        WI.showShadowDOMSetting.addEventListener(WI.Setting.Event.Changed, this._showShadowDOMSettingChanged, this);
    4547        this._showsShadowDOMButtonNavigationItem = new WI.ActivateButtonNavigationItem("shows-shadow-DOM", WI.UIString("Show shadow DOM nodes"), WI.UIString("Hide shadow DOM nodes"), "Images/ShadowDOM.svg", 13, 13);
    4648        this._showsShadowDOMButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._toggleShowsShadowDOMSetting, this);
     49        this._showsShadowDOMButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    4750        this._showShadowDOMSettingChanged();
    4851
     
    5053        this._showPrintStylesButtonNavigationItem = new WI.ActivateButtonNavigationItem("print-styles", WI.UIString("Force Print Media Styles"), WI.UIString("Use Default Media Styles"), "Images/Printer.svg", 16, 16);
    5154        this._showPrintStylesButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._togglePrintStylesSetting, this);
     55        this._showPrintStylesButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    5256        this._showPrintStylesSettingChanged();
    5357
  • trunk/Source/WebInspectorUI/UserInterface/Views/GroupNavigationItem.js

    r221337 r221338  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2017 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 .navigation-bar {
    27     display: flex;
    28     justify-content: center;
    29     align-items: center;
    30     flex-wrap: wrap;
     26WI.GroupNavigationItem = class GroupNavigationItem extends WI.NavigationItem
     27{
     28    constructor(navigationItems)
     29    {
     30        console.assert(Array.isArray(navigationItems));
    3131
    32     border-bottom: 1px solid var(--border-color);
     32        super();
    3333
    34     height: var(--navigation-bar-height);
     34        this._navigationItems = navigationItems;
    3535
    36     white-space: nowrap;
    37     overflow: hidden;
     36        for (let item of this._navigationItems) {
     37            console.assert(item instanceof WI.NavigationItem);
     38            this.element.appendChild(item.element);
     39        }
     40    }
    3841
    39     outline: none;
     42    // Public
     43
     44    get navigationItems() { return this._navigationItems; }
     45
     46    get minimumWidth()
     47    {
     48        return this._navigationItems.reduce((total, item) => total + item.minimumWidth, 0);
     49    }
     50
     51    // Protected
     52
     53    updateLayout(expandOnly)
     54    {
     55        super.updateLayout(expandOnly);
     56
     57        for (let item of this._navigationItems)
     58            item.updateLayout(expandOnly);
     59    }
     60
     61    didAttach(navigationBar)
     62    {
     63        super.didAttach(navigationBar);
     64
     65        for (let item of this._navigationItems)
     66            item.didAttach(navigationBar);
     67    }
     68
     69    didDetach()
     70    {
     71        for (let item of this._navigationItems)
     72            item.didDetach();
     73
     74        super.didDetach();
     75    }
    4076}
    41 
    42 .navigation-bar .item {
    43     display: flex;
    44     align-items: center;
    45     flex-wrap: wrap;
    46 
    47     height: auto;
    48     outline: none;
    49 }
  • trunk/Source/WebInspectorUI/UserInterface/Views/HierarchicalPathNavigationItem.js

    r220119 r221338  
    101101    updateLayout(expandOnly)
    102102    {
     103        super.updateLayout(expandOnly);
     104
    103105        var navigationBar = this.parentNavigationBar;
    104106        if (!navigationBar)
  • trunk/Source/WebInspectorUI/UserInterface/Views/ImageResourceContentView.js

    r220119 r221338  
    3535        const activatedToolTip = WI.UIString("Hide Grid");
    3636        this._showGridButtonNavigationItem = new WI.ActivateButtonNavigationItem("show-grid", toolTip, activatedToolTip, "Images/NavigationItemCheckers.svg", 13, 13);
     37        this._showGridButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    3738        this._showGridButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._showGridButtonClicked, this);
    3839        this._showGridButtonNavigationItem.activated = !!WI.settings.showImageGrid.value;
  • trunk/Source/WebInspectorUI/UserInterface/Views/IndexedDatabaseObjectStoreContentView.js

    r220119 r221338  
    8282
    8383        this._clearButtonNavigationItem = new WI.ButtonNavigationItem("indexed-database-object-store-clear", WI.UIString("Clear object store"), "Images/NavigationItemTrash.svg", 15, 15);
     84        this._clearButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    8485        this._clearButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._clearButtonClicked, this);
    8586    }
  • trunk/Source/WebInspectorUI/UserInterface/Views/LogContentView.js

    r220609 r221338  
    7878
    7979        this._garbageCollectNavigationItem = new WI.ButtonNavigationItem("clear-log", WI.UIString("Collect garbage"), "Images/NavigationItemGarbageCollect.svg", 16, 16);
     80        this._garbageCollectNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    8081        this._garbageCollectNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._garbageCollect, this);
    8182
    8283        this._clearLogNavigationItem = new WI.ButtonNavigationItem("clear-log", WI.UIString("Clear log (%s or %s)").format(WI.clearKeyboardShortcut.displayName, this._logViewController.messagesAlternateClearKeyboardShortcut.displayName), "Images/NavigationItemClear.svg", 16, 16);
     84        this._clearLogNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    8385        this._clearLogNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._clearLog, this);
    8486
    8587        this._showConsoleTabNavigationItem = new WI.ButtonNavigationItem("show-tab", WI.UIString("Show Console tab"), "Images/SplitToggleUp.svg", 16, 16);
     88        this._showConsoleTabNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.High;
    8689        this._showConsoleTabNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._showConsoleTab, this);
    8790
  • trunk/Source/WebInspectorUI/UserInterface/Views/NavigationBar.css

    r220114 r221338  
    4848    outline: none;
    4949}
     50
     51.navigation-bar .item.force-hidden {
     52    display: none;
     53}
  • trunk/Source/WebInspectorUI/UserInterface/Views/NavigationBar.js

    r220119 r221338  
    7070            navigationItem.parentNavigationBar.removeNavigationItem(navigationItem);
    7171
    72         navigationItem._parentNavigationBar = this;
     72        navigationItem.didAttach(this);
    7373
    7474        console.assert(index >= 0 && index <= this._navigationItems.length);
     
    107107            return null;
    108108
    109         navigationItem._parentNavigationBar = null;
     109        navigationItem.didDetach();
    110110
    111111        if (this._selectedNavigationItem === navigationItem)
     
    175175    findNavigationItem(identifier)
    176176    {
    177         return this._navigationItems.find((item) => item.identifier === identifier) || null;
     177        function matchingSelfOrChild(item) {
     178            if (item.identifier === identifier)
     179                return item;
     180
     181            if (item instanceof WI.GroupNavigationItem) {
     182                for (let childItem of item.navigationItems) {
     183                    let result = matchingSelfOrChild(childItem);
     184                    if (result)
     185                        return result;
     186                }
     187            }
     188
     189            return null;
     190        }
     191
     192        for (let item of this._navigationItems) {
     193            let result = matchingSelfOrChild(item);
     194            if (result)
     195                return result;
     196        }
     197
     198        return null;
    178199    }
    179200
     
    195216        this.element.classList.remove(WI.NavigationBar.CollapsedStyleClassName);
    196217
     218        function forceItemHidden(item, hidden) {
     219            item[WI.NavigationBar.ForceHiddenSymbol] = hidden;
     220            item.element.classList.toggle("force-hidden", hidden);
     221        }
     222
     223        function isDivider(item) {
     224            return item instanceof WI.DividerNavigationItem;
     225        }
     226
    197227        // Tell each navigation item to update to full width if needed.
    198         for (let navigationItem of this._navigationItems)
    199             navigationItem.updateLayout(true);
    200 
    201         let totalItemWidth = 0;
    202         for (let navigationItem of this._navigationItems) {
    203             // Skip flexible space items since they can take up no space at the minimum width.
    204             if (navigationItem instanceof WI.FlexibleSpaceNavigationItem)
    205                 continue;
    206 
    207             totalItemWidth += navigationItem.element.realOffsetWidth;
    208         }
     228        for (let item of this._navigationItems) {
     229            forceItemHidden(item, false);
     230            item.updateLayout(true);
     231        }
     232
     233        let visibleNavigationItems = this._visibleNavigationItems;
     234
     235        function calculateVisibleItemWidth() {
     236            return visibleNavigationItems.reduce((total, item) => total + item.width, 0);
     237        }
     238
     239        let totalItemWidth = calculateVisibleItemWidth();
    209240
    210241        const barWidth = this.element.realOffsetWidth;
     
    215246
    216247        // Give each navigation item the opportunity to collapse further.
    217         for (let navigationItem of this._navigationItems)
    218             navigationItem.updateLayout(false);
     248        for (let item of visibleNavigationItems)
     249            item.updateLayout(false);
     250
     251        totalItemWidth = calculateVisibleItemWidth();
     252        if (totalItemWidth <= barWidth)
     253            return;
     254
     255        // Hide visible items, starting with the lowest priority item, until the
     256        // bar fits the available width.
     257        visibleNavigationItems.sort((a, b) => a.visibilityPriority - b.visibilityPriority);
     258
     259        while (totalItemWidth > barWidth && visibleNavigationItems.length) {
     260            let navigationItem = visibleNavigationItems.shift();
     261            totalItemWidth -= navigationItem.width;
     262            forceItemHidden(navigationItem, true);
     263        }
     264
     265        visibleNavigationItems = this._visibleNavigationItems;
     266
     267        // Hide leading, trailing, and consecutive dividers.
     268        let previousItem = null;
     269        for (let item of visibleNavigationItems) {
     270            if (isDivider(item) && (!previousItem || isDivider(previousItem))) {
     271                forceItemHidden(item);
     272                continue;
     273            }
     274
     275            previousItem = item;
     276        }
     277
     278        if (isDivider(previousItem))
     279            forceItemHidden(previousItem);
    219280    }
    220281
     
    370431            this.element.classList.add(WI.NavigationBar.CollapsedStyleClassName);
    371432
    372         let totalItemWidth = 0;
    373         for (let item of this._navigationItems) {
    374             // Skip flexible space items since they can take up no space at the minimum width.
    375             if (item instanceof WI.FlexibleSpaceNavigationItem)
    376                 continue;
    377 
    378             totalItemWidth += item.minimumWidth;
    379         }
     433        let totalItemWidth = this._visibleNavigationItems.reduce((total, item) => item.minimumWidth, 0);
    380434
    381435        // Remove the collapsed style class if we were not collapsed before.
     
    385439        return totalItemWidth;
    386440    }
     441
     442    get _visibleNavigationItems()
     443    {
     444        return this._navigationItems.filter((item) => {
     445            if (item instanceof WI.FlexibleSpaceNavigationItem)
     446                return false;
     447            if (item.hidden || item[WI.NavigationBar.ForceHiddenSymbol])
     448                return false;
     449            return true;
     450        });
     451    }
    387452};
     453
     454WI.NavigationBar.CachedWidthSymbol = Symbol("cached-width");
     455WI.NavigationBar.ForceHiddenSymbol = Symbol("force-hidden");
    388456
    389457WI.NavigationBar.CollapsedStyleClassName = "collapsed";
  • trunk/Source/WebInspectorUI/UserInterface/Views/NavigationItem.js

    r220119 r221338  
    3535        this._hidden = false;
    3636        this._parentNavigationBar = null;
     37        this._visibilityPriority = WI.NavigationItem.VisibilityPriority.Normal;
     38        this._cachedWidth = NaN;
    3739
    3840        if (role)
     
    4951    get identifier() { return this._identifier; }
    5052    get element() { return this._element; }
    51     get minimumWidth() { return this._element.realOffsetWidth; }
     53    get minimumWidth() { return this.width; }
    5254    get parentNavigationBar() { return this._parentNavigationBar; }
     55
     56    get width()
     57    {
     58        if (isNaN(this._cachedWidth))
     59            this._cachedWidth = this._element.realOffsetWidth;
     60        return this._cachedWidth;
     61    }
     62
     63    get visibilityPriority() { return this._visibilityPriority; }
     64    set visibilityPriority(priority) { this._visibilityPriority = priority; }
    5365
    5466    updateLayout(expandOnly)
    5567    {
    5668        // Implemented by subclasses.
     69
     70        this._cachedWidth = NaN;
    5771    }
    5872
     
    7589    }
    7690
     91    // Protected
     92
     93    didAttach(navigationBar)
     94    {
     95        console.assert(navigationBar instanceof WI.NavigationBar);
     96        this._parentNavigationBar = navigationBar;
     97    }
     98
     99    didDetach()
     100    {
     101        this._cachedWidth = NaN;
     102        this._parentNavigationBar = null;
     103    }
     104
    77105    // Private
    78106
     
    87115    }
    88116};
     117
     118WI.NavigationItem.VisibilityPriority = {
     119    Low: -100,
     120    Normal: 0,
     121    High: 100,
     122};
  • trunk/Source/WebInspectorUI/UserInterface/Views/NetworkGridContentView.js

    r220119 r221338  
    142142
    143143        this._clearNetworkItemsNavigationItem = new WI.ButtonNavigationItem("clear-network-items", WI.UIString("Clear Network Items (%s)").format(WI.clearKeyboardShortcut.displayName), "Images/NavigationItemClear.svg", 16, 16);
     144        this._clearNetworkItemsNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    144145        this._clearNetworkItemsNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, () => this.reset());
    145146
  • trunk/Source/WebInspectorUI/UserInterface/Views/RadioButtonNavigationItem.js

    r220119 r221338  
    6363    updateLayout(expandOnly)
    6464    {
     65        super.updateLayout(expandOnly);
     66
    6567        if (expandOnly)
    6668            return;
  • trunk/Source/WebInspectorUI/UserInterface/Views/RecordingContentView.js

    r221232 r221338  
    5050
    5151            this._showGridButtonNavigationItem = new WI.ActivateButtonNavigationItem("show-grid", WI.UIString("Show Grid"), WI.UIString("Hide Grid"), "Images/NavigationItemCheckers.svg", 13, 13);
     52            this._showGridButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    5253            this._showGridButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._showGridButtonClicked, this);
    5354            this._showGridButtonNavigationItem.activated = !!WI.settings.showImageGrid.value;
  • trunk/Source/WebInspectorUI/UserInterface/Views/ScriptContentView.js

    r220119 r221338  
    5858        this._prettyPrintButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._togglePrettyPrint, this);
    5959        this._prettyPrintButtonNavigationItem.enabled = false; // Enabled when the text editor is populated with content.
     60        this._prettyPrintButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    6061
    6162        var toolTipTypes = WI.UIString("Show type information");
     
    6465        this._showTypesButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._toggleTypeAnnotations, this);
    6566        this._showTypesButtonNavigationItem.enabled = false;
     67        this._showTypesButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
     68
    6669        WI.showJavaScriptTypeInformationSetting.addEventListener(WI.Setting.Event.Changed, this._showJavaScriptTypeInformationSettingChanged, this);
    6770
     
    7174        this._codeCoverageButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._toggleUnexecutedCodeHighlights, this);
    7275        this._codeCoverageButtonNavigationItem.enabled = false;
     76        this._codeCoverageButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
     77
    7378        WI.enableControlFlowProfilerSetting.addEventListener(WI.Setting.Event.Changed, this._enableControlFlowProfilerSettingChanged, this);
    7479    }
  • trunk/Source/WebInspectorUI/UserInterface/Views/TextContentView.js

    r220119 r221338  
    4747        this._prettyPrintButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._togglePrettyPrint, this);
    4848        this._prettyPrintButtonNavigationItem.enabled = this._textEditor.canBeFormatted();
     49        this._prettyPrintButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    4950
    5051        var toolTipTypes = WI.UIString("Show type information");
     
    5253        this._showTypesButtonNavigationItem = new WI.ActivateButtonNavigationItem("show-types", toolTipTypes, activatedToolTipTypes, "Images/NavigationItemTypes.svg", 13, 14);
    5354        this._showTypesButtonNavigationItem.enabled = false;
     55        this._showTypesButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    5456
    5557        let toolTipCodeCoverage = WI.UIString("Fade unexecuted code");
     
    5759        this._codeCoverageButtonNavigationItem = new WI.ActivateButtonNavigationItem("code-coverage", toolTipCodeCoverage, activatedToolTipCodeCoverage, "Images/NavigationItemCodeCoverage.svg", 13, 14);
    5860        this._codeCoverageButtonNavigationItem.enabled = false;
     61        this._codeCoverageButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    5962    }
    6063
  • trunk/Source/WebInspectorUI/UserInterface/Views/TextResourceContentView.js

    r220119 r221338  
    4949        this._prettyPrintButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._togglePrettyPrint, this);
    5050        this._prettyPrintButtonNavigationItem.enabled = false; // Enabled when the text editor is populated with content.
     51        this._prettyPrintButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    5152
    5253        var toolTipTypes = WI.UIString("Show type information");
     
    5556        this._showTypesButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._toggleTypeAnnotations, this);
    5657        this._showTypesButtonNavigationItem.enabled = false;
     58        this._showTypesButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    5759        WI.showJavaScriptTypeInformationSetting.addEventListener(WI.Setting.Event.Changed, this._showJavaScriptTypeInformationSettingChanged, this);
    5860
     
    6264        this._codeCoverageButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._toggleUnexecutedCodeHighlights, this);
    6365        this._codeCoverageButtonNavigationItem.enabled = false;
     66        this._codeCoverageButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    6467        WI.enableControlFlowProfilerSetting.addEventListener(WI.Setting.Event.Changed, this._enableControlFlowProfilerSettingChanged, this);
    6568    }
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordingContentView.js

    r220609 r221338  
    5858
    5959        this._clearTimelineNavigationItem = new WI.ButtonNavigationItem("clear-timeline", WI.UIString("Clear Timeline (%s)").format(WI.clearKeyboardShortcut.displayName), "Images/NavigationItemClear.svg", 16, 16);
     60        this._clearTimelineNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    6061        this._clearTimelineNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._clearTimeline, this);
    6162
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineTabContentView.js

    r220119 r221338  
    5151        let altToolTip = WI.UIString("Stop recording (%s)").format(this._toggleRecordingShortcut.displayName);
    5252        this._recordButton = new WI.ToggleButtonNavigationItem("record-start-stop", toolTip, altToolTip, "Images/Record.svg", "Images/Stop.svg", 13, 13);
     53        this._recordButton.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
    5354        this._recordButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._recordButtonClicked, this);
    5455
     
    5960            let renderingFramesNavigationItem = new WI.RadioButtonNavigationItem(WI.TimelineOverview.ViewMode.RenderingFrames, WI.UIString("Frames"));
    6061
    61             this.contentBrowser.navigationBar.insertNavigationItem(timelinesNavigationItem, 1);
    62             this.contentBrowser.navigationBar.insertNavigationItem(renderingFramesNavigationItem, 2);
    63 
     62            let viewModeGroup = new WI.GroupNavigationItem([timelinesNavigationItem, renderingFramesNavigationItem]);
     63            viewModeGroup.visibilityPriority = WI.NavigationItem.VisibilityPriority.High;
     64
     65            this.contentBrowser.navigationBar.insertNavigationItem(viewModeGroup, 1);
    6466            this.contentBrowser.navigationBar.addEventListener(WI.NavigationBar.Event.NavigationItemSelected, this._viewModeSelected, this);
    6567        }
Note: See TracChangeset for help on using the changeset viewer.