new API, importTabs() (and moveTabs())

This commit is contained in:
SHIMODA Hiroshi 2011-06-15 18:13:23 +09:00
parent c39d55061a
commit f9e9e4efd4
2 changed files with 127 additions and 86 deletions

View File

@ -4709,6 +4709,111 @@ TreeStyleTabBrowser.prototype = {
return false;
},
/**
* Imports tabs from another window with their tree structure.
* aOptions is an optional hash which can have two properties:
* * duplicate (boolean)
* * insertBefore (nsIDOMElement)
*/
importTabs : function TSTBrowser_importTabs(aTabs, aOptions) /* PUBLIC API */
{
return this.moveTabs(aTabs, aOptions);
},
moveTabs : function TSTBrowser_importTabs(aTabs, aOptions) /* PUBLIC API */
{
aOptions = aOptions || {};
var targetBrowser = this.mTabBrowser;
var sourceWindow = aTabs[0].ownerDocument.defaultView;
var sourceBrowser = sourceWindow.TreeStyleTabService.getTabBrowserFromChild(aTabs[0]);
var sourceService = sourceBrowser.treeStyleTab;
// prevent Multiple Tab Handler feature
targetBrowser.duplicatingSelectedTabs = true;
targetBrowser.movingSelectedTabs = true;
var shouldClose = (
!aOptions.duplicate &&
sourceService.getAllTabsArray(sourceBrowser).length == aTabs.length
);
var newTabs = [];
var treeStructure = sourceService.getTreeStructureFromTabs(aTabs);
// Firefox fails to "move" collapsed tabs. So, expand them first
// and collapse them after they are moved.
var collapsedStates = sourceService.forceExpandTabs(aTabs);;
var shouldResetSelection = (
aTabs.every(function(aTab) {
return aTab.getAttribute('multiselected') == 'true';
}) &&
(sourceService != this || aOptions.duplicate)
);
var tabs = this.getTabsArray(targetBrowser);
var lastTabIndex = tabs[tabs.length -1]._tPos;
for (let i in aTabs)
{
let tab = aTabs[i];
if (shouldResetSelection) {
if ('MultipleTabService' in sourceWindow)
sourceWindow.MultipleTabService.setSelection(tab, false);
else
tab.removeAttribute('multiselected');
}
if (aOptions.duplicate) {
tab = this.duplicateTabAsOrphan(tab);
newTabs.push(tab);
}
else if (sourceService != this) {
tab = this.importTab(tab);
newTabs.push(tab);
}
if (shouldResetSelection) {
if ('MultipleTabService' in sourceWindow)
sourceWindow.MultipleTabService.setSelection(tab, true);
else
tab.setAttribute('multiselected', true);
}
lastTabIndex++;
let newIndex = aOptions.insertBefore ? aOptions.insertBefore._tPos : lastTabIndex ;
if (aOptions.insertBefore && newIndex > tab._tPos) newIndex--;
this.internallyTabMovingCount++;
targetBrowser.moveTabTo(tab, newIndex);
this.collapseExpandTab(tab, false, true);
this.internallyTabMovingCount--;
}
if (shouldClose)
sourceService.closeOwner(sourceBrowser);
if (newTabs.length)
this.applyTreeStructureToTabs(
newTabs,
treeStructure,
collapsedStates.map(function(aCollapsed) {
return !aCollapsed
})
);
for (let i = collapsedStates.length - 1; i > -1; i--)
{
sourceService.collapseExpandSubtree(aTabs[i], collapsedStates[i], true);
}
// Multiple Tab Handler
targetBrowser.movingSelectedTabs = false;
targetBrowser.duplicatingSelectedTabs = false;
return newTabs;
},
importTab : function TSTBrowser_importTab(aTab)
{
var newTab = this.mTabBrowser.addTab();
@ -4726,6 +4831,23 @@ TreeStyleTabBrowser.prototype = {
this.deleteTabValue(newTab, this.kPARENT);
return newTab;
},
closeOwner : function TSTBrowser_closeOwner(aTabOwner)
{
var w = aTabOwner.ownerDocument.defaultView;
if (!w) return;
if ('SplitBrowser' in w) {
if ('getSubBrowserFromChild' in w.SplitBrowser) {
var subbrowser = w.SplitBrowser.getSubBrowserFromChild(aTabOwner);
if (subbrowser) {
subbrowser.close();
return;
}
}
if (w.SplitBrowser.browsers.length) return;
}
w.close();
},
/* collapse/expand */

View File

@ -411,7 +411,7 @@ catch(e) {
var targetBrowser = b;
var tabs = sourceService.getTabsArray(targetBrowser);
var tabs = sv.getTabsArray(targetBrowser);
var draggedWholeTree = [].concat(draggedRoots);
for each (let root in draggedRoots)
@ -459,72 +459,12 @@ catch(e) {
}
}
// prevent Multiple Tab Handler feature
targetBrowser.duplicatingSelectedTabs = true;
targetBrowser.movingSelectedTabs = true;
var shouldClose = (
aInfo.action & sv.kACTION_IMPORT &&
sourceService.getAllTabsArray(sourceBrowser).length == draggedTabs.length
);
var newTabs = [];
var treeStructure = sourceService.getTreeStructureFromTabs(draggedTabs);
// Firefox fails to "move" collapsed tabs. So, expand them first
// and collapse them after they are moved.
var collapsedStates = (
aInfo.action & sv.kACTION_MOVE ||
aInfo.action & sv.kACTION_IMPORT ||
aInfo.action & sv.kACTION_DUPLICATE
) ?
sourceService.forceExpandTabs(draggedWholeTree) :
[] ;
var lastTabIndex = tabs[tabs.length -1]._tPos;
for (let i in draggedTabs)
{
let tab = draggedTabs[i];
let TST = sourceService;
if (aInfo.action & sv.kACTIONS_FOR_DESTINATION) {
if (tabsInfo.isMultipleMove && 'MultipleTabService' in sourceWindow)
sourceWindow.MultipleTabService.setSelection(tab, false);
tab = (aInfo.action & sv.kACTION_IMPORT) ?
sv.importTab(tab) :
sv.duplicateTabAsOrphan(tab) ;
newTabs.push(tab);
if (tabsInfo.isMultipleMove && 'MultipleTabService' in w)
w.MultipleTabService.setSelection(tab, true);
lastTabIndex++;
TST = sv;
}
let newIndex = aInfo.insertBefore ? aInfo.insertBefore._tPos : lastTabIndex ;
if (aInfo.insertBefore && newIndex > tab._tPos) newIndex--;
TST.internallyTabMovingCount++;
targetBrowser.moveTabTo(tab, newIndex);
TST.collapseExpandTab(tab, false, true);
TST.internallyTabMovingCount--;
}
if (shouldClose)
this.closeOwner(sourceBrowser);
if (newTabs.length)
sv.applyTreeStructureToTabs(
newTabs,
treeStructure,
collapsedStates.map(function(aCollapsed) {
return !aCollapsed
})
);
for (let i = collapsedStates.length - 1; i > -1; i--)
{
sourceService.collapseExpandSubtree(draggedWholeTree[i], collapsedStates[i], true);
}
var newTabs = sv.importTabs(draggedTabs, {
duplicate : aInfo.action & sv.kACTION_DUPLICATE,
insertBefore : aInfo.insertBefore
});
if (newTabs.length && aInfo.action & sv.kACTION_ATTACH)
this.attachTabsOnDrop(
@ -534,10 +474,6 @@ catch(e) {
aInfo.parent
);
// Multiple Tab Handler
targetBrowser.movingSelectedTabs = false;
targetBrowser.duplicatingSelectedTabs = false;
return true;
},
@ -603,23 +539,6 @@ catch(e) {
}, sv);
b.movingSelectedTabs = false; // Multiple Tab Handler
},
closeOwner : function TabbarDND_closeOwner(aTabOwner)
{
var w = aTabOwner.ownerDocument.defaultView;
if (!w) return;
if ('SplitBrowser' in w) {
if ('getSubBrowserFromChild' in w.SplitBrowser) {
var subbrowser = w.SplitBrowser.getSubBrowserFromChild(aTabOwner);
if (subbrowser) {
subbrowser.close();
return;
}
}
if (w.SplitBrowser.browsers.length) return;
}
w.close();
},
clearDropPosition : function TabbarDND_clearDropPosition()
{