Commit 4bcbaf1e authored by John Lee's avatar John Lee Committed by Commit Bot

Tab Strip WebUI: Add options to test MRU/auto-close behavior

This CL adds temporary checkboxes to the bottom right of the tab strip
to allow for easy testing of 4 modes:

1) Most Recently Used ordering with auto-closing tab strip
2) Most Recently Used ordering when tab strip is closed manually
3) Default ordering with auto-closing tab strip
4) Default ordering with no auto-closing tab strip

This CL also brings back drag-and-drop for unpinned tabs for cases where
MRU is disabled.

Bug: 989131, 1005554, 1005565
Change-Id: Iae066c2d85da712ecae29c040468cf67b31fd0d1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1867477
Commit-Queue: John Lee <johntlee@chromium.org>
Reviewed-by: default avatarDemetrios Papadopoulos <dpapad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#708018}
parent 25f42167
...@@ -13,6 +13,7 @@ js_type_check("closure_compile") { ...@@ -13,6 +13,7 @@ js_type_check("closure_compile") {
":tab", ":tab",
":tab_list", ":tab_list",
":tab_strip_embedder_proxy", ":tab_strip_embedder_proxy",
":tab_strip_options",
":tabs_api_proxy", ":tabs_api_proxy",
] ]
} }
...@@ -36,6 +37,7 @@ js_library("tabs_api_proxy") { ...@@ -36,6 +37,7 @@ js_library("tabs_api_proxy") {
js_library("tab") { js_library("tab") {
deps = [ deps = [
"//ui/webui/resources/js:icon.m", "//ui/webui/resources/js:icon.m",
"//ui/webui/resources/js:load_time_data.m",
] ]
} }
...@@ -48,6 +50,9 @@ js_library("tab_strip_embedder_proxy") { ...@@ -48,6 +50,9 @@ js_library("tab_strip_embedder_proxy") {
] ]
} }
js_library("tab_strip_options") {
}
group("tab_strip_modules") { group("tab_strip_modules") {
deps = [ deps = [
":alert_indicator_module", ":alert_indicator_module",
......
...@@ -8,6 +8,7 @@ import {getFavicon} from 'chrome://resources/js/icon.m.js'; ...@@ -8,6 +8,7 @@ import {getFavicon} from 'chrome://resources/js/icon.m.js';
import {AlertIndicatorsElement} from './alert_indicators.js'; import {AlertIndicatorsElement} from './alert_indicators.js';
import {CustomElement} from './custom_element.js'; import {CustomElement} from './custom_element.js';
import {TabStripEmbedderProxy} from './tab_strip_embedder_proxy.js'; import {TabStripEmbedderProxy} from './tab_strip_embedder_proxy.js';
import {tabStripOptions} from './tab_strip_options.js';
import {TabData, TabNetworkState, TabsApiProxy} from './tabs_api_proxy.js'; import {TabData, TabNetworkState, TabsApiProxy} from './tabs_api_proxy.js';
export const DEFAULT_ANIMATION_DURATION = 125; export const DEFAULT_ANIMATION_DURATION = 125;
...@@ -87,7 +88,7 @@ export class TabElement extends CustomElement { ...@@ -87,7 +88,7 @@ export class TabElement extends CustomElement {
tab.networkState === TabNetworkState.LOADING); tab.networkState === TabNetworkState.LOADING);
this.toggleAttribute('pinned', tab.pinned); this.toggleAttribute('pinned', tab.pinned);
this.toggleAttribute('blocked_', tab.blocked); this.toggleAttribute('blocked_', tab.blocked);
this.setAttribute('draggable', tab.pinned); this.setAttribute('draggable', true);
this.toggleAttribute('crashed_', tab.crashed); this.toggleAttribute('crashed_', tab.crashed);
if (!this.tab_ || this.tab_.title !== tab.title) { if (!this.tab_ || this.tab_.title !== tab.title) {
...@@ -140,7 +141,10 @@ export class TabElement extends CustomElement { ...@@ -140,7 +141,10 @@ export class TabElement extends CustomElement {
} }
this.tabsApi_.activateTab(this.tab_.id); this.tabsApi_.activateTab(this.tab_.id);
this.embedderApi_.closeContainer();
if (tabStripOptions.autoCloseEnabled) {
this.embedderApi_.closeContainer();
}
} }
/** @private */ /** @private */
......
...@@ -33,7 +33,25 @@ ...@@ -33,7 +33,25 @@
#tabsContainer tabstrip-tab:not(:last-child) { #tabsContainer tabstrip-tab:not(:last-child) {
margin-inline-end: 16px; margin-inline-end: 16px;
} }
#demoOptions {
bottom: 15px;
display: none;
font-size: 16px;
position: fixed;
right: 15px;
}
</style> </style>
<div id="pinnedTabsContainer"></div> <div id="pinnedTabsContainer"></div>
<div id="tabsContainer"></div> <div id="tabsContainer"></div>
<div id="demoOptions">
<label>
<input type="checkbox" id="mruCheckbox">MRU model
</label>
<label>
<input type="checkbox" id="autoCloseCheckbox">Auto-close
</label>
</div>
...@@ -2,14 +2,17 @@ ...@@ -2,14 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import './strings.m.js';
import './tab.js'; import './tab.js';
import {assert} from 'chrome://resources/js/assert.m.js'; import {assert} from 'chrome://resources/js/assert.m.js';
import {addWebUIListener} from 'chrome://resources/js/cr.m.js'; import {addWebUIListener} from 'chrome://resources/js/cr.m.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
import {CustomElement} from './custom_element.js'; import {CustomElement} from './custom_element.js';
import {TabElement} from './tab.js'; import {TabElement} from './tab.js';
import {TabStripEmbedderProxy} from './tab_strip_embedder_proxy.js'; import {TabStripEmbedderProxy} from './tab_strip_embedder_proxy.js';
import {tabStripOptions} from './tab_strip_options.js';
import {TabData, TabsApiProxy} from './tabs_api_proxy.js'; import {TabData, TabsApiProxy} from './tabs_api_proxy.js';
/** /**
...@@ -84,6 +87,23 @@ class TabListElement extends CustomElement { ...@@ -84,6 +87,23 @@ class TabListElement extends CustomElement {
'dragover', (e) => this.onDragOver_(/** @type {!DragEvent} */ (e))); 'dragover', (e) => this.onDragOver_(/** @type {!DragEvent} */ (e)));
document.addEventListener( document.addEventListener(
'visibilitychange', () => this.moveOrScrollToActiveTab_()); 'visibilitychange', () => this.moveOrScrollToActiveTab_());
if (loadTimeData.getBoolean('showDemoOptions')) {
this.shadowRoot.querySelector('#demoOptions').style.display = 'block';
const mruCheckbox = this.shadowRoot.querySelector('#mruCheckbox');
mruCheckbox.checked = tabStripOptions.mruEnabled;
mruCheckbox.addEventListener('change', () => {
tabStripOptions.mruEnabled = mruCheckbox.checked;
});
const autoCloseCheckbox =
this.shadowRoot.querySelector('#autoCloseCheckbox');
autoCloseCheckbox.checked = tabStripOptions.autoCloseEnabled;
autoCloseCheckbox.addEventListener('change', () => {
tabStripOptions.autoCloseEnabled = autoCloseCheckbox.checked;
});
}
} }
/** /**
...@@ -178,7 +198,8 @@ class TabListElement extends CustomElement { ...@@ -178,7 +198,8 @@ class TabListElement extends CustomElement {
return; return;
} }
if (!this.tabStripEmbedderProxy_.isVisible() && !activeTab.tab.pinned && if (tabStripOptions.mruEnabled &&
!this.tabStripEmbedderProxy_.isVisible() && !activeTab.tab.pinned &&
this.tabsContainerElement_.firstChild !== activeTab) { this.tabsContainerElement_.firstChild !== activeTab) {
this.tabsApi_.moveTab( this.tabsApi_.moveTab(
activeTab.tab.id, this.pinnedTabsContainerElement_.childElementCount); activeTab.tab.id, this.pinnedTabsContainerElement_.childElementCount);
...@@ -210,14 +231,19 @@ class TabListElement extends CustomElement { ...@@ -210,14 +231,19 @@ class TabListElement extends CustomElement {
return pathItem !== this.draggedItem_ && isTabElement(pathItem); return pathItem !== this.draggedItem_ && isTabElement(pathItem);
}); });
if (!dragOverItem || !this.draggedItem_ || !dragOverItem.tab.pinned) { if (!dragOverItem || !this.draggedItem_ ||
dragOverItem.tab.pinned !== this.draggedItem_.tab.pinned) {
return; return;
} }
event.dataTransfer.dropEffect = 'move'; event.dataTransfer.dropEffect = 'move';
const dragOverIndex = let dragOverIndex =
Array.from(dragOverItem.parentNode.children).indexOf(dragOverItem); Array.from(dragOverItem.parentNode.children).indexOf(dragOverItem);
if (!this.draggedItem_.tab.pinned) {
dragOverIndex += this.pinnedTabsContainerElement_.childElementCount;
}
this.tabsApi_.moveTab(this.draggedItem_.tab.id, dragOverIndex); this.tabsApi_.moveTab(this.draggedItem_.tab.id, dragOverIndex);
} }
...@@ -231,7 +257,16 @@ class TabListElement extends CustomElement { ...@@ -231,7 +257,16 @@ class TabListElement extends CustomElement {
return; return;
} }
assert(draggedItem.tab.pinned); if (tabStripOptions.mruEnabled && !draggedItem.tab.pinned) {
// If MRU is enabled, unpinned tabs should not be draggable.
event.preventDefault();
return;
}
if (tabStripOptions.mruEnabled) {
assert(draggedItem.tab.pinned);
}
this.draggedItem_ = /** @type {!TabElement} */ (draggedItem); this.draggedItem_ = /** @type {!TabElement} */ (draggedItem);
this.draggedItem_.setDragging(true); this.draggedItem_.setDragging(true);
event.dataTransfer.effectAllowed = 'move'; event.dataTransfer.effectAllowed = 'move';
...@@ -273,7 +308,7 @@ class TabListElement extends CustomElement { ...@@ -273,7 +308,7 @@ class TabListElement extends CustomElement {
onTabCreated_(tab) { onTabCreated_(tab) {
const tabElement = this.createTabElement_(tab); const tabElement = this.createTabElement_(tab);
if (tab.active && !tab.pinned && if (tabStripOptions.mruEnabled && tab.active && !tab.pinned &&
tab.index !== this.pinnedTabsContainerElement_.childElementCount) { tab.index !== this.pinnedTabsContainerElement_.childElementCount) {
// Newly created active tabs should first be moved to the very beginning // Newly created active tabs should first be moved to the very beginning
// of the tab strip to enforce the tab strip's most recently used ordering // of the tab strip to enforce the tab strip's most recently used ordering
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* TODO(johntlee): Remove after settling on desired behavior.
* An object of various options to test various behaviors of the Tab Strip.
* @const {!Object<string, boolean>}
*/
export const tabStripOptions = {
autoCloseEnabled: true,
mruEnabled: true,
};
...@@ -56,6 +56,11 @@ ...@@ -56,6 +56,11 @@
file="tab_strip_embedder_proxy.js" file="tab_strip_embedder_proxy.js"
type="chrome_html" type="chrome_html"
compress="gzip"/> compress="gzip"/>
<structure
name="IDR_TAB_STRIP_OPTIONS_JS"
file="tab_strip_options.js"
type="chrome_html"
compress="gzip"/>
</structures> </structures>
<includes> <includes>
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/base64.h" #include "base/base64.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/feature_list.h"
#include "base/strings/string_piece.h" #include "base/strings/string_piece.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/extensions/extension_tab_util.h"
...@@ -26,6 +27,7 @@ ...@@ -26,6 +27,7 @@
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "chrome/browser/ui/tabs/tab_utils.h" #include "chrome/browser/ui/tabs/tab_utils.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/webui/favicon_source.h" #include "chrome/browser/ui/webui/favicon_source.h"
#include "chrome/browser/ui/webui/theme_handler.h" #include "chrome/browser/ui/webui/theme_handler.h"
#include "chrome/common/webui_url_constants.h" #include "chrome/common/webui_url_constants.h"
...@@ -431,6 +433,11 @@ TabStripUI::TabStripUI(content::WebUI* web_ui) ...@@ -431,6 +433,11 @@ TabStripUI::TabStripUI(content::WebUI* web_ui)
color_utils::SkColorToRgbaString( color_utils::SkColorToRgbaString(
tp.GetColor(ThemeProperties::COLOR_FRAME))); tp.GetColor(ThemeProperties::COLOR_FRAME)));
html_source->AddBoolean(
"showDemoOptions",
base::FeatureList::IsEnabled(features::kWebUITabStripDemoOptions));
html_source->UseStringsJs();
content::WebUIDataSource::Add(profile, html_source); content::WebUIDataSource::Add(profile, html_source);
content::URLDataSource::Add( content::URLDataSource::Add(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment