diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/chrome/browser/resources/tab_strip | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-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')
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); |