feat: Started working on drag and dropping to essentials, b=no-bug, c=no-component

This commit is contained in:
mr. m
2025-12-24 16:13:16 +01:00
parent 98e8017ad1
commit 1e1236838b
2 changed files with 100 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/drag-and-drop.js b/browser/components/tabbrowser/content/drag-and-drop.js
index 97b931c3c7385a52d20204369fcf6d6999053687..78c8f0ad686e72d281370c934d2dbf5f70311117 100644
index 97b931c3c7385a52d20204369fcf6d6999053687..6c24d636459d1d83b6d8dcf8157b3f25b0158436 100644
--- a/browser/components/tabbrowser/content/drag-and-drop.js
+++ b/browser/components/tabbrowser/content/drag-and-drop.js
@@ -32,6 +32,9 @@
@@ -222,7 +222,18 @@ index 97b931c3c7385a52d20204369fcf6d6999053687..78c8f0ad686e72d281370c934d2dbf5f
let isPinned = tab.pinned;
let numPinned = gBrowser.pinnedTabCount;
let allTabs = this._tabbrowserTabs.ariaFocusableItems;
@@ -1624,10 +1657,7 @@
@@ -1608,8 +1641,9 @@
_animateExpandedPinnedTabMove(event) {
let draggedTab = event.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
+ let zenFakeTab = this._invisibleTempTab || draggedTab;
let dragData = draggedTab._dragData;
- let movingTabs = dragData.movingTabs;
+ let movingTabs = this._invisibleTempTab ? [this._invisibleTempTab] : dragData.movingTabs;
dragData.animLastScreenX ??= dragData.screenX;
dragData.animLastScreenY ??= dragData.screenY;
@@ -1624,10 +1658,7 @@
return;
}
@@ -234,16 +245,18 @@ index 97b931c3c7385a52d20204369fcf6d6999053687..78c8f0ad686e72d281370c934d2dbf5f
let directionX = screenX > dragData.animLastScreenX;
let directionY = screenY > dragData.animLastScreenY;
@@ -1636,6 +1666,8 @@
@@ -1635,7 +1666,9 @@
dragData.animLastScreenX = screenX;
let { width: tabWidth, height: tabHeight } =
draggedTab.getBoundingClientRect();
- draggedTab.getBoundingClientRect();
+ zenFakeTab.getBoundingClientRect();
+ tabWidth += 4; // Add 4px to account for the gap
+ tabHeight += 4;
let shiftSizeX = tabWidth * movingTabs.length;
let shiftSizeY = tabHeight;
dragData.tabWidth = tabWidth;
@@ -1672,8 +1704,8 @@
@@ -1672,8 +1705,8 @@
let lastBoundX =
lastTabInRow.screenX +
lastTabInRow.getBoundingClientRect().width -
@@ -254,6 +267,41 @@ index 97b931c3c7385a52d20204369fcf6d6999053687..78c8f0ad686e72d281370c934d2dbf5f
translateX = Math.min(Math.max(translateX, firstBoundX), lastBoundX);
translateY = Math.min(Math.max(translateY, firstBoundY), lastBoundY);
@@ -1704,7 +1737,6 @@
// * We're doing a binary search in order to reduce the amount of
// tabs we need to check.
- tabs = tabs.filter(t => !movingTabs.includes(t) || t == draggedTab);
let firstTabCenterX = firstMovingTabScreenX + translateX + tabWidth / 2;
let lastTabCenterX = lastMovingTabScreenX + translateX + tabWidth / 2;
let tabCenterX = directionX ? lastTabCenterX : firstTabCenterX;
@@ -1716,7 +1748,7 @@
let getTabShift = (tab, dropIndex) => {
if (
- tab.elementIndex < draggedTab.elementIndex &&
+ tab.elementIndex < zenFakeTab.elementIndex &&
tab.elementIndex >= dropIndex
) {
// If tab is at the end of a row, shift back and down
@@ -1733,7 +1765,7 @@
return [RTL_UI ? -shiftSizeX : shiftSizeX, 0];
}
if (
- tab.elementIndex > draggedTab.elementIndex &&
+ tab.elementIndex > zenFakeTab.elementIndex &&
tab.elementIndex < dropIndex
) {
// If tab is not index 0 and at the start of a row, shift across and up
@@ -1759,7 +1791,7 @@
dragData.animDropElementIndex ?? movingTabs[0].elementIndex;
while (low <= high) {
let mid = Math.floor((low + high) / 2);
- if (tabs[mid] == draggedTab && ++mid > high) {
+ if (tabs[mid] == zenFakeTab && ++mid > high) {
break;
}
let [shiftX, shiftY] = getTabShift(tabs[mid], oldIndex);
@@ -2457,7 +2489,7 @@
tab.style.left = "";
tab.style.top = "";

View File

@@ -428,10 +428,12 @@
delete dragData.shouldDropIntoCollapsedTabGroup;
[dropBefore, dropElement] = this.#applyDragoverIndicator(event, tabs, movingTabs) ?? [
dropBefore,
dropElement,
];
[dropBefore, dropElement] = this.#applyDragoverIndicator(
event,
tabs,
movingTabs,
draggedTab
) ?? [dropBefore, dropElement];
// Default to dropping into `dropElement`'s tab group, if it exists.
let dropElementGroup = dropElement?.group;
@@ -501,7 +503,8 @@
}
handle_windowDragLeave(event) {
if (!this.#isMovingTab() || !this._tabbrowserTabs._dndCanvas) {
const canvas = this._tabbrowserTabs._dndCanvas;
if (!this.#isMovingTab() || !canvas) {
return;
}
let draggedTab = event.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
@@ -516,8 +519,18 @@
this.#isOutOfWindow = true;
this.clearDragOverVisuals();
const dt = event.dataTransfer;
if (!this._browserDragImageWrapper) {
const wrappingDiv = document.createXULElement('vbox');
wrappingDiv.style.borderRadius = canvas.style.borderRadius = '8px';
wrappingDiv.style.border = '2px solid white';
wrappingDiv.style.width = 200 + 'px';
wrappingDiv.style.height = 130 + 'px';
wrappingDiv.appendChild(canvas);
this._browserDragImageWrapper = wrappingDiv;
document.documentElement.appendChild(wrappingDiv);
}
dt.updateDragImage(
this._tabbrowserTabs._dndCanvas,
this._browserDragImageWrapper,
this.originalDragImageArgs[1],
this.originalDragImageArgs[2]
);
@@ -604,6 +617,11 @@
this.originalDragImageArgs = [];
window.removeEventListener('dragover', this.handle_windowDragEnter, { capture: true });
this.#isOutOfWindow = false;
this.#clearInvisibleTempTab();
if (this._browserDragImageWrapper) {
this._browserDragImageWrapper.remove();
delete this._browserDragImageWrapper;
}
}
#applyDragOverBackground(element) {
@@ -634,7 +652,15 @@
gZenPinnedTabManager.removeTabContainersDragoverClass();
}
#applyDragoverIndicator(event, tabs, movingTabs) {
#clearInvisibleTempTab() {
if (this._invisibleTempTab) {
this._invisibleTempTab.remove();
delete this._invisibleTempTab;
this._tabbrowserTabs._invalidateCachedTabs();
}
}
#applyDragoverIndicator(event, tabs, movingTabs, draggedTab) {
const separation = 4;
const dropZoneSelector = ':is(.tabbrowser-tab, .zen-drop-target, .tab-group-label)';
let shouldPlayHapticFeedback = false;
@@ -654,9 +680,20 @@
dropElement = event.clientY > draggedTabRect.top ? relativeTabs.at(-1) : relativeTabs[0];
}
dropElement = elementToMove(dropElement);
if (this._isContainerVerticalPinnedGrid(dropElement)) {
if (this._isContainerVerticalPinnedGrid(dropElement) && isTab(draggedTab)) {
if (!draggedTab.hasAttribute('zen-essential') && !this._invisibleTempTab) {
this._invisibleTempTab = draggedTab.cloneNode(true);
this._invisibleTempTab.setAttribute('zen-essential', 'true');
//this._invisibleTempTab.style.visibility = 'hidden';
this._tabbrowserTabs.ariaFocusableItems[gBrowser._numZenEssentials - 1].after(
this._invisibleTempTab
);
this._tabbrowserTabs._invalidateCachedTabs();
}
this._animateExpandedPinnedTabMove(event);
return;
} else if (this._invisibleTempTab) {
this.#clearInvisibleTempTab();
}
if (this.#lastDropTarget !== dropElement) {
shouldPlayHapticFeedback = this.#lastDropTarget !== null;
@@ -673,7 +710,8 @@
let dropIntoFolder =
isZenFolder && (overlapPercent < threshold || overlapPercent > 1 - threshold);
if (
movingTabs[0].group?.isZenFolder &&
isTabGroupLabel(draggedTab) &&
draggedTab.group?.isZenFolder &&
isTab(dropElement) &&
(!dropElement.pinned || dropElement.hasAttribute('zen-essential'))
) {