Modified: trunk/Source/WebInspectorUI/ChangeLog (282904 => 282905)
--- trunk/Source/WebInspectorUI/ChangeLog 2021-09-23 03:28:06 UTC (rev 282904)
+++ trunk/Source/WebInspectorUI/ChangeLog 2021-09-23 04:08:29 UTC (rev 282905)
@@ -1,3 +1,32 @@
+2021-09-22 Devin Rousso <drou...@apple.com>
+
+ Web Inspector: add a pinned [+] button to the tab bar to make it easier to re-open closed tabs
+ https://bugs.webkit.org/show_bug.cgi?id=230600
+
+ Reviewed by BJ Burg.
+
+ * UserInterface/Views/TabBar.js:
+ (WI.TabBar):
+ (WI.TabBar.prototype.selectTabBarItem):
+ (WI.TabBar.prototype.layout):
+ (WI.TabBar.prototype._pinnedButtons): Added.
+ (WI.TabBar.prototype._closedTabClasses): Added.
+ (WI.TabBar.prototype._handleTabContainerMouseDown):
+ (WI.TabBar.prototype._handleShowHiddenTabsTabBarItemMouseDown): Added.
+ (WI.TabBar.prototype._handleAddClosedTabsTabBarItemMouseDown): Added.
+ (WI.TabBar.prototype._handleTabContainerClick): Deleted.
+ Add a `_openClosedTabsTabBarItem` that's a `WI.PinnedTabBarItem` without a `representedObject`,
+ meaning that it's basically just a button and won't actually open a tab when clicked. This
+ suits our purposes perfectly as we only want to show a contextmenu on click, not to mention
+ that it will only be shown if there are closed tabs.
+ Drive-by: Rename `_tabPickerTabBarItem` to `_showHiddenTabsTabBarItem` to clarify purpose.
+ Drive-by: Remove `_handleTabContainerClick` as tabs can only be removed via the contextmenu.
+
+ * UserInterface/Images/Overflow.svg: Renamed from UserInterface/Images/TabPicker.svg.
+ Drive-by: Rename to clarify purpose.
+
+ * Localizations/en.lproj/localizedStrings.js:
+
2021-09-16 Patrick Angle <pan...@apple.com>
Web Inspector: Regression(r279613) Audit result scope toggles are missing
Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (282904 => 282905)
--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2021-09-23 03:28:06 UTC (rev 282904)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2021-09-23 04:08:29 UTC (rev 282905)
@@ -1027,6 +1027,7 @@
localizedStrings["Only show resources with issues"] = "Only show resources with issues";
localizedStrings["Only show visual actions"] = "Only show visual actions";
localizedStrings["Open"] = "Open";
+localizedStrings["Open closed tabs\u2026"] = "Open closed tabs\u2026";
/* Context menu item for opening the target item in a new window. */
localizedStrings["Open in New Window @ Context Menu Item"] = "Open in New Window";
localizedStrings["Option-click to show source"] = "Option-click to show source";
@@ -1343,7 +1344,7 @@
/* Label for option to toggle the extended lines setting for CSS grid overlays */
localizedStrings["Show extended lines @ Layout Panel Overlay Options"] = "Extended Grid Lines";
localizedStrings["Show full certificate"] = "Show full certificate";
-localizedStrings["Show hidden tabs"] = "Show hidden tabs";
+localizedStrings["Show hidden tabs\u2026"] = "Show hidden tabs\u2026";
/* Settings tab checkbox label for whether the independent styles sidebar should be shown */
localizedStrings["Show independent Styles sidebar @ Settings Elements Pane"] = "Show independent Styles sidebar";
localizedStrings["Show jump to effective property button"] = "Show jump to effective property button";
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TabBar.js (282904 => 282905)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TabBar.js 2021-09-23 03:28:06 UTC (rev 282904)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TabBar.js 2021-09-23 04:08:29 UTC (rev 282905)
@@ -42,7 +42,6 @@
this._tabContainer.className = "tabs";
this._tabContainer.setAttribute("role", "tablist");
this._tabContainer.addEventListener("mousedown", this._handleTabContainerMouseDown.bind(this));
- this._tabContainer.addEventListener("click", this._handleTabContainerClick.bind(this));
this._tabContainer.addEventListener("mouseleave", this._handleTabContainerMouseLeave.bind(this));
this._tabContainer.addEventListener("contextmenu", this._handleTabContainerContextMenu.bind(this));
@@ -55,13 +54,18 @@
this._tabBarItems = [];
this._hiddenTabBarItems = [];
- const tabPickerRepresentedObject = null;
- const tabPickerDisplayName = null;
- this._tabPickerTabBarItem = new WI.PinnedTabBarItem(tabPickerRepresentedObject, "Images/TabPicker.svg", tabPickerDisplayName, WI.UIString("Show hidden tabs"));
- this._tabPickerTabBarItem.hidden = true;
- this._tabPickerTabBarItem.element.classList.add("tab-picker");
- this.addTabBarItem(this._tabPickerTabBarItem, {suppressAnimations: true});
+ const showHiddenTabsRepresentedObject = null;
+ const showHiddenTabsDisplayName = null;
+ this._showHiddenTabsTabBarItem = new WI.PinnedTabBarItem(showHiddenTabsRepresentedObject, "Images/Overflow.svg", showHiddenTabsDisplayName, WI.UIString("Show hidden tabs\u2026"));
+ this._showHiddenTabsTabBarItem.hidden = true;
+ this.addTabBarItem(this._showHiddenTabsTabBarItem, {suppressAnimations: true});
+ const openClosedTabsRepresentedObject = null;
+ const openClosedTabsDisplayName = null;
+ this._openClosedTabsTabBarItem = new WI.PinnedTabBarItem(openClosedTabsRepresentedObject, "Images/Plus15.svg", openClosedTabsDisplayName, WI.UIString("Open closed tabs\u2026"));
+ this._openClosedTabsTabBarItem.hidden = true;
+ this.addTabBarItem(this._openClosedTabsTabBarItem, {suppressAnimations: true});
+
this._mouseDownPageX = NaN;
this._isDragging = false;
}
@@ -129,7 +133,7 @@
if (this._tabContainer.contains(nextSibling.element)) {
if (!(tabBarItem instanceof WI.PinnedTabBarItem) && nextSibling instanceof WI.PinnedTabBarItem)
- this._tabContainer.insertBefore(tabBarItem.element, this._tabPickerTabBarItem.element);
+ this._tabContainer.insertBefore(tabBarItem.element, this._pinnedButtons()[0].element);
else
this._tabContainer.insertBefore(tabBarItem.element, nextSibling.element);
} else {
@@ -136,11 +140,9 @@
if (tabBarItem instanceof WI.PinnedTabBarItem)
this._tabContainer.appendChild(tabBarItem.element);
else
- this._tabContainer.insertBefore(tabBarItem.element, this._tabPickerTabBarItem.element);
+ this._tabContainer.insertBefore(tabBarItem.element, this._pinnedButtons()[0].element);
}
- this._tabContainer.classList.toggle("single-tab", !this._hasMoreThanOneNormalTab());
-
tabBarItem.element.style.left = null;
tabBarItem.element.style.width = null;
@@ -232,10 +234,9 @@
this._tabBarItems.remove(tabBarItem);
tabBarItem.element.remove();
- var hasMoreThanOneNormalTab = this._hasMoreThanOneNormalTab();
- this._tabContainer.classList.toggle("single-tab", !hasMoreThanOneNormalTab);
+ this._openClosedTabsTabBarItem.hidden = !this._closedTabClasses().length;
- if (!hasMoreThanOneNormalTab || wasLastNormalTab || !options.suppressExpansion) {
+ if (!this._hasMoreThanOneNormalTab() || wasLastNormalTab || !options.suppressExpansion) {
if (!options.suppressAnimations) {
this._tabAnimatedClosedSinceMouseEnter = true;
this._finishExpandingTabsAfterClose(beforeTabSizesAndPositions);
@@ -376,7 +377,7 @@
selectTabBarItem(tabBarItemOrIndex, options = {})
{
let tabBarItem = this._findTabBarItem(tabBarItemOrIndex);
- if (tabBarItem === this._tabPickerTabBarItem) {
+ if (this._pinnedButtons().includes(tabBarItem)) {
// Get the last normal tab item if the item is not selectable.
tabBarItem = this._tabBarItems[this.normalTabCount - 1];
}
@@ -445,9 +446,17 @@
let normalTabBarItems = [];
for (let tabBarItem of this._tabBarItemsFromLeftToRight()) {
- if (tabBarItem === this._tabPickerTabBarItem) {
+ switch (tabBarItem) {
+ case this._showHiddenTabsTabBarItem:
tabBarItem.hidden = true;
continue;
+
+ case this._openClosedTabsTabBarItem:
+ tabBarItem.hidden = !this._closedTabClasses().length;
+ if (tabBarItem.hidden)
+ continue;
+ else
+ break; // Make sure to calculate its width below.
}
tabBarItem.hidden = false;
@@ -468,8 +477,8 @@
// Wait to measure widths until all `WI.TabBarItem` are un-hidden for the reason above.
let normalTabBarItemsWidth = normalTabBarItems.reduce((accumulator, tabBarItem) => accumulator + measureWidth(tabBarItem), 0);
if (Math.round(normalTabBarItemsWidth) >= Math.floor(availableSpace)) {
- this._tabPickerTabBarItem.hidden = false;
- availableSpace -= measureWidth(this._tabPickerTabBarItem);
+ this._showHiddenTabsTabBarItem.hidden = false;
+ availableSpace -= measureWidth(this._showHiddenTabsTabBarItem);
let index = normalTabBarItems.length - 1;
do {
@@ -501,11 +510,21 @@
// Private
+ _pinnedButtons()
+ {
+ return [this._showHiddenTabsTabBarItem, this._openClosedTabsTabBarItem];
+ }
+
_tabBarItemsFromLeftToRight()
{
return WI.resolvedLayoutDirection() === WI.LayoutDirection.LTR ? this._tabBarItems : this._tabBarItems.slice().reverse();
}
+ _closedTabClasses()
+ {
+ return Array.from(WI.knownTabClasses()).filter((tabClass) => WI.isNewTabWithTypeAllowed(tabClass.Type));
+ }
+
_findTabBarItem(tabBarItemOrIndex)
{
if (typeof tabBarItemOrIndex === "number")
@@ -661,29 +680,13 @@
if (tabBarItem.disabled)
return;
- if (tabBarItem === this._tabPickerTabBarItem) {
- if (!this._hiddenTabBarItems.length)
- return;
+ switch (tabBarItem) {
+ case this._showHiddenTabsTabBarItem:
+ this._handleShowHiddenTabsTabBarItemMouseDown(event);
+ return;
- if (this._ignoreTabPickerMouseDown)
- return;
-
- this._ignoreTabPickerMouseDown = true;
-
- let contextMenu = WI.ContextMenu.createFromEvent(event);
- contextMenu.addBeforeShowCallback(() => {
- this._ignoreTabPickerMouseDown = false;
- });
-
- for (let item of this._hiddenTabBarItems) {
- contextMenu.appendItem(item.displayName, () => {
- this.selectTabBarItem(item, {
- initiator: WI.TabBrowser.TabNavigationInitiator.ContextMenu
- });
- });
- }
-
- contextMenu.show();
+ case this._openClosedTabsTabBarItem:
+ this._handleAddClosedTabsTabBarItemMouseDown(event);
return;
}
@@ -716,40 +719,55 @@
event.stopPropagation();
}
- _handleTabContainerClick(event)
+ _handleShowHiddenTabsTabBarItemMouseDown(event)
{
- var itemElement = event.target.closest("." + WI.TabBarItem.StyleClassName);
- if (!itemElement)
+ if (!this._hiddenTabBarItems.length)
return;
- var tabBarItem = itemElement[WI.TabBarItem.ElementReferenceSymbol];
- if (!tabBarItem)
+ if (this._ignoreShowHiddenTabsTabBarItemMouseDown)
return;
- if (tabBarItem.disabled)
+ this._ignoreShowHiddenTabsTabBarItemMouseDown = true;
+
+ let contextMenu = WI.ContextMenu.createFromEvent(event);
+ contextMenu.addBeforeShowCallback(() => {
+ this._ignoreShowHiddenTabsTabBarItemMouseDown = false;
+ });
+
+ for (let item of this._hiddenTabBarItems) {
+ contextMenu.appendItem(item.displayName, () => {
+ this.selectTabBarItem(item, {
+ initiator: WI.TabBrowser.TabNavigationInitiator.ContextMenu
+ });
+ });
+ }
+
+ contextMenu.show();
+ }
+
+ _handleAddClosedTabsTabBarItemMouseDown(event)
+ {
+ let closedTabClasses = this._closedTabClasses();
+ if (!closedTabClasses.length)
return;
- if (event.button === 1) {
- // Disallow closing the only tab.
- if (this._tabContainer.classList.contains("single-tab"))
- return;
+ if (this._ignoreAddClosedTabsTabBarItemMouseDown)
+ return;
- if (!event.altKey) {
- let options = {
- suppressExpansion: true,
- initiatorHint: WI.TabBrowser.TabNavigationInitiator.TabClick,
- };
- this.removeTabBarItem(tabBarItem, options);
- return;
- }
+ this._ignoreAddClosedTabsTabBarItemMouseDown = true;
- for (let i = this._tabBarItems.length - 1; i >= 0; --i) {
- let item = this._tabBarItems[i];
- if (item === tabBarItem || item instanceof WI.PinnedTabBarItem)
- continue;
- this.removeTabBarItem(item);
- }
+ let contextMenu = WI.ContextMenu.createFromEvent(event);
+ contextMenu.addBeforeShowCallback(() => {
+ this._ignoreAddClosedTabsTabBarItemMouseDown = false;
+ });
+
+ for (let closedTabClass of closedTabClasses) {
+ contextMenu.appendItem(closedTabClass.tabInfo().displayName, () => {
+ WI.createNewTabWithType(closedTabClass.Type, {shouldShowNewTab: true});
+ });
}
+
+ contextMenu.show();
}
_handleMouseMoved(event)