diff --git a/webextensions/background/commands.js b/webextensions/background/commands.js index 9b38ee5b5..cc495c84d 100644 --- a/webextensions/background/commands.js +++ b/webextensions/background/commands.js @@ -532,14 +532,7 @@ export async function moveTabsWithStructure(tabs, params = {}) { let movedRoots = params.import ? [] : Tab.collectRootTabs(movedTabs); - const movedWholeTree = [].concat(movedRoots); - for (const movedRoot of movedRoots) { - const descendants = movedRoot.$TST.descendants; - for (const descendant of descendants) { - if (!movedWholeTree.includes(descendant)) - movedWholeTree.push(descendant); - } - } + const movedWholeTree = Tree.getWholeTree(movedRoots); log('=> movedTabs: ', () => ['moved', movedTabs.map(dumpTab).join(' / '), 'whole', movedWholeTree.map(dumpTab).join(' / ')]); const movedTabsSet = new Set(movedTabs); @@ -568,6 +561,7 @@ export async function moveTabsWithStructure(tabs, params = {}) { await Tree.detachTabsFromTree(movedTabs, { insertBefore: params.insertBefore, insertAfter: params.insertAfter, + partial: true, broadcast: params.broadcast, }); } diff --git a/webextensions/background/tree.js b/webextensions/background/tree.js index 494b73254..9336ac145 100644 --- a/webextensions/background/tree.js +++ b/webextensions/background/tree.js @@ -624,15 +624,40 @@ export function detachTab(child, options = {}) { }); } +export function getWholeTree(rootTabs) { + if (!Array.isArray(rootTabs)) + rootTabs = [rootTabs]; + const wholeTree = [].concat(rootTabs); + for (const movedRoot of rootTabs) { + const descendants = movedRoot.$TST.descendants; + for (const descendant of descendants) { + if (!wholeTree.includes(descendant)) + wholeTree.push(descendant); + } + } + return wholeTree; +} + export async function detachTabsFromTree(tabs, options = {}) { if (!Array.isArray(tabs)) tabs = [tabs]; tabs = Array.from(tabs).reverse(); + // you should specify this option if you already call "Tree.getWholeTree()" for the tabs. + const partial = 'partial' in options ? + options.partial : + getWholeTree(tabs).length != tabs.length; const promisedAttach = []; for (const tab of tabs) { + let behavior = partial ? + TreeBehavior.getParentTabOperationBehavior(tab, { + context: Constants.kPARENT_TAB_OPERATION_CONTEXT_CLOSE, + }) : + Constants.kPARENT_TAB_OPERATION_BEHAVIOR_PROMOTE_FIRST_CHILD; + if (behavior == Constants.kPARENT_TAB_OPERATION_BEHAVIOR_ENTIRE_TREE) + behavior = Constants.kPARENT_TAB_OPERATION_BEHAVIOR_PROMOTE_FIRST_CHILD; promisedAttach.push(detachAllChildren(tab, { ...options, - behavior: Constants.kPARENT_TAB_OPERATION_BEHAVIOR_PROMOTE_FIRST_CHILD, + behavior, ignoreTabs: tabs, })); }