mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1908433 - Add UI for editing an existing tab group. r=jswinarton,dao,fluent-reviewers,desktop-theme-reviewers,tabbrowser-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D223876
This commit is contained in:
parent
bce997cb7f
commit
1b77a1b222
@ -27,7 +27,8 @@
|
||||
role="menu"
|
||||
norolluponanchor="true">
|
||||
<html:div class="panel-header">
|
||||
<html:h1 data-l10n-id="tab-group-editor-title-create"></html:h1>
|
||||
<html:h1 class="tab-group-create-mode-only" data-l10n-id="tab-group-editor-title-create"></html:h1>
|
||||
<html:h1 class="tab-group-edit-mode-only" data-l10n-id="tab-group-editor-title-edit"></html:h1>
|
||||
</html:div>
|
||||
<toolbarseparator />
|
||||
<html:div class="panel-body tab-group-editor-name">
|
||||
@ -36,14 +37,26 @@
|
||||
</html:div>
|
||||
<html:div class="panel-body tab-group-editor-swatches">
|
||||
</html:div>
|
||||
<html:moz-button-group class="panel-body tab-group-editor-actions">
|
||||
<html:moz-button-group class="panel-body tab-group-create-actions tab-group-create-mode-only">
|
||||
<html:moz-button id="tab-group-editor-button-cancel" data-l10n-id="tab-group-editor-cancel"></html:moz-button>
|
||||
<html:moz-button type="primary" id="tab-group-editor-button-create" data-l10n-id="tab-group-editor-done"></html:moz-button>
|
||||
</html:moz-button-group>
|
||||
<toolbarseparator class="tab-group-edit-mode-only" />
|
||||
<html:div class="panel-body tab-group-edit-actions tab-group-edit-mode-only">
|
||||
<toolbarbutton id="tabGroupEditor_addNewTabInGroup" class="subviewbutton" data-l10n-id="tab-group-editor-action-add-new"></toolbarbutton>
|
||||
<toolbarbutton disabled="true" id="tabGroupEditor_moveGroupToNewWindow" class="subviewbutton" data-l10n-id="tab-group-editor-action-new-window"></toolbarbutton>
|
||||
<toolbarbutton disabled="true" id="tabGroupEditor_saveAndCloseGroup" class="subviewbutton" data-l10n-id="tab-group-editor-action-save"></toolbarbutton>
|
||||
<toolbarbutton id="tabGroupEditor_ungroupTabs" class="subviewbutton" data-l10n-id="tab-group-editor-action-ungroup"></toolbarbutton>
|
||||
</html:div>
|
||||
<toolbarseparator class="tab-group-edit-mode-only" />
|
||||
<html:div class="tab-group-edit-mode-only panel-body tab-group-delete">
|
||||
<toolbarbutton disabled="true" id="tabGroupEditor_deleteGroup" class="subviewbutton" data-l10n-id="tab-group-editor-action-delete"></toolbarbutton>
|
||||
</html:div>
|
||||
</panel>
|
||||
`;
|
||||
|
||||
#activeGroup;
|
||||
#createMode;
|
||||
#cancelButton;
|
||||
#createButton;
|
||||
#nameField;
|
||||
@ -93,6 +106,18 @@
|
||||
}
|
||||
});
|
||||
|
||||
document
|
||||
.getElementById("tabGroupEditor_addNewTabInGroup")
|
||||
.addEventListener("command", () => {
|
||||
this.#handleNewTabInGroup();
|
||||
});
|
||||
|
||||
document
|
||||
.getElementById("tabGroupEditor_ungroupTabs")
|
||||
.addEventListener("command", () => {
|
||||
this.#handleUngroup();
|
||||
});
|
||||
|
||||
this.addEventListener("change", this);
|
||||
}
|
||||
|
||||
@ -130,6 +155,15 @@
|
||||
return this.#activeGroup;
|
||||
}
|
||||
|
||||
get createMode() {
|
||||
return this.#createMode;
|
||||
}
|
||||
|
||||
set createMode(mode) {
|
||||
this.#panel.classList.toggle("tab-group-editor-mode-create", mode);
|
||||
this.#createMode = mode;
|
||||
}
|
||||
|
||||
set activeGroup(group = null) {
|
||||
this.#activeGroup = group;
|
||||
this.#nameField.value = group ? group.label : "";
|
||||
@ -148,6 +182,15 @@
|
||||
|
||||
openCreateModal(group) {
|
||||
this.activeGroup = group;
|
||||
this.createMode = true;
|
||||
this.#panel.openPopup(group.firstChild, {
|
||||
position: "bottomleft topleft",
|
||||
});
|
||||
}
|
||||
|
||||
openEditModal(group) {
|
||||
this.activeGroup = group;
|
||||
this.createMode = false;
|
||||
this.#panel.openPopup(group.firstChild, {
|
||||
position: "bottomleft topleft",
|
||||
});
|
||||
@ -174,6 +217,21 @@
|
||||
this.#panel.hidePopup();
|
||||
this.activeGroup = null;
|
||||
}
|
||||
|
||||
async #handleNewTabInGroup() {
|
||||
let lastTab = this.activeGroup?.tabs.at(-1);
|
||||
let onTabOpened = async aEvent => {
|
||||
this.activeGroup?.addTabs([aEvent.target]);
|
||||
this.#panel.hidePopup();
|
||||
window.removeEventListener("TabOpen", onTabOpened);
|
||||
};
|
||||
window.addEventListener("TabOpen", onTabOpened);
|
||||
gBrowser.addAdjacentNewTab(lastTab);
|
||||
}
|
||||
|
||||
#handleUngroup() {
|
||||
this.activeGroup?.ungroupTabs();
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("tabgroup-menu", MozTabbrowserTabGroupMenu);
|
||||
|
@ -75,6 +75,12 @@
|
||||
}
|
||||
});
|
||||
this._tabsChangedObserver.observe(this, { childList: true });
|
||||
|
||||
this.#labelElement.addEventListener("contextmenu", e => {
|
||||
e.preventDefault();
|
||||
gBrowser.tabGroupMenu.openEditModal(this);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
|
@ -947,13 +947,15 @@ add_task(async function test_tabsContainNoTabGroups() {
|
||||
* Tests behavior of the group management panel.
|
||||
*/
|
||||
add_task(async function test_tabGroupCreatePanel() {
|
||||
let tabgroupPanel = document.getElementById("tab-group-editor").panel;
|
||||
let tabgroupEditor = document.getElementById("tab-group-editor");
|
||||
let tabgroupPanel = tabgroupEditor.panel;
|
||||
let nameField = tabgroupPanel.querySelector("#tab-group-name");
|
||||
let tab = BrowserTestUtils.addTab(gBrowser, "about:blank");
|
||||
|
||||
let panelShown = BrowserTestUtils.waitForPopupEvent(tabgroupPanel, "shown");
|
||||
let group = gBrowser.addTabGroup("cyan", "Food", [tab]);
|
||||
await panelShown;
|
||||
Assert.ok(tabgroupEditor.createMode, "Group editor is in create mode");
|
||||
// Edit panel should be populated with correct group details
|
||||
Assert.ok(
|
||||
nameField.value == group.label,
|
||||
@ -1002,5 +1004,82 @@ add_task(async function test_tabGroupCreatePanel() {
|
||||
Assert.ok(group.label == "Shopping");
|
||||
Assert.ok(group.color == "red");
|
||||
|
||||
await removeTabGroup(group);
|
||||
// right-clicking on the group label reopens the panel in edit mode
|
||||
panelShown = BrowserTestUtils.waitForPopupEvent(tabgroupPanel, "shown");
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
group.querySelector(".tab-group-label"),
|
||||
{ type: "contextmenu", button: 2 },
|
||||
window
|
||||
);
|
||||
await panelShown;
|
||||
Assert.ok(tabgroupPanel.state == "open", "Tabgroup edit panel is open");
|
||||
Assert.ok(!tabgroupEditor.createMode, "Group editor is not in create mode");
|
||||
|
||||
panelHidden = BrowserTestUtils.waitForPopupEvent(tabgroupPanel, "hidden");
|
||||
EventUtils.synthesizeKey("KEY_Escape");
|
||||
await panelHidden;
|
||||
gBrowser.removeTabGroup(group, { animate: false });
|
||||
});
|
||||
|
||||
async function createTabGroupAndOpenEditPanel() {
|
||||
let tabgroupEditor = document.getElementById("tab-group-editor");
|
||||
let tabgroupPanel = tabgroupEditor.panel;
|
||||
let tab = BrowserTestUtils.addTab(gBrowser, "about:blank", {
|
||||
animate: false,
|
||||
});
|
||||
|
||||
let panelShown = BrowserTestUtils.waitForPopupEvent(tabgroupPanel, "shown");
|
||||
let group = gBrowser.addTabGroup("cyan", "Food", [tab]);
|
||||
await panelShown;
|
||||
|
||||
// Panel dismissed after clicking Create and group remains
|
||||
let panelHidden = BrowserTestUtils.waitForPopupEvent(tabgroupPanel, "hidden");
|
||||
tabgroupPanel.querySelector("#tab-group-editor-button-create").click();
|
||||
await panelHidden;
|
||||
|
||||
panelShown = BrowserTestUtils.waitForPopupEvent(tabgroupPanel, "shown");
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
group.querySelector(".tab-group-label"),
|
||||
{ type: "contextmenu", button: 2 },
|
||||
window
|
||||
);
|
||||
return new Promise(resolve => {
|
||||
panelShown.then(() => {
|
||||
resolve({ tabgroupEditor, tabgroupPanel, tab, group });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
add_task(async function test_tabGroupPanelAddTab() {
|
||||
let { tabgroupPanel, group } = await createTabGroupAndOpenEditPanel();
|
||||
|
||||
let addNewTabButton = tabgroupPanel.querySelector(
|
||||
"#tabGroupEditor_addNewTabInGroup"
|
||||
);
|
||||
|
||||
Assert.equal(group.tabs.length, 1, "Group has 1 tab");
|
||||
let panelHidden = BrowserTestUtils.waitForPopupEvent(tabgroupPanel, "hidden");
|
||||
addNewTabButton.click();
|
||||
await panelHidden;
|
||||
Assert.ok(tabgroupPanel.state === "closed", "Group editor is closed");
|
||||
Assert.equal(group.tabs.length, 2, "Group has 2 tabs");
|
||||
|
||||
for (let tab of group.tabs) {
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(async function test_tabGroupPanelUngroupTabs() {
|
||||
let { tabgroupPanel, tab, group } = await createTabGroupAndOpenEditPanel();
|
||||
let ungroupTabsButton = tabgroupPanel.querySelector(
|
||||
"#tabGroupEditor_ungroupTabs"
|
||||
);
|
||||
|
||||
Assert.ok(tab.group.id == group.id, "Tab is in group");
|
||||
let panelHidden = BrowserTestUtils.waitForPopupEvent(tabgroupPanel, "hidden");
|
||||
ungroupTabsButton.click();
|
||||
await panelHidden;
|
||||
Assert.ok(!tab.group, "Tab is no longer grouped");
|
||||
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
@ -23,6 +23,11 @@ tab-context-move-tab-to-group =
|
||||
}
|
||||
.accesskey = G
|
||||
|
||||
tab-group-editor-action-add-new = Add tab to group
|
||||
tab-group-editor-action-new-window = Move group to new window
|
||||
tab-group-editor-action-save = Save and close group
|
||||
tab-group-editor-action-ungroup = Ungroup tabs
|
||||
tab-group-editor-action-delete = Delete group
|
||||
tab-group-editor-done =
|
||||
.label = Done
|
||||
.accessKey = D
|
||||
|
@ -788,16 +788,25 @@ tab-group {
|
||||
|
||||
.panel-header {
|
||||
min-height: auto;
|
||||
> h1 {
|
||||
margin-top: 0;
|
||||
margin-bottom: var(--space-small);
|
||||
}
|
||||
}
|
||||
|
||||
toolbarseparator {
|
||||
margin-top: var(--space-medium);
|
||||
margin-block: var(--space-medium);
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
padding-block: var(--space-medium);
|
||||
}
|
||||
|
||||
&.tab-group-editor-mode-create .tab-group-edit-mode-only,
|
||||
&:not(.tab-group-editor-mode-create) .tab-group-create-mode-only {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tab-group-editor-name {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -836,6 +845,21 @@ tab-group {
|
||||
border-radius: 20%;
|
||||
background-color: light-dark(var(--tabgroup-swatch-color), var(--tabgroup-swatch-color-invert));
|
||||
}
|
||||
|
||||
.tab-group-edit-actions,
|
||||
.tab-group-delete {
|
||||
padding-block: 0;
|
||||
> toolbarbutton {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
toolbarbutton {
|
||||
margin: 0;
|
||||
}
|
||||
.tab-group-delete label {
|
||||
color: var(--text-color-error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user