mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1920852: Add closing tabs remotely to Firefox View r=lina,fxview-reviewers,jsudiaman
Differential Revision: https://phabricator.services.mozilla.com/D223448
This commit is contained in:
parent
7dc01ce4ff
commit
3c7cbd61fb
@ -267,8 +267,8 @@ export class SyncedTabsController {
|
||||
|
||||
for (let id in renderInfo) {
|
||||
renderInfo[id].tabItems = this.searchQuery
|
||||
? searchTabList(this.searchQuery, this.getTabItems(renderInfo[id].tabs))
|
||||
: this.getTabItems(renderInfo[id].tabs);
|
||||
? searchTabList(this.searchQuery, this.getTabItems(renderInfo[id]))
|
||||
: this.getTabItems(renderInfo[id]);
|
||||
}
|
||||
return renderInfo;
|
||||
}
|
||||
@ -304,22 +304,63 @@ export class SyncedTabsController {
|
||||
return null;
|
||||
}
|
||||
|
||||
getTabItems(tabs) {
|
||||
return tabs?.map(tab => ({
|
||||
icon: tab.icon,
|
||||
title: tab.title,
|
||||
time: tab.lastUsed * 1000,
|
||||
url: tab.url,
|
||||
fxaDeviceId: tab.fxaDeviceId,
|
||||
primaryL10nId: "firefoxview-tabs-list-tab-button",
|
||||
primaryL10nArgs: JSON.stringify({ targetURI: tab.url }),
|
||||
secondaryL10nId: this.contextMenu
|
||||
? "fxviewtabrow-options-menu-button"
|
||||
: undefined,
|
||||
secondaryL10nArgs: this.contextMenu
|
||||
? JSON.stringify({ tabTitle: tab.title })
|
||||
: undefined,
|
||||
}));
|
||||
/**
|
||||
* Turn renderInfo into a list of tabs for syncedtabs-tab-list
|
||||
*
|
||||
* @param {object} renderInfo
|
||||
* @param {Array<object>} [renderInfo.tabs]
|
||||
* tabs to display to the user
|
||||
* @param {string} [renderInfo.name]
|
||||
* The name of the device for use when the user hovers over
|
||||
* the close button for context
|
||||
* @param {boolean} [renderInfo.canClose]
|
||||
* Whether the list should support remotely closing tabs
|
||||
*/
|
||||
getTabItems({ tabs, name, canClose }) {
|
||||
return tabs
|
||||
?.map(tab => {
|
||||
let tabItem = {
|
||||
icon: tab.icon,
|
||||
title: tab.title,
|
||||
time: tab.lastUsed * 1000,
|
||||
url: tab.url,
|
||||
fxaDeviceId: tab.fxaDeviceId,
|
||||
primaryL10nId: "firefoxview-tabs-list-tab-button",
|
||||
primaryL10nArgs: JSON.stringify({ targetURI: tab.url }),
|
||||
secondaryL10nId: this.contextMenu
|
||||
? "fxviewtabrow-options-menu-button"
|
||||
: undefined,
|
||||
secondaryL10nArgs: this.contextMenu
|
||||
? JSON.stringify({ tabTitle: tab.title })
|
||||
: undefined,
|
||||
};
|
||||
// We don't want to show the option to close remotely if the
|
||||
// device doesn't support it
|
||||
if (!canClose) {
|
||||
return tabItem;
|
||||
}
|
||||
|
||||
// If this item has been requested to be closed, show
|
||||
// the undo instead until removed from the list
|
||||
if (tabItem.url === this.lastClosedURL) {
|
||||
tabItem.tertiaryL10nId = "text-action-undo";
|
||||
tabItem.tertiaryActionClass = "undo-button";
|
||||
tabItem.tertiaryL10nArgs = null;
|
||||
tabItem.closeRequested = true;
|
||||
} else {
|
||||
// Otherwise default to showing the close/dismiss button
|
||||
tabItem.tertiaryL10nId = "synced-tabs-context-close-tab-title";
|
||||
tabItem.tertiaryL10nArgs = JSON.stringify({ deviceName: name });
|
||||
tabItem.tertiaryActionClass = "dismiss-button";
|
||||
tabItem.closeRequested = false;
|
||||
}
|
||||
return tabItem;
|
||||
})
|
||||
.filter(
|
||||
item =>
|
||||
!this.isURLQueuedToClose(item.fxaDeviceId, item.url) ||
|
||||
item.url === this.lastClosedURL
|
||||
);
|
||||
}
|
||||
|
||||
updateTabsList(syncedTabs) {
|
||||
|
@ -114,7 +114,9 @@ class CardContainer extends MozLitElement {
|
||||
}
|
||||
|
||||
updateTabLists() {
|
||||
let tabLists = this.querySelectorAll("fxview-tab-list, opentabs-tab-list");
|
||||
let tabLists = this.querySelectorAll(
|
||||
"fxview-tab-list, opentabs-tab-list, syncedtabs-tab-list"
|
||||
);
|
||||
if (tabLists) {
|
||||
tabLists.forEach(tabList => {
|
||||
tabList.updatesPaused = !this.visible || !this.isExpanded;
|
||||
|
@ -14,6 +14,8 @@
|
||||
<title data-l10n-id="firefoxview-page-title"></title>
|
||||
<link rel="localization" href="branding/brand.ftl" />
|
||||
<link rel="localization" href="browser/firefoxView.ftl" />
|
||||
<link rel="localization" href="browser/sidebar.ftl" />
|
||||
<link rel="localization" href="toolkit/global/textActions.ftl" />
|
||||
<link rel="localization" href="toolkit/branding/brandings.ftl" />
|
||||
<link rel="localization" href="browser/migrationWizard.ftl" />
|
||||
<link
|
||||
|
@ -125,6 +125,10 @@
|
||||
|
||||
.fxview-tab-row-button.dismiss-button::part(button) {
|
||||
background-image: url("chrome://global/skin/icons/close.svg");
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.fxview-tab-row-button.options-button::part(button) {
|
||||
@ -135,3 +139,8 @@
|
||||
font-size: var(--font-size-small);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.fxview-tab-row-button.dismiss-button,
|
||||
.fxview-tab-row-button.undo-button {
|
||||
justify-self: end;
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ browser.jar:
|
||||
content/browser/firefoxview/opentabs-tab-list.css
|
||||
content/browser/firefoxview/opentabs-tab-list.mjs
|
||||
content/browser/firefoxview/opentabs-tab-row.css
|
||||
content/browser/firefoxview/syncedtabs-tab-list.css
|
||||
content/browser/firefoxview/syncedtabs-tab-list.mjs
|
||||
content/browser/firefoxview/recentlyclosed.mjs
|
||||
content/browser/firefoxview/viewpage.mjs
|
||||
content/browser/firefoxview/history-empty.svg (content/history-empty.svg)
|
||||
|
14
browser/components/firefoxview/syncedtabs-tab-list.css
Normal file
14
browser/components/firefoxview/syncedtabs-tab-list.css
Normal file
@ -0,0 +1,14 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
virtual-list {
|
||||
display: grid;
|
||||
grid-column: span 9;
|
||||
grid-template-columns: subgrid;
|
||||
|
||||
.top-padding,
|
||||
.bottom-padding {
|
||||
grid-column: span 9;
|
||||
}
|
||||
}
|
195
browser/components/firefoxview/syncedtabs-tab-list.mjs
Normal file
195
browser/components/firefoxview/syncedtabs-tab-list.mjs
Normal file
@ -0,0 +1,195 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import {
|
||||
classMap,
|
||||
html,
|
||||
ifDefined,
|
||||
when,
|
||||
} from "chrome://global/content/vendor/lit.all.mjs";
|
||||
import {
|
||||
FxviewTabListBase,
|
||||
FxviewTabRowBase,
|
||||
} from "chrome://browser/content/firefoxview/fxview-tab-list.mjs";
|
||||
// eslint-disable-next-line import/no-unassigned-import
|
||||
import "chrome://global/content/elements/moz-button.mjs";
|
||||
|
||||
const lazy = {};
|
||||
let XPCOMUtils;
|
||||
|
||||
XPCOMUtils = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/XPCOMUtils.sys.mjs"
|
||||
).XPCOMUtils;
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
lazy,
|
||||
"virtualListEnabledPref",
|
||||
"browser.firefox-view.virtual-list.enabled"
|
||||
);
|
||||
|
||||
/**
|
||||
* A list of synced tabs that are clickable and able to be remotely closed
|
||||
*/
|
||||
|
||||
export class SyncedTabsTabList extends FxviewTabListBase {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
static queries = {
|
||||
...FxviewTabListBase.queries,
|
||||
rowEls: {
|
||||
all: "syncedtabs-tab-row",
|
||||
},
|
||||
};
|
||||
|
||||
itemTemplate = (tabItem, i) => {
|
||||
return html`
|
||||
<syncedtabs-tab-row
|
||||
?active=${i == this.activeIndex}
|
||||
.canClose=${ifDefined(tabItem.canClose)}
|
||||
.closeRequested=${ifDefined(tabItem.closeRequested)}
|
||||
?compact=${this.compactRows}
|
||||
.currentActiveElementId=${this.currentActiveElementId}
|
||||
.favicon=${tabItem.icon}
|
||||
.fxaDeviceId=${tabItem.fxaDeviceId}
|
||||
.primaryL10nId=${tabItem.primaryL10nId}
|
||||
.primaryL10nArgs=${ifDefined(tabItem.primaryL10nArgs)}
|
||||
.secondaryL10nId=${tabItem.secondaryL10nId}
|
||||
.secondaryL10nArgs=${ifDefined(tabItem.secondaryL10nArgs)}
|
||||
.tertiaryL10nId=${ifDefined(tabItem.tertiaryL10nId)}
|
||||
.tertiaryL10nArgs=${ifDefined(tabItem.tertiaryL10nArgs)}
|
||||
.secondaryActionClass=${this.secondaryActionClass}
|
||||
.tertiaryActionClass=${ifDefined(tabItem.tertiaryActionClass)}
|
||||
.sourceClosedId=${ifDefined(tabItem.sourceClosedId)}
|
||||
.sourceWindowId=${ifDefined(tabItem.sourceWindowId)}
|
||||
.closedId=${ifDefined(tabItem.closedId || tabItem.closedId)}
|
||||
role="listitem"
|
||||
.tabElement=${ifDefined(tabItem.tabElement)}
|
||||
.title=${tabItem.title}
|
||||
.url=${tabItem.url}
|
||||
.searchQuery=${ifDefined(this.searchQuery)}
|
||||
.hasPopup=${this.hasPopup}
|
||||
></fxview-tab-row>
|
||||
`;
|
||||
};
|
||||
|
||||
stylesheets() {
|
||||
return [
|
||||
super.stylesheets(),
|
||||
html`<link
|
||||
rel="stylesheet"
|
||||
href="chrome://browser/content/firefoxview/syncedtabs-tab-list.css"
|
||||
/>`,
|
||||
];
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.searchQuery && !this.tabItems.length) {
|
||||
return this.emptySearchResultsTemplate();
|
||||
}
|
||||
return html`
|
||||
${this.stylesheets()}
|
||||
<div
|
||||
id="fxview-tab-list"
|
||||
class="fxview-tab-list"
|
||||
data-l10n-id="firefoxview-tabs"
|
||||
role="list"
|
||||
@keydown=${this.handleFocusElementInRow}
|
||||
>
|
||||
${when(
|
||||
lazy.virtualListEnabledPref,
|
||||
() => html`
|
||||
<virtual-list
|
||||
.activeIndex=${this.activeIndex}
|
||||
.items=${this.tabItems}
|
||||
.template=${this.itemTemplate}
|
||||
></virtual-list>
|
||||
`,
|
||||
() =>
|
||||
html`${this.tabItems.map((tabItem, i) =>
|
||||
this.itemTemplate(tabItem, i)
|
||||
)}`
|
||||
)}
|
||||
</div>
|
||||
<slot name="menu"></slot>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("syncedtabs-tab-list", SyncedTabsTabList);
|
||||
|
||||
/**
|
||||
* A tab item that displays favicon, title, url, and time of last access
|
||||
*
|
||||
* @property {boolean} canClose - Whether the tab item has the ability to be closed remotely
|
||||
* @property {boolean} closeRequested - Whether the tab has been requested closed but not removed from the list
|
||||
* @property {string} fxaDeviceId - The device Id the tab item belongs to, for closing tabs remotely
|
||||
*/
|
||||
|
||||
export class SyncedTabsTabRow extends FxviewTabRowBase {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
static properties = {
|
||||
...FxviewTabRowBase.properties,
|
||||
canClose: { type: Boolean },
|
||||
closeRequested: { type: Boolean },
|
||||
fxaDeviceId: { type: String },
|
||||
};
|
||||
|
||||
secondaryButtonTemplate() {
|
||||
return html`${when(
|
||||
this.secondaryL10nId && this.secondaryActionHandler,
|
||||
() => html`<moz-button
|
||||
type="icon ghost"
|
||||
class=${classMap({
|
||||
"fxview-tab-row-button": true,
|
||||
[this.secondaryActionClass]: this.secondaryActionClass,
|
||||
})}
|
||||
?disabled=${this.closeRequested}
|
||||
id="fxview-tab-row-secondary-button"
|
||||
data-l10n-id=${this.secondaryL10nId}
|
||||
data-l10n-args=${ifDefined(this.secondaryL10nArgs)}
|
||||
aria-haspopup=${ifDefined(this.hasPopup)}
|
||||
@click=${this.secondaryActionHandler}
|
||||
tabindex="${this.active &&
|
||||
this.currentActiveElementId === "fxview-tab-row-secondary-button"
|
||||
? "0"
|
||||
: "-1"}"
|
||||
></moz-button>`
|
||||
)}`;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
${this.stylesheets()}
|
||||
<a
|
||||
href=${ifDefined(this.url)}
|
||||
class="fxview-tab-row-main"
|
||||
id="fxview-tab-row-main"
|
||||
disabled=${this.closeRequested}
|
||||
tabindex=${this.active &&
|
||||
this.currentActiveElementId === "fxview-tab-row-main"
|
||||
? "0"
|
||||
: "-1"}
|
||||
data-l10n-id=${ifDefined(this.primaryL10nId)}
|
||||
data-l10n-args=${ifDefined(this.primaryL10nArgs)}
|
||||
@click=${this.primaryActionHandler}
|
||||
@keydown=${this.primaryActionHandler}
|
||||
title=${!this.primaryL10nId ? this.url : null}
|
||||
>
|
||||
${this.faviconTemplate()} ${this.titleTemplate()}
|
||||
${when(
|
||||
!this.compact,
|
||||
() => html`${this.urlTemplate()} ${this.dateTemplate()}
|
||||
${this.timeTemplate()}`
|
||||
)}
|
||||
</a>
|
||||
${this.secondaryButtonTemplate()} ${this.tertiaryButtonTemplate()}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("syncedtabs-tab-row", SyncedTabsTabRow);
|
@ -22,6 +22,8 @@ import {
|
||||
MAX_TABS_FOR_RECENT_BROWSING,
|
||||
navigateToLink,
|
||||
} from "./helpers.mjs";
|
||||
// eslint-disable-next-line import/no-unassigned-import
|
||||
import "chrome://browser/content/firefoxview/syncedtabs-tab-list.mjs";
|
||||
|
||||
const UI_OPEN_STATE = "browser.tabs.firefox-view.ui-state.tab-pickup.open";
|
||||
|
||||
@ -61,7 +63,7 @@ class SyncedTabsInView extends ViewPage {
|
||||
cardEls: { all: "card-container" },
|
||||
emptyState: "fxview-empty-state",
|
||||
searchTextbox: "fxview-search-textbox",
|
||||
tabLists: { all: "fxview-tab-list" },
|
||||
tabLists: { all: "syncedtabs-tab-list" },
|
||||
};
|
||||
|
||||
start() {
|
||||
@ -186,6 +188,18 @@ class SyncedTabsInView extends ViewPage {
|
||||
e.target.querySelector("panel-list").toggle(e.detail.originalEvent);
|
||||
}
|
||||
|
||||
onCloseTab(e) {
|
||||
const { url, fxaDeviceId, tertiaryActionClass } = e.originalTarget;
|
||||
if (tertiaryActionClass === "dismiss-button") {
|
||||
// Set new pending close tab
|
||||
this.controller.requestCloseRemoteTab(fxaDeviceId, url);
|
||||
} else if (tertiaryActionClass === "undo-button") {
|
||||
// User wants to undo
|
||||
this.controller.removePendingTabToClose(fxaDeviceId, url);
|
||||
}
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
panelListTemplate() {
|
||||
return html`
|
||||
<panel-list slot="menu" data-tab-type="syncedtabs">
|
||||
@ -259,19 +273,19 @@ class SyncedTabsInView extends ViewPage {
|
||||
<span class="icon ${deviceType}" role="presentation"></span>
|
||||
${deviceName}
|
||||
</h3>
|
||||
<fxview-tab-list
|
||||
<syncedtabs-tab-list
|
||||
slot="main"
|
||||
secondaryActionClass="options-button"
|
||||
hasPopup="menu"
|
||||
.hasPopup=${"menu"}
|
||||
.tabItems=${ifDefined(tabItems)}
|
||||
.searchQuery=${this.controller.searchQuery}
|
||||
maxTabsLength=${this.showAll ? -1 : this.maxTabsLength}
|
||||
.maxTabsLength=${this.showAll ? -1 : this.maxTabsLength}
|
||||
@fxview-tab-list-primary-action=${this.onOpenLink}
|
||||
@fxview-tab-list-secondary-action=${this.onContextMenu}
|
||||
@fxview-tab-list-tertiary-action=${this.onCloseTab}
|
||||
secondaryActionClass="options-button"
|
||||
>
|
||||
${this.panelListTemplate()}
|
||||
</fxview-tab-list>`;
|
||||
</syncedtabs-tab-list>`;
|
||||
}
|
||||
|
||||
generateTabList() {
|
||||
|
@ -475,18 +475,20 @@ add_task(async function search_synced_tabs() {
|
||||
is(syncedTabsComponent.cardEls.length, 2, "There are two device cards.");
|
||||
await TestUtils.waitForCondition(
|
||||
() =>
|
||||
syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list") &&
|
||||
syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls
|
||||
.length &&
|
||||
syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list") &&
|
||||
syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list").rowEls
|
||||
.length,
|
||||
syncedTabsComponent.cardEls[0].querySelector("syncedtabs-tab-list") &&
|
||||
syncedTabsComponent.cardEls[0].querySelector("syncedtabs-tab-list")
|
||||
.rowEls.length &&
|
||||
syncedTabsComponent.cardEls[1].querySelector("syncedtabs-tab-list") &&
|
||||
syncedTabsComponent.cardEls[1].querySelector("syncedtabs-tab-list")
|
||||
.rowEls.length,
|
||||
"The tab list has loaded for the first two cards."
|
||||
);
|
||||
let deviceOneTabs =
|
||||
syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls;
|
||||
let deviceTwoTabs =
|
||||
syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list").rowEls;
|
||||
let deviceOneTabs = syncedTabsComponent.cardEls[0].querySelector(
|
||||
"syncedtabs-tab-list"
|
||||
).rowEls;
|
||||
let deviceTwoTabs = syncedTabsComponent.cardEls[1].querySelector(
|
||||
"syncedtabs-tab-list"
|
||||
).rowEls;
|
||||
|
||||
info("Input a search query.");
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
@ -501,19 +503,20 @@ add_task(async function search_synced_tabs() {
|
||||
);
|
||||
await TestUtils.waitForCondition(
|
||||
() =>
|
||||
syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list") &&
|
||||
syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls
|
||||
.length,
|
||||
syncedTabsComponent.cardEls[0].querySelector("syncedtabs-tab-list") &&
|
||||
syncedTabsComponent.cardEls[0].querySelector("syncedtabs-tab-list")
|
||||
.rowEls.length,
|
||||
"The tab list has loaded for the first card."
|
||||
);
|
||||
await TestUtils.waitForCondition(
|
||||
() =>
|
||||
syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls
|
||||
.length === 1,
|
||||
syncedTabsComponent.cardEls[0].querySelector("syncedtabs-tab-list")
|
||||
.rowEls.length === 1,
|
||||
"There is one matching search result for the first device."
|
||||
);
|
||||
await TestUtils.waitForCondition(
|
||||
() => !syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list"),
|
||||
() =>
|
||||
!syncedTabsComponent.cardEls[1].querySelector("syncedtabs-tab-list"),
|
||||
"There are no matching search results for the second device."
|
||||
);
|
||||
|
||||
@ -529,28 +532,30 @@ add_task(async function search_synced_tabs() {
|
||||
);
|
||||
await TestUtils.waitForCondition(
|
||||
() =>
|
||||
syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list") &&
|
||||
syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls
|
||||
.length &&
|
||||
syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list") &&
|
||||
syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list").rowEls
|
||||
.length,
|
||||
syncedTabsComponent.cardEls[0].querySelector("syncedtabs-tab-list") &&
|
||||
syncedTabsComponent.cardEls[0].querySelector("syncedtabs-tab-list")
|
||||
.rowEls.length &&
|
||||
syncedTabsComponent.cardEls[1].querySelector("syncedtabs-tab-list") &&
|
||||
syncedTabsComponent.cardEls[1].querySelector("syncedtabs-tab-list")
|
||||
.rowEls.length,
|
||||
"The tab list has loaded for the first two cards."
|
||||
);
|
||||
deviceOneTabs =
|
||||
syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls;
|
||||
deviceTwoTabs =
|
||||
syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list").rowEls;
|
||||
deviceOneTabs = syncedTabsComponent.cardEls[0].querySelector(
|
||||
"syncedtabs-tab-list"
|
||||
).rowEls;
|
||||
deviceTwoTabs = syncedTabsComponent.cardEls[1].querySelector(
|
||||
"syncedtabs-tab-list"
|
||||
).rowEls;
|
||||
await TestUtils.waitForCondition(
|
||||
() =>
|
||||
syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls
|
||||
.length === deviceOneTabs.length,
|
||||
syncedTabsComponent.cardEls[0].querySelector("syncedtabs-tab-list")
|
||||
.rowEls.length === deviceOneTabs.length,
|
||||
"The original device's list is restored."
|
||||
);
|
||||
await TestUtils.waitForCondition(
|
||||
() =>
|
||||
syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list").rowEls
|
||||
.length === deviceTwoTabs.length,
|
||||
syncedTabsComponent.cardEls[1].querySelector("syncedtabs-tab-list")
|
||||
.rowEls.length === deviceTwoTabs.length,
|
||||
"The new devices's list is restored."
|
||||
);
|
||||
syncedTabsComponent.searchTextbox.blur();
|
||||
@ -564,19 +569,20 @@ add_task(async function search_synced_tabs() {
|
||||
);
|
||||
await TestUtils.waitForCondition(
|
||||
() =>
|
||||
syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list") &&
|
||||
syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls
|
||||
.length,
|
||||
syncedTabsComponent.cardEls[0].querySelector("syncedtabs-tab-list") &&
|
||||
syncedTabsComponent.cardEls[0].querySelector("syncedtabs-tab-list")
|
||||
.rowEls.length,
|
||||
"The tab list has loaded for the first card."
|
||||
);
|
||||
await TestUtils.waitForCondition(() => {
|
||||
return (
|
||||
syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls
|
||||
.length === 1
|
||||
syncedTabsComponent.cardEls[0].querySelector("syncedtabs-tab-list")
|
||||
.rowEls.length === 1
|
||||
);
|
||||
}, "There is one matching search result for the first device.");
|
||||
await TestUtils.waitForCondition(
|
||||
() => !syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list"),
|
||||
() =>
|
||||
!syncedTabsComponent.cardEls[1].querySelector("syncedtabs-tab-list"),
|
||||
"There are no matching search results for the second device."
|
||||
);
|
||||
|
||||
@ -598,28 +604,30 @@ add_task(async function search_synced_tabs() {
|
||||
);
|
||||
await TestUtils.waitForCondition(
|
||||
() =>
|
||||
syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list") &&
|
||||
syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls
|
||||
.length &&
|
||||
syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list") &&
|
||||
syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list").rowEls
|
||||
.length,
|
||||
syncedTabsComponent.cardEls[0].querySelector("syncedtabs-tab-list") &&
|
||||
syncedTabsComponent.cardEls[0].querySelector("syncedtabs-tab-list")
|
||||
.rowEls.length &&
|
||||
syncedTabsComponent.cardEls[1].querySelector("syncedtabs-tab-list") &&
|
||||
syncedTabsComponent.cardEls[1].querySelector("syncedtabs-tab-list")
|
||||
.rowEls.length,
|
||||
"The tab list has loaded for the first two cards."
|
||||
);
|
||||
deviceOneTabs =
|
||||
syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls;
|
||||
deviceTwoTabs =
|
||||
syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list").rowEls;
|
||||
deviceOneTabs = syncedTabsComponent.cardEls[0].querySelector(
|
||||
"syncedtabs-tab-list"
|
||||
).rowEls;
|
||||
deviceTwoTabs = syncedTabsComponent.cardEls[1].querySelector(
|
||||
"syncedtabs-tab-list"
|
||||
).rowEls;
|
||||
await TestUtils.waitForCondition(
|
||||
() =>
|
||||
syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls
|
||||
.length === deviceOneTabs.length,
|
||||
syncedTabsComponent.cardEls[0].querySelector("syncedtabs-tab-list")
|
||||
.rowEls.length === deviceOneTabs.length,
|
||||
"The original device's list is restored."
|
||||
);
|
||||
await TestUtils.waitForCondition(
|
||||
() =>
|
||||
syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list").rowEls
|
||||
.length === deviceTwoTabs.length,
|
||||
syncedTabsComponent.cardEls[1].querySelector("syncedtabs-tab-list")
|
||||
.rowEls.length === deviceTwoTabs.length,
|
||||
"The new devices's list is restored."
|
||||
);
|
||||
});
|
||||
|
@ -320,6 +320,11 @@ function setupMocks({ fxaDevices = null, state, syncEnabled = true }) {
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
// whatever was passed in was the "found" client
|
||||
sandbox
|
||||
.stub(SyncedTabs._internal, "_getClientFxaDeviceId")
|
||||
.callsFake(clientId => clientId);
|
||||
// This is converting the device list to a client list.
|
||||
// There are two primary differences:
|
||||
// 1. The client list doesn't return the current device.
|
||||
|
@ -201,7 +201,9 @@ export class ViewPage extends ViewPageContent {
|
||||
let tabLists = [];
|
||||
if (!isOpenTabs) {
|
||||
cards = this.shadowRoot.querySelectorAll("card-container");
|
||||
tabLists = this.shadowRoot.querySelectorAll("fxview-tab-list");
|
||||
tabLists = this.shadowRoot.querySelectorAll(
|
||||
"fxview-tab-list, syncedtabs-tab-list"
|
||||
);
|
||||
} else {
|
||||
this.viewCards.forEach(viewCard => {
|
||||
if (viewCard.cardEl) {
|
||||
|
Loading…
Reference in New Issue
Block a user