@mintplayer/ng-bootstrap 20.5.0 → 20.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dock/index.d.ts
CHANGED
|
@@ -150,6 +150,11 @@ declare class MintDockManagerElement extends HTMLElement {
|
|
|
150
150
|
private onGlobalDragEnd;
|
|
151
151
|
private updateDraggedFloatingPositionFromPoint;
|
|
152
152
|
private updatePaneDragDropTargetFromPoint;
|
|
153
|
+
private isPointerOverSourceHeader;
|
|
154
|
+
private isPointWithinBounds;
|
|
155
|
+
private ensureHeaderDragPlaceholder;
|
|
156
|
+
private updateHeaderDragPlaceholderPosition;
|
|
157
|
+
private clearHeaderDragPlaceholder;
|
|
153
158
|
private startDragPointerTracking;
|
|
154
159
|
private stopDragPointerTracking;
|
|
155
160
|
private onDragMouseMove;
|
|
@@ -159,6 +164,7 @@ declare class MintDockManagerElement extends HTMLElement {
|
|
|
159
164
|
private computeHeaderInsertIndex;
|
|
160
165
|
private reorderPaneInLocationAtIndex;
|
|
161
166
|
private onDragTouchEnd;
|
|
167
|
+
private finalizeDropFromPoint;
|
|
162
168
|
private clearPendingDragEndTimeout;
|
|
163
169
|
private scheduleDeferredDragEnd;
|
|
164
170
|
private onDrop;
|
|
@@ -1222,7 +1222,6 @@ class MintDockManagerElement extends HTMLElement {
|
|
|
1222
1222
|
this.handleFloatingResizeMove(event);
|
|
1223
1223
|
}
|
|
1224
1224
|
if (this.floatingDragState && event.pointerId === this.floatingDragState.pointerId) {
|
|
1225
|
-
console.warn('state', this.floatingDragState);
|
|
1226
1225
|
this.handleFloatingDragMove(event);
|
|
1227
1226
|
}
|
|
1228
1227
|
}
|
|
@@ -1265,6 +1264,8 @@ class MintDockManagerElement extends HTMLElement {
|
|
|
1265
1264
|
top,
|
|
1266
1265
|
width,
|
|
1267
1266
|
height,
|
|
1267
|
+
startClientX: event.clientX,
|
|
1268
|
+
startClientY: event.clientY,
|
|
1268
1269
|
};
|
|
1269
1270
|
}
|
|
1270
1271
|
clearPendingTabDragMetrics() {
|
|
@@ -1285,7 +1286,9 @@ class MintDockManagerElement extends HTMLElement {
|
|
|
1285
1286
|
this.shadowRoot?.appendChild(ghost);
|
|
1286
1287
|
// Use the ghost element as the drag image.
|
|
1287
1288
|
// The offset is set to where the user's cursor is on the original element.
|
|
1288
|
-
|
|
1289
|
+
const dragImgOffsetX = Number.isFinite(event.offsetX) ? event.offsetX : 0;
|
|
1290
|
+
const dragImgOffsetY = Number.isFinite(event.offsetY) ? event.offsetY : 0;
|
|
1291
|
+
event.dataTransfer.setDragImage(ghost, dragImgOffsetX, dragImgOffsetY);
|
|
1289
1292
|
// The ghost element is no longer needed after the drag image is set.
|
|
1290
1293
|
// We defer its removal to ensure the browser has captured it.
|
|
1291
1294
|
setTimeout(() => ghost.remove(), 0);
|
|
@@ -1296,6 +1299,7 @@ class MintDockManagerElement extends HTMLElement {
|
|
|
1296
1299
|
const headerBounds = headerRect
|
|
1297
1300
|
? { left: headerRect.left, top: headerRect.top, right: headerRect.right, bottom: headerRect.bottom }
|
|
1298
1301
|
: null;
|
|
1302
|
+
const metrics = this.pendingTabDragMetrics;
|
|
1299
1303
|
this.dragState = {
|
|
1300
1304
|
pane,
|
|
1301
1305
|
sourcePath: this.clonePath(sourcePath),
|
|
@@ -1305,9 +1309,27 @@ class MintDockManagerElement extends HTMLElement {
|
|
|
1305
1309
|
dropHandled: false,
|
|
1306
1310
|
sourceStackEl: stackEl,
|
|
1307
1311
|
sourceHeaderBounds: headerBounds,
|
|
1308
|
-
startClientX: Number.isFinite(
|
|
1309
|
-
|
|
1312
|
+
startClientX: metrics && Number.isFinite(metrics.startClientX)
|
|
1313
|
+
? metrics.startClientX
|
|
1314
|
+
: Number.isFinite(event.clientX)
|
|
1315
|
+
? event.clientX
|
|
1316
|
+
: undefined,
|
|
1317
|
+
startClientY: metrics && Number.isFinite(metrics.startClientY)
|
|
1318
|
+
? metrics.startClientY
|
|
1319
|
+
: Number.isFinite(event.clientY)
|
|
1320
|
+
? event.clientY
|
|
1321
|
+
: undefined,
|
|
1310
1322
|
};
|
|
1323
|
+
// Seed last known pointer position from pointerdown metrics to avoid (0,0) glitches in Firefox
|
|
1324
|
+
if (this.dragState.startClientX !== undefined &&
|
|
1325
|
+
this.dragState.startClientY !== undefined &&
|
|
1326
|
+
Number.isFinite(this.dragState.startClientX) &&
|
|
1327
|
+
Number.isFinite(this.dragState.startClientY)) {
|
|
1328
|
+
this.lastDragPointerPosition = {
|
|
1329
|
+
x: this.dragState.startClientX,
|
|
1330
|
+
y: this.dragState.startClientY,
|
|
1331
|
+
};
|
|
1332
|
+
}
|
|
1311
1333
|
// Prefer the pointer offset relative to the dragged tab to avoid jumps on conversion
|
|
1312
1334
|
if (Number.isFinite(event.offsetX)) {
|
|
1313
1335
|
this.dragState.pointerOffsetX = event.offsetX;
|
|
@@ -1400,6 +1422,7 @@ class MintDockManagerElement extends HTMLElement {
|
|
|
1400
1422
|
const state = this.dragState;
|
|
1401
1423
|
this.dragState = null;
|
|
1402
1424
|
this.hideDropIndicator();
|
|
1425
|
+
this.clearHeaderDragPlaceholder();
|
|
1403
1426
|
this.stopDragPointerTracking();
|
|
1404
1427
|
this.lastDragPointerPosition = null;
|
|
1405
1428
|
if (state && state.floatingIndex !== null && !state.dropHandled) {
|
|
@@ -1435,6 +1458,21 @@ class MintDockManagerElement extends HTMLElement {
|
|
|
1435
1458
|
return;
|
|
1436
1459
|
}
|
|
1437
1460
|
const path = this.parsePath(stack.dataset['path']);
|
|
1461
|
+
// While reordering within the same header, suppress the joystick/indicator entirely
|
|
1462
|
+
if (this.dragState &&
|
|
1463
|
+
this.dragState.floatingIndex !== null &&
|
|
1464
|
+
this.dragState.floatingIndex < 0 &&
|
|
1465
|
+
path &&
|
|
1466
|
+
this.pathsEqual(path, this.dragState.sourcePath)) {
|
|
1467
|
+
const px = (point ? point.clientX : event.clientX);
|
|
1468
|
+
const py = (point ? point.clientY : event.clientY);
|
|
1469
|
+
if (Number.isFinite(px) && Number.isFinite(py) && this.isPointerOverSourceHeader(px, py)) {
|
|
1470
|
+
// Drive live reorder using the unified path so we update instantly.
|
|
1471
|
+
this.updatePaneDragDropTargetFromPoint(px, py);
|
|
1472
|
+
this.hideDropIndicator();
|
|
1473
|
+
return;
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1438
1476
|
// If the hovered stack changed, clear any sticky zone from the previous
|
|
1439
1477
|
// target before computing the new zone.
|
|
1440
1478
|
if (this.dropJoystickTarget && this.dropJoystickTarget !== stack) {
|
|
@@ -1450,10 +1488,10 @@ class MintDockManagerElement extends HTMLElement {
|
|
|
1450
1488
|
if (!this.dragState) {
|
|
1451
1489
|
return;
|
|
1452
1490
|
}
|
|
1453
|
-
const { clientX, clientY
|
|
1491
|
+
const { clientX, clientY } = event;
|
|
1454
1492
|
const hasValidCoordinates = Number.isFinite(clientX) &&
|
|
1455
1493
|
Number.isFinite(clientY) &&
|
|
1456
|
-
!(clientX === 0 && clientY === 0
|
|
1494
|
+
!(clientX === 0 && clientY === 0);
|
|
1457
1495
|
if (hasValidCoordinates) {
|
|
1458
1496
|
this.lastDragPointerPosition = { x: clientX, y: clientY };
|
|
1459
1497
|
this.updateDraggedFloatingPositionFromPoint(clientX, clientY);
|
|
@@ -1477,7 +1515,31 @@ class MintDockManagerElement extends HTMLElement {
|
|
|
1477
1515
|
this.updateDraggedFloatingPosition(event);
|
|
1478
1516
|
}
|
|
1479
1517
|
onGlobalDragEnd() {
|
|
1480
|
-
|
|
1518
|
+
// Attempt to finalize a drop even if the drop event doesn't reach us (Firefox/edge cases)
|
|
1519
|
+
const state = this.dragState;
|
|
1520
|
+
const pos = this.lastDragPointerPosition;
|
|
1521
|
+
if (state && pos) {
|
|
1522
|
+
const stack = this.findStackAtPoint(pos.x, pos.y);
|
|
1523
|
+
const joystickVisible = this.dropJoystick.dataset['visible'] === 'true';
|
|
1524
|
+
const joystickPath = this.parsePath(this.dropJoystick.dataset['path']);
|
|
1525
|
+
const joystickTarget = this.dropJoystickTarget;
|
|
1526
|
+
const joystickTargetPath = joystickTarget ? this.parsePath(joystickTarget.dataset['path']) : null;
|
|
1527
|
+
const path = stack ? this.parsePath(stack.dataset['path']) : (joystickPath ?? joystickTargetPath);
|
|
1528
|
+
const joystickZone = this.dropJoystick.dataset['zone'];
|
|
1529
|
+
const zone = this.isDropZone(joystickZone)
|
|
1530
|
+
? joystickZone
|
|
1531
|
+
: (stack ? this.computeDropZone(stack, { clientX: pos.x, clientY: pos.y }, null) : null);
|
|
1532
|
+
if (path && this.isDropZone(zone)) {
|
|
1533
|
+
this.handleDrop(path, zone);
|
|
1534
|
+
this.hideDropIndicator();
|
|
1535
|
+
if (this.dragState) {
|
|
1536
|
+
this.dragState.dropHandled = true;
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
else {
|
|
1541
|
+
this.hideDropIndicator();
|
|
1542
|
+
}
|
|
1481
1543
|
if (!this.dragState) {
|
|
1482
1544
|
this.clearPendingTabDragMetrics();
|
|
1483
1545
|
return;
|
|
@@ -1492,17 +1554,22 @@ class MintDockManagerElement extends HTMLElement {
|
|
|
1492
1554
|
if (!Number.isFinite(clientX) || !Number.isFinite(clientY)) {
|
|
1493
1555
|
return;
|
|
1494
1556
|
}
|
|
1495
|
-
//
|
|
1557
|
+
// Ignore obviously bogus coordinates sometimes seen during HTML5 drag
|
|
1558
|
+
if (clientX === 0 && clientY === 0) {
|
|
1559
|
+
return;
|
|
1560
|
+
}
|
|
1561
|
+
// If still dragging a tab inside its header, only convert to floating once we leave the header.
|
|
1496
1562
|
if (this.dragState.floatingIndex !== null && this.dragState.floatingIndex < 0) {
|
|
1497
1563
|
const b = this.dragState.sourceHeaderBounds;
|
|
1498
1564
|
const sx = this.dragState.startClientX ?? clientX;
|
|
1499
1565
|
const sy = this.dragState.startClientY ?? clientY;
|
|
1500
1566
|
const dist = Math.hypot(clientX - sx, clientY - sy);
|
|
1501
|
-
const threshold =
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1567
|
+
const threshold = 8; // pixels to move before converting (tuned up)
|
|
1568
|
+
// Default to inside while bounds are unknown to avoid premature floating
|
|
1569
|
+
let insideHeader = true;
|
|
1570
|
+
const insideByBounds = b ? this.isPointWithinBounds(b, clientX, clientY) : true;
|
|
1571
|
+
const insideByHitTest = this.isPointerOverSourceHeader(clientX, clientY);
|
|
1572
|
+
insideHeader = insideByBounds || insideByHitTest;
|
|
1506
1573
|
if (!insideHeader && dist > threshold) {
|
|
1507
1574
|
// Convert to floating now using current pointer position
|
|
1508
1575
|
this.convertPendingTabDragToFloating(clientX, clientY);
|
|
@@ -1548,10 +1615,120 @@ class MintDockManagerElement extends HTMLElement {
|
|
|
1548
1615
|
delete this.dropJoystick.dataset['zone'];
|
|
1549
1616
|
this.updateDropJoystickActiveZone(null);
|
|
1550
1617
|
}
|
|
1618
|
+
// Previous behavior hid the indicator and returned early here; instead,
|
|
1619
|
+
// allow the live-reorder branch below to handle in-header drags.
|
|
1620
|
+
// While reordering within the same header, update order live and suppress joystick/indicator
|
|
1621
|
+
if (this.dragState &&
|
|
1622
|
+
this.dragState.floatingIndex !== null &&
|
|
1623
|
+
this.dragState.floatingIndex < 0 &&
|
|
1624
|
+
path &&
|
|
1625
|
+
this.pathsEqual(path, this.dragState.sourcePath)) {
|
|
1626
|
+
const inHeaderByBounds = !!this.dragState.sourceHeaderBounds && this.isPointWithinBounds(this.dragState.sourceHeaderBounds, clientX, clientY);
|
|
1627
|
+
const inHeaderByHitTest = this.isPointerOverSourceHeader(clientX, clientY);
|
|
1628
|
+
if (inHeaderByBounds || inHeaderByHitTest) {
|
|
1629
|
+
const header = stack.querySelector('.dock-stack__header');
|
|
1630
|
+
if (header) {
|
|
1631
|
+
const idx = this.computeHeaderInsertIndex(header, clientX);
|
|
1632
|
+
if (this.dragState.liveReorderIndex !== idx) {
|
|
1633
|
+
this.ensureHeaderDragPlaceholder(header, this.dragState.pane);
|
|
1634
|
+
this.updateHeaderDragPlaceholderPosition(header, idx);
|
|
1635
|
+
const location = this.resolveStackLocation(path);
|
|
1636
|
+
if (location) {
|
|
1637
|
+
this.reorderPaneInLocationAtIndex(location, this.dragState.pane, idx);
|
|
1638
|
+
this.render();
|
|
1639
|
+
this.dispatchLayoutChanged();
|
|
1640
|
+
}
|
|
1641
|
+
this.dragState.liveReorderIndex = idx;
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
this.hideDropIndicator();
|
|
1645
|
+
return;
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1551
1648
|
const zoneHint = this.findDropZoneByPoint(clientX, clientY);
|
|
1552
1649
|
const zone = this.computeDropZone(stack, { clientX, clientY }, zoneHint);
|
|
1553
1650
|
this.showDropIndicator(stack, zone);
|
|
1554
1651
|
}
|
|
1652
|
+
// Returns true when the pointer is currently over the source stack's header (tab strip)
|
|
1653
|
+
isPointerOverSourceHeader(clientX, clientY) {
|
|
1654
|
+
const state = this.dragState;
|
|
1655
|
+
if (!state) {
|
|
1656
|
+
return false;
|
|
1657
|
+
}
|
|
1658
|
+
const stackEl = state.sourceStackEl ?? null;
|
|
1659
|
+
const header = stackEl?.querySelector('.dock-stack__header');
|
|
1660
|
+
if (!header) {
|
|
1661
|
+
// Be conservative: if we cannot resolve the header, treat as inside
|
|
1662
|
+
return true;
|
|
1663
|
+
}
|
|
1664
|
+
const sr = this.shadowRoot;
|
|
1665
|
+
const elements = sr ? sr.elementsFromPoint(clientX, clientY) : [];
|
|
1666
|
+
for (const el of elements) {
|
|
1667
|
+
if (el instanceof HTMLElement && header.contains(el)) {
|
|
1668
|
+
return true;
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
return false;
|
|
1672
|
+
}
|
|
1673
|
+
isPointWithinBounds(bounds, x, y) {
|
|
1674
|
+
return x >= bounds.left && x <= bounds.right && y >= bounds.top && y <= bounds.bottom;
|
|
1675
|
+
}
|
|
1676
|
+
// Ensure a placeholder tab exists during in-header drag and hide the real dragged tab visually
|
|
1677
|
+
ensureHeaderDragPlaceholder(header, pane) {
|
|
1678
|
+
if (this.dragState?.placeholderHeader === header && this.dragState.placeholderEl) {
|
|
1679
|
+
return;
|
|
1680
|
+
}
|
|
1681
|
+
const dragged = Array.from(header.querySelectorAll('.dock-tab')).find((t) => t.dataset['pane'] === pane) ?? null;
|
|
1682
|
+
if (!dragged) {
|
|
1683
|
+
return;
|
|
1684
|
+
}
|
|
1685
|
+
// Create placeholder
|
|
1686
|
+
const placeholder = this.documentRef.createElement('button');
|
|
1687
|
+
placeholder.type = 'button';
|
|
1688
|
+
placeholder.classList.add('dock-tab');
|
|
1689
|
+
placeholder.dataset['placeholder'] = 'true';
|
|
1690
|
+
placeholder.textContent = dragged.textContent ?? '';
|
|
1691
|
+
// Hide the original dragged tab so it doesn't duplicate visually
|
|
1692
|
+
dragged.style.visibility = 'hidden';
|
|
1693
|
+
// Insert placeholder next to dragged initially
|
|
1694
|
+
header.insertBefore(placeholder, dragged.nextSibling);
|
|
1695
|
+
if (this.dragState) {
|
|
1696
|
+
this.dragState.placeholderHeader = header;
|
|
1697
|
+
this.dragState.placeholderEl = placeholder;
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
// Move the placeholder to the computed target index within the header
|
|
1701
|
+
updateHeaderDragPlaceholderPosition(header, targetIndex) {
|
|
1702
|
+
const placeholder = this.dragState?.placeholderEl ?? null;
|
|
1703
|
+
if (!placeholder) {
|
|
1704
|
+
return;
|
|
1705
|
+
}
|
|
1706
|
+
const tabs = Array.from(header.querySelectorAll('.dock-tab'))
|
|
1707
|
+
.filter((t) => t !== placeholder);
|
|
1708
|
+
const clampedTarget = Math.max(0, Math.min(targetIndex, tabs.length));
|
|
1709
|
+
const ref = tabs[clampedTarget] ?? null;
|
|
1710
|
+
header.insertBefore(placeholder, ref);
|
|
1711
|
+
}
|
|
1712
|
+
// Remove placeholder and restore original tab visibility
|
|
1713
|
+
clearHeaderDragPlaceholder() {
|
|
1714
|
+
const ph = this.dragState?.placeholderEl ?? null;
|
|
1715
|
+
const header = this.dragState?.placeholderHeader ?? null;
|
|
1716
|
+
if (header) {
|
|
1717
|
+
const dragged = this.dragState?.pane
|
|
1718
|
+
? (Array.from(header.querySelectorAll('.dock-tab')).find((t) => t.dataset['pane'] === this.dragState?.pane) ?? null)
|
|
1719
|
+
: null;
|
|
1720
|
+
if (dragged) {
|
|
1721
|
+
dragged.style.visibility = '';
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
if (ph && ph.parentElement) {
|
|
1725
|
+
ph.parentElement.removeChild(ph);
|
|
1726
|
+
}
|
|
1727
|
+
if (this.dragState) {
|
|
1728
|
+
this.dragState.placeholderEl = null;
|
|
1729
|
+
this.dragState.placeholderHeader = null;
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1555
1732
|
startDragPointerTracking() {
|
|
1556
1733
|
if (this.dragPointerTrackingActive) {
|
|
1557
1734
|
return;
|
|
@@ -1606,6 +1783,13 @@ class MintDockManagerElement extends HTMLElement {
|
|
|
1606
1783
|
this.updateDraggedFloatingPositionFromPoint(touch.clientX, touch.clientY);
|
|
1607
1784
|
}
|
|
1608
1785
|
onDragMouseUp() {
|
|
1786
|
+
// Prefer committing a drop from pointer-up since some browsers suppress drop events
|
|
1787
|
+
if (this.dragState) {
|
|
1788
|
+
const pos = this.lastDragPointerPosition;
|
|
1789
|
+
if (pos) {
|
|
1790
|
+
this.finalizeDropFromPoint(pos.x, pos.y);
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1609
1793
|
this.handleDragPointerUpCommon();
|
|
1610
1794
|
}
|
|
1611
1795
|
// Convert a currently in-header tab drag into a floating window
|
|
@@ -1617,6 +1801,8 @@ class MintDockManagerElement extends HTMLElement {
|
|
|
1617
1801
|
if (state.floatingIndex !== null && state.floatingIndex >= 0) {
|
|
1618
1802
|
return; // already floating
|
|
1619
1803
|
}
|
|
1804
|
+
// Clean up any placeholder before converting
|
|
1805
|
+
this.clearHeaderDragPlaceholder();
|
|
1620
1806
|
const location = this.resolveStackLocation(state.sourcePath);
|
|
1621
1807
|
if (!location) {
|
|
1622
1808
|
return;
|
|
@@ -1687,7 +1873,8 @@ class MintDockManagerElement extends HTMLElement {
|
|
|
1687
1873
|
}
|
|
1688
1874
|
// Compute the intended tab insert index within a header based on pointer X
|
|
1689
1875
|
computeHeaderInsertIndex(header, clientX) {
|
|
1690
|
-
const tabs = Array.from(header.querySelectorAll('.dock-tab'))
|
|
1876
|
+
const tabs = Array.from(header.querySelectorAll('.dock-tab'))
|
|
1877
|
+
.filter((t) => t.dataset['placeholder'] !== 'true');
|
|
1691
1878
|
if (tabs.length === 0) {
|
|
1692
1879
|
return 0;
|
|
1693
1880
|
}
|
|
@@ -1723,6 +1910,49 @@ class MintDockManagerElement extends HTMLElement {
|
|
|
1723
1910
|
onDragTouchEnd() {
|
|
1724
1911
|
this.handleDragPointerUpCommon();
|
|
1725
1912
|
}
|
|
1913
|
+
// Commit a drop using current pointer coordinates and joystick state
|
|
1914
|
+
finalizeDropFromPoint(clientX, clientY) {
|
|
1915
|
+
if (!this.dragState) {
|
|
1916
|
+
return;
|
|
1917
|
+
}
|
|
1918
|
+
const stack = this.findStackAtPoint(clientX, clientY);
|
|
1919
|
+
const stackPath = stack ? this.parsePath(stack.dataset['path']) : null;
|
|
1920
|
+
const joystickVisible = this.dropJoystick.dataset['visible'] === 'true';
|
|
1921
|
+
const joystickStoredPath = this.parsePath(this.dropJoystick.dataset['path']);
|
|
1922
|
+
const joystickTarget = this.dropJoystickTarget;
|
|
1923
|
+
const joystickTargetPath = joystickTarget ? this.parsePath(joystickTarget.dataset['path']) : null;
|
|
1924
|
+
const path = (joystickVisible ? (joystickStoredPath ?? joystickTargetPath) : null) ?? stackPath;
|
|
1925
|
+
const joystickZone = this.dropJoystick.dataset['zone'];
|
|
1926
|
+
const zone = this.isDropZone(joystickZone)
|
|
1927
|
+
? joystickZone
|
|
1928
|
+
: (stack ? this.computeDropZone(stack, { clientX, clientY }, null) : null);
|
|
1929
|
+
// Same-header reorder case when no side zone is chosen
|
|
1930
|
+
if (this.dragState &&
|
|
1931
|
+
this.dragState.floatingIndex !== null &&
|
|
1932
|
+
this.dragState.floatingIndex < 0 &&
|
|
1933
|
+
stack &&
|
|
1934
|
+
path &&
|
|
1935
|
+
stackPath &&
|
|
1936
|
+
this.pathsEqual(stackPath, this.dragState.sourcePath) &&
|
|
1937
|
+
(!zone || zone === 'center')) {
|
|
1938
|
+
const header = stack.querySelector('.dock-stack__header');
|
|
1939
|
+
if (header) {
|
|
1940
|
+
const location = this.resolveStackLocation(path);
|
|
1941
|
+
if (location) {
|
|
1942
|
+
const idx = this.computeHeaderInsertIndex(header, clientX);
|
|
1943
|
+
this.reorderPaneInLocationAtIndex(location, this.dragState.pane, idx);
|
|
1944
|
+
this.render();
|
|
1945
|
+
this.dispatchLayoutChanged();
|
|
1946
|
+
this.dragState.dropHandled = true;
|
|
1947
|
+
return;
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
if (path && this.isDropZone(zone)) {
|
|
1952
|
+
this.handleDrop(path, zone);
|
|
1953
|
+
this.dragState.dropHandled = true;
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1726
1956
|
clearPendingDragEndTimeout() {
|
|
1727
1957
|
if (this.pendingDragEndTimeout !== null) {
|
|
1728
1958
|
const win = this.windowRef;
|
|
@@ -1771,18 +2001,37 @@ class MintDockManagerElement extends HTMLElement {
|
|
|
1771
2001
|
: null);
|
|
1772
2002
|
const stack = this.findStackElement(event) ??
|
|
1773
2003
|
(point ? this.findStackAtPoint(point.clientX, point.clientY) : null);
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
2004
|
+
// Prefer joystick's stored target path when the joystick is visible (drop over buttons)
|
|
2005
|
+
const joystickVisible = this.dropJoystick.dataset['visible'] === 'true';
|
|
2006
|
+
const joystickPath = this.parsePath(this.dropJoystick.dataset['path']);
|
|
2007
|
+
const joystickTarget = this.dropJoystickTarget;
|
|
2008
|
+
const joystickTargetPath = joystickTarget ? this.parsePath(joystickTarget.dataset['path']) : null;
|
|
2009
|
+
let path = stack
|
|
2010
|
+
? this.parsePath(stack.dataset['path'])
|
|
2011
|
+
: (joystickPath ?? joystickTargetPath);
|
|
2012
|
+
if (!path && joystickVisible) {
|
|
2013
|
+
// As a last resort, target the main dock surface only when empty
|
|
2014
|
+
const dockPath = this.parsePath(this.dockedEl.dataset['path']);
|
|
2015
|
+
path = (!this.rootLayout ? dockPath : null);
|
|
2016
|
+
}
|
|
2017
|
+
// Defer same-header reorder decision until after zone resolution below
|
|
2018
|
+
// Prefer joystick's active zone if available, else infer from event/point
|
|
2019
|
+
const joystickZone = this.dropJoystick.dataset['zone'];
|
|
2020
|
+
const eventZoneHint = this.extractDropZoneFromEvent(event);
|
|
2021
|
+
const pointZoneHint = point ? this.findDropZoneByPoint(point.clientX, point.clientY) : null;
|
|
2022
|
+
const zone = this.isDropZone(joystickZone)
|
|
2023
|
+
? joystickZone
|
|
2024
|
+
: stack
|
|
2025
|
+
? this.computeDropZone(stack, point ?? event, pointZoneHint ?? eventZoneHint)
|
|
2026
|
+
: (this.isDropZone(pointZoneHint ?? eventZoneHint) ? (pointZoneHint ?? eventZoneHint) : null);
|
|
2027
|
+
// If still in same header and no side zone chosen, treat as in-header reorder
|
|
1781
2028
|
if (this.dragState &&
|
|
1782
2029
|
this.dragState.floatingIndex !== null &&
|
|
1783
2030
|
this.dragState.floatingIndex < 0 &&
|
|
2031
|
+
stack &&
|
|
1784
2032
|
path &&
|
|
1785
|
-
this.pathsEqual(path, this.dragState.sourcePath)
|
|
2033
|
+
this.pathsEqual(path, this.dragState.sourcePath) &&
|
|
2034
|
+
(!zone || zone === 'center')) {
|
|
1786
2035
|
const header = stack.querySelector('.dock-stack__header');
|
|
1787
2036
|
if (header) {
|
|
1788
2037
|
const x = (point ? point.clientX : event.clientX);
|
|
@@ -1800,9 +2049,12 @@ class MintDockManagerElement extends HTMLElement {
|
|
|
1800
2049
|
}
|
|
1801
2050
|
}
|
|
1802
2051
|
}
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
2052
|
+
// If joystick is visible and both path and zone are resolved, force using joystick as authoritative
|
|
2053
|
+
if (joystickVisible && path && this.isDropZone(joystickZone)) {
|
|
2054
|
+
this.handleDrop(path, joystickZone);
|
|
2055
|
+
this.endPaneDrag();
|
|
2056
|
+
return;
|
|
2057
|
+
}
|
|
1806
2058
|
if (!zone) {
|
|
1807
2059
|
this.hideDropIndicator();
|
|
1808
2060
|
this.endPaneDrag();
|