タブのドラッグ&ドロップの処理のオーバーライド

git-svn-id: http://www.cozmixng.org/repos/piro/treestyletab/trunk@6428 599a83e7-65a4-db11-8015-0010dcdd6dc2
This commit is contained in:
piro 2010-03-24 17:20:30 +00:00
parent aaa28a1142
commit 0b0de3ebaa
3 changed files with 131 additions and 61 deletions

View File

@ -12,21 +12,21 @@ var TreeStyleTabService = {
return this.utils.currentTabbarPosition; return this.utils.currentTabbarPosition;
}, },
set currentTabbarPosition(aValue) set currentTabbarPosition(aValue)
{ {
if ('UndoTabService' in window && UndoTabService.isUndoable()) { if ('UndoTabService' in window && UndoTabService.isUndoable()) {
var current = this.utils.currentTabbarPosition; var current = this.utils.currentTabbarPosition;
var self = this; var self = this;
UndoTabService.doOperation( UndoTabService.doOperation(
function() { function() {
self.utils.currentTabbarPosition = aValue; self.utils.currentTabbarPosition = aValue;
}, },
{ {
label : self.treeBundle.getString('undo_changeTabbarPosition_label'), label : self.treeBundle.getString('undo_changeTabbarPosition_label'),
name : 'treestyletab-changeTabbarPosition', name : 'treestyletab-changeTabbarPosition',
data : { data : {
oldPosition : current, oldPosition : current,
newPosition : aValue newPosition : aValue
} }
} }
); );
} }
@ -288,7 +288,7 @@ var TreeStyleTabService = {
var appcontent = document.getElementById('appcontent'); var appcontent = document.getElementById('appcontent');
appcontent.addEventListener('SubBrowserAdded', this, false); appcontent.addEventListener('SubBrowserAdded', this, false);
appcontent.addEventListener('SubBrowserRemoveRequest', this, false); appcontent.addEventListener('SubBrowserRemoveRequest', this, false);
window.addEventListener('UIOperationHistoryUndo:TabbarOperations', this, false); window.addEventListener('UIOperationHistoryUndo:TabbarOperations', this, false);
window.addEventListener('UIOperationHistoryRedo:TabbarOperations', this, false); window.addEventListener('UIOperationHistoryRedo:TabbarOperations', this, false);
@ -344,10 +344,44 @@ var TreeStyleTabService = {
updateTabDNDObserver : function TSTService_updateTabDNDObserver(aObserver) updateTabDNDObserver : function TSTService_updateTabDNDObserver(aObserver)
{ {
if (aObserver.tabContainer && if (aObserver.tabContainer &&
aObserver.tabContainer.tabbrowser == aObserver) aObserver.tabContainer.tabbrowser == aObserver) { // Firefox 3.7 or later
aObserver = aObserver.tabContainer; aObserver = aObserver.tabContainer;
aObserver.addEventListener('dragstart', this, true);
aObserver.addEventListener('dragover', this, true);
aObserver.addEventListener('dragleave', this, true);
}
if ('_onDragStart' in aObserver) { // Firefox 3.5 or later var canDropFunctionName = '_setEffectAllowedForDataTransfer' in aObserver ?
'_setEffectAllowedForDataTransfer' : // Firefox 3.5 or later
'canDrop' ; // Firefox 3.0.x
if (canDropFunctionName in aObserver) {
eval('aObserver.'+canDropFunctionName+' = '+
aObserver[canDropFunctionName].toSource().replace(
'{',
'{ var TSTTabBrowser = this;'
).replace(
/\.screenX/g, '[TreeStyleTabService.getTabBrowserFromChild(TSTTabBrowser).treeStyleTab.positionProp]'
).replace(
/\.width/g, '[TreeStyleTabService.getTabBrowserFromChild(TSTTabBrowser).treeStyleTab.sizeProp]'
).replace(
/(return (?:true|dt.effectAllowed = "copyMove");)/,
<![CDATA[
if (!this.treeStyleTab.checkCanTabDrop(arguments[0], this)) {
return TST_DRAGDROP_DISALLOW_RETRUN_VALUE;
}
$1
]]>
).replace(
/TST_DRAGDROP_DISALLOW_RETRUN_VALUE/g,
(canDropFunctionName == 'canDrop' ?
'false' :
'dt.effectAllowed = "none"'
)
)
);
}
if ('_onDragStart' in aObserver) { // Firefox 3.5 - 3.6
eval('aObserver._onDragStart = '+ eval('aObserver._onDragStart = '+
aObserver._onDragStart.toSource().replace( aObserver._onDragStart.toSource().replace(
'if (target.localName == "tab"', 'if (target.localName == "tab"',
@ -373,38 +407,8 @@ var TreeStyleTabService = {
); );
} }
var canDropFunctionName = '_setEffectAllowedForDataTransfer' in aObserver ?
'_setEffectAllowedForDataTransfer' : // Firefox 3.5 or later
'canDrop' ; // Firefox 3.0.x
if (canDropFunctionName in aObserver) {
eval('aObserver.'+canDropFunctionName+' = '+
aObserver[canDropFunctionName].toSource().replace(
'{',
'{ var TSTTabBrowser = this;'
).replace(
/\.screenX/g, '[TreeStyleTabService.getTabBrowserFromChild(TSTTabBrowser).treeStyleTab.positionProp]'
).replace(
/\.width/g, '[TreeStyleTabService.getTabBrowserFromChild(TSTTabBrowser).treeStyleTab.sizeProp]'
).replace(
/(return (?:true|dt.effectAllowed = "copyMove");)/,
<![CDATA[
if (!this.treeStyleTab.checkCanTabDrop(aEvent, this)) {
return TST_DRAGDROP_DISALLOW_RETRUN_VALUE;
}
$1
]]>
).replace(
/TST_DRAGDROP_DISALLOW_RETRUN_VALUE/g,
(canDropFunctionName == 'canDrop' ?
'false' :
'dt.effectAllowed = "none"'
)
)
);
}
var dragOverFunctionName = '_onDragOver' in aObserver ? var dragOverFunctionName = '_onDragOver' in aObserver ?
'_onDragOver' : // Firefox 3.5 or later '_onDragOver' : // Firefox 3.5 - 3.6
'onDragOver' ; // Firefox 3.0.x 'onDragOver' ; // Firefox 3.0.x
if (dragOverFunctionName in aObserver) { if (dragOverFunctionName in aObserver) {
eval('aObserver.'+dragOverFunctionName+' = '+ eval('aObserver.'+dragOverFunctionName+' = '+
@ -421,7 +425,7 @@ var TreeStyleTabService = {
} }
var dragExitFunctionName = '_onDragLeave' in aObserver ? var dragExitFunctionName = '_onDragLeave' in aObserver ?
'_onDragLeave' : // Firefox 3.5 or later '_onDragLeave' : // Firefox 3.5 - 3.6
'onDragExit' ; // Firefox 3.0.x 'onDragExit' ; // Firefox 3.0.x
if (dragExitFunctionName in aObserver) { if (dragExitFunctionName in aObserver) {
eval('aObserver.'+dragExitFunctionName+' = '+ eval('aObserver.'+dragExitFunctionName+' = '+
@ -501,7 +505,18 @@ var TreeStyleTabService = {
); );
} }
}, },
onTabbarDragStart : function TSTService_onTabbarDragStart(aEvent, aTabBrowser) destroyTabDNDObserver : function TSTService_destroyTabDNDObserver(aObserver)
{
if (aObserver.tabContainer &&
aObserver.tabContainer.tabbrowser == aObserver) { // Firefox 3.7 or later
aObserver = aObserver.tabContainer;
aObserver.removeEventListener('dragstart', this, true);
aObserver.removeEventListener('dragover', this, true);
aObserver.removeEventListener('dragleave', this, true);
}
},
onTabbarDragStart : function TSTService_onTabbarDragStart(aEvent, aTabBrowser)
{ {
var dt = aEvent.dataTransfer; var dt = aEvent.dataTransfer;
dt.mozSetDataAt( dt.mozSetDataAt(
@ -524,7 +539,8 @@ var TreeStyleTabService = {
aEvent.stopPropagation(); aEvent.stopPropagation();
aTabBrowser.treeStyleTab.tabbarDNDObserver.readyToStartDrag(); aTabBrowser.treeStyleTab.tabbarDNDObserver.readyToStartDrag();
}, },
checkCanTabDrop : function TSTService_checkCanTabDrop(aEvent, aTabBrowser)
checkCanTabDrop : function TSTService_checkCanTabDrop(aEvent, aTabBrowser)
{ {
try{ try{
var session = this.getCurrentDragSession(); var session = this.getCurrentDragSession();
@ -547,7 +563,8 @@ catch(e) {
return false; return false;
} }
}, },
processTabDragOverEvent : function TSTService_processTabDragOverEvent(aEvent, aTabBrowser)
processTabDragOverEvent : function TSTService_processTabDragOverEvent(aEvent, aTabBrowser)
{ {
try{ try{
var session = this.getCurrentDragSession(); var session = this.getCurrentDragSession();
@ -556,13 +573,25 @@ try{
var info = this.getDropAction(aEvent, session); var info = this.getDropAction(aEvent, session);
// auto-switch for staying on tabs (Firefox 3.0 or later) // auto-switch for staying on tabs (Firefox 3.0 or later)
var isHTML5Event = '_setEffectAllowedForDataTransfer' in aTabBrowser; var setEffectAllowedFunc;
if (isHTML5Event && if (aTabBrowser._setEffectAllowedForDataTransfer) {
setEffectAllowedFunc = function(aEvent) {
return aTabBrowser._setEffectAllowedForDataTransfer(aEvent);
};
}
else if (aTabBrowser.tabContainer &&
aTabBrowser.tabContainer._setEffectAllowedForDataTransfer) {
setEffectAllowedFunc = function(aEvent) {
return aTabBrowser.tabContainer._setEffectAllowedForDataTransfer(aEvent);
};
}
if (setEffectAllowedFunc &&
info.target && info.target &&
!info.target.selected && !info.target.selected &&
'mDragTime' in aTabBrowser && 'mDragTime' in aTabBrowser &&
'mDragOverDelay' in aTabBrowser) { 'mDragOverDelay' in aTabBrowser) {
let effects = aTabBrowser._setEffectAllowedForDataTransfer(aEvent); let effects = setEffectAllowedFunc(aEvent);
if (effects == 'link') { if (effects == 'link') {
let now = Date.now(); let now = Date.now();
if (!aTabBrowser.mDragTime) if (!aTabBrowser.mDragTime)
@ -579,8 +608,8 @@ try{
).singleNodeValue) ).singleNodeValue)
this.clearDropPosition(); this.clearDropPosition();
if (isHTML5Event ? if (setEffectAllowedFunc ?
(aTabBrowser._setEffectAllowedForDataTransfer(aEvent) == 'none') : (setEffectAllowedFunc(aEvent) == 'none') :
!aTabBrowser.canDrop(aEvent, session) !aTabBrowser.canDrop(aEvent, session)
) )
return true; return true;
@ -591,7 +620,8 @@ try{
info.position == this.kDROP_AFTER ? 'after' : info.position == this.kDROP_AFTER ? 'after' :
'self' 'self'
); );
aTabBrowser.mTabDropIndicatorBar.setAttribute('dragging', (info.position == this.kDROP_ON) ? 'false' : 'true' ); var indicator = aTabBrowser.mTabDropIndicatorBar || aTabBrowser.tabContainer._tabDropIndicator;
indicator.setAttribute('dragging', (info.position == this.kDROP_ON) ? 'false' : 'true' );
return (info.position == this.kDROP_ON || aTabBrowser.getAttribute(this.kTABBAR_POSITION) != 'top') return (info.position == this.kDROP_ON || aTabBrowser.getAttribute(this.kTABBAR_POSITION) != 'top')
} }
catch(e) { catch(e) {
@ -599,6 +629,30 @@ catch(e) {
} }
}, },
/* tab DND listening for Firefox 3.7 or later */
onTabDNDObserverDragStart : function TSTService_onTabDNDObserverDragStart(aEvent)
{
var tabbar = aEvent.currentTarget;
if (tabbar.treeStyleTab.tabbarDNDObserver.canDragTabbar(aEvent))
tabbar.treeStyleTab.onTabbarDragStart(aEvent, tabbar.tabbrowser);
},
onTabDNDObserverDragOver : function TSTService_onTabDNDObserverDragOver(aEvent)
{
var tabbar = aEvent.currentTarget;
if (tabbar.treeStyleTab.processTabDragOverEvent(aEvent, tabbar.tabbrowser))
aEvent.stopPropagation();
},
onTabDNDObserverDragLeave : function TSTService_onTabDNDObserverDragLeave(aEvent)
{
var tabbar = aEvent.currentTarget;
var tabbarFromEvent = this.getTabbarFromChild(aEvent.relatedTarget);
if (!tabbarFromEvent)
tabbar.treeStyleTab.clearDropPosition();
},
overrideGlobalFunctions : function TSTService_overrideGlobalFunctions() overrideGlobalFunctions : function TSTService_overrideGlobalFunctions()
{ {
// window.__treestyletab__BrowserCustomizeToolbar = window.BrowserCustomizeToolbar; // window.__treestyletab__BrowserCustomizeToolbar = window.BrowserCustomizeToolbar;
@ -945,7 +999,7 @@ catch(e) {
var appcontent = document.getElementById('appcontent'); var appcontent = document.getElementById('appcontent');
appcontent.removeEventListener('SubBrowserAdded', this, false); appcontent.removeEventListener('SubBrowserAdded', this, false);
appcontent.removeEventListener('SubBrowserRemoveRequest', this, false); appcontent.removeEventListener('SubBrowserRemoveRequest', this, false);
window.removeEventListener('UIOperationHistoryUndo:TabbarOperations', this, false); window.removeEventListener('UIOperationHistoryUndo:TabbarOperations', this, false);
window.removeEventListener('UIOperationHistoryRedo:TabbarOperations', this, false); window.removeEventListener('UIOperationHistoryRedo:TabbarOperations', this, false);
@ -1043,6 +1097,11 @@ catch(e) {
this.currentTabbarPosition = aEvent.entry.data.newPosition; this.currentTabbarPosition = aEvent.entry.data.newPosition;
return; return;
} }
// tab drag drop listeners for Firefox 3.7 or later
case 'dragstart': return this.onTabDNDObserverDragStart(aEvent);
case 'dragover': return this.onTabDNDObserverDragOver(aEvent);
case 'dragleave': return this.onTabDNDObserverDragLeave(aEvent);
} }
}, },

View File

@ -342,7 +342,7 @@ TreeStyleTabBrowser.prototype = {
) )
); );
this.updateTabDNDObserver(b); TreeStyleTabService.updateTabDNDObserver(b);
if (b.tabContainer && '_getDropIndex' in b.tabContainer) { // Firefox 3.7 or later if (b.tabContainer && '_getDropIndex' in b.tabContainer) { // Firefox 3.7 or later
eval('b.tabContainer._getDropIndex = '+ eval('b.tabContainer._getDropIndex = '+
@ -1266,6 +1266,8 @@ TreeStyleTabBrowser.prototype = {
b.removeEventListener('MultipleTabHandlerTabsClosing', this, false); b.removeEventListener('MultipleTabHandlerTabsClosing', this, false);
TreeStyleTabService.destroyTabDNDObserver(b);
this.tabbarDNDObserver.destroy(); this.tabbarDNDObserver.destroy();
delete this._tabbarDNDObserver; delete this._tabbarDNDObserver;
this.panelDNDObserver.destroy(); this.panelDNDObserver.destroy();
@ -1274,7 +1276,8 @@ TreeStyleTabBrowser.prototype = {
this.scrollBox.removeEventListener('overflow', this, true); this.scrollBox.removeEventListener('overflow', this, true);
this.scrollBox.removeEventListener('underflow', this, true); this.scrollBox.removeEventListener('underflow', this, true);
var tabContextMenu = document.getAnonymousElementByAttribute(b, 'anonid', 'tabContextMenu'); var tabContextMenu = document.getAnonymousElementByAttribute(b, 'anonid', 'tabContextMenu') ||
document.getAnonymousElementByAttribute(b.tabContainer, 'anonid', 'tabContextMenu');
tabContextMenu.removeEventListener('popupshowing', this, false); tabContextMenu.removeEventListener('popupshowing', this, false);
var allTabPopup = document.getAnonymousElementByAttribute(b.mTabContainer, 'anonid', 'alltabs-popup'); var allTabPopup = document.getAnonymousElementByAttribute(b.mTabContainer, 'anonid', 'alltabs-popup');
@ -2839,7 +2842,10 @@ TreeStyleTabBrowser.prototype = {
return info; return info;
} }
else { else {
info.target = tabs[Math.min(b.getNewIndex(aEvent), lastTabIndex)]; let index = b.getNewIndex ?
b.getNewIndex(aEvent) :
b.tabContainer._getDropIndex(aEvent) ;
info.target = tabs[Math.min(index, lastTabIndex)];
} }
} }
else { else {

View File

@ -723,15 +723,20 @@ var TreeStyleTabUtils = {
return null; return null;
}, },
getTabbarFromEvent : function TSTUtils_getTabbarFromEvent(aEvent) getTabbarFromChild : function TSTUtils_getTabbarFromChild(aNode)
{ {
return this.evaluateXPath( return this.evaluateXPath(
'ancestor-or-self::*[contains(concat(" ", normalize-space(@class), " "), " tabbrowser-strip ") or (local-name()="tabs" and @tabbrowser)]', 'ancestor-or-self::*[contains(concat(" ", normalize-space(@class), " "), " tabbrowser-strip ") or (local-name()="tabs" and @tabbrowser)]',
aEvent.originalTarget || aEvent.target, aNode,
Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE
).singleNodeValue; ).singleNodeValue;
}, },
getTabbarFromEvent : function TSTUtils_getTabbarFromEvent(aEvent)
{
return this.getTabbarFromChild(aEvent.originalTarget || aEvent.target);
},
cleanUpTabsArray : function TSTUtils_cleanUpTabsArray(aTabs) cleanUpTabsArray : function TSTUtils_cleanUpTabsArray(aTabs)
{ {
var newTabs = []; var newTabs = [];