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") {
":tab",
":tab_list",
":tab_strip_embedder_proxy",
":tab_strip_options",
":tabs_api_proxy",
]
}
......@@ -36,6 +37,7 @@ js_library("tabs_api_proxy") {
js_library("tab") {
deps = [
"//ui/webui/resources/js:icon.m",
"//ui/webui/resources/js:load_time_data.m",
]
}
......@@ -48,6 +50,9 @@ js_library("tab_strip_embedder_proxy") {
]
}
js_library("tab_strip_options") {
}
group("tab_strip_modules") {
deps = [
":alert_indicator_module",
......
......@@ -8,6 +8,7 @@ import {getFavicon} from 'chrome://resources/js/icon.m.js';
import {AlertIndicatorsElement} from './alert_indicators.js';
import {CustomElement} from './custom_element.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';
export const DEFAULT_ANIMATION_DURATION = 125;
......@@ -87,7 +88,7 @@ export class TabElement extends CustomElement {
tab.networkState === TabNetworkState.LOADING);
this.toggleAttribute('pinned', tab.pinned);
this.toggleAttribute('blocked_', tab.blocked);
this.setAttribute('draggable', tab.pinned);
this.setAttribute('draggable', true);
this.toggleAttribute('crashed_', tab.crashed);
if (!this.tab_ || this.tab_.title !== tab.title) {
......@@ -140,7 +141,10 @@ export class TabElement extends CustomElement {
}
this.tabsApi_.activateTab(this.tab_.id);
this.embedderApi_.closeContainer();
if (tabStripOptions.autoCloseEnabled) {
this.embedderApi_.closeContainer();
}
}
/** @private */
......
......@@ -33,7 +33,25 @@
#tabsContainer tabstrip-tab:not(:last-child) {
margin-inline-end: 16px;
}
#demoOptions {
bottom: 15px;
display: none;
font-size: 16px;
position: fixed;
right: 15px;
}
</style>
<div id="pinnedTabsContainer"></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 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import './strings.m.js';
import './tab.js';
import {assert} from 'chrome://resources/js/assert.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 {TabElement} from './tab.js';
import {TabStripEmbedderProxy} from './tab_strip_embedder_proxy.js';
import {tabStripOptions} from './tab_strip_options.js';
import {TabData, TabsApiProxy} from './tabs_api_proxy.js';
/**
......@@ -84,6 +87,23 @@ class TabListElement extends CustomElement {
'dragover', (e) => this.onDragOver_(/** @type {!DragEvent} */ (e)));
document.addEventListener(
'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 {
return;
}
if (!this.tabStripEmbedderProxy_.isVisible() && !activeTab.tab.pinned &&
if (tabStripOptions.mruEnabled &&
!this.tabStripEmbedderProxy_.isVisible() && !activeTab.tab.pinned &&
this.tabsContainerElement_.firstChild !== activeTab) {
this.tabsApi_.moveTab(
activeTab.tab.id, this.pinnedTabsContainerElement_.childElementCount);
......@@ -210,14 +231,19 @@ class TabListElement extends CustomElement {
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;
}
event.dataTransfer.dropEffect = 'move';
const dragOverIndex =
let dragOverIndex =
Array.from(dragOverItem.parentNode.children).indexOf(dragOverItem);
if (!this.draggedItem_.tab.pinned) {
dragOverIndex += this.pinnedTabsContainerElement_.childElementCount;
}
this.tabsApi_.moveTab(this.draggedItem_.tab.id, dragOverIndex);
}
......@@ -231,7 +257,16 @@ class TabListElement extends CustomElement {
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_.setDragging(true);
event.dataTransfer.effectAllowed = 'move';
......@@ -273,7 +308,7 @@ class TabListElement extends CustomElement {
onTabCreated_(tab) {
const tabElement = this.createTabElement_(tab);
if (tab.active && !tab.pinned &&
if (tabStripOptions.mruEnabled && tab.active && !tab.pinned &&
tab.index !== this.pinnedTabsContainerElement_.childElementCount) {
// 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
......
// 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 @@
file="tab_strip_embedder_proxy.js"
type="chrome_html"
compress="gzip"/>
<structure
name="IDR_TAB_STRIP_OPTIONS_JS"
file="tab_strip_options.js"
type="chrome_html"
compress="gzip"/>
</structures>
<includes>
......
......@@ -11,6 +11,7 @@
#include "base/base64.h"
#include "base/bind.h"
#include "base/feature_list.h"
#include "base/strings/string_piece.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_tab_util.h"
......@@ -26,6 +27,7 @@
#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_utils.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/webui/favicon_source.h"
#include "chrome/browser/ui/webui/theme_handler.h"
#include "chrome/common/webui_url_constants.h"
......@@ -431,6 +433,11 @@ TabStripUI::TabStripUI(content::WebUI* web_ui)
color_utils::SkColorToRgbaString(
tp.GetColor(ThemeProperties::COLOR_FRAME)));
html_source->AddBoolean(
"showDemoOptions",
base::FeatureList::IsEnabled(features::kWebUITabStripDemoOptions));
html_source->UseStringsJs();
content::WebUIDataSource::Add(profile, html_source);
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