Process animation effect for dragged tabs correctly
This commit is contained in:
parent
f090ce14b1
commit
4d19cd75c6
@ -15,7 +15,7 @@
|
|||||||
http://github.com/piroor/fxaddonlibs/blob/master/tabsDragUtils.js
|
http://github.com/piroor/fxaddonlibs/blob/master/tabsDragUtils.js
|
||||||
*/
|
*/
|
||||||
(function() {
|
(function() {
|
||||||
const currentRevision = 20;
|
const currentRevision = 21;
|
||||||
|
|
||||||
if (!('piro.sakura.ne.jp' in window)) window['piro.sakura.ne.jp'] = {};
|
if (!('piro.sakura.ne.jp' in window)) window['piro.sakura.ne.jp'] = {};
|
||||||
|
|
||||||
@ -159,17 +159,17 @@
|
|||||||
).replace(
|
).replace(
|
||||||
/(let tabCenter = [^;]+)\/ 2;/,
|
/(let tabCenter = [^;]+)\/ 2;/,
|
||||||
'$1 / units/*2*/;\n' + // support drop on self
|
'$1 / units/*2*/;\n' + // support drop on self
|
||||||
'let firstTabCenter = tabCenter;\n' +
|
'let tabLeftCenter = tabCenter;\n' +
|
||||||
'let lastTabCenter = tabScreenX + translateX + tabsWidth - tabWidth / units;'
|
'let tabRightCenter = tabScreenX + translateX + tabsWidth - tabWidth / units;'
|
||||||
).replace(
|
).replace(
|
||||||
'tabs[mid] == draggedTab',
|
'tabs[mid] == draggedTab',
|
||||||
'/* $& */ false'
|
'/* $& */ false'
|
||||||
).replace(
|
).replace(
|
||||||
'(screenX > tabCenter)',
|
'(screenX > tabCenter)',
|
||||||
'/* $& */ (screenX > lastTabCenter + (aAcceptDropOnSelf ? tabWidth / units : 0 ))'
|
'/* $& */ (screenX > tabRightCenter)'
|
||||||
).replace(
|
).replace(
|
||||||
'(screenX + boxObject[size] < tabCenter)',
|
'(screenX + boxObject[size] < tabCenter)',
|
||||||
'/* $& */ (screenX + boxObject[size] < firstTabCenter)'
|
'/* $& */ (screenX + boxObject[size] < tabLeftCenter)'
|
||||||
).replace(
|
).replace(
|
||||||
'-tabWidth : tabWidth',
|
'-tabWidth : tabWidth',
|
||||||
'/* $& */ -tabsWidth : tabsWidth'
|
'/* $& */ -tabsWidth : tabsWidth'
|
||||||
@ -271,8 +271,8 @@
|
|||||||
// tab.style.transform = draggedTab.style.transform;
|
// tab.style.transform = draggedTab.style.transform;
|
||||||
// }, this);
|
// }, this);
|
||||||
// let tabCenter = tabScreenX + translateX + tabWidth / units/*2*/;
|
// let tabCenter = tabScreenX + translateX + tabWidth / units/*2*/;
|
||||||
// let firstTabCenter = tabCenter;
|
// let tabLeftCenter = tabCenter;
|
||||||
// let lastTabCenter = tabScreenX + translateX + tabsWidth - tabWidth / units;
|
// let tabRightCenter = tabScreenX + translateX + tabsWidth - tabWidth / units;
|
||||||
// let newIndex = -1;
|
// let newIndex = -1;
|
||||||
// let oldIndex = "animDropIndex" in draggedTab._dragData ?
|
// let oldIndex = "animDropIndex" in draggedTab._dragData ?
|
||||||
// draggedTab._dragData.animDropIndex : draggedTab._tPos;
|
// draggedTab._dragData.animDropIndex : draggedTab._tPos;
|
||||||
@ -287,10 +287,10 @@
|
|||||||
// let boxObject = tabs[mid].boxObject;
|
// let boxObject = tabs[mid].boxObject;
|
||||||
// let screenX = boxObject[position]/*.screenX*/ + getTabShift(tabs[mid], oldIndex);
|
// let screenX = boxObject[position]/*.screenX*/ + getTabShift(tabs[mid], oldIndex);
|
||||||
// // if (screenX > tabCenter) {
|
// // if (screenX > tabCenter) {
|
||||||
// if (screenX > lastTabCenter + (aAcceptDropOnSelf ? tabWidth / units : 0 )) {
|
// if (screenX > tabRightCenter) {
|
||||||
// high = mid - 1;
|
// high = mid - 1;
|
||||||
// // } else if (screenX + boxObject.width < tabCenter) {
|
// // } else if (screenX + boxObject.width < tabCenter) {
|
||||||
// } else if (screenX + boxObject[size]/*.width*/ < firstTabCenter) {
|
// } else if (screenX + boxObject[size]/*.width*/ < tabLeftCenter) {
|
||||||
// low = mid + 1;
|
// low = mid + 1;
|
||||||
// } else {
|
// } else {
|
||||||
// newIndex = tabs[mid]._tPos;
|
// newIndex = tabs[mid]._tPos;
|
||||||
@ -360,7 +360,7 @@
|
|||||||
navigator.platform.toLowerCase().indexOf('win') < 0)
|
navigator.platform.toLowerCase().indexOf('win') < 0)
|
||||||
dt.mozCursor = 'default';
|
dt.mozCursor = 'default';
|
||||||
|
|
||||||
if (this.shouldAnimateDragggedTabs(aEvent)) {
|
if (this.canAnimateDraggedTabs(aEvent)) {
|
||||||
let tabbar = this.getTabbarFromEvent(aEvent);
|
let tabbar = this.getTabbarFromEvent(aEvent);
|
||||||
let tabbarOffsetX = this.getClientX(tabbar.children[0].pinned ? tabbar.children[0] : tabbar );
|
let tabbarOffsetX = this.getClientX(tabbar.children[0].pinned ? tabbar.children[0] : tabbar );
|
||||||
let tabbarOffsetY = this.getClientY(tabbar.children[0].pinned ? tabbar.children[0] : tabbar );
|
let tabbarOffsetY = this.getClientY(tabbar.children[0].pinned ? tabbar.children[0] : tabbar );
|
||||||
@ -484,25 +484,23 @@
|
|||||||
).singleNodeValue;
|
).singleNodeValue;
|
||||||
return (b && b.tabbrowser) || b;
|
return (b && b.tabbrowser) || b;
|
||||||
},
|
},
|
||||||
shouldAnimateDragggedTabs: function TDU_shouldAnimateDragggedTabs(aEvent)
|
canAnimateDraggedTabs: function TDU_canAnimateDraggedTabs(aEvent)
|
||||||
{
|
{
|
||||||
var tabbar = this.getTabbarFromEvent(aEvent);
|
var tabbar = this.getTabbarFromEvent(aEvent);
|
||||||
return tabbar && '_animateTabMove' in tabbar;
|
return tabbar && '_animateTabMove' in tabbar;
|
||||||
},
|
},
|
||||||
|
|
||||||
processTabsDragging: function TDU_processTabsDragging(aEvent, aWillDropOnSelf)
|
processTabsDragging: function TDU_processTabsDragging(aEvent, aCanDropOnSelf)
|
||||||
{
|
{
|
||||||
// Firefox 17 and later
|
// Firefox 17 and later
|
||||||
if (this.shouldAnimateDraggedTabs(aEvent)) {
|
if (this.canAnimateDraggedTabs(aEvent)) {
|
||||||
let tabbar = this.getTabbarFromEvent(aEvent);
|
let tabbar = this.getTabbarFromEvent(aEvent);
|
||||||
let draggedTab = aEvent.dataTransfer && aEvent.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
|
let draggedTab = aEvent.dataTransfer && aEvent.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
|
||||||
if (!draggedTab || draggedTab.ownerDocument != tabbar.ownerDocument) return false;
|
if (!draggedTab || draggedTab.ownerDocument != tabbar.ownerDocument) return false;
|
||||||
|
|
||||||
if (!tabbar.hasAttribute('movingtab'))
|
if (!tabbar.hasAttribute('movingtab'))
|
||||||
tabbar.setAttribute('movingtab', 'true');
|
tabbar.setAttribute('movingtab', 'true');
|
||||||
if (!aWillDropOnSelf) {
|
tabbar._animateTabMove(aEvent, aCanDropOnSelf);
|
||||||
tabbar._animateTabMove(aEvent);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -2423,6 +2423,35 @@ var TreeStyleTabBase = {
|
|||||||
screenY : tabBox.screenY + yOffset
|
screenY : tabBox.screenY + yOffset
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
getTabActualScreenPosition : function TSTUtils_getTabActualScreenPosition(aTab)
|
||||||
|
{
|
||||||
|
return aTab.parentNode.orient == 'vertical' ?
|
||||||
|
this.getTabActualScreenY(aTab) :
|
||||||
|
this.getTabActualScreenX(aTab) ;
|
||||||
|
},
|
||||||
|
MATRIX_PATTERN : /matrix\((-?\d+),\s*(-?\d+),\s*(-?\d+),\s*(-?\d+),\s*(-?\d+),\s*(-?\d+)\)/,
|
||||||
|
getTabActualScreenX : function TSTUtils_getTabActualScreenX(aTab)
|
||||||
|
{
|
||||||
|
var x = aTab.boxObject.screenX;
|
||||||
|
|
||||||
|
var w = aTab.ownerDocument.defaultView;
|
||||||
|
var transform = w.getComputedStyle(aTab, null).transform;
|
||||||
|
var offset = transform.match(this.MATRIX_PATTERN);
|
||||||
|
offset = offset ? parseFloat(offset[5]) : 0 ;
|
||||||
|
|
||||||
|
return x + offset;
|
||||||
|
},
|
||||||
|
getTabActualScreenY : function TSTUtils_getTabActualScreenY(aTab)
|
||||||
|
{
|
||||||
|
var y = aTab.boxObject.screenY;
|
||||||
|
|
||||||
|
var w = aTab.ownerDocument.defaultView;
|
||||||
|
var transform = w.getComputedStyle(aTab, null).transform;
|
||||||
|
var offset = transform.match(this.MATRIX_PATTERN);
|
||||||
|
offset = offset ? parseFloat(offset[6]) : 0 ;
|
||||||
|
|
||||||
|
return y + offset;
|
||||||
|
},
|
||||||
|
|
||||||
isGroupTab : function TSTUtils_isGroupTab(aTab, aLazyCheck)
|
isGroupTab : function TSTUtils_isGroupTab(aTab, aLazyCheck)
|
||||||
{
|
{
|
||||||
|
@ -270,14 +270,14 @@ catch(e) {
|
|||||||
if (DEBUG) dump(' not on a tab\n');
|
if (DEBUG) dump(' not on a tab\n');
|
||||||
let action = isTabMoveFromOtherWindow ? sv.kACTION_STAY : (sv.kACTION_MOVE | sv.kACTION_PART) ;
|
let action = isTabMoveFromOtherWindow ? sv.kACTION_STAY : (sv.kACTION_MOVE | sv.kACTION_PART) ;
|
||||||
if (isNewTabAction) action |= sv.kACTION_NEWTAB;
|
if (isNewTabAction) action |= sv.kACTION_NEWTAB;
|
||||||
if (aEvent[sv.screenPositionProp] < firstTab.boxObject[sv.screenPositionProp]) {
|
if (aEvent[sv.screenPositionProp] < sv.getTabActualScreenPosition(firstTab)) {
|
||||||
if (DEBUG) dump(' above the first tab\n');
|
if (DEBUG) dump(' above the first tab\n');
|
||||||
info.target = info.parent = info.insertBefore = firstTab;
|
info.target = info.parent = info.insertBefore = firstTab;
|
||||||
info.position = isInverted ? sv.kDROP_AFTER : sv.kDROP_BEFORE ;
|
info.position = isInverted ? sv.kDROP_AFTER : sv.kDROP_BEFORE ;
|
||||||
info.action = action;
|
info.action = action;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
else if (aEvent[sv.screenPositionProp] > tabs[lastTabIndex].boxObject[sv.screenPositionProp] + tabs[lastTabIndex].boxObject[sv.sizeProp]) {
|
else if (aEvent[sv.screenPositionProp] > sv.getTabActualScreenPosition(tabs[lastTabIndex]) + tabs[lastTabIndex].boxObject[sv.sizeProp]) {
|
||||||
if (DEBUG) dump(' below the last tab\n');
|
if (DEBUG) dump(' below the last tab\n');
|
||||||
info.target = info.parent = tabs[lastTabIndex];
|
info.target = info.parent = tabs[lastTabIndex];
|
||||||
info.position = isInverted ? sv.kDROP_BEFORE : sv.kDROP_AFTER ;
|
info.position = isInverted ? sv.kDROP_BEFORE : sv.kDROP_AFTER ;
|
||||||
@ -309,7 +309,7 @@ catch(e) {
|
|||||||
var dropAreasCount = (aSourceTab && pinned) ? 2 : 3 ;
|
var dropAreasCount = (aSourceTab && pinned) ? 2 : 3 ;
|
||||||
var screenPositionProp = sv.isVertical && pinned ? sv.invertedScreenPositionProp : sv.screenPositionProp ;
|
var screenPositionProp = sv.isVertical && pinned ? sv.invertedScreenPositionProp : sv.screenPositionProp ;
|
||||||
var sizeProp = sv.isVertical && pinned ? sv.invertedSizeProp : sv.sizeProp ;
|
var sizeProp = sv.isVertical && pinned ? sv.invertedSizeProp : sv.sizeProp ;
|
||||||
var boxPos = tab.boxObject[screenPositionProp];
|
var boxPos = sv.getTabActualScreenPosition(tab);
|
||||||
var boxUnit = Math.round(tab.boxObject[sizeProp] / dropAreasCount);
|
var boxUnit = Math.round(tab.boxObject[sizeProp] / dropAreasCount);
|
||||||
if (aEvent[screenPositionProp] < boxPos + boxUnit) {
|
if (aEvent[screenPositionProp] < boxPos + boxUnit) {
|
||||||
info.position = isInverted ? sv.kDROP_AFTER : sv.kDROP_BEFORE ;
|
info.position = isInverted ? sv.kDROP_AFTER : sv.kDROP_BEFORE ;
|
||||||
@ -839,6 +839,15 @@ try{
|
|||||||
|
|
||||||
sv.autoScroll.processAutoScroll(aEvent);
|
sv.autoScroll.processAutoScroll(aEvent);
|
||||||
|
|
||||||
|
var dragOverTab = sv.getTabFromEvent(aEvent) || sv.getTabFromTabbarEvent(aEvent) || aEvent.target;
|
||||||
|
b.ownerDocument.defaultView['piro.sakura.ne.jp'].tabsDragUtils
|
||||||
|
.processTabsDragging(aEvent, !dragOverTab || !dragOverTab.pinned);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We must calculate drop action after tabsDragUtils.processTabsDragging(),
|
||||||
|
* because the drop position depends on tabs' actual
|
||||||
|
* positions (which can be changed by animation effects.)
|
||||||
|
*/
|
||||||
var info = this.getDropAction(aEvent, session);
|
var info = this.getDropAction(aEvent, session);
|
||||||
|
|
||||||
var observer = b;
|
var observer = b;
|
||||||
@ -894,7 +903,7 @@ try{
|
|||||||
this.clearDropPosition();
|
this.clearDropPosition();
|
||||||
indicatorTab.setAttribute(sv.kDROP_POSITION, dropPosition);
|
indicatorTab.setAttribute(sv.kDROP_POSITION, dropPosition);
|
||||||
if (b.ownerDocument.defaultView['piro.sakura.ne.jp'].tabsDragUtils
|
if (b.ownerDocument.defaultView['piro.sakura.ne.jp'].tabsDragUtils
|
||||||
.processTabsDragging(aEvent, dropPosition == 'self')) { // Firefox 17 and later
|
.canAnimateDraggedTabs(aEvent)) { // Firefox 17 and later
|
||||||
if (dropPosition == 'self') {
|
if (dropPosition == 'self') {
|
||||||
draggedTab.style.opacity = 0.5; // to prevent the dragged tab hides the drop target itself
|
draggedTab.style.opacity = 0.5; // to prevent the dragged tab hides the drop target itself
|
||||||
} else {
|
} else {
|
||||||
@ -944,13 +953,18 @@ catch(e) {
|
|||||||
var tabbar = b.mTabContainer;
|
var tabbar = b.mTabContainer;
|
||||||
var dt = aEvent.dataTransfer;
|
var dt = aEvent.dataTransfer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We must calculate drop action before clearing "dragging"
|
||||||
|
* state, because the drop position depends on tabs' actual
|
||||||
|
* positions (they are applied only while tab dragging.)
|
||||||
|
*/
|
||||||
|
var session = sv.currentDragSession;
|
||||||
|
var dropActionInfo = this.getDropAction(aEvent, session);
|
||||||
|
|
||||||
this.clearDropPosition(true);
|
this.clearDropPosition(true);
|
||||||
if (tabbar._tabDropIndicator)
|
if (tabbar._tabDropIndicator)
|
||||||
tabbar._tabDropIndicator.collapsed = true;
|
tabbar._tabDropIndicator.collapsed = true;
|
||||||
|
|
||||||
var session = sv.currentDragSession;
|
|
||||||
var dropActionInfo = this.getDropAction(aEvent, session);
|
|
||||||
|
|
||||||
var draggedTab;
|
var draggedTab;
|
||||||
if (dt.dropEffect != 'link') {
|
if (dt.dropEffect != 'link') {
|
||||||
draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
|
draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user