ドラッグ&ドロップによるツリーの移動をブラッシュアップ

git-svn-id: http://www.cozmixng.org/repos/piro/treestyletab/trunk@3191 599a83e7-65a4-db11-8015-0010dcdd6dc2
This commit is contained in:
piro 2008-10-17 17:16:16 +00:00
parent 870d11e0cb
commit 54c96e04cb
3 changed files with 139 additions and 136 deletions

View File

@ -403,13 +403,13 @@ TreeStyleTabService.overrideExtensionsOnInitAfter = function() {
).replace( ).replace(
/(var newIndex =)/, /(var newIndex =)/,
<><![CDATA[ <><![CDATA[
if (isTabReorder && TSTTabBrowser.treeStyleTab.processDropAction(dropActionInfo, aDragSession.sourceNode)) if (isTabReorder && TSTTabBrowser.treeStyleTab.performDrop(dropActionInfo, aDragSession.sourceNode))
return; return;
]]></> ]]></>
).replace( ).replace(
/(aTab = gBrowser.addTab\(url\));/, /(aTab = gBrowser.addTab\(url\));/,
<><![CDATA[ <><![CDATA[
TSTTabBrowser.treeStyleTab.processDropAction(dropActionInfo, $1); TSTTabBrowser.treeStyleTab.performDrop(dropActionInfo, $1);
return; return;
]]></> ]]></>
).replace( ).replace(
@ -421,7 +421,7 @@ TreeStyleTabService.overrideExtensionsOnInitAfter = function() {
TreeStyleTabService.getTreePref('loadDroppedLinkToNewChildTab') || TreeStyleTabService.getTreePref('loadDroppedLinkToNewChildTab') ||
dropActionInfo.position != TreeStyleTabService.kDROP_ON dropActionInfo.position != TreeStyleTabService.kDROP_ON
) { ) {
TSTTabBrowser.treeStyleTab.processDropAction(dropActionInfo, TSTTabBrowser.loadOneTab(url, null, null, null, bgLoad, false)); TSTTabBrowser.treeStyleTab.performDrop(dropActionInfo, TSTTabBrowser.loadOneTab(url, null, null, null, bgLoad, false));
return; return;
} }
]]></> ]]></>

View File

@ -42,11 +42,13 @@ var TreeStyleTabService = {
kDROP_AFTER : 1, kDROP_AFTER : 1,
kACTION_MOVE : 1, kACTION_MOVE : 1,
kACTION_ATTACH : 2, kACTION_STAY : 2,
kACTION_PART : 4, kACTION_DUPLICATE : 4,
kACTION_DUPLICATE : 8, kACTION_IMPORT : 8,
kACTION_MOVE_FROM_OTHER_WINDOW : 16, kACTION_ATTACH : 1024,
kACTION_MAY_DUPLICATE : 24, kACTION_PART : 2048,
kACTIONS_FOR_SOURCE : 1 | 2,
kACTIONS_FOR_DESTINATION : 4 | 8,
kTABBAR_TOP : 1, kTABBAR_TOP : 1,
kTABBAR_BOTTOM : 2, kTABBAR_BOTTOM : 2,
@ -1038,13 +1040,13 @@ catch(e) {
).replace( // Firefox 2 ).replace( // Firefox 2
/(if \(aDragSession[^\)]+\) \{)/, /(if \(aDragSession[^\)]+\) \{)/,
<><![CDATA[$1 <><![CDATA[$1
if (TSTTabBrowser.treeStyleTab.processDropAction(dropActionInfo, TST_DRAGSESSION.sourceNode)) if (TSTTabBrowser.treeStyleTab.performDrop(dropActionInfo, TST_DRAGSESSION.sourceNode))
return; return;
]]></> ]]></>
).replace( // Firefox 3.0.x, 3.1 or later ).replace( // Firefox 3.0.x, 3.1 or later
/(if \((accelKeyPressed|isCopy|dropEffect == "copy")\) {)/, /(if \((accelKeyPressed|isCopy|dropEffect == "copy")\) {)/,
<><![CDATA[ <><![CDATA[
if (TSTTabBrowser.treeStyleTab.processDropAction(dropActionInfo, draggedTab)) if (TSTTabBrowser.treeStyleTab.performDrop(dropActionInfo, draggedTab))
return; return;
$1]]></> $1]]></>
).replace( // Firefox 3, duplication of tab ).replace( // Firefox 3, duplication of tab
@ -1056,13 +1058,13 @@ catch(e) {
).replace( // Firefox 3, dragging tab from another window ).replace( // Firefox 3, dragging tab from another window
'else if (draggedTab) {', 'else if (draggedTab) {',
<><![CDATA[$& <><![CDATA[$&
if (TSTTabBrowser.treeStyleTab.processDropAction(dropActionInfo, draggedTab)) if (TSTTabBrowser.treeStyleTab.performDrop(dropActionInfo, draggedTab))
return; return;
]]></> ]]></>
).replace( ).replace(
/(this.loadOneTab\([^;]+\));/, /(this.loadOneTab\([^;]+\));/,
<><![CDATA[ <><![CDATA[
TSTTabBrowser.treeStyleTab.processDropAction(dropActionInfo, $1); TSTTabBrowser.treeStyleTab.performDrop(dropActionInfo, $1);
return; return;
]]></> ]]></>
).replace( ).replace(
@ -1077,7 +1079,7 @@ catch(e) {
TreeStyleTabService.getTreePref('loadDroppedLinkToNewChildTab') || TreeStyleTabService.getTreePref('loadDroppedLinkToNewChildTab') ||
dropActionInfo.position != TreeStyleTabService.kDROP_ON dropActionInfo.position != TreeStyleTabService.kDROP_ON
) { ) {
TSTTabBrowser.treeStyleTab.processDropAction(dropActionInfo, TSTTabBrowser.loadOneTab(getShortcutOrURI(url), null, null, null, bgLoad, false)); TSTTabBrowser.treeStyleTab.performDrop(dropActionInfo, TSTTabBrowser.loadOneTab(getShortcutOrURI(url), null, null, null, bgLoad, false));
return; return;
} }
]]></> ]]></>

View File

@ -1974,26 +1974,31 @@ TreeStyleTabBrowser.prototype = {
if (tab) { if (tab) {
var isCopy = this.isAccelKeyPressed(aEvent); var isCopy = this.isAccelKeyPressed(aEvent);
if (isCopy && 'duplicateTab' in this.mTabBrowser) { if (isCopy && 'duplicateTab' in this.mTabBrowser) {
info.action = this.kACTION_DUPLICATE; info.action |= this.kACTION_DUPLICATE;
} }
if ( if (
!isCopy && !isCopy &&
tab.ownerDocument != document && this.getTabBrowserFromChild(tab) != this.mTabBrowser &&
( (
('duplicateTab' in this.mTabBrowser) || ('duplicateTab' in this.mTabBrowser) ||
('swapBrowsersAndCloseOther' in this.mTabBrowser) ('swapBrowsersAndCloseOther' in this.mTabBrowser)
) )
) { ) {
info.action |= this.kACTION_MOVE_FROM_OTHER_WINDOW; info.action |= this.kACTION_IMPORT;
}
if (info.action & this.kACTIONS_FOR_DESTINATION) {
if (info.action & this.kACTION_MOVE) info.action ^= this.kACTION_MOVE;
if (info.action & this.kACTION_STAY) info.action ^= this.kACTION_STAY;
} }
if (info.action & this.kACTION_ATTACH) { if (info.action & this.kACTION_ATTACH) {
var orig = tab; if (info.parent == tab) {
if (orig == info.parent) {
info.canDrop = false; info.canDrop = false;
} }
else { else {
var tab = info.target; var orig = tab;
tab = info.target;
while (tab = this.getParentTab(tab)) while (tab = this.getParentTab(tab))
{ {
if (tab != orig) continue; if (tab != orig) continue;
@ -2023,7 +2028,7 @@ TreeStyleTabBrowser.prototype = {
var isTabMoveFromOtherWindow = aSourceTab && aSourceTab.ownerDocument != document; var isTabMoveFromOtherWindow = aSourceTab && aSourceTab.ownerDocument != document;
if (tab.localName != 'tab') { if (tab.localName != 'tab') {
var action = isTabMoveFromOtherWindow ? 0 : (this.kACTION_MOVE | this.kACTION_PART) ; var action = isTabMoveFromOtherWindow ? this.kACTION_STAY : (this.kACTION_MOVE | this.kACTION_PART) ;
if (aEvent[this.positionProp] < tabs[0].boxObject[this.positionProp]) { if (aEvent[this.positionProp] < tabs[0].boxObject[this.positionProp]) {
info.target = info.parent = info.insertBefore = tabs[0]; info.target = info.parent = info.insertBefore = tabs[0];
info.position = isInverted ? this.kDROP_AFTER : this.kDROP_BEFORE ; info.position = isInverted ? this.kDROP_AFTER : this.kDROP_BEFORE ;
@ -2059,7 +2064,7 @@ TreeStyleTabBrowser.prototype = {
switch (info.position) switch (info.position)
{ {
case this.kDROP_ON: case this.kDROP_ON:
info.action = this.kACTION_ATTACH; info.action = this.kACTION_STAY | this.kACTION_ATTACH;
info.parent = tab; info.parent = tab;
info.insertBefore = this.getNextVisibleTab(tab); info.insertBefore = this.getNextVisibleTab(tab);
break; break;
@ -2122,7 +2127,7 @@ TreeStyleTabBrowser.prototype = {
return info; return info;
}, },
processDropAction : function(aInfo, aDraggedTab) performDrop : function(aInfo, aDraggedTab)
{ {
aDraggedTab = this.getTabFromChild(aDraggedTab); aDraggedTab = this.getTabFromChild(aDraggedTab);
@ -2135,15 +2140,15 @@ TreeStyleTabBrowser.prototype = {
var sourceWindow = aDraggedTab.ownerDocument.defaultView; var sourceWindow = aDraggedTab.ownerDocument.defaultView;
var sourceBrowser = this.getTabBrowserFromChild(aDraggedTab); var sourceBrowser = this.getTabBrowserFromChild(aDraggedTab);
var moveSelection = ( var isSelectionMove = (
'MultipleTabService' in sourceWindow && 'MultipleTabService' in sourceWindow &&
sourceWindow.MultipleTabService.isSelected(aDraggedTab) && sourceWindow.MultipleTabService.isSelected(aDraggedTab) &&
MultipleTabService.allowMoveMultipleTabs MultipleTabService.allowMoveMultipleTabs
); );
if (moveSelection) { if (isSelectionMove) {
draggedTabs = sourceWindow.MultipleTabService.getSelectedTabs(sourceBrowser); draggedTabs = sourceWindow.MultipleTabService.getSelectedTabs(sourceBrowser);
if (!(aInfo.action & this.kACTION_MAY_DUPLICATE)) { if (!(aInfo.action & this.kACTIONS_FOR_DESTINATION)) {
draggedRoots = []; draggedRoots = [];
draggedTabs.forEach(function(aTab) { draggedTabs.forEach(function(aTab) {
var parent = aTab, var parent = aTab,
@ -2159,47 +2164,39 @@ TreeStyleTabBrowser.prototype = {
}, this); }, this);
} }
} }
else if (sourceWindow != window || aInfo.action & this.kACTION_DUPLICATE) { else if (aInfo.action & this.kACTIONS_FOR_DESTINATION) {
draggedTabs = draggedTabs.concat(sourceBrowser.treeStyleTab.getDescendantTabs(aDraggedTab)); draggedTabs = draggedTabs.concat(sourceBrowser.treeStyleTab.getDescendantTabs(aDraggedTab));
} }
if (aDraggedTab && aInfo.action & this.kACTION_PART) { if (aInfo.action & this.kACTIONS_FOR_SOURCE) {
if (!(aInfo.action & this.kACTION_MAY_DUPLICATE)) if (aInfo.action & this.kACTION_PART) {
this.partTabsOnDrop(draggedRoots); this.partTabsOnDrop(draggedRoots);
} }
else if (aInfo.action & this.kACTION_ATTACH) { else if (aInfo.action & this.kACTION_ATTACH) {
if (!(aInfo.action & this.kACTION_MAY_DUPLICATE))
this.attachTabsOnDrop(draggedRoots, aInfo.parent); this.attachTabsOnDrop(draggedRoots, aInfo.parent);
} }
else if (
(draggedTabs.length > 1) &&
(
(aInfo.action & this.kACTION_MOVE_FROM_OTHER_WINDOW) ||
(aInfo.action & this.kACTION_MAY_DUPLICATE)
)
) {
}
else { else {
return false; return false;
} }
var newSelection = []; if ( // if this move will cause no change...
if ( sourceBrowser == targetBrowser &&
( sourceBrowser.treeStyleTab.getNextVisibleTab(draggedTabs[draggedTabs.length-1]) == aInfo.insertBefore
aInfo.action & this.kACTION_MOVE ||
aInfo.action & this.kACTION_MAY_DUPLICATE
) &&
(
!aInfo.insertBefore ||
sourceBrowser.treeStyleTab.getNextVisibleTab(draggedTabs[0]) != aInfo.insertBefore
)
) { ) {
targetBrowser.duplicatingSelectedTabs = (aInfo.action & this.kACTION_MAY_DUPLICATE) ? true : false ; // Multiple Tab Handler // then, do nothing
targetBrowser.movingSelectedTabs = true; // Multiple Tab Handler return true;
}
}
// prevent Multiple Tab Handler feature
targetBrowser.duplicatingSelectedTabs = true;
targetBrowser.movingSelectedTabs = true;
var newRoots = []; var newRoots = [];
var shouldClose = ( var shouldClose = (
aInfo.action & this.kACTION_MOVE_FROM_OTHER_WINDOW && aInfo.action & this.kACTION_IMPORT &&
sourceBrowser.mTabContainer.childNodes.length == draggedTabs.length sourceBrowser.mTabContainer.childNodes.length == draggedTabs.length
); );
var oldTabs = []; var oldTabs = [];
@ -2211,11 +2208,11 @@ TreeStyleTabBrowser.prototype = {
draggedTabs.forEach(function(aTab) { draggedTabs.forEach(function(aTab) {
var tab = aTab; var tab = aTab;
if (aInfo.action & this.kACTION_MAY_DUPLICATE) { if (aInfo.action & this.kACTIONS_FOR_DESTINATION) {
var parent = sourceBrowser.treeStyleTab.getParentTab(aTab); var parent = sourceBrowser.treeStyleTab.getParentTab(aTab);
if (moveSelection) if (isSelectionMove)
sourceWindow.MultipleTabService.setSelection(aTab, false); sourceWindow.MultipleTabService.setSelection(aTab, false);
if (aInfo.action & this.kACTION_MOVE_FROM_OTHER_WINDOW && if (aInfo.action & this.kACTION_IMPORT &&
'swapBrowsersAndCloseOther' in targetBrowser) { 'swapBrowsersAndCloseOther' in targetBrowser) {
tab = targetBrowser.addTab(); tab = targetBrowser.addTab();
tab.linkedBrowser.stop(); tab.linkedBrowser.stop();
@ -2227,11 +2224,11 @@ TreeStyleTabBrowser.prototype = {
tab = targetBrowser.duplicateTab(aTab); tab = targetBrowser.duplicateTab(aTab);
this.deleteTabValue(tab, this.kCHILDREN); this.deleteTabValue(tab, this.kCHILDREN);
this.deleteTabValue(tab, this.kPARENT); this.deleteTabValue(tab, this.kPARENT);
if (aInfo.action & this.kACTION_MOVE_FROM_OTHER_WINDOW) if (aInfo.action & this.kACTION_IMPORT)
oldTabs.push(aTab); oldTabs.push(aTab);
} }
newTabs.push(tab); newTabs.push(tab);
if (moveSelection) if (isSelectionMove)
MultipleTabService.setSelection(tab, true); MultipleTabService.setSelection(tab, true);
if (!parent || draggedTabs.indexOf(parent) < 0) if (!parent || draggedTabs.indexOf(parent) < 0)
newRoots.push(tab); newRoots.push(tab);
@ -2247,28 +2244,30 @@ TreeStyleTabBrowser.prototype = {
}, this); }, this);
// close imported tabs from the source browser
oldTabs.forEach(function(aTab) { oldTabs.forEach(function(aTab) {
sourceBrowser.removeTab(aTab); sourceBrowser.removeTab(aTab);
}); });
if (shouldClose) this.closeOwner(sourceBrowser);
// restore tree structure for newly opened tabs
newTabs.forEach(function(aTab, aIndex) { newTabs.forEach(function(aTab, aIndex) {
var index = treeStructure[aIndex]; var index = treeStructure[aIndex];
if (index < 0) return; if (index < 0) return;
targetBrowser.treeStyleTab.attachTabTo(aTab, newTabs[index]); targetBrowser.treeStyleTab.attachTabTo(aTab, newTabs[index]);
}); });
if (aInfo.action & this.kACTION_MAY_DUPLICATE && if (aInfo.action & this.kACTIONS_FOR_DESTINATION &&
aInfo.action & this.kACTION_ATTACH) aInfo.action & this.kACTION_ATTACH)
this.attachTabsOnDrop(newRoots, aInfo.parent); this.attachTabsOnDrop(newRoots, aInfo.parent);
if (shouldClose) this.closeOwner(sourceBrowser); // Multiple Tab Handler
targetBrowser.movingSelectedTabs = false;
targetBrowser.movingSelectedTabs = false; // Multiple Tab Handler targetBrowser.duplicatingSelectedTabs = false;
targetBrowser.duplicatingSelectedTabs = false; // Multiple Tab Handler
}
return true; return true;
}, },
attachTabsOnDrop : function(aTabs, aParent) attachTabsOnDrop : function(aTabs, aParent)
{ {
this.mTabBrowser.movingSelectedTabs = true; // Multiple Tab Handler this.mTabBrowser.movingSelectedTabs = true; // Multiple Tab Handler
@ -2281,6 +2280,7 @@ TreeStyleTabBrowser.prototype = {
}, this); }, this);
this.mTabBrowser.movingSelectedTabs = false; // Multiple Tab Handler this.mTabBrowser.movingSelectedTabs = false; // Multiple Tab Handler
}, },
partTabsOnDrop : function(aTabs) partTabsOnDrop : function(aTabs)
{ {
this.mTabBrowser.movingSelectedTabs = true; // Multiple Tab Handler this.mTabBrowser.movingSelectedTabs = true; // Multiple Tab Handler
@ -2290,6 +2290,7 @@ TreeStyleTabBrowser.prototype = {
}, this); }, this);
this.mTabBrowser.movingSelectedTabs = false; // Multiple Tab Handler this.mTabBrowser.movingSelectedTabs = false; // Multiple Tab Handler
}, },
closeOwner : function(aTabOwner) closeOwner : function(aTabOwner)
{ {
var w = aTabOwner.ownerDocument.defaultView; var w = aTabOwner.ownerDocument.defaultView;