summaryrefslogtreecommitdiff
path: root/chromium/chrome/browser/resources/tab_strip
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/chrome/browser/resources/tab_strip
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/chrome/browser/resources/tab_strip')
-rw-r--r--chromium/chrome/browser/resources/tab_strip/drag_manager.js19
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab.js26
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab_group.js21
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab_list.html3
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab_list.js227
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab_strip_embedder_proxy.js97
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd60
-rw-r--r--chromium/chrome/browser/resources/tab_strip/tabs_api_proxy.js94
8 files changed, 377 insertions, 170 deletions
diff --git a/chromium/chrome/browser/resources/tab_strip/drag_manager.js b/chromium/chrome/browser/resources/tab_strip/drag_manager.js
index 69b836bf742..b50733200f8 100644
--- a/chromium/chrome/browser/resources/tab_strip/drag_manager.js
+++ b/chromium/chrome/browser/resources/tab_strip/drag_manager.js
@@ -9,7 +9,7 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
import {isTabElement, TabElement} from './tab.js';
import {isTabGroupElement, TabGroupElement} from './tab_group.js';
-import {TabData, TabNetworkState, TabsApiProxy} from './tabs_api_proxy.js';
+import {TabData, TabNetworkState, TabsApiProxy, TabsApiProxyImpl} from './tabs_api_proxy.js';
/** @const {number} */
export const PLACEHOLDER_TAB_ID = -1;
@@ -107,7 +107,7 @@ class DragSession {
this.srcGroup = srcGroup;
/** @private @const {!TabsApiProxy} */
- this.tabsProxy_ = TabsApiProxy.getInstance();
+ this.tabsProxy_ = TabsApiProxyImpl.getInstance();
}
/**
@@ -359,7 +359,8 @@ class DragSession {
const dragOverTabElement =
/** @type {!TabElement|undefined} */ (composedPath.find(isTabElement));
- if (dragOverTabElement && !dragOverTabElement.tab.pinned) {
+ if (dragOverTabElement && !dragOverTabElement.tab.pinned &&
+ dragOverTabElement.isValidDragOverTarget) {
let dragOverIndex = this.delegate_.getIndexOfTab(dragOverTabElement);
dragOverIndex +=
this.shouldOffsetIndexForGroup_(dragOverTabElement) ? 1 : 0;
@@ -369,7 +370,7 @@ class DragSession {
const dragOverGroupElement = /** @type {!TabGroupElement|undefined} */ (
composedPath.find(isTabGroupElement));
- if (dragOverGroupElement) {
+ if (dragOverGroupElement && dragOverGroupElement.isValidDragOverTarget) {
let dragOverIndex = this.delegate_.getIndexOfTab(
/** @type {!TabElement} */ (dragOverGroupElement.firstElementChild));
dragOverIndex +=
@@ -388,8 +389,9 @@ class DragSession {
const dragOverTabElement =
/** @type {?TabElement} */ (composedPath.find(isTabElement));
if (dragOverTabElement &&
- dragOverTabElement.tab.pinned !== tabElement.tab.pinned) {
- // Can only drag between the same pinned states.
+ (dragOverTabElement.tab.pinned !== tabElement.tab.pinned ||
+ !dragOverTabElement.isValidDragOverTarget)) {
+ // Can only drag between the same pinned states and valid TabElements.
return;
}
@@ -401,7 +403,8 @@ class DragSession {
const dragOverTabGroup =
/** @type {?TabGroupElement} */ (composedPath.find(isTabGroupElement));
if (dragOverTabGroup &&
- dragOverTabGroup.dataset.groupId !== previousGroupId) {
+ dragOverTabGroup.dataset.groupId !== previousGroupId &&
+ dragOverTabGroup.isValidDragOverTarget) {
this.delegate_.placeTabElement(
tabElement, this.dstIndex, false, dragOverTabGroup.dataset.groupId);
return;
@@ -433,7 +436,7 @@ export class DragManager {
this.dragSession_ = null;
/** @private {!TabsApiProxy} */
- this.tabsProxy_ = TabsApiProxy.getInstance();
+ this.tabsProxy_ = TabsApiProxyImpl.getInstance();
}
/** @private */
diff --git a/chromium/chrome/browser/resources/tab_strip/tab.js b/chromium/chrome/browser/resources/tab_strip/tab.js
index 4c6fbb904e1..61da08df076 100644
--- a/chromium/chrome/browser/resources/tab_strip/tab.js
+++ b/chromium/chrome/browser/resources/tab_strip/tab.js
@@ -11,10 +11,10 @@ import {isRTL} from 'chrome://resources/js/util.m.js';
import {AlertIndicatorsElement} from './alert_indicators.js';
import {CustomElement} from './custom_element.js';
-import {TabStripEmbedderProxy} from './tab_strip_embedder_proxy.js';
+import {TabStripEmbedderProxy, TabStripEmbedderProxyImpl} from './tab_strip_embedder_proxy.js';
import {tabStripOptions} from './tab_strip_options.js';
import {TabSwiper} from './tab_swiper.js';
-import {CloseTabAction, TabData, TabNetworkState, TabsApiProxy} from './tabs_api_proxy.js';
+import {CloseTabAction, TabData, TabNetworkState, TabsApiProxy, TabsApiProxyImpl} from './tabs_api_proxy.js';
const DEFAULT_ANIMATION_DURATION = 125;
@@ -84,14 +84,22 @@ export class TabElement extends CustomElement {
this.tab_;
/** @private {!TabsApiProxy} */
- this.tabsApi_ = TabsApiProxy.getInstance();
+ this.tabsApi_ = TabsApiProxyImpl.getInstance();
/** @private {!TabStripEmbedderProxy} */
- this.embedderApi_ = TabStripEmbedderProxy.getInstance();
+ this.embedderApi_ = TabStripEmbedderProxyImpl.getInstance();
/** @private {!HTMLElement} */
this.titleTextEl_ = /** @type {!HTMLElement} */ (this.$('#titleText'));
+ /**
+ * Flag indicating if this TabElement can accept dragover events. This
+ * is used to pause dragover events while animating as animating causes
+ * the elements below the pointer to shift.
+ * @private {boolean}
+ */
+ this.isValidDragOverTarget_ = true;
+
this.tabEl_.addEventListener('click', () => this.onClick_());
this.tabEl_.addEventListener('contextmenu', e => this.onContextMenu_(e));
this.tabEl_.addEventListener(
@@ -169,6 +177,16 @@ export class TabElement extends CustomElement {
this.tab_ = Object.freeze(tab);
}
+ /** @return {boolean} */
+ get isValidDragOverTarget() {
+ return !this.hasAttribute('dragging_') && this.isValidDragOverTarget_;
+ }
+
+ /** @param {boolean} isValid */
+ set isValidDragOverTarget(isValid) {
+ this.isValidDragOverTarget_ = isValid;
+ }
+
/** @param {!Function} callback */
set onTabActivating(callback) {
this.onTabActivating_ = callback;
diff --git a/chromium/chrome/browser/resources/tab_strip/tab_group.js b/chromium/chrome/browser/resources/tab_strip/tab_group.js
index e50abdbf55a..cfd47a53868 100644
--- a/chromium/chrome/browser/resources/tab_strip/tab_group.js
+++ b/chromium/chrome/browser/resources/tab_strip/tab_group.js
@@ -5,7 +5,7 @@
import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
import {CustomElement} from './custom_element.js';
-import {TabStripEmbedderProxy} from './tab_strip_embedder_proxy.js';
+import {TabStripEmbedderProxy, TabStripEmbedderProxyImpl} from './tab_strip_embedder_proxy.js';
import {TabGroupVisualData} from './tabs_api_proxy.js';
export class TabGroupElement extends CustomElement {
@@ -17,13 +17,30 @@ export class TabGroupElement extends CustomElement {
super();
/** @private @const {!TabStripEmbedderProxy} */
- this.embedderApi_ = TabStripEmbedderProxy.getInstance();
+ this.embedderApi_ = TabStripEmbedderProxyImpl.getInstance();
/** @private @const {!HTMLElement} */
this.chip_ = /** @type {!HTMLElement} */ (this.$('#chip'));
this.chip_.addEventListener('click', () => this.onClickChip_());
this.chip_.addEventListener(
'keydown', e => this.onKeydownChip_(/** @type {!KeyboardEvent} */ (e)));
+
+ /**
+ * Flag indicating if this element can accept dragover events. This flag
+ * is updated by TabListElement while animating.
+ * @private {boolean}
+ */
+ this.isValidDragOverTarget_ = true;
+ }
+
+ /** @return {boolean} */
+ get isValidDragOverTarget() {
+ return !this.hasAttribute('dragging_') && this.isValidDragOverTarget_;
+ }
+
+ /** @param {boolean} isValid */
+ set isValidDragOverTarget(isValid) {
+ this.isValidDragOverTarget_ = isValid;
}
/** @return {!HTMLElement} */
diff --git a/chromium/chrome/browser/resources/tab_strip/tab_list.html b/chromium/chrome/browser/resources/tab_strip/tab_list.html
index 12be60a5f39..f6cb511ab76 100644
--- a/chromium/chrome/browser/resources/tab_strip/tab_list.html
+++ b/chromium/chrome/browser/resources/tab_strip/tab_list.html
@@ -41,11 +41,12 @@
* tab. 20px is subtracted from the height of an unpinned tab as there
* are two 10px gaps to separate each of the 3 pinned tabs. */
--tabstrip-pinned-tab-size: calc((var(--tabstrip-tab-height) - 20px) / 3);
+ --tabstrip-tab-spacing: 10px;
display: grid;
grid-auto-columns: var(--tabstrip-pinned-tab-size);
grid-auto-flow: column;
- grid-gap: 10px;
+ grid-gap: var(--tabstrip-tab-spacing);
grid-template-rows: repeat(3, var(--tabstrip-pinned-tab-size));
padding-block-end: var(--tabstrip-tab-list-vertical-padding);
padding-block-start: var(--tabstrip-tab-list-vertical-padding);
diff --git a/chromium/chrome/browser/resources/tab_strip/tab_list.js b/chromium/chrome/browser/resources/tab_strip/tab_list.js
index 08ac72db837..5ab5de62076 100644
--- a/chromium/chrome/browser/resources/tab_strip/tab_list.js
+++ b/chromium/chrome/browser/resources/tab_strip/tab_list.js
@@ -15,11 +15,11 @@ import {isRTL} from 'chrome://resources/js/util.m.js';
import {CustomElement} from './custom_element.js';
import {DragManager, DragManagerDelegate} from './drag_manager.js';
-import {TabElement} from './tab.js';
+import {isTabElement, TabElement} from './tab.js';
import {isTabGroupElement, TabGroupElement} from './tab_group.js';
-import {TabStripEmbedderProxy} from './tab_strip_embedder_proxy.js';
+import {TabStripEmbedderProxy, TabStripEmbedderProxyImpl} from './tab_strip_embedder_proxy.js';
import {tabStripOptions} from './tab_strip_options.js';
-import {TabData, TabGroupVisualData, TabsApiProxy} from './tabs_api_proxy.js';
+import {TabData, TabGroupVisualData, TabsApiProxy, TabsApiProxyImpl} from './tabs_api_proxy.js';
/**
* The amount of padding to leave between the edge of the screen and the active
@@ -47,8 +47,88 @@ const LayoutVariable = {
TAB_WIDTH: '--tabstrip-tab-thumbnail-width',
};
+/**
+ * Animates a series of elements to indicate that tabs have moved position.
+ * @param {!Element} movedElement
+ * @param {number} prevIndex
+ * @param {number} newIndex
+ */
+function animateElementMoved(movedElement, prevIndex, newIndex) {
+ // Direction is -1 for moving towards a lower index, +1 for moving
+ // towards a higher index. If moving towards a lower index, the TabList needs
+ // to animate everything from the movedElement's current index to its prev
+ // index by traversing the nextElementSibling of each element because the
+ // movedElement is now at a preceding position from all the elements it has
+ // slid across. If moving towards a higher index, the TabList needs to
+ // traverse the previousElementSiblings.
+ const direction = Math.sign(newIndex - prevIndex);
+
+ /**
+ * @param {!Element} element
+ * @return {?Element}
+ */
+ function getSiblingToAnimate(element) {
+ return direction === -1 ? element.nextElementSibling :
+ element.previousElementSibling;
+ }
+ let elementToAnimate = getSiblingToAnimate(movedElement);
+ for (let i = newIndex; i !== prevIndex && elementToAnimate; i -= direction) {
+ const elementToAnimatePrevIndex = i;
+ const elementToAnimateNewIndex = i - direction;
+ slideElement(
+ elementToAnimate, elementToAnimatePrevIndex, elementToAnimateNewIndex);
+ elementToAnimate = getSiblingToAnimate(elementToAnimate);
+ }
+
+ slideElement(movedElement, prevIndex, newIndex);
+}
+
+/**
+ * Animates the slide of an element across the tab strip (both vertically and
+ * horizontally for pinned tabs, and horizontally for other tabs and groups).
+ * @param {!Element} element
+ * @param {number} prevIndex
+ * @param {number} newIndex
+ */
+function slideElement(element, prevIndex, newIndex) {
+ let horizontalMovement = newIndex - prevIndex;
+ let verticalMovement = 0;
+
+ if (isTabElement(element) && element.tab.pinned) {
+ const pinnedTabsPerColumn = 3;
+ const columnChange = Math.floor(newIndex / pinnedTabsPerColumn) -
+ Math.floor(prevIndex / pinnedTabsPerColumn);
+ horizontalMovement = columnChange;
+ verticalMovement =
+ (newIndex - prevIndex) - (columnChange * pinnedTabsPerColumn);
+ }
+
+ horizontalMovement *= isRTL() ? -1 : 1;
+
+ const translateX = `calc(${horizontalMovement * -1} * ` +
+ '(var(--tabstrip-tab-width) + var(--tabstrip-tab-spacing)))';
+ const translateY = `calc(${verticalMovement * -1} * ` +
+ '(var(--tabstrip-tab-height) + var(--tabstrip-tab-spacing)))';
+
+ element.isValidDragOverTarget = false;
+ const animation = element.animate(
+ [
+ {transform: `translate(${translateX}, ${translateY})`},
+ {transform: 'translate(0, 0)'},
+ ],
+ {
+ duration: 120,
+ easing: 'ease-out',
+ });
+ function onComplete() {
+ element.isValidDragOverTarget = true;
+ }
+ animation.oncancel = onComplete;
+ animation.onfinish = onComplete;
+}
+
/** @implements {DragManagerDelegate} */
-class TabListElement extends CustomElement {
+export class TabListElement extends CustomElement {
static get template() {
return `{__html_template__}`;
}
@@ -122,10 +202,10 @@ class TabListElement extends CustomElement {
this.pinnedTabsElement_ = /** @type {!Element} */ (this.$('#pinnedTabs'));
/** @private {!TabStripEmbedderProxy} */
- this.tabStripEmbedderProxy_ = TabStripEmbedderProxy.getInstance();
+ this.tabStripEmbedderProxy_ = TabStripEmbedderProxyImpl.getInstance();
/** @private {!TabsApiProxy} */
- this.tabsApi_ = TabsApiProxy.getInstance();
+ this.tabsApi_ = TabsApiProxyImpl.getInstance();
/** @private {!Element} */
this.unpinnedTabsElement_ =
@@ -265,7 +345,9 @@ class TabListElement extends CustomElement {
this.addWebUIListener_('tab-created', tab => this.onTabCreated_(tab));
this.addWebUIListener_(
- 'tab-moved', (tabId, newIndex) => this.onTabMoved_(tabId, newIndex));
+ 'tab-moved',
+ (tabId, newIndex, pinned) =>
+ this.onTabMoved_(tabId, newIndex, pinned));
this.addWebUIListener_('tab-removed', tabId => this.onTabRemoved_(tabId));
this.addWebUIListener_(
'tab-replaced', (oldId, newId) => this.onTabReplaced_(oldId, newId));
@@ -556,13 +638,13 @@ class TabListElement extends CustomElement {
/**
* @param {number} tabId
* @param {number} newIndex
+ * @param {boolean} pinned
* @private
*/
- onTabMoved_(tabId, newIndex) {
+ onTabMoved_(tabId, newIndex, pinned) {
const movedTab = this.findTabElement_(tabId);
if (movedTab) {
- this.placeTabElement(
- movedTab, newIndex, movedTab.tab.pinned, movedTab.tab.groupId);
+ this.placeTabElement(movedTab, newIndex, pinned, movedTab.tab.groupId);
if (movedTab.tab.active) {
this.scrollToTab_(movedTab);
}
@@ -638,50 +720,14 @@ class TabListElement extends CustomElement {
placeTabElement(element, index, pinned, groupId) {
const isInserting = !element.isConnected;
- // Remove the element if it already exists in the DOM.
- element.remove();
-
- if (pinned) {
- this.pinnedTabsElement_.insertBefore(
- element, this.pinnedTabsElement_.childNodes[index]);
- } else {
- let elementToInsert = element;
- let elementAtIndex = this.$all('tabstrip-tab').item(index);
- let parentElement = this.unpinnedTabsElement_;
-
- if (groupId) {
- let tabGroupElement = this.findTabGroupElement_(groupId);
- if (tabGroupElement) {
- // If a TabGroupElement already exists, add the TabElement to it.
- parentElement = tabGroupElement;
- } else {
- // If a TabGroupElement does not exist, create one and add the
- // TabGroupElement into the DOM.
- tabGroupElement = document.createElement('tabstrip-tab-group');
- tabGroupElement.setAttribute('data-group-id', groupId);
- tabGroupElement.appendChild(element);
- elementToInsert = tabGroupElement;
- }
- }
-
- if (elementAtIndex && elementAtIndex.parentElement &&
- isTabGroupElement(elementAtIndex.parentElement) &&
- (elementAtIndex.previousElementSibling === null &&
- elementAtIndex.tab.groupId !== groupId)) {
- // If the element at the model index is in a group, and the group is
- // different from the new tab's group, and is the first element in its
- // group, insert the new element before its TabGroupElement. If a
- // TabElement is being sandwiched between two TabElements in a group, it
- // can be assumed that the tab will eventually be inserted into the
- // group as well.
- elementAtIndex = elementAtIndex.parentElement;
- }
+ const previousIndex = isInserting ? -1 : this.getIndexOfTab(element);
+ const previousParent = element.parentElement;
+ this.updateTabElementDomPosition_(element, index, pinned, groupId);
- if (elementAtIndex && elementAtIndex.parentElement === parentElement) {
- parentElement.insertBefore(elementToInsert, elementAtIndex);
- } else {
- parentElement.appendChild(elementToInsert);
- }
+ if (!isInserting && previousParent === element.parentElement) {
+ // Only animate if the tab is being moved within the same parent. Tab
+ // moves that change pinned state or grouped states do not animate.
+ animateElementMoved(element, previousIndex, index);
}
if (isInserting) {
@@ -694,7 +740,15 @@ class TabListElement extends CustomElement {
* @param {number} index
*/
placeTabGroupElement(element, index) {
- element.remove();
+ const previousDomIndex =
+ Array.from(this.unpinnedTabsElement_.children).indexOf(element);
+ if (element.isConnected && element.childElementCount &&
+ this.getIndexOfTab(
+ /** @type {!TabElement} */ (element.firstElementChild)) < index) {
+ // If moving after its original position, the index value needs to be
+ // offset by 1 to consider itself already attached to the DOM.
+ index++;
+ }
let elementAtIndex = this.$all('tabstrip-tab')[index];
if (elementAtIndex && elementAtIndex.parentElement &&
@@ -703,6 +757,14 @@ class TabListElement extends CustomElement {
}
this.unpinnedTabsElement_.insertBefore(element, elementAtIndex);
+
+ // Animating the TabGroupElement move should be treated the same as
+ // animating a TabElement. Therefore, treat indices as if they were mere
+ // tabs and do not use the group's model index as they are not as accurate
+ // in representing DOM movements.
+ animateElementMoved(
+ element, previousDomIndex,
+ Array.from(this.unpinnedTabsElement_.children).indexOf(element));
}
/** @private */
@@ -775,6 +837,63 @@ class TabListElement extends CustomElement {
}
/**
+ * @param {!TabElement} element
+ * @param {number} index
+ * @param {boolean} pinned
+ * @param {string=} groupId
+ * @private
+ */
+ updateTabElementDomPosition_(element, index, pinned, groupId) {
+ // Remove the element if it already exists in the DOM. This simplifies
+ // the way indices work as it does not have to count its old index in
+ // the initial layout of the DOM.
+ element.remove();
+
+ if (pinned) {
+ this.pinnedTabsElement_.insertBefore(
+ element, this.pinnedTabsElement_.childNodes[index]);
+ } else {
+ let elementToInsert = element;
+ let elementAtIndex = this.$all('tabstrip-tab').item(index);
+ let parentElement = this.unpinnedTabsElement_;
+
+ if (groupId) {
+ let tabGroupElement = this.findTabGroupElement_(groupId);
+ if (tabGroupElement) {
+ // If a TabGroupElement already exists, add the TabElement to it.
+ parentElement = tabGroupElement;
+ } else {
+ // If a TabGroupElement does not exist, create one and add the
+ // TabGroupElement into the DOM.
+ tabGroupElement = document.createElement('tabstrip-tab-group');
+ tabGroupElement.setAttribute('data-group-id', groupId);
+ tabGroupElement.appendChild(element);
+ elementToInsert = tabGroupElement;
+ }
+ }
+
+ if (elementAtIndex && elementAtIndex.parentElement &&
+ isTabGroupElement(elementAtIndex.parentElement) &&
+ (elementAtIndex.previousElementSibling === null &&
+ elementAtIndex.tab.groupId !== groupId)) {
+ // If the element at the model index is in a group, and the group is
+ // different from the new tab's group, and is the first element in its
+ // group, insert the new element before its TabGroupElement. If a
+ // TabElement is being sandwiched between two TabElements in a group, it
+ // can be assumed that the tab will eventually be inserted into the
+ // group as well.
+ elementAtIndex = elementAtIndex.parentElement;
+ }
+
+ if (elementAtIndex && elementAtIndex.parentElement === parentElement) {
+ parentElement.insertBefore(elementToInsert, elementAtIndex);
+ } else {
+ parentElement.appendChild(elementToInsert);
+ }
+ }
+ }
+
+ /**
* @param {!TabElement} tabElement
* @private
*/
diff --git a/chromium/chrome/browser/resources/tab_strip/tab_strip_embedder_proxy.js b/chromium/chrome/browser/resources/tab_strip/tab_strip_embedder_proxy.js
index 898858e782c..3bfcc59f238 100644
--- a/chromium/chrome/browser/resources/tab_strip/tab_strip_embedder_proxy.js
+++ b/chromium/chrome/browser/resources/tab_strip/tab_strip_embedder_proxy.js
@@ -4,31 +4,24 @@
import {addSingletonGetter, addWebUIListener, sendWithPromise} from 'chrome://resources/js/cr.m.js';
+/** @interface */
export class TabStripEmbedderProxy {
/** @return {boolean} */
- isVisible() {
- return document.visibilityState === 'visible';
- }
+ isVisible() {}
/**
* @return {!Promise<!Object<string, string>>} Object with CSS variables
* as keys and rgba strings as values
*/
- getColors() {
- return sendWithPromise('getThemeColors');
- }
+ getColors() {}
/**
* @return {!Promise<!Object<string, string>>} Object with CSS variables
* as keys and pixel lengths as values
*/
- getLayout() {
- return sendWithPromise('getLayout');
- }
+ getLayout() {}
- observeThemeChanges() {
- chrome.send('observeThemeChanges');
- }
+ observeThemeChanges() {}
/**
* @param {string} groupId
@@ -37,53 +30,97 @@ export class TabStripEmbedderProxy {
* @param {number} width
* @param {number} height
*/
- showEditDialogForGroup(groupId, locationX, locationY, width, height) {
- chrome.send(
- 'showEditDialogForGroup',
- [groupId, locationX, locationY, width, height]);
- }
+ showEditDialogForGroup(groupId, locationX, locationY, width, height) {}
/**
* @param {number} tabId
* @param {number} locationX
* @param {number} locationY
*/
- showTabContextMenu(tabId, locationX, locationY) {
- chrome.send('showTabContextMenu', [tabId, locationX, locationY]);
- }
+ showTabContextMenu(tabId, locationX, locationY) {}
/**
* @param {number} locationX
* @param {number} locationY
*/
+ showBackgroundContextMenu(locationX, locationY) {}
+
+ closeContainer() {}
+
+ /** @param {number} durationMs Activation duration time in ms. */
+ reportTabActivationDuration(durationMs) {}
+
+ /**
+ * @param {number} tabCount Number of tabs.
+ * @param {number} durationMs Activation duration time in ms.
+ */
+ reportTabDataReceivedDuration(tabCount, durationMs) {}
+
+ /**
+ * @param {number} tabCount Number of tabs.
+ * @param {number} durationMs Creation duration time in ms.
+ */
+ reportTabCreationDuration(tabCount, durationMs) {}
+}
+
+/** @implements {TabStripEmbedderProxy} */
+export class TabStripEmbedderProxyImpl {
+ /** @override */
+ isVisible() {
+ return document.visibilityState === 'visible';
+ }
+
+ /** @override */
+ getColors() {
+ return sendWithPromise('getThemeColors');
+ }
+
+ /** @override */
+ getLayout() {
+ return sendWithPromise('getLayout');
+ }
+
+ /** @override */
+ observeThemeChanges() {
+ chrome.send('observeThemeChanges');
+ }
+
+ /** @override */
+ showEditDialogForGroup(groupId, locationX, locationY, width, height) {
+ chrome.send(
+ 'showEditDialogForGroup',
+ [groupId, locationX, locationY, width, height]);
+ }
+
+ /** @override */
+ showTabContextMenu(tabId, locationX, locationY) {
+ chrome.send('showTabContextMenu', [tabId, locationX, locationY]);
+ }
+
+ /** @override */
showBackgroundContextMenu(locationX, locationY) {
chrome.send('showBackgroundContextMenu', [locationX, locationY]);
}
+ /** @override */
closeContainer() {
chrome.send('closeContainer');
}
- /** @param {number} durationMs Activation duration time in ms. */
+ /** @override */
reportTabActivationDuration(durationMs) {
chrome.send('reportTabActivationDuration', [durationMs]);
}
- /**
- * @param {number} tabCount Number of tabs.
- * @param {number} durationMs Activation duration time in ms.
- */
+ /** @override */
reportTabDataReceivedDuration(tabCount, durationMs) {
chrome.send('reportTabDataReceivedDuration', [tabCount, durationMs]);
}
- /**
- * @param {number} tabCount Number of tabs.
- * @param {number} durationMs Creation duration time in ms.
- */
+ /** @override */
reportTabCreationDuration(tabCount, durationMs) {
chrome.send('reportTabCreationDuration', [tabCount, durationMs]);
}
}
-addSingletonGetter(TabStripEmbedderProxy);
+addSingletonGetter(TabStripEmbedderProxyImpl);
diff --git a/chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd b/chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd
index fe3ddc57f85..64fb60b1810 100644
--- a/chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd
+++ b/chromium/chrome/browser/resources/tab_strip/tab_strip_resources.grd
@@ -16,69 +16,57 @@
name="IDR_TAB_STRIP_HTML"
file="tab_strip.html"
type="chrome_html"
- compress="gzip"
preprocess="true"/>
<structure
name="IDR_TAB_STRIP_TABS_API_PROXY_JS"
file="tabs_api_proxy.js"
- type="chrome_html"
- compress="gzip"/>
+ type="chrome_html"/>
<structure
name="IDR_TAB_STRIP_CUSTOM_ELEMENT_JS"
file="custom_element.js"
- type="chrome_html"
- compress="gzip"/>
+ type="chrome_html"/>
<structure
name="IDR_TAB_STRIP_TAB_GROUP_JS"
file="${root_gen_dir}/chrome/browser/resources/tab_strip/tab_group.js"
use_base_dir="false"
- type="chrome_html"
- compress="gzip"/>
+ type="chrome_html"/>
<structure
name="IDR_TAB_STRIP_TAB_LIST_JS"
file="${root_gen_dir}/chrome/browser/resources/tab_strip/tab_list.js"
use_base_dir="false"
type="chrome_html"
- compress="gzip"
preprocess="true"/>
<structure
name="IDR_TAB_STRIP_TAB_JS"
file="${root_gen_dir}/chrome/browser/resources/tab_strip/tab.js"
use_base_dir="false"
- type="chrome_html"
- compress="gzip"/>
+ type="chrome_html"/>
<structure
name="IDR_TAB_STRIP_ALERT_INDICATOR_JS"
file="${root_gen_dir}/chrome/browser/resources/tab_strip/alert_indicator.js"
use_base_dir="false"
- type="chrome_html"
- compress="gzip"/>
+ type="chrome_html"/>
<structure
name="IDR_TAB_STRIP_ALERT_INDICATORS_JS"
file="${root_gen_dir}/chrome/browser/resources/tab_strip/alert_indicators.js"
use_base_dir="false"
- type="chrome_html"
- compress="gzip"/>
+ type="chrome_html"/>
<structure
name="IDR_TAB_STRIP_EMBEDDER_PROXY_JS"
file="tab_strip_embedder_proxy.js"
- type="chrome_html"
- compress="gzip"/>
+ type="chrome_html"/>
<structure
name="IDR_TAB_STRIP_OPTIONS_JS"
file="tab_strip_options.js"
- type="chrome_html"
- compress="gzip"/>
+ type="chrome_html"/>
<structure
name="IDR_TAB_STRIP_TAB_SWIPER_JS"
file="tab_swiper.js"
- type="chrome_html"
- compress="gzip"/>
+ type="chrome_html"/>
<structure
name="IDR_TAB_STRIP_DRAG_MANAGER_JS"
file="drag_manager.js"
type="chrome_html"
- compress="gzip"
preprocess="true"/>
</structures>
@@ -87,53 +75,43 @@
<include
name="IDR_TAB_STRIP_PICTURE_IN_PICTURE_ALT_SVG"
file="alert_indicators/picture_in_picture_alt.svg"
- type="BINDATA"
- compress="gzip" />
+ type="BINDATA" />
<include
name="IDR_TAB_STRIP_SERIAL_PORT_SVG"
file="alert_indicators/serial_port.svg"
- type="BINDATA"
- compress="gzip" />
+ type="BINDATA" />
<include
name="IDR_TAB_STRIP_TAB_AUDIO_MUTING_ROUNDED_SVG"
file="alert_indicators/tab_audio_muting_rounded.svg"
- type="BINDATA"
- compress="gzip" />
+ type="BINDATA" />
<include
name="IDR_TAB_STRIP_TAB_AUDIO_ROUNDED_SVG"
file="alert_indicators/tab_audio_rounded.svg"
- type="BINDATA"
- compress="gzip" />
+ type="BINDATA" />
<include
name="IDR_TAB_STRIP_TAB_BLUETOOTH_CONNECTED_SVG"
file="alert_indicators/tab_bluetooth_connected.svg"
- type="BINDATA"
- compress="gzip" />
+ type="BINDATA" />
<include
name="IDR_TAB_STRIP_TAB_HID_CONNECTED_SVG"
file="alert_indicators/tab_hid_connected.svg"
- type="BINDATA"
- compress="gzip" />
+ type="BINDATA" />
<include
name="IDR_TAB_STRIP_TAB_MEDIA_CAPTURING_WITH_ARROW_SVG"
file="alert_indicators/tab_media_capturing_with_arrow.svg"
- type="BINDATA"
- compress="gzip" />
+ type="BINDATA" />
<include
name="IDR_TAB_STRIP_TAB_MEDIA_RECORING_SVG"
file="alert_indicators/tab_media_recording.svg"
- type="BINDATA"
- compress="gzip" />
+ type="BINDATA" />
<include
name="IDR_TAB_STRIP_TAB_USB_CONNECTED_SVG"
file="alert_indicators/tab_usb_connected.svg"
- type="BINDATA"
- compress="gzip" />
+ type="BINDATA" />
<include
name="IDR_TAB_STRIP_VR_HEADSET_SVG"
file="alert_indicators/vr_headset.svg"
- type="BINDATA"
- compress="gzip" />
+ type="BINDATA" />
</includes>
</release>
</grit>
diff --git a/chromium/chrome/browser/resources/tab_strip/tabs_api_proxy.js b/chromium/chrome/browser/resources/tab_strip/tabs_api_proxy.js
index a2faa8074d7..b691666cc5a 100644
--- a/chromium/chrome/browser/resources/tab_strip/tabs_api_proxy.js
+++ b/chromium/chrome/browser/resources/tab_strip/tabs_api_proxy.js
@@ -67,7 +67,7 @@ export const TabAlertState = {
export let TabData;
/** @typedef {!Tab} */
-let ExtensionsApiTab;
+export let ExtensionsApiTab;
/**
* @typedef {{
@@ -78,40 +78,86 @@ let ExtensionsApiTab;
*/
export let TabGroupVisualData;
+/** @interface */
export class TabsApiProxy {
/**
* @param {number} tabId
* @return {!Promise<!ExtensionsApiTab>}
*/
+ activateTab(tabId) {}
+
+ createNewTab() {}
+
+ /**
+ * @return {!Promise<!Object<!TabGroupVisualData>>} Object of group IDs as
+ * strings mapped to their visual data.
+ */
+ getGroupVisualData() {}
+
+ /**
+ * @return {!Promise<!Array<!TabData>>}
+ */
+ getTabs() {}
+
+ /**
+ * @param {number} tabId
+ * @param {!CloseTabAction} closeTabAction
+ */
+ closeTab(tabId, closeTabAction) {}
+
+ /**
+ * @param {number} tabId
+ * @param {string} groupId
+ */
+ groupTab(tabId, groupId) {}
+
+ /**
+ * @param {string} groupId
+ * @param {number} newIndex
+ */
+ moveGroup(groupId, newIndex) {}
+
+ /**
+ * @param {number} tabId
+ * @param {number} newIndex
+ */
+ moveTab(tabId, newIndex) {}
+
+ /**
+ * @param {number} tabId
+ * @param {boolean} thumbnailTracked
+ */
+ setThumbnailTracked(tabId, thumbnailTracked) {}
+
+ /** @param {number} tabId */
+ ungroupTab(tabId) {}
+}
+
+/** @implements {TabsApiProxy} */
+export class TabsApiProxyImpl {
+ /** @override */
activateTab(tabId) {
return new Promise(resolve => {
chrome.tabs.update(tabId, {active: true}, resolve);
});
}
+ /** @override */
createNewTab() {
chrome.send('createNewTab');
}
- /**
- * @return {!Promise<!Object<!TabGroupVisualData>>} Object of group IDs as
- * strings mapped to their visual data.
- */
+ /** @override */
getGroupVisualData() {
return sendWithPromise('getGroupVisualData');
}
- /**
- * @return {!Promise<!Array<!TabData>>}
- */
+ /** @override */
getTabs() {
return sendWithPromise('getTabs');
}
- /**
- * @param {number} tabId
- * @param {!CloseTabAction} closeTabAction
- */
+ /** @override */
closeTab(tabId, closeTabAction) {
chrome.send(
'closeTab', [tabId, closeTabAction === CloseTabAction.SWIPED_TO_CLOSE]);
@@ -120,42 +166,30 @@ export class TabsApiProxy {
Object.keys(CloseTabAction).length);
}
- /**
- * @param {number} tabId
- * @param {string} groupId
- */
+ /** @override */
groupTab(tabId, groupId) {
chrome.send('groupTab', [tabId, groupId]);
}
- /**
- * @param {string} groupId
- * @param {number} newIndex
- */
+ /** @override */
moveGroup(groupId, newIndex) {
chrome.send('moveGroup', [groupId, newIndex]);
}
- /**
- * @param {number} tabId
- * @param {number} newIndex
- */
+ /** @override */
moveTab(tabId, newIndex) {
chrome.send('moveTab', [tabId, newIndex]);
}
- /**
- * @param {number} tabId
- * @param {boolean} thumbnailTracked
- */
+ /** @override */
setThumbnailTracked(tabId, thumbnailTracked) {
chrome.send('setThumbnailTracked', [tabId, thumbnailTracked]);
}
- /** @param {number} tabId */
+ /** @override */
ungroupTab(tabId) {
chrome.send('ungroupTab', [tabId]);
}
}
-addSingletonGetter(TabsApiProxy);
+addSingletonGetter(TabsApiProxyImpl);