Skip to content

Commit

Permalink
Fix multi-row in FF53+ and tab move indicator bug
Browse files Browse the repository at this point in the history
  • Loading branch information
TroudhuK authored Aug 26, 2017
1 parent 342bc3e commit ba93f98
Showing 1 changed file with 167 additions and 2 deletions.
169 changes: 167 additions & 2 deletions chrome/content/tabutils-mt.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ tabutils._multirowTabs = function() {
};

tabutils.addEventListener(gBrowser.mTabContainer, "overflow", function(event) {
if (event.target.tagName == "tab") {
event.stopPropagation();
return;
}
this.enterBlockMode();
}, false);

Expand Down Expand Up @@ -69,6 +73,71 @@ tabutils._multirowTabs = function() {
ind.style.top = tab.getBoundingClientRect().top + "px";
ind.style.lineHeight = tab.getBoundingClientRect().height + "px";
ind.firstChild.style.verticalAlign = "bottom";

////////// copy/paste to enable tabDropIndicator at move without animation
var effects = this._getDropEffectForTabDrag(event);

var ind = this._tabDropIndicator;
if (effects == "" || effects == "none") {
ind.collapsed = true;
return;
}
event.preventDefault();
event.stopPropagation();

var tabStrip = this.mTabstrip;
var ltr = (window.getComputedStyle(this, null).direction == "ltr");

if (effects == "move" &&
this == event.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0).parentNode &&
!TU_getPref("extensions.tabutils.disableTabMoveAnimation", true)) {
ind.collapsed = true;
this._animateTabMove(event);
return;
}

this._finishAnimateTabMove();

if (effects == "link") {
let tab = this._getDragTargetTab(event, true);
if (tab) {
if (!this._dragTime)
this._dragTime = Date.now();
if (Date.now() >= this._dragTime + this._dragOverDelay)
this.selectedItem = tab;
ind.collapsed = true;
return;
}
}

var rect = tabStrip.getBoundingClientRect();
var newMargin;
{
let newIndex = this._getDropIndex(event, effects == "link");
if (newIndex == this.childNodes.length) {
let tabRect = this.childNodes[newIndex-1].getBoundingClientRect();
if (ltr)
newMargin = tabRect.right - rect.left;
else
newMargin = rect.right - tabRect.left;
}
else {
let tabRect = this.childNodes[newIndex].getBoundingClientRect();
if (ltr)
newMargin = tabRect.left - rect.left;
else
newMargin = rect.right - tabRect.right;
}
}

ind.collapsed = false;

newMargin += ind.clientWidth / 2;
if (!ltr)
newMargin *= -1;

ind.style.transform = "translate(" + Math.round(newMargin) + "px)";
ind.style.marginInlineStart = (-ind.clientWidth) + "px";
}, true);

TU_hookCode("gBrowser.mTabContainer._animateTabMove", "{", function() {
Expand All @@ -79,6 +148,102 @@ tabutils._multirowTabs = function() {
).apply(this, arguments);
return;
}
else {
let draggedTab = event.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);

if (this.getAttribute("movingtab") != "true") {
this.setAttribute("movingtab", "true");
this.selectedItem = draggedTab;
}

if (!("animLastScreenX" in draggedTab._dragData))
draggedTab._dragData.animLastScreenX = draggedTab._dragData.screenX;

let screenX = event.screenX;
if (screenX == draggedTab._dragData.animLastScreenX)
return;

let draggingRight = screenX > draggedTab._dragData.animLastScreenX;
draggedTab._dragData.animLastScreenX = screenX;

let rtl = (window.getComputedStyle(this).direction == "rtl");
let pinned = draggedTab.pinned;
let numPinned = this.tabbrowser._numPinnedTabs;
let tabs = this.tabbrowser.visibleTabs
.slice(pinned ? 0 : numPinned,
pinned ? numPinned : undefined);
if (rtl)
tabs.reverse();
let tabWidth = draggedTab.getBoundingClientRect().width;

// Move the dragged tab based on the mouse position.

let leftTab = tabs[0];
let rightTab = tabs[tabs.length - 1];
let tabScreenX = draggedTab.boxObject.screenX;
let translateX = screenX - draggedTab._dragData.screenX;
if (!pinned)
translateX += this.mTabstrip.scrollPosition - draggedTab._dragData.scrollX;
let leftBound = leftTab.boxObject.screenX - tabScreenX;
let rightBound = (rightTab.boxObject.screenX + rightTab.boxObject.width) -
(tabScreenX + tabWidth);
translateX = Math.max(translateX, leftBound);
translateX = Math.min(translateX, rightBound);
draggedTab.style.transform = "translateX(" + translateX + "px)";

// Determine what tab we're dragging over.
// * Point of reference is the center of the dragged tab. If that
// point touches a background tab, the dragged tab would take that
// tab's position when dropped.
// * We're doing a binary search in order to reduce the amount of
// tabs we need to check.

let tabCenter = tabScreenX + translateX + tabWidth / 2;
let newIndex = -1;
let oldIndex = "animDropIndex" in draggedTab._dragData ?
draggedTab._dragData.animDropIndex : draggedTab._tPos;
let low = 0;
let high = tabs.length - 1;
while (low <= high) {
let mid = Math.floor((low + high) / 2);
if (tabs[mid] == draggedTab &&
++mid > high)
break;
let boxObject = tabs[mid].boxObject;
let screenX = boxObject.screenX + getTabShift(tabs[mid], oldIndex);
if (screenX > tabCenter) {
high = mid - 1;
} else if (screenX + boxObject.width < tabCenter) {
low = mid + 1;
} else {
newIndex = tabs[mid]._tPos;
break;
}
}
if (newIndex >= oldIndex)
newIndex++;
if (newIndex < 0 || newIndex == oldIndex)
return;
draggedTab._dragData.animDropIndex = newIndex;

// Shift background tabs to leave a gap where the dragged tab
// would currently be dropped.

for (let tab of tabs) {
if (tab != draggedTab) {
let shift = getTabShift(tab, newIndex);
tab.style.transform = shift ? "translateX(" + shift + "px)" : "";
}
}

function getTabShift(tab, dropIndex) {
if (tab._tPos < draggedTab._tPos && tab._tPos >= dropIndex)
return rtl ? -tabWidth : tabWidth;
if (tab._tPos > draggedTab._tPos && tab._tPos < dropIndex)
return rtl ? tabWidth : -tabWidth;
return 0;
}
}
});

tabutils.addEventListener(gBrowser.mTabContainer, "drop", function(event) {
Expand Down Expand Up @@ -107,11 +272,11 @@ tabutils._multirowTabs = function() {
});

tabutils.addEventListener(gBrowser.mTabContainer, "dragexit", function(event) {
this._tabDropIndicator.collapsed = true;
//this._tabDropIndicator.collapsed = true;
}, true);

tabutils.addEventListener(gBrowser.mTabContainer, "dragend", function(event) {
this._tabDropIndicator.collapsed = true;
//this._tabDropIndicator.collapsed = true;
}, true);

tabutils._tabPrefObserver.showAllTabs = function() {
Expand Down

0 comments on commit ba93f98

Please sign in to comment.