mirror of
https://github.com/zen-browser/desktop.git
synced 2026-09-14 00:50:46 +00:00
gh-15329: Prevent split view preview from opening for multiple tabs (gh-15340)
This commit is contained in:
@@ -336,7 +336,9 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
|
||||
if (
|
||||
!gBrowser.isTab(draggedTab) ||
|
||||
gBrowser.selectedTab.hasAttribute("zen-empty-tab") ||
|
||||
draggedTab.documentGlobal !== window
|
||||
draggedTab.documentGlobal !== window ||
|
||||
// See gh-15329.
|
||||
draggedTab.multiselected
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -526,9 +526,6 @@ class nsZenSpacesSyncApplier {
|
||||
if (!folder?.isZenFolder) {
|
||||
continue;
|
||||
}
|
||||
// Members without their own tombstone survive: unpack, then delete
|
||||
// the (now empty) folder.
|
||||
await folder.unpackTabs();
|
||||
await folder.delete();
|
||||
} catch (e) {
|
||||
fail(record, e);
|
||||
|
||||
@@ -12,6 +12,8 @@ support-files = [
|
||||
"head.js",
|
||||
]
|
||||
|
||||
["browser_folder_delete.js"]
|
||||
|
||||
["browser_normal_tabs_apply.js"]
|
||||
|
||||
["browser_normal_tabs_projection.js"]
|
||||
100
src/zen/tests/device_sync/browser_folder_delete.js
Normal file
100
src/zen/tests/device_sync/browser_folder_delete.js
Normal file
@@ -0,0 +1,100 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
https://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
async function applyFolderWithMembers(fid, memberIds) {
|
||||
const failed = await ZenSpacesSyncApplier.applyBatch([
|
||||
folderRecord(fid),
|
||||
...memberIds.map(id => tabRecord(id, { pinned: true, folderId: fid })),
|
||||
]);
|
||||
Assert.deepEqual(failed, [], "The folder batch should apply cleanly");
|
||||
const folder = document.getElementById(fid);
|
||||
Assert.ok(folder?.isZenFolder, "The folder should materialize");
|
||||
for (const id of memberIds) {
|
||||
Assert.equal(
|
||||
document.getElementById(id)?.group,
|
||||
folder,
|
||||
`member ${id} should live in the folder`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
add_task(async function test_FolderTombstoneWithMemberTombstones() {
|
||||
await gZenWorkspaces.promiseInitialized;
|
||||
const fid = "test-sync-del-a-folder";
|
||||
const members = ["test-sync-del-a-1", "test-sync-del-a-2"];
|
||||
await applyFolderWithMembers(fid, members);
|
||||
|
||||
const failed = await ZenSpacesSyncApplier.applyBatch([
|
||||
tombstone(fid),
|
||||
...members.map(tombstone),
|
||||
]);
|
||||
Assert.deepEqual(failed, [], "The tombstone batch should apply cleanly");
|
||||
await TestUtils.waitForCondition(
|
||||
() => !document.getElementById(fid),
|
||||
"waiting for the folder to be removed"
|
||||
);
|
||||
for (const id of members) {
|
||||
Assert.ok(!document.getElementById(id), `member ${id} should be gone`);
|
||||
}
|
||||
|
||||
for (const id of [fid, ...members]) {
|
||||
ZenSpacesSyncModel.noteApplied(id, null);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(async function test_FolderTombstoneAloneDeletesMembers() {
|
||||
await gZenWorkspaces.promiseInitialized;
|
||||
const fid = "test-sync-del-b-folder";
|
||||
const members = ["test-sync-del-b-1", "test-sync-del-b-2"];
|
||||
await applyFolderWithMembers(fid, members);
|
||||
|
||||
const failed = await ZenSpacesSyncApplier.applyBatch([tombstone(fid)]);
|
||||
Assert.deepEqual(failed, [], "The tombstone batch should apply cleanly");
|
||||
await TestUtils.waitForCondition(
|
||||
() => !document.getElementById(fid),
|
||||
"waiting for the folder to be removed"
|
||||
);
|
||||
for (const id of members) {
|
||||
const tab = document.getElementById(id);
|
||||
Assert.ok(!tab, `member ${id} should be deleted, not orphaned as pinned`);
|
||||
}
|
||||
|
||||
for (const id of [fid, ...members]) {
|
||||
ZenSpacesSyncModel.noteApplied(id, null);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(async function test_MemberMovedOutSurvivesFolderTombstone() {
|
||||
await gZenWorkspaces.promiseInitialized;
|
||||
const fid = "test-sync-del-c-folder";
|
||||
const stays = "test-sync-del-c-stays";
|
||||
const moved = "test-sync-del-c-moved";
|
||||
await applyFolderWithMembers(fid, [stays, moved]);
|
||||
|
||||
const failed = await ZenSpacesSyncApplier.applyBatch([
|
||||
tabRecord(moved, { pinned: true, folderId: null }),
|
||||
tombstone(fid),
|
||||
]);
|
||||
Assert.deepEqual(failed, [], "The batch should apply cleanly");
|
||||
await TestUtils.waitForCondition(
|
||||
() => !document.getElementById(fid),
|
||||
"waiting for the folder to be removed"
|
||||
);
|
||||
const movedTab = document.getElementById(moved);
|
||||
Assert.ok(movedTab, "the moved-out member should survive");
|
||||
Assert.ok(!movedTab.group?.isZenFolder, "and no longer be in a folder");
|
||||
Assert.ok(
|
||||
!document.getElementById(stays),
|
||||
"the member with no surviving record should be deleted"
|
||||
);
|
||||
|
||||
ZenSpacesSyncModel.noteApplied(moved, null);
|
||||
for (const id of [fid, stays]) {
|
||||
ZenSpacesSyncModel.noteApplied(id, null);
|
||||
}
|
||||
if (movedTab) {
|
||||
BrowserTestUtils.removeTab(movedTab);
|
||||
}
|
||||
});
|
||||
@@ -22,6 +22,11 @@ const { TestUtils } = ChromeUtils.importESModule(
|
||||
const { E10SUtils } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/E10SUtils.sys.mjs"
|
||||
);
|
||||
const { PromiseTestUtils } = ChromeUtils.importESModule(
|
||||
"resource://testing-common/PromiseTestUtils.sys.mjs"
|
||||
);
|
||||
|
||||
PromiseTestUtils.allowMatchingRejectionsGlobally(/menu-bookmark-tab/);
|
||||
|
||||
const NORMAL_TABS_PREF = "zen.spaces-sync.normal-tabs";
|
||||
|
||||
@@ -47,7 +52,13 @@ async function openSyncableTab(url, { pinned = false } = {}) {
|
||||
|
||||
function tabRecord(
|
||||
id,
|
||||
{ pinned, url = "https://example.com/", current = null, workspaceUuid } = {}
|
||||
{
|
||||
pinned,
|
||||
url = "https://example.com/",
|
||||
current = null,
|
||||
workspaceUuid,
|
||||
folderId = null,
|
||||
} = {}
|
||||
) {
|
||||
return {
|
||||
id,
|
||||
@@ -64,7 +75,7 @@ function tabRecord(
|
||||
essential: false,
|
||||
pinned,
|
||||
workspaceUuid: workspaceUuid ?? gZenWorkspaces.activeWorkspace,
|
||||
folderId: null,
|
||||
folderId,
|
||||
staticLabel: null,
|
||||
hasStaticIcon: false,
|
||||
defaultContainer: false,
|
||||
@@ -72,3 +83,26 @@ function tabRecord(
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function folderRecord(id, { name = "Synced folder", workspaceUuid } = {}) {
|
||||
return {
|
||||
id,
|
||||
deleted: false,
|
||||
cleartext: {
|
||||
kind: "folder",
|
||||
data: {
|
||||
folderId: id,
|
||||
name,
|
||||
icon: null,
|
||||
workspaceUuid: workspaceUuid ?? gZenWorkspaces.activeWorkspace,
|
||||
parentFolderId: null,
|
||||
live: null,
|
||||
children: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function tombstone(id) {
|
||||
return { id, deleted: true };
|
||||
}
|
||||
@@ -6,6 +6,7 @@ BROWSER_CHROME_MANIFESTS += [
|
||||
"boosts/browser.toml",
|
||||
"compact_mode/browser.toml",
|
||||
"container_essentials/browser.toml",
|
||||
"device_sync/browser.toml",
|
||||
"folders/browser.toml",
|
||||
"glance/browser.toml",
|
||||
"live-folders/browser.toml",
|
||||
@@ -16,7 +17,6 @@ BROWSER_CHROME_MANIFESTS += [
|
||||
"site_control/browser.toml",
|
||||
"space_routing/browser.toml",
|
||||
"spaces/browser.toml",
|
||||
"spaces_sync/browser.toml",
|
||||
"split_view/browser.toml",
|
||||
"tabs/browser.toml",
|
||||
"ub-actions/browser.toml",
|
||||
|
||||
Reference in New Issue
Block a user