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
|
||||
*/
|
||||
(function() {
|
||||
const currentRevision = 20;
|
||||
const currentRevision = 21;
|
||||
|
||||
if (!('piro.sakura.ne.jp' in window)) window['piro.sakura.ne.jp'] = {};
|
||||
|
||||
@ -159,17 +159,17 @@
|
||||
).replace(
|
||||
/(let tabCenter = [^;]+)\/ 2;/,
|
||||
'$1 / units/*2*/;\n' + // support drop on self
|
||||
'let firstTabCenter = tabCenter;\n' +
|
||||
'let lastTabCenter = tabScreenX + translateX + tabsWidth - tabWidth / units;'
|
||||
'let tabLeftCenter = tabCenter;\n' +
|
||||
'let tabRightCenter = tabScreenX + translateX + tabsWidth - tabWidth / units;'
|
||||
).replace(
|
||||
'tabs[mid] == draggedTab',
|
||||
'/* $& */ false'
|
||||
).replace(
|
||||
'(screenX > tabCenter)',
|
||||
'/* $& */ (screenX > lastTabCenter + (aAcceptDropOnSelf ? tabWidth / units : 0 ))'
|
||||
'/* $& */ (screenX > tabRightCenter)'
|
||||
).replace(
|
||||
'(screenX + boxObject[size] < tabCenter)',
|
||||
'/* $& */ (screenX + boxObject[size] < firstTabCenter)'
|
||||
'/* $& */ (screenX + boxObject[size] < tabLeftCenter)'
|
||||
).replace(
|
||||
'-tabWidth : tabWidth',
|
||||
'/* $& */ -tabsWidth : tabsWidth'
|
||||
@ -271,8 +271,8 @@
|
||||
// tab.style.transform = draggedTab.style.transform;
|
||||
// }, this);
|
||||
// let tabCenter = tabScreenX + translateX + tabWidth / units/*2*/;
|
||||
// let firstTabCenter = tabCenter;
|
||||
// let lastTabCenter = tabScreenX + translateX + tabsWidth - tabWidth / units;
|
||||
// let tabLeftCenter = tabCenter;
|
||||
// let tabRightCenter = tabScreenX + translateX + tabsWidth - tabWidth / units;
|
||||
// let newIndex = -1;
|
||||
// let oldIndex = "animDropIndex" in draggedTab._dragData ?
|
||||
// draggedTab._dragData.animDropIndex : draggedTab._tPos;
|
||||
@ -287,10 +287,10 @@
|
||||
// let boxObject = tabs[mid].boxObject;
|
||||
// let screenX = boxObject[position]/*.screenX*/ + getTabShift(tabs[mid], oldIndex);
|
||||
// // if (screenX > tabCenter) {
|
||||
// if (screenX > lastTabCenter + (aAcceptDropOnSelf ? tabWidth / units : 0 )) {
|
||||
// if (screenX > tabRightCenter) {
|
||||
// high = mid - 1;
|
||||
// // } else if (screenX + boxObject.width < tabCenter) {
|
||||
// } else if (screenX + boxObject[size]/*.width*/ < firstTabCenter) {
|
||||
// } else if (screenX + boxObject[size]/*.width*/ < tabLeftCenter) {
|
||||
// low = mid + 1;
|
||||
// } else {
|
||||
// newIndex = tabs[mid]._tPos;
|
||||
@ -360,7 +360,7 @@
|
||||
navigator.platform.toLowerCase().indexOf('win') < 0)
|
||||
dt.mozCursor = 'default';
|
||||
|
||||
if (this.shouldAnimateDragggedTabs(aEvent)) {
|
||||
if (this.canAnimateDraggedTabs(aEvent)) {
|
||||
let tabbar = this.getTabbarFromEvent(aEvent);
|
||||
let tabbarOffsetX = this.getClientX(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;
|
||||
return (b && b.tabbrowser) || b;
|
||||
},
|
||||
shouldAnimateDragggedTabs: function TDU_shouldAnimateDragggedTabs(aEvent)
|
||||
canAnimateDraggedTabs: function TDU_canAnimateDraggedTabs(aEvent)
|
||||
{
|
||||
var tabbar = this.getTabbarFromEvent(aEvent);
|
||||
return tabbar && '_animateTabMove' in tabbar;
|
||||
},
|
||||
|
||||
processTabsDragging: function TDU_processTabsDragging(aEvent, aWillDropOnSelf)
|
||||
processTabsDragging: function TDU_processTabsDragging(aEvent, aCanDropOnSelf)
|
||||
{
|
||||
// Firefox 17 and later
|
||||
if (this.shouldAnimateDraggedTabs(aEvent)) {
|
||||
if (this.canAnimateDraggedTabs(aEvent)) {
|
||||
let tabbar = this.getTabbarFromEvent(aEvent);
|
||||
let draggedTab = aEvent.dataTransfer && aEvent.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
|
||||
if (!draggedTab || draggedTab.ownerDocument != tabbar.ownerDocument) return false;
|
||||
|
||||
if (!tabbar.hasAttribute('movingtab'))
|
||||
tabbar.setAttribute('movingtab', 'true');
|
||||
if (!aWillDropOnSelf) {
|
||||
tabbar._animateTabMove(aEvent);
|
||||
}
|
||||
tabbar._animateTabMove(aEvent, aCanDropOnSelf);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -2423,6 +2423,35 @@ var TreeStyleTabBase = {
|
||||
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)
|
||||
{
|
||||
|
@ -270,14 +270,14 @@ catch(e) {
|
||||
if (DEBUG) dump(' not on a tab\n');
|
||||
let action = isTabMoveFromOtherWindow ? sv.kACTION_STAY : (sv.kACTION_MOVE | sv.kACTION_PART) ;
|
||||
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');
|
||||
info.target = info.parent = info.insertBefore = firstTab;
|
||||
info.position = isInverted ? sv.kDROP_AFTER : sv.kDROP_BEFORE ;
|
||||
info.action = action;
|
||||
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');
|
||||
info.target = info.parent = tabs[lastTabIndex];
|
||||
info.position = isInverted ? sv.kDROP_BEFORE : sv.kDROP_AFTER ;
|
||||
@ -309,7 +309,7 @@ catch(e) {
|
||||
var dropAreasCount = (aSourceTab && pinned) ? 2 : 3 ;
|
||||
var screenPositionProp = sv.isVertical && pinned ? sv.invertedScreenPositionProp : sv.screenPositionProp ;
|
||||
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);
|
||||
if (aEvent[screenPositionProp] < boxPos + boxUnit) {
|
||||
info.position = isInverted ? sv.kDROP_AFTER : sv.kDROP_BEFORE ;
|
||||
@ -839,6 +839,15 @@ try{
|
||||
|
||||
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 observer = b;
|
||||
@ -894,7 +903,7 @@ try{
|
||||
this.clearDropPosition();
|
||||
indicatorTab.setAttribute(sv.kDROP_POSITION, dropPosition);
|
||||
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') {
|
||||
draggedTab.style.opacity = 0.5; // to prevent the dragged tab hides the drop target itself
|
||||
} else {
|
||||
@ -944,13 +953,18 @@ catch(e) {
|
||||
var tabbar = b.mTabContainer;
|
||||
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);
|
||||
if (tabbar._tabDropIndicator)
|
||||
tabbar._tabDropIndicator.collapsed = true;
|
||||
|
||||
var session = sv.currentDragSession;
|
||||
var dropActionInfo = this.getDropAction(aEvent, session);
|
||||
|
||||
var draggedTab;
|
||||
if (dt.dropEffect != 'link') {
|
||||
draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user