svelte-dnd-action 0.9.71 → 0.9.72
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/dist/index.js +117 -41
- package/dist/index.mjs +117 -41
- package/package.json +1 -1
- package/src/keyboardAction.js +43 -18
- package/src/pointerAction.js +49 -17
- package/src/wrappers/withDragHandles.js +2 -0
package/dist/index.js
CHANGED
|
@@ -1413,6 +1413,8 @@
|
|
|
1413
1413
|
var touchDragHoldTimer;
|
|
1414
1414
|
var touchHoldElapsed = false;
|
|
1415
1415
|
var useCursorForDetectionActive = false;
|
|
1416
|
+
var pendingDragOwner;
|
|
1417
|
+
var watchedDropZones = new Set();
|
|
1416
1418
|
|
|
1417
1419
|
// a map from type to a set of drop-zones
|
|
1418
1420
|
var typeToDropZones$1 = new Map();
|
|
@@ -1435,9 +1437,10 @@
|
|
|
1435
1437
|
}
|
|
1436
1438
|
}
|
|
1437
1439
|
function unregisterDropZone$1(dropZoneEl, type) {
|
|
1438
|
-
typeToDropZones$1.get(type)
|
|
1440
|
+
var dropZones = typeToDropZones$1.get(type);
|
|
1441
|
+
if (!dropZones || !dropZones["delete"](dropZoneEl)) return;
|
|
1439
1442
|
decrementActiveDropZoneCount();
|
|
1440
|
-
if (
|
|
1443
|
+
if (dropZones.size === 0) {
|
|
1441
1444
|
typeToDropZones$1["delete"](type);
|
|
1442
1445
|
}
|
|
1443
1446
|
}
|
|
@@ -1448,7 +1451,10 @@
|
|
|
1448
1451
|
return "watching dragged element";
|
|
1449
1452
|
});
|
|
1450
1453
|
var dropZones = typeToDropZones$1.get(draggedElType);
|
|
1451
|
-
|
|
1454
|
+
if (!dropZones || dropZones.size === 0) return;
|
|
1455
|
+
if (watchedDropZones.size > 0) unWatchDraggedElement();
|
|
1456
|
+
watchedDropZones = new Set(dropZones);
|
|
1457
|
+
var _iterator = _createForOfIteratorHelper(watchedDropZones),
|
|
1452
1458
|
_step;
|
|
1453
1459
|
try {
|
|
1454
1460
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
@@ -1465,11 +1471,11 @@
|
|
|
1465
1471
|
window.addEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop$1);
|
|
1466
1472
|
|
|
1467
1473
|
// it is important that we don't have an interval that is faster than the flip duration because it can cause elements to jump bach and forth
|
|
1468
|
-
var setIntervalMs = Math.max.apply(Math, _toConsumableArray(Array.from(
|
|
1474
|
+
var setIntervalMs = Math.max.apply(Math, _toConsumableArray(Array.from(watchedDropZones).map(function (dz) {
|
|
1469
1475
|
return dzToConfig$1.get(dz).dropAnimationDurationMs;
|
|
1470
1476
|
})));
|
|
1471
1477
|
var observationIntervalMs = setIntervalMs === 0 ? DISABLED_OBSERVATION_INTERVAL_MS : Math.max(setIntervalMs, MIN_OBSERVATION_INTERVAL_MS); // if setIntervalMs is 0 it goes to 20, otherwise it is max between it and min observation.
|
|
1472
|
-
multiScroller = createMultiScroller(
|
|
1478
|
+
multiScroller = createMultiScroller(watchedDropZones, function () {
|
|
1473
1479
|
return currentMousePosition;
|
|
1474
1480
|
});
|
|
1475
1481
|
// Returns reference point in document coordinates - either cursor position or element center
|
|
@@ -1481,14 +1487,13 @@
|
|
|
1481
1487
|
} : function () {
|
|
1482
1488
|
return findCenterOfElement(draggedEl);
|
|
1483
1489
|
};
|
|
1484
|
-
observe(draggedEl,
|
|
1490
|
+
observe(draggedEl, watchedDropZones, observationIntervalMs * 1.07, multiScroller, getReferencePoint);
|
|
1485
1491
|
}
|
|
1486
1492
|
function unWatchDraggedElement() {
|
|
1487
1493
|
printDebug(function () {
|
|
1488
1494
|
return "unwatching dragged element";
|
|
1489
1495
|
});
|
|
1490
|
-
var
|
|
1491
|
-
var _iterator2 = _createForOfIteratorHelper(dropZones),
|
|
1496
|
+
var _iterator2 = _createForOfIteratorHelper(watchedDropZones),
|
|
1492
1497
|
_step2;
|
|
1493
1498
|
try {
|
|
1494
1499
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
@@ -1502,6 +1507,7 @@
|
|
|
1502
1507
|
} finally {
|
|
1503
1508
|
_iterator2.f();
|
|
1504
1509
|
}
|
|
1510
|
+
watchedDropZones = new Set();
|
|
1505
1511
|
window.removeEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop$1);
|
|
1506
1512
|
// ensuring multiScroller is not already destroyed before destroying
|
|
1507
1513
|
if (multiScroller) {
|
|
@@ -1733,11 +1739,13 @@
|
|
|
1733
1739
|
window.setTimeout(callback, dropAnimationDurationMs);
|
|
1734
1740
|
}
|
|
1735
1741
|
function scheduleDZForRemovalAfterDrop(dz, destroy) {
|
|
1736
|
-
|
|
1742
|
+
var scheduledRemoval = {
|
|
1737
1743
|
dz: dz,
|
|
1738
1744
|
destroy: destroy
|
|
1739
|
-
}
|
|
1745
|
+
};
|
|
1746
|
+
scheduledForRemovalAfterDrop.push(scheduledRemoval);
|
|
1740
1747
|
window.requestAnimationFrame(function () {
|
|
1748
|
+
if (!scheduledForRemovalAfterDrop.includes(scheduledRemoval)) return;
|
|
1741
1749
|
hideElement(dz);
|
|
1742
1750
|
document.body.appendChild(dz);
|
|
1743
1751
|
});
|
|
@@ -1771,6 +1779,7 @@
|
|
|
1771
1779
|
touchDragHoldTimer = undefined;
|
|
1772
1780
|
touchHoldElapsed = false;
|
|
1773
1781
|
useCursorForDetectionActive = false;
|
|
1782
|
+
pendingDragOwner = undefined;
|
|
1774
1783
|
if (scheduledForRemovalAfterDrop.length) {
|
|
1775
1784
|
printDebug(function () {
|
|
1776
1785
|
return ["will destroy zones that were removed during drag", scheduledForRemovalAfterDrop];
|
|
@@ -1786,6 +1795,7 @@
|
|
|
1786
1795
|
}
|
|
1787
1796
|
function dndzone$2(node, options) {
|
|
1788
1797
|
var initialized = false;
|
|
1798
|
+
var destroyed = false;
|
|
1789
1799
|
var config = {
|
|
1790
1800
|
items: undefined,
|
|
1791
1801
|
type: undefined,
|
|
@@ -1833,11 +1843,17 @@
|
|
|
1833
1843
|
touchHoldElapsed = false;
|
|
1834
1844
|
}
|
|
1835
1845
|
}
|
|
1836
|
-
function
|
|
1846
|
+
function cancelPendingDrag() {
|
|
1847
|
+
if (pendingDragOwner !== node) return;
|
|
1837
1848
|
removeMaybeListeners();
|
|
1849
|
+
pendingDragOwner = undefined;
|
|
1838
1850
|
originalDragTarget = undefined;
|
|
1839
1851
|
dragStartMousePosition = undefined;
|
|
1840
1852
|
currentMousePosition = undefined;
|
|
1853
|
+
}
|
|
1854
|
+
function handleFalseAlarm(e) {
|
|
1855
|
+
if (pendingDragOwner !== node) return;
|
|
1856
|
+
cancelPendingDrag();
|
|
1841
1857
|
|
|
1842
1858
|
// dragging initiated by touch events prevents onclick from initially firing
|
|
1843
1859
|
if (e.type === "touchend") {
|
|
@@ -1850,6 +1866,7 @@
|
|
|
1850
1866
|
}
|
|
1851
1867
|
}
|
|
1852
1868
|
function handleMouseMoveMaybeDragStart(e) {
|
|
1869
|
+
if (destroyed || pendingDragOwner !== node) return;
|
|
1853
1870
|
var isTouch = !!e.touches;
|
|
1854
1871
|
var c = isTouch ? e.touches[0] : e;
|
|
1855
1872
|
// If touch drag delay is configured and not elapsed yet, allow scrolling until either
|
|
@@ -1878,7 +1895,6 @@
|
|
|
1878
1895
|
y: c.clientY
|
|
1879
1896
|
};
|
|
1880
1897
|
if (Math.abs(currentMousePosition.x - dragStartMousePosition.x) >= MIN_MOVEMENT_BEFORE_DRAG_START_PX || Math.abs(currentMousePosition.y - dragStartMousePosition.y) >= MIN_MOVEMENT_BEFORE_DRAG_START_PX) {
|
|
1881
|
-
removeMaybeListeners();
|
|
1882
1898
|
handleDragStart();
|
|
1883
1899
|
}
|
|
1884
1900
|
}
|
|
@@ -1897,9 +1913,9 @@
|
|
|
1897
1913
|
});
|
|
1898
1914
|
return;
|
|
1899
1915
|
}
|
|
1900
|
-
if (isWorkingOnPreviousDrag) {
|
|
1916
|
+
if (destroyed || isWorkingOnPreviousDrag || pendingDragOwner) {
|
|
1901
1917
|
printDebug(function () {
|
|
1902
|
-
return "cannot start a new drag before finalizing
|
|
1918
|
+
return "cannot start a new drag before finalizing the current drag or pending gesture";
|
|
1903
1919
|
});
|
|
1904
1920
|
return;
|
|
1905
1921
|
}
|
|
@@ -1909,6 +1925,7 @@
|
|
|
1909
1925
|
e.preventDefault();
|
|
1910
1926
|
}
|
|
1911
1927
|
e.stopPropagation();
|
|
1928
|
+
pendingDragOwner = node;
|
|
1912
1929
|
var c = isTouchStart ? e.touches[0] : e;
|
|
1913
1930
|
dragStartMousePosition = {
|
|
1914
1931
|
x: c.clientX,
|
|
@@ -1917,18 +1934,25 @@
|
|
|
1917
1934
|
currentMousePosition = _objectSpread2({}, dragStartMousePosition);
|
|
1918
1935
|
originalDragTarget = e.currentTarget;
|
|
1919
1936
|
if (useDelay) {
|
|
1937
|
+
var pendingTarget = originalDragTarget;
|
|
1920
1938
|
touchHoldElapsed = false;
|
|
1921
1939
|
touchDragHoldTimer = window.setTimeout(function () {
|
|
1922
|
-
// If the
|
|
1923
|
-
if (
|
|
1940
|
+
// If this action still owns the same pending gesture, transition it to a drag.
|
|
1941
|
+
if (destroyed || pendingDragOwner !== node || originalDragTarget !== pendingTarget) return;
|
|
1924
1942
|
touchHoldElapsed = true;
|
|
1925
|
-
removeMaybeListeners();
|
|
1926
1943
|
handleDragStart();
|
|
1927
1944
|
}, config.delayTouchStartMs);
|
|
1928
1945
|
}
|
|
1929
1946
|
addMaybeListeners();
|
|
1930
1947
|
}
|
|
1931
1948
|
function handleDragStart() {
|
|
1949
|
+
var _originalDragTarget;
|
|
1950
|
+
if (destroyed || pendingDragOwner !== node || isWorkingOnPreviousDrag || !((_originalDragTarget = originalDragTarget) !== null && _originalDragTarget !== void 0 && _originalDragTarget.parentElement)) {
|
|
1951
|
+
cancelPendingDrag();
|
|
1952
|
+
return;
|
|
1953
|
+
}
|
|
1954
|
+
removeMaybeListeners();
|
|
1955
|
+
pendingDragOwner = undefined;
|
|
1932
1956
|
printDebug(function () {
|
|
1933
1957
|
return ["drag start config: ".concat(toString(config)), originalDragTarget];
|
|
1934
1958
|
});
|
|
@@ -2127,11 +2151,29 @@
|
|
|
2127
2151
|
configure(newOptions);
|
|
2128
2152
|
},
|
|
2129
2153
|
destroy: function destroy() {
|
|
2154
|
+
if (destroyed) return;
|
|
2155
|
+
destroyed = true;
|
|
2156
|
+
cancelPendingDrag();
|
|
2157
|
+
var _iterator3 = _createForOfIteratorHelper(node.children),
|
|
2158
|
+
_step3;
|
|
2159
|
+
try {
|
|
2160
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
2161
|
+
var draggableEl = _step3.value;
|
|
2162
|
+
draggableEl.removeEventListener("mousedown", elToMouseDownListener.get(draggableEl));
|
|
2163
|
+
draggableEl.removeEventListener("touchstart", elToMouseDownListener.get(draggableEl));
|
|
2164
|
+
}
|
|
2165
|
+
} catch (err) {
|
|
2166
|
+
_iterator3.e(err);
|
|
2167
|
+
} finally {
|
|
2168
|
+
_iterator3.f();
|
|
2169
|
+
}
|
|
2130
2170
|
function destroyDz() {
|
|
2131
2171
|
printDebug(function () {
|
|
2132
2172
|
return "pointer dndzone will destroy";
|
|
2133
2173
|
});
|
|
2134
|
-
|
|
2174
|
+
var registeredConfig = dzToConfig$1.get(node);
|
|
2175
|
+
if (!registeredConfig) return;
|
|
2176
|
+
unregisterDropZone$1(node, registeredConfig.type);
|
|
2135
2177
|
dzToConfig$1["delete"](node);
|
|
2136
2178
|
}
|
|
2137
2179
|
if (isWorkingOnPreviousDrag && !node.closest("[".concat(ORIGINAL_DRAGGED_ITEM_MARKER_ATTRIBUTE, "]"))) {
|
|
@@ -2288,12 +2330,13 @@
|
|
|
2288
2330
|
printDebug(function () {
|
|
2289
2331
|
return "unregistering drop-zone";
|
|
2290
2332
|
});
|
|
2291
|
-
if (focusedDz === dropZoneEl) {
|
|
2333
|
+
if (isDragging && focusedDz === dropZoneEl) {
|
|
2292
2334
|
handleDrop();
|
|
2293
2335
|
}
|
|
2294
|
-
typeToDropZones.get(type)
|
|
2336
|
+
var dropZones = typeToDropZones.get(type);
|
|
2337
|
+
if (!dropZones || !dropZones["delete"](dropZoneEl)) return;
|
|
2295
2338
|
decrementActiveDropZoneCount();
|
|
2296
|
-
if (
|
|
2339
|
+
if (dropZones.size === 0) {
|
|
2297
2340
|
typeToDropZones["delete"](type);
|
|
2298
2341
|
}
|
|
2299
2342
|
if (typeToDropZones.size === 0) {
|
|
@@ -2355,17 +2398,20 @@
|
|
|
2355
2398
|
}
|
|
2356
2399
|
}
|
|
2357
2400
|
var dzFrom = focusedDz;
|
|
2401
|
+
var movedItemId = focusedItemId;
|
|
2402
|
+
focusedDz = newlyFocusedDz;
|
|
2358
2403
|
dispatchFinalizeEvent(dzFrom, originItems, {
|
|
2359
2404
|
trigger: TRIGGERS.DROPPED_INTO_ANOTHER,
|
|
2360
|
-
id:
|
|
2361
|
-
source: SOURCES.KEYBOARD
|
|
2362
|
-
});
|
|
2363
|
-
dispatchFinalizeEvent(newlyFocusedDz, targetItems, {
|
|
2364
|
-
trigger: TRIGGERS.DROPPED_INTO_ZONE,
|
|
2365
|
-
id: focusedItemId,
|
|
2405
|
+
id: movedItemId,
|
|
2366
2406
|
source: SOURCES.KEYBOARD
|
|
2367
2407
|
});
|
|
2368
|
-
|
|
2408
|
+
if (dzToConfig.has(newlyFocusedDz)) {
|
|
2409
|
+
dispatchFinalizeEvent(newlyFocusedDz, targetItems, {
|
|
2410
|
+
trigger: TRIGGERS.DROPPED_INTO_ZONE,
|
|
2411
|
+
id: movedItemId,
|
|
2412
|
+
source: SOURCES.KEYBOARD
|
|
2413
|
+
});
|
|
2414
|
+
}
|
|
2369
2415
|
}
|
|
2370
2416
|
function triggerAllDzsUpdate() {
|
|
2371
2417
|
dzToHandles.forEach(function (_ref, dz) {
|
|
@@ -2375,27 +2421,23 @@
|
|
|
2375
2421
|
}
|
|
2376
2422
|
function handleDrop() {
|
|
2377
2423
|
var dispatchConsider = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
2424
|
+
if (!isDragging || !focusedDz) return;
|
|
2378
2425
|
printDebug(function () {
|
|
2379
2426
|
return "drop";
|
|
2380
2427
|
});
|
|
2381
|
-
|
|
2428
|
+
var droppedDz = focusedDz;
|
|
2429
|
+
var droppedConfig = dzToConfig.get(droppedDz);
|
|
2430
|
+
var droppedItemId = focusedItemId;
|
|
2431
|
+
var droppedItemType = draggedItemType;
|
|
2432
|
+
if (!droppedConfig) return;
|
|
2433
|
+
if (!droppedConfig.autoAriaDisabled) {
|
|
2382
2434
|
alertToScreenReader("Stopped dragging item ".concat(focusedItemLabel));
|
|
2383
2435
|
}
|
|
2384
2436
|
if (allDragTargets.has(document.activeElement)) {
|
|
2385
2437
|
document.activeElement.blur();
|
|
2386
2438
|
}
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
trigger: TRIGGERS.DRAG_STOPPED,
|
|
2390
|
-
id: focusedItemId,
|
|
2391
|
-
source: SOURCES.KEYBOARD
|
|
2392
|
-
});
|
|
2393
|
-
}
|
|
2394
|
-
styleInactiveDropZones(typeToDropZones.get(draggedItemType), function (dz) {
|
|
2395
|
-
return dzToConfig.get(dz).dropTargetStyle;
|
|
2396
|
-
}, function (dz) {
|
|
2397
|
-
return dzToConfig.get(dz).dropTargetClasses;
|
|
2398
|
-
});
|
|
2439
|
+
// Clear global drag state before dispatching. A synchronous handler may destroy the
|
|
2440
|
+
// focused zone, and unregisterDropZone must not recursively enter handleDrop.
|
|
2399
2441
|
focusedItem = null;
|
|
2400
2442
|
focusedItemId = null;
|
|
2401
2443
|
focusedItemLabel = "";
|
|
@@ -2403,10 +2445,26 @@
|
|
|
2403
2445
|
focusedDz = null;
|
|
2404
2446
|
focusedDzLabel = "";
|
|
2405
2447
|
isDragging = false;
|
|
2448
|
+
if (dispatchConsider) {
|
|
2449
|
+
dispatchConsiderEvent(droppedDz, droppedConfig.items, {
|
|
2450
|
+
trigger: TRIGGERS.DRAG_STOPPED,
|
|
2451
|
+
id: droppedItemId,
|
|
2452
|
+
source: SOURCES.KEYBOARD
|
|
2453
|
+
});
|
|
2454
|
+
}
|
|
2455
|
+
var dropZones = typeToDropZones.get(droppedItemType);
|
|
2456
|
+
if (dropZones) {
|
|
2457
|
+
styleInactiveDropZones(dropZones, function (dz) {
|
|
2458
|
+
return dzToConfig.get(dz).dropTargetStyle;
|
|
2459
|
+
}, function (dz) {
|
|
2460
|
+
return dzToConfig.get(dz).dropTargetClasses;
|
|
2461
|
+
});
|
|
2462
|
+
}
|
|
2406
2463
|
triggerAllDzsUpdate();
|
|
2407
2464
|
}
|
|
2408
2465
|
//////
|
|
2409
2466
|
function dndzone$1(node, options) {
|
|
2467
|
+
var destroyed = false;
|
|
2410
2468
|
var config = {
|
|
2411
2469
|
items: undefined,
|
|
2412
2470
|
type: undefined,
|
|
@@ -2631,9 +2689,25 @@
|
|
|
2631
2689
|
configure(newOptions);
|
|
2632
2690
|
},
|
|
2633
2691
|
destroy: function destroy() {
|
|
2692
|
+
if (destroyed) return;
|
|
2693
|
+
destroyed = true;
|
|
2634
2694
|
printDebug(function () {
|
|
2635
2695
|
return "keyboard dndzone will destroy";
|
|
2636
2696
|
});
|
|
2697
|
+
node.removeEventListener("focus", handleZoneFocus);
|
|
2698
|
+
var _iterator = _createForOfIteratorHelper(node.children),
|
|
2699
|
+
_step;
|
|
2700
|
+
try {
|
|
2701
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
2702
|
+
var draggableEl = _step.value;
|
|
2703
|
+
draggableEl.removeEventListener("keydown", elToKeyDownListeners.get(draggableEl));
|
|
2704
|
+
draggableEl.removeEventListener("click", elToFocusListeners.get(draggableEl));
|
|
2705
|
+
}
|
|
2706
|
+
} catch (err) {
|
|
2707
|
+
_iterator.e(err);
|
|
2708
|
+
} finally {
|
|
2709
|
+
_iterator.f();
|
|
2710
|
+
}
|
|
2637
2711
|
unregisterDropZone(node, config.type);
|
|
2638
2712
|
dzToConfig["delete"](node);
|
|
2639
2713
|
dzToHandles["delete"](node);
|
|
@@ -2842,6 +2916,8 @@
|
|
|
2842
2916
|
updateZone();
|
|
2843
2917
|
},
|
|
2844
2918
|
destroy: function destroy() {
|
|
2919
|
+
isItemsDragDisabled.set(true);
|
|
2920
|
+
zone.destroy();
|
|
2845
2921
|
node.removeEventListener("consider", consider);
|
|
2846
2922
|
node.removeEventListener("finalize", finalize);
|
|
2847
2923
|
isItemsDragDisabled.unsubscribe(updateZone);
|
package/dist/index.mjs
CHANGED
|
@@ -1407,6 +1407,8 @@ var multiScroller;
|
|
|
1407
1407
|
var touchDragHoldTimer;
|
|
1408
1408
|
var touchHoldElapsed = false;
|
|
1409
1409
|
var useCursorForDetectionActive = false;
|
|
1410
|
+
var pendingDragOwner;
|
|
1411
|
+
var watchedDropZones = new Set();
|
|
1410
1412
|
|
|
1411
1413
|
// a map from type to a set of drop-zones
|
|
1412
1414
|
var typeToDropZones$1 = new Map();
|
|
@@ -1429,9 +1431,10 @@ function registerDropZone$1(dropZoneEl, type) {
|
|
|
1429
1431
|
}
|
|
1430
1432
|
}
|
|
1431
1433
|
function unregisterDropZone$1(dropZoneEl, type) {
|
|
1432
|
-
typeToDropZones$1.get(type)
|
|
1434
|
+
var dropZones = typeToDropZones$1.get(type);
|
|
1435
|
+
if (!dropZones || !dropZones["delete"](dropZoneEl)) return;
|
|
1433
1436
|
decrementActiveDropZoneCount();
|
|
1434
|
-
if (
|
|
1437
|
+
if (dropZones.size === 0) {
|
|
1435
1438
|
typeToDropZones$1["delete"](type);
|
|
1436
1439
|
}
|
|
1437
1440
|
}
|
|
@@ -1442,7 +1445,10 @@ function watchDraggedElement() {
|
|
|
1442
1445
|
return "watching dragged element";
|
|
1443
1446
|
});
|
|
1444
1447
|
var dropZones = typeToDropZones$1.get(draggedElType);
|
|
1445
|
-
|
|
1448
|
+
if (!dropZones || dropZones.size === 0) return;
|
|
1449
|
+
if (watchedDropZones.size > 0) unWatchDraggedElement();
|
|
1450
|
+
watchedDropZones = new Set(dropZones);
|
|
1451
|
+
var _iterator = _createForOfIteratorHelper(watchedDropZones),
|
|
1446
1452
|
_step;
|
|
1447
1453
|
try {
|
|
1448
1454
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
@@ -1459,11 +1465,11 @@ function watchDraggedElement() {
|
|
|
1459
1465
|
window.addEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop$1);
|
|
1460
1466
|
|
|
1461
1467
|
// it is important that we don't have an interval that is faster than the flip duration because it can cause elements to jump bach and forth
|
|
1462
|
-
var setIntervalMs = Math.max.apply(Math, _toConsumableArray(Array.from(
|
|
1468
|
+
var setIntervalMs = Math.max.apply(Math, _toConsumableArray(Array.from(watchedDropZones).map(function (dz) {
|
|
1463
1469
|
return dzToConfig$1.get(dz).dropAnimationDurationMs;
|
|
1464
1470
|
})));
|
|
1465
1471
|
var observationIntervalMs = setIntervalMs === 0 ? DISABLED_OBSERVATION_INTERVAL_MS : Math.max(setIntervalMs, MIN_OBSERVATION_INTERVAL_MS); // if setIntervalMs is 0 it goes to 20, otherwise it is max between it and min observation.
|
|
1466
|
-
multiScroller = createMultiScroller(
|
|
1472
|
+
multiScroller = createMultiScroller(watchedDropZones, function () {
|
|
1467
1473
|
return currentMousePosition;
|
|
1468
1474
|
});
|
|
1469
1475
|
// Returns reference point in document coordinates - either cursor position or element center
|
|
@@ -1475,14 +1481,13 @@ function watchDraggedElement() {
|
|
|
1475
1481
|
} : function () {
|
|
1476
1482
|
return findCenterOfElement(draggedEl);
|
|
1477
1483
|
};
|
|
1478
|
-
observe(draggedEl,
|
|
1484
|
+
observe(draggedEl, watchedDropZones, observationIntervalMs * 1.07, multiScroller, getReferencePoint);
|
|
1479
1485
|
}
|
|
1480
1486
|
function unWatchDraggedElement() {
|
|
1481
1487
|
printDebug(function () {
|
|
1482
1488
|
return "unwatching dragged element";
|
|
1483
1489
|
});
|
|
1484
|
-
var
|
|
1485
|
-
var _iterator2 = _createForOfIteratorHelper(dropZones),
|
|
1490
|
+
var _iterator2 = _createForOfIteratorHelper(watchedDropZones),
|
|
1486
1491
|
_step2;
|
|
1487
1492
|
try {
|
|
1488
1493
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
@@ -1496,6 +1501,7 @@ function unWatchDraggedElement() {
|
|
|
1496
1501
|
} finally {
|
|
1497
1502
|
_iterator2.f();
|
|
1498
1503
|
}
|
|
1504
|
+
watchedDropZones = new Set();
|
|
1499
1505
|
window.removeEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop$1);
|
|
1500
1506
|
// ensuring multiScroller is not already destroyed before destroying
|
|
1501
1507
|
if (multiScroller) {
|
|
@@ -1727,11 +1733,13 @@ function animateDraggedToFinalPosition(shadowElIdx, callback) {
|
|
|
1727
1733
|
window.setTimeout(callback, dropAnimationDurationMs);
|
|
1728
1734
|
}
|
|
1729
1735
|
function scheduleDZForRemovalAfterDrop(dz, destroy) {
|
|
1730
|
-
|
|
1736
|
+
var scheduledRemoval = {
|
|
1731
1737
|
dz: dz,
|
|
1732
1738
|
destroy: destroy
|
|
1733
|
-
}
|
|
1739
|
+
};
|
|
1740
|
+
scheduledForRemovalAfterDrop.push(scheduledRemoval);
|
|
1734
1741
|
window.requestAnimationFrame(function () {
|
|
1742
|
+
if (!scheduledForRemovalAfterDrop.includes(scheduledRemoval)) return;
|
|
1735
1743
|
hideElement(dz);
|
|
1736
1744
|
document.body.appendChild(dz);
|
|
1737
1745
|
});
|
|
@@ -1765,6 +1773,7 @@ function cleanupPostDrop() {
|
|
|
1765
1773
|
touchDragHoldTimer = undefined;
|
|
1766
1774
|
touchHoldElapsed = false;
|
|
1767
1775
|
useCursorForDetectionActive = false;
|
|
1776
|
+
pendingDragOwner = undefined;
|
|
1768
1777
|
if (scheduledForRemovalAfterDrop.length) {
|
|
1769
1778
|
printDebug(function () {
|
|
1770
1779
|
return ["will destroy zones that were removed during drag", scheduledForRemovalAfterDrop];
|
|
@@ -1780,6 +1789,7 @@ function cleanupPostDrop() {
|
|
|
1780
1789
|
}
|
|
1781
1790
|
function dndzone$2(node, options) {
|
|
1782
1791
|
var initialized = false;
|
|
1792
|
+
var destroyed = false;
|
|
1783
1793
|
var config = {
|
|
1784
1794
|
items: undefined,
|
|
1785
1795
|
type: undefined,
|
|
@@ -1827,11 +1837,17 @@ function dndzone$2(node, options) {
|
|
|
1827
1837
|
touchHoldElapsed = false;
|
|
1828
1838
|
}
|
|
1829
1839
|
}
|
|
1830
|
-
function
|
|
1840
|
+
function cancelPendingDrag() {
|
|
1841
|
+
if (pendingDragOwner !== node) return;
|
|
1831
1842
|
removeMaybeListeners();
|
|
1843
|
+
pendingDragOwner = undefined;
|
|
1832
1844
|
originalDragTarget = undefined;
|
|
1833
1845
|
dragStartMousePosition = undefined;
|
|
1834
1846
|
currentMousePosition = undefined;
|
|
1847
|
+
}
|
|
1848
|
+
function handleFalseAlarm(e) {
|
|
1849
|
+
if (pendingDragOwner !== node) return;
|
|
1850
|
+
cancelPendingDrag();
|
|
1835
1851
|
|
|
1836
1852
|
// dragging initiated by touch events prevents onclick from initially firing
|
|
1837
1853
|
if (e.type === "touchend") {
|
|
@@ -1844,6 +1860,7 @@ function dndzone$2(node, options) {
|
|
|
1844
1860
|
}
|
|
1845
1861
|
}
|
|
1846
1862
|
function handleMouseMoveMaybeDragStart(e) {
|
|
1863
|
+
if (destroyed || pendingDragOwner !== node) return;
|
|
1847
1864
|
var isTouch = !!e.touches;
|
|
1848
1865
|
var c = isTouch ? e.touches[0] : e;
|
|
1849
1866
|
// If touch drag delay is configured and not elapsed yet, allow scrolling until either
|
|
@@ -1872,7 +1889,6 @@ function dndzone$2(node, options) {
|
|
|
1872
1889
|
y: c.clientY
|
|
1873
1890
|
};
|
|
1874
1891
|
if (Math.abs(currentMousePosition.x - dragStartMousePosition.x) >= MIN_MOVEMENT_BEFORE_DRAG_START_PX || Math.abs(currentMousePosition.y - dragStartMousePosition.y) >= MIN_MOVEMENT_BEFORE_DRAG_START_PX) {
|
|
1875
|
-
removeMaybeListeners();
|
|
1876
1892
|
handleDragStart();
|
|
1877
1893
|
}
|
|
1878
1894
|
}
|
|
@@ -1891,9 +1907,9 @@ function dndzone$2(node, options) {
|
|
|
1891
1907
|
});
|
|
1892
1908
|
return;
|
|
1893
1909
|
}
|
|
1894
|
-
if (isWorkingOnPreviousDrag) {
|
|
1910
|
+
if (destroyed || isWorkingOnPreviousDrag || pendingDragOwner) {
|
|
1895
1911
|
printDebug(function () {
|
|
1896
|
-
return "cannot start a new drag before finalizing
|
|
1912
|
+
return "cannot start a new drag before finalizing the current drag or pending gesture";
|
|
1897
1913
|
});
|
|
1898
1914
|
return;
|
|
1899
1915
|
}
|
|
@@ -1903,6 +1919,7 @@ function dndzone$2(node, options) {
|
|
|
1903
1919
|
e.preventDefault();
|
|
1904
1920
|
}
|
|
1905
1921
|
e.stopPropagation();
|
|
1922
|
+
pendingDragOwner = node;
|
|
1906
1923
|
var c = isTouchStart ? e.touches[0] : e;
|
|
1907
1924
|
dragStartMousePosition = {
|
|
1908
1925
|
x: c.clientX,
|
|
@@ -1911,18 +1928,25 @@ function dndzone$2(node, options) {
|
|
|
1911
1928
|
currentMousePosition = _objectSpread2({}, dragStartMousePosition);
|
|
1912
1929
|
originalDragTarget = e.currentTarget;
|
|
1913
1930
|
if (useDelay) {
|
|
1931
|
+
var pendingTarget = originalDragTarget;
|
|
1914
1932
|
touchHoldElapsed = false;
|
|
1915
1933
|
touchDragHoldTimer = window.setTimeout(function () {
|
|
1916
|
-
// If the
|
|
1917
|
-
if (
|
|
1934
|
+
// If this action still owns the same pending gesture, transition it to a drag.
|
|
1935
|
+
if (destroyed || pendingDragOwner !== node || originalDragTarget !== pendingTarget) return;
|
|
1918
1936
|
touchHoldElapsed = true;
|
|
1919
|
-
removeMaybeListeners();
|
|
1920
1937
|
handleDragStart();
|
|
1921
1938
|
}, config.delayTouchStartMs);
|
|
1922
1939
|
}
|
|
1923
1940
|
addMaybeListeners();
|
|
1924
1941
|
}
|
|
1925
1942
|
function handleDragStart() {
|
|
1943
|
+
var _originalDragTarget;
|
|
1944
|
+
if (destroyed || pendingDragOwner !== node || isWorkingOnPreviousDrag || !((_originalDragTarget = originalDragTarget) !== null && _originalDragTarget !== void 0 && _originalDragTarget.parentElement)) {
|
|
1945
|
+
cancelPendingDrag();
|
|
1946
|
+
return;
|
|
1947
|
+
}
|
|
1948
|
+
removeMaybeListeners();
|
|
1949
|
+
pendingDragOwner = undefined;
|
|
1926
1950
|
printDebug(function () {
|
|
1927
1951
|
return ["drag start config: ".concat(toString(config)), originalDragTarget];
|
|
1928
1952
|
});
|
|
@@ -2121,11 +2145,29 @@ function dndzone$2(node, options) {
|
|
|
2121
2145
|
configure(newOptions);
|
|
2122
2146
|
},
|
|
2123
2147
|
destroy: function destroy() {
|
|
2148
|
+
if (destroyed) return;
|
|
2149
|
+
destroyed = true;
|
|
2150
|
+
cancelPendingDrag();
|
|
2151
|
+
var _iterator3 = _createForOfIteratorHelper(node.children),
|
|
2152
|
+
_step3;
|
|
2153
|
+
try {
|
|
2154
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
2155
|
+
var draggableEl = _step3.value;
|
|
2156
|
+
draggableEl.removeEventListener("mousedown", elToMouseDownListener.get(draggableEl));
|
|
2157
|
+
draggableEl.removeEventListener("touchstart", elToMouseDownListener.get(draggableEl));
|
|
2158
|
+
}
|
|
2159
|
+
} catch (err) {
|
|
2160
|
+
_iterator3.e(err);
|
|
2161
|
+
} finally {
|
|
2162
|
+
_iterator3.f();
|
|
2163
|
+
}
|
|
2124
2164
|
function destroyDz() {
|
|
2125
2165
|
printDebug(function () {
|
|
2126
2166
|
return "pointer dndzone will destroy";
|
|
2127
2167
|
});
|
|
2128
|
-
|
|
2168
|
+
var registeredConfig = dzToConfig$1.get(node);
|
|
2169
|
+
if (!registeredConfig) return;
|
|
2170
|
+
unregisterDropZone$1(node, registeredConfig.type);
|
|
2129
2171
|
dzToConfig$1["delete"](node);
|
|
2130
2172
|
}
|
|
2131
2173
|
if (isWorkingOnPreviousDrag && !node.closest("[".concat(ORIGINAL_DRAGGED_ITEM_MARKER_ATTRIBUTE, "]"))) {
|
|
@@ -2282,12 +2324,13 @@ function unregisterDropZone(dropZoneEl, type) {
|
|
|
2282
2324
|
printDebug(function () {
|
|
2283
2325
|
return "unregistering drop-zone";
|
|
2284
2326
|
});
|
|
2285
|
-
if (focusedDz === dropZoneEl) {
|
|
2327
|
+
if (isDragging && focusedDz === dropZoneEl) {
|
|
2286
2328
|
handleDrop();
|
|
2287
2329
|
}
|
|
2288
|
-
typeToDropZones.get(type)
|
|
2330
|
+
var dropZones = typeToDropZones.get(type);
|
|
2331
|
+
if (!dropZones || !dropZones["delete"](dropZoneEl)) return;
|
|
2289
2332
|
decrementActiveDropZoneCount();
|
|
2290
|
-
if (
|
|
2333
|
+
if (dropZones.size === 0) {
|
|
2291
2334
|
typeToDropZones["delete"](type);
|
|
2292
2335
|
}
|
|
2293
2336
|
if (typeToDropZones.size === 0) {
|
|
@@ -2349,17 +2392,20 @@ function handleZoneFocus(e) {
|
|
|
2349
2392
|
}
|
|
2350
2393
|
}
|
|
2351
2394
|
var dzFrom = focusedDz;
|
|
2395
|
+
var movedItemId = focusedItemId;
|
|
2396
|
+
focusedDz = newlyFocusedDz;
|
|
2352
2397
|
dispatchFinalizeEvent(dzFrom, originItems, {
|
|
2353
2398
|
trigger: TRIGGERS.DROPPED_INTO_ANOTHER,
|
|
2354
|
-
id:
|
|
2355
|
-
source: SOURCES.KEYBOARD
|
|
2356
|
-
});
|
|
2357
|
-
dispatchFinalizeEvent(newlyFocusedDz, targetItems, {
|
|
2358
|
-
trigger: TRIGGERS.DROPPED_INTO_ZONE,
|
|
2359
|
-
id: focusedItemId,
|
|
2399
|
+
id: movedItemId,
|
|
2360
2400
|
source: SOURCES.KEYBOARD
|
|
2361
2401
|
});
|
|
2362
|
-
|
|
2402
|
+
if (dzToConfig.has(newlyFocusedDz)) {
|
|
2403
|
+
dispatchFinalizeEvent(newlyFocusedDz, targetItems, {
|
|
2404
|
+
trigger: TRIGGERS.DROPPED_INTO_ZONE,
|
|
2405
|
+
id: movedItemId,
|
|
2406
|
+
source: SOURCES.KEYBOARD
|
|
2407
|
+
});
|
|
2408
|
+
}
|
|
2363
2409
|
}
|
|
2364
2410
|
function triggerAllDzsUpdate() {
|
|
2365
2411
|
dzToHandles.forEach(function (_ref, dz) {
|
|
@@ -2369,27 +2415,23 @@ function triggerAllDzsUpdate() {
|
|
|
2369
2415
|
}
|
|
2370
2416
|
function handleDrop() {
|
|
2371
2417
|
var dispatchConsider = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
2418
|
+
if (!isDragging || !focusedDz) return;
|
|
2372
2419
|
printDebug(function () {
|
|
2373
2420
|
return "drop";
|
|
2374
2421
|
});
|
|
2375
|
-
|
|
2422
|
+
var droppedDz = focusedDz;
|
|
2423
|
+
var droppedConfig = dzToConfig.get(droppedDz);
|
|
2424
|
+
var droppedItemId = focusedItemId;
|
|
2425
|
+
var droppedItemType = draggedItemType;
|
|
2426
|
+
if (!droppedConfig) return;
|
|
2427
|
+
if (!droppedConfig.autoAriaDisabled) {
|
|
2376
2428
|
alertToScreenReader("Stopped dragging item ".concat(focusedItemLabel));
|
|
2377
2429
|
}
|
|
2378
2430
|
if (allDragTargets.has(document.activeElement)) {
|
|
2379
2431
|
document.activeElement.blur();
|
|
2380
2432
|
}
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
trigger: TRIGGERS.DRAG_STOPPED,
|
|
2384
|
-
id: focusedItemId,
|
|
2385
|
-
source: SOURCES.KEYBOARD
|
|
2386
|
-
});
|
|
2387
|
-
}
|
|
2388
|
-
styleInactiveDropZones(typeToDropZones.get(draggedItemType), function (dz) {
|
|
2389
|
-
return dzToConfig.get(dz).dropTargetStyle;
|
|
2390
|
-
}, function (dz) {
|
|
2391
|
-
return dzToConfig.get(dz).dropTargetClasses;
|
|
2392
|
-
});
|
|
2433
|
+
// Clear global drag state before dispatching. A synchronous handler may destroy the
|
|
2434
|
+
// focused zone, and unregisterDropZone must not recursively enter handleDrop.
|
|
2393
2435
|
focusedItem = null;
|
|
2394
2436
|
focusedItemId = null;
|
|
2395
2437
|
focusedItemLabel = "";
|
|
@@ -2397,10 +2439,26 @@ function handleDrop() {
|
|
|
2397
2439
|
focusedDz = null;
|
|
2398
2440
|
focusedDzLabel = "";
|
|
2399
2441
|
isDragging = false;
|
|
2442
|
+
if (dispatchConsider) {
|
|
2443
|
+
dispatchConsiderEvent(droppedDz, droppedConfig.items, {
|
|
2444
|
+
trigger: TRIGGERS.DRAG_STOPPED,
|
|
2445
|
+
id: droppedItemId,
|
|
2446
|
+
source: SOURCES.KEYBOARD
|
|
2447
|
+
});
|
|
2448
|
+
}
|
|
2449
|
+
var dropZones = typeToDropZones.get(droppedItemType);
|
|
2450
|
+
if (dropZones) {
|
|
2451
|
+
styleInactiveDropZones(dropZones, function (dz) {
|
|
2452
|
+
return dzToConfig.get(dz).dropTargetStyle;
|
|
2453
|
+
}, function (dz) {
|
|
2454
|
+
return dzToConfig.get(dz).dropTargetClasses;
|
|
2455
|
+
});
|
|
2456
|
+
}
|
|
2400
2457
|
triggerAllDzsUpdate();
|
|
2401
2458
|
}
|
|
2402
2459
|
//////
|
|
2403
2460
|
function dndzone$1(node, options) {
|
|
2461
|
+
var destroyed = false;
|
|
2404
2462
|
var config = {
|
|
2405
2463
|
items: undefined,
|
|
2406
2464
|
type: undefined,
|
|
@@ -2625,9 +2683,25 @@ function dndzone$1(node, options) {
|
|
|
2625
2683
|
configure(newOptions);
|
|
2626
2684
|
},
|
|
2627
2685
|
destroy: function destroy() {
|
|
2686
|
+
if (destroyed) return;
|
|
2687
|
+
destroyed = true;
|
|
2628
2688
|
printDebug(function () {
|
|
2629
2689
|
return "keyboard dndzone will destroy";
|
|
2630
2690
|
});
|
|
2691
|
+
node.removeEventListener("focus", handleZoneFocus);
|
|
2692
|
+
var _iterator = _createForOfIteratorHelper(node.children),
|
|
2693
|
+
_step;
|
|
2694
|
+
try {
|
|
2695
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
2696
|
+
var draggableEl = _step.value;
|
|
2697
|
+
draggableEl.removeEventListener("keydown", elToKeyDownListeners.get(draggableEl));
|
|
2698
|
+
draggableEl.removeEventListener("click", elToFocusListeners.get(draggableEl));
|
|
2699
|
+
}
|
|
2700
|
+
} catch (err) {
|
|
2701
|
+
_iterator.e(err);
|
|
2702
|
+
} finally {
|
|
2703
|
+
_iterator.f();
|
|
2704
|
+
}
|
|
2631
2705
|
unregisterDropZone(node, config.type);
|
|
2632
2706
|
dzToConfig["delete"](node);
|
|
2633
2707
|
dzToHandles["delete"](node);
|
|
@@ -2836,6 +2910,8 @@ function dragHandleZone(node, options) {
|
|
|
2836
2910
|
updateZone();
|
|
2837
2911
|
},
|
|
2838
2912
|
destroy: function destroy() {
|
|
2913
|
+
isItemsDragDisabled.set(true);
|
|
2914
|
+
zone.destroy();
|
|
2839
2915
|
node.removeEventListener("consider", consider);
|
|
2840
2916
|
node.removeEventListener("finalize", finalize);
|
|
2841
2917
|
isItemsDragDisabled.unsubscribe(updateZone);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-dnd-action",
|
|
3
3
|
"description": "*An awesome drag and drop library for Svelte 3 and 4 (not using the browser's built-in dnd, thanks god): Rich animations, nested containers, touch support and more *",
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.72",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/isaacHagoel/svelte-dnd-action.git"
|
package/src/keyboardAction.js
CHANGED
|
@@ -50,12 +50,13 @@ function registerDropZone(dropZoneEl, type) {
|
|
|
50
50
|
}
|
|
51
51
|
function unregisterDropZone(dropZoneEl, type) {
|
|
52
52
|
printDebug(() => "unregistering drop-zone");
|
|
53
|
-
if (focusedDz === dropZoneEl) {
|
|
53
|
+
if (isDragging && focusedDz === dropZoneEl) {
|
|
54
54
|
handleDrop();
|
|
55
55
|
}
|
|
56
|
-
typeToDropZones.get(type)
|
|
56
|
+
const dropZones = typeToDropZones.get(type);
|
|
57
|
+
if (!dropZones || !dropZones.delete(dropZoneEl)) return;
|
|
57
58
|
decrementActiveDropZoneCount();
|
|
58
|
-
if (
|
|
59
|
+
if (dropZones.size === 0) {
|
|
59
60
|
typeToDropZones.delete(type);
|
|
60
61
|
}
|
|
61
62
|
if (typeToDropZones.size === 0) {
|
|
@@ -112,9 +113,12 @@ function handleZoneFocus(e) {
|
|
|
112
113
|
}
|
|
113
114
|
}
|
|
114
115
|
const dzFrom = focusedDz;
|
|
115
|
-
|
|
116
|
-
dispatchFinalizeEvent(newlyFocusedDz, targetItems, {trigger: TRIGGERS.DROPPED_INTO_ZONE, id: focusedItemId, source: SOURCES.KEYBOARD});
|
|
116
|
+
const movedItemId = focusedItemId;
|
|
117
117
|
focusedDz = newlyFocusedDz;
|
|
118
|
+
dispatchFinalizeEvent(dzFrom, originItems, {trigger: TRIGGERS.DROPPED_INTO_ANOTHER, id: movedItemId, source: SOURCES.KEYBOARD});
|
|
119
|
+
if (dzToConfig.has(newlyFocusedDz)) {
|
|
120
|
+
dispatchFinalizeEvent(newlyFocusedDz, targetItems, {trigger: TRIGGERS.DROPPED_INTO_ZONE, id: movedItemId, source: SOURCES.KEYBOARD});
|
|
121
|
+
}
|
|
118
122
|
}
|
|
119
123
|
|
|
120
124
|
function triggerAllDzsUpdate() {
|
|
@@ -122,25 +126,22 @@ function triggerAllDzsUpdate() {
|
|
|
122
126
|
}
|
|
123
127
|
|
|
124
128
|
function handleDrop(dispatchConsider = true) {
|
|
129
|
+
if (!isDragging || !focusedDz) return;
|
|
125
130
|
printDebug(() => "drop");
|
|
126
|
-
|
|
131
|
+
const droppedDz = focusedDz;
|
|
132
|
+
const droppedConfig = dzToConfig.get(droppedDz);
|
|
133
|
+
const droppedItemId = focusedItemId;
|
|
134
|
+
const droppedItemType = draggedItemType;
|
|
135
|
+
if (!droppedConfig) return;
|
|
136
|
+
|
|
137
|
+
if (!droppedConfig.autoAriaDisabled) {
|
|
127
138
|
alertToScreenReader(`Stopped dragging item ${focusedItemLabel}`);
|
|
128
139
|
}
|
|
129
140
|
if (allDragTargets.has(document.activeElement)) {
|
|
130
141
|
document.activeElement.blur();
|
|
131
142
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
trigger: TRIGGERS.DRAG_STOPPED,
|
|
135
|
-
id: focusedItemId,
|
|
136
|
-
source: SOURCES.KEYBOARD
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
styleInactiveDropZones(
|
|
140
|
-
typeToDropZones.get(draggedItemType),
|
|
141
|
-
dz => dzToConfig.get(dz).dropTargetStyle,
|
|
142
|
-
dz => dzToConfig.get(dz).dropTargetClasses
|
|
143
|
-
);
|
|
143
|
+
// Clear global drag state before dispatching. A synchronous handler may destroy the
|
|
144
|
+
// focused zone, and unregisterDropZone must not recursively enter handleDrop.
|
|
144
145
|
focusedItem = null;
|
|
145
146
|
focusedItemId = null;
|
|
146
147
|
focusedItemLabel = "";
|
|
@@ -148,10 +149,27 @@ function handleDrop(dispatchConsider = true) {
|
|
|
148
149
|
focusedDz = null;
|
|
149
150
|
focusedDzLabel = "";
|
|
150
151
|
isDragging = false;
|
|
152
|
+
|
|
153
|
+
if (dispatchConsider) {
|
|
154
|
+
dispatchConsiderEvent(droppedDz, droppedConfig.items, {
|
|
155
|
+
trigger: TRIGGERS.DRAG_STOPPED,
|
|
156
|
+
id: droppedItemId,
|
|
157
|
+
source: SOURCES.KEYBOARD
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
const dropZones = typeToDropZones.get(droppedItemType);
|
|
161
|
+
if (dropZones) {
|
|
162
|
+
styleInactiveDropZones(
|
|
163
|
+
dropZones,
|
|
164
|
+
dz => dzToConfig.get(dz).dropTargetStyle,
|
|
165
|
+
dz => dzToConfig.get(dz).dropTargetClasses
|
|
166
|
+
);
|
|
167
|
+
}
|
|
151
168
|
triggerAllDzsUpdate();
|
|
152
169
|
}
|
|
153
170
|
//////
|
|
154
171
|
export function dndzone(node, options) {
|
|
172
|
+
let destroyed = false;
|
|
155
173
|
const config = {
|
|
156
174
|
items: undefined,
|
|
157
175
|
type: undefined,
|
|
@@ -344,7 +362,14 @@ export function dndzone(node, options) {
|
|
|
344
362
|
configure(newOptions);
|
|
345
363
|
},
|
|
346
364
|
destroy: () => {
|
|
365
|
+
if (destroyed) return;
|
|
366
|
+
destroyed = true;
|
|
347
367
|
printDebug(() => "keyboard dndzone will destroy");
|
|
368
|
+
node.removeEventListener("focus", handleZoneFocus);
|
|
369
|
+
for (const draggableEl of node.children) {
|
|
370
|
+
draggableEl.removeEventListener("keydown", elToKeyDownListeners.get(draggableEl));
|
|
371
|
+
draggableEl.removeEventListener("click", elToFocusListeners.get(draggableEl));
|
|
372
|
+
}
|
|
348
373
|
unregisterDropZone(node, config.type);
|
|
349
374
|
dzToConfig.delete(node);
|
|
350
375
|
dzToHandles.delete(node);
|
package/src/pointerAction.js
CHANGED
|
@@ -64,6 +64,8 @@ let multiScroller;
|
|
|
64
64
|
let touchDragHoldTimer;
|
|
65
65
|
let touchHoldElapsed = false;
|
|
66
66
|
let useCursorForDetectionActive = false;
|
|
67
|
+
let pendingDragOwner;
|
|
68
|
+
let watchedDropZones = new Set();
|
|
67
69
|
|
|
68
70
|
// a map from type to a set of drop-zones
|
|
69
71
|
const typeToDropZones = new Map();
|
|
@@ -84,9 +86,10 @@ function registerDropZone(dropZoneEl, type) {
|
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
function unregisterDropZone(dropZoneEl, type) {
|
|
87
|
-
typeToDropZones.get(type)
|
|
89
|
+
const dropZones = typeToDropZones.get(type);
|
|
90
|
+
if (!dropZones || !dropZones.delete(dropZoneEl)) return;
|
|
88
91
|
decrementActiveDropZoneCount();
|
|
89
|
-
if (
|
|
92
|
+
if (dropZones.size === 0) {
|
|
90
93
|
typeToDropZones.delete(type);
|
|
91
94
|
}
|
|
92
95
|
}
|
|
@@ -95,8 +98,11 @@ function unregisterDropZone(dropZoneEl, type) {
|
|
|
95
98
|
function watchDraggedElement() {
|
|
96
99
|
printDebug(() => "watching dragged element");
|
|
97
100
|
const dropZones = typeToDropZones.get(draggedElType);
|
|
101
|
+
if (!dropZones || dropZones.size === 0) return;
|
|
102
|
+
if (watchedDropZones.size > 0) unWatchDraggedElement();
|
|
103
|
+
watchedDropZones = new Set(dropZones);
|
|
98
104
|
|
|
99
|
-
for (const dz of
|
|
105
|
+
for (const dz of watchedDropZones) {
|
|
100
106
|
dz.addEventListener(DRAGGED_ENTERED_EVENT_NAME, handleDraggedEntered);
|
|
101
107
|
dz.addEventListener(DRAGGED_LEFT_EVENT_NAME, handleDraggedLeft);
|
|
102
108
|
dz.addEventListener(DRAGGED_OVER_INDEX_EVENT_NAME, handleDraggedIsOverIndex);
|
|
@@ -104,9 +110,9 @@ function watchDraggedElement() {
|
|
|
104
110
|
window.addEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop);
|
|
105
111
|
|
|
106
112
|
// it is important that we don't have an interval that is faster than the flip duration because it can cause elements to jump bach and forth
|
|
107
|
-
const setIntervalMs = Math.max(...Array.from(
|
|
113
|
+
const setIntervalMs = Math.max(...Array.from(watchedDropZones).map(dz => dzToConfig.get(dz).dropAnimationDurationMs));
|
|
108
114
|
const observationIntervalMs = setIntervalMs === 0 ? DISABLED_OBSERVATION_INTERVAL_MS : Math.max(setIntervalMs, MIN_OBSERVATION_INTERVAL_MS); // if setIntervalMs is 0 it goes to 20, otherwise it is max between it and min observation.
|
|
109
|
-
multiScroller = createMultiScroller(
|
|
115
|
+
multiScroller = createMultiScroller(watchedDropZones, () => currentMousePosition);
|
|
110
116
|
// Returns reference point in document coordinates - either cursor position or element center
|
|
111
117
|
const getReferencePoint = useCursorForDetectionActive
|
|
112
118
|
? () => ({
|
|
@@ -114,16 +120,16 @@ function watchDraggedElement() {
|
|
|
114
120
|
y: currentMousePosition.y + window.scrollY
|
|
115
121
|
})
|
|
116
122
|
: () => findCenterOfElement(draggedEl);
|
|
117
|
-
observe(draggedEl,
|
|
123
|
+
observe(draggedEl, watchedDropZones, observationIntervalMs * 1.07, multiScroller, getReferencePoint);
|
|
118
124
|
}
|
|
119
125
|
function unWatchDraggedElement() {
|
|
120
126
|
printDebug(() => "unwatching dragged element");
|
|
121
|
-
const
|
|
122
|
-
for (const dz of dropZones) {
|
|
127
|
+
for (const dz of watchedDropZones) {
|
|
123
128
|
dz.removeEventListener(DRAGGED_ENTERED_EVENT_NAME, handleDraggedEntered);
|
|
124
129
|
dz.removeEventListener(DRAGGED_LEFT_EVENT_NAME, handleDraggedLeft);
|
|
125
130
|
dz.removeEventListener(DRAGGED_OVER_INDEX_EVENT_NAME, handleDraggedIsOverIndex);
|
|
126
131
|
}
|
|
132
|
+
watchedDropZones = new Set();
|
|
127
133
|
window.removeEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop);
|
|
128
134
|
// ensuring multiScroller is not already destroyed before destroying
|
|
129
135
|
if (multiScroller) {
|
|
@@ -315,8 +321,10 @@ function animateDraggedToFinalPosition(shadowElIdx, callback) {
|
|
|
315
321
|
}
|
|
316
322
|
|
|
317
323
|
function scheduleDZForRemovalAfterDrop(dz, destroy) {
|
|
318
|
-
|
|
324
|
+
const scheduledRemoval = {dz, destroy};
|
|
325
|
+
scheduledForRemovalAfterDrop.push(scheduledRemoval);
|
|
319
326
|
window.requestAnimationFrame(() => {
|
|
327
|
+
if (!scheduledForRemovalAfterDrop.includes(scheduledRemoval)) return;
|
|
320
328
|
hideElement(dz);
|
|
321
329
|
document.body.appendChild(dz);
|
|
322
330
|
});
|
|
@@ -351,6 +359,7 @@ function cleanupPostDrop() {
|
|
|
351
359
|
touchDragHoldTimer = undefined;
|
|
352
360
|
touchHoldElapsed = false;
|
|
353
361
|
useCursorForDetectionActive = false;
|
|
362
|
+
pendingDragOwner = undefined;
|
|
354
363
|
if (scheduledForRemovalAfterDrop.length) {
|
|
355
364
|
printDebug(() => ["will destroy zones that were removed during drag", scheduledForRemovalAfterDrop]);
|
|
356
365
|
scheduledForRemovalAfterDrop.forEach(({dz, destroy}) => {
|
|
@@ -363,6 +372,7 @@ function cleanupPostDrop() {
|
|
|
363
372
|
|
|
364
373
|
export function dndzone(node, options) {
|
|
365
374
|
let initialized = false;
|
|
375
|
+
let destroyed = false;
|
|
366
376
|
const config = {
|
|
367
377
|
items: undefined,
|
|
368
378
|
type: undefined,
|
|
@@ -398,11 +408,17 @@ export function dndzone(node, options) {
|
|
|
398
408
|
touchHoldElapsed = false;
|
|
399
409
|
}
|
|
400
410
|
}
|
|
401
|
-
function
|
|
411
|
+
function cancelPendingDrag() {
|
|
412
|
+
if (pendingDragOwner !== node) return;
|
|
402
413
|
removeMaybeListeners();
|
|
414
|
+
pendingDragOwner = undefined;
|
|
403
415
|
originalDragTarget = undefined;
|
|
404
416
|
dragStartMousePosition = undefined;
|
|
405
417
|
currentMousePosition = undefined;
|
|
418
|
+
}
|
|
419
|
+
function handleFalseAlarm(e) {
|
|
420
|
+
if (pendingDragOwner !== node) return;
|
|
421
|
+
cancelPendingDrag();
|
|
406
422
|
|
|
407
423
|
// dragging initiated by touch events prevents onclick from initially firing
|
|
408
424
|
if (e.type === "touchend") {
|
|
@@ -416,6 +432,7 @@ export function dndzone(node, options) {
|
|
|
416
432
|
}
|
|
417
433
|
|
|
418
434
|
function handleMouseMoveMaybeDragStart(e) {
|
|
435
|
+
if (destroyed || pendingDragOwner !== node) return;
|
|
419
436
|
const isTouch = !!e.touches;
|
|
420
437
|
const c = isTouch ? e.touches[0] : e;
|
|
421
438
|
// If touch drag delay is configured and not elapsed yet, allow scrolling until either
|
|
@@ -445,7 +462,6 @@ export function dndzone(node, options) {
|
|
|
445
462
|
Math.abs(currentMousePosition.x - dragStartMousePosition.x) >= MIN_MOVEMENT_BEFORE_DRAG_START_PX ||
|
|
446
463
|
Math.abs(currentMousePosition.y - dragStartMousePosition.y) >= MIN_MOVEMENT_BEFORE_DRAG_START_PX
|
|
447
464
|
) {
|
|
448
|
-
removeMaybeListeners();
|
|
449
465
|
handleDragStart();
|
|
450
466
|
}
|
|
451
467
|
}
|
|
@@ -460,8 +476,8 @@ export function dndzone(node, options) {
|
|
|
460
476
|
printDebug(() => `ignoring none left click button: ${e.button}`);
|
|
461
477
|
return;
|
|
462
478
|
}
|
|
463
|
-
if (isWorkingOnPreviousDrag) {
|
|
464
|
-
printDebug(() => "cannot start a new drag before finalizing
|
|
479
|
+
if (destroyed || isWorkingOnPreviousDrag || pendingDragOwner) {
|
|
480
|
+
printDebug(() => "cannot start a new drag before finalizing the current drag or pending gesture");
|
|
465
481
|
return;
|
|
466
482
|
}
|
|
467
483
|
const isTouchStart = !!e.touches;
|
|
@@ -471,6 +487,7 @@ export function dndzone(node, options) {
|
|
|
471
487
|
e.preventDefault();
|
|
472
488
|
}
|
|
473
489
|
e.stopPropagation();
|
|
490
|
+
pendingDragOwner = node;
|
|
474
491
|
|
|
475
492
|
const c = isTouchStart ? e.touches[0] : e;
|
|
476
493
|
dragStartMousePosition = {x: c.clientX, y: c.clientY};
|
|
@@ -478,12 +495,12 @@ export function dndzone(node, options) {
|
|
|
478
495
|
originalDragTarget = e.currentTarget;
|
|
479
496
|
|
|
480
497
|
if (useDelay) {
|
|
498
|
+
const pendingTarget = originalDragTarget;
|
|
481
499
|
touchHoldElapsed = false;
|
|
482
500
|
touchDragHoldTimer = window.setTimeout(() => {
|
|
483
|
-
// If the
|
|
484
|
-
if (
|
|
501
|
+
// If this action still owns the same pending gesture, transition it to a drag.
|
|
502
|
+
if (destroyed || pendingDragOwner !== node || originalDragTarget !== pendingTarget) return;
|
|
485
503
|
touchHoldElapsed = true;
|
|
486
|
-
removeMaybeListeners();
|
|
487
504
|
handleDragStart();
|
|
488
505
|
}, config.delayTouchStartMs);
|
|
489
506
|
}
|
|
@@ -492,6 +509,12 @@ export function dndzone(node, options) {
|
|
|
492
509
|
}
|
|
493
510
|
|
|
494
511
|
function handleDragStart() {
|
|
512
|
+
if (destroyed || pendingDragOwner !== node || isWorkingOnPreviousDrag || !originalDragTarget?.parentElement) {
|
|
513
|
+
cancelPendingDrag();
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
removeMaybeListeners();
|
|
517
|
+
pendingDragOwner = undefined;
|
|
495
518
|
printDebug(() => [`drag start config: ${toString(config)}`, originalDragTarget]);
|
|
496
519
|
isWorkingOnPreviousDrag = true;
|
|
497
520
|
|
|
@@ -670,9 +693,18 @@ export function dndzone(node, options) {
|
|
|
670
693
|
configure(newOptions);
|
|
671
694
|
},
|
|
672
695
|
destroy: () => {
|
|
696
|
+
if (destroyed) return;
|
|
697
|
+
destroyed = true;
|
|
698
|
+
cancelPendingDrag();
|
|
699
|
+
for (const draggableEl of node.children) {
|
|
700
|
+
draggableEl.removeEventListener("mousedown", elToMouseDownListener.get(draggableEl));
|
|
701
|
+
draggableEl.removeEventListener("touchstart", elToMouseDownListener.get(draggableEl));
|
|
702
|
+
}
|
|
673
703
|
function destroyDz() {
|
|
674
704
|
printDebug(() => "pointer dndzone will destroy");
|
|
675
|
-
|
|
705
|
+
const registeredConfig = dzToConfig.get(node);
|
|
706
|
+
if (!registeredConfig) return;
|
|
707
|
+
unregisterDropZone(node, registeredConfig.type);
|
|
676
708
|
dzToConfig.delete(node);
|
|
677
709
|
}
|
|
678
710
|
if (isWorkingOnPreviousDrag && !node.closest(`[${ORIGINAL_DRAGGED_ITEM_MARKER_ATTRIBUTE}]`)) {
|
|
@@ -77,6 +77,8 @@ export function dragHandleZone(node, options) {
|
|
|
77
77
|
updateZone();
|
|
78
78
|
},
|
|
79
79
|
destroy: () => {
|
|
80
|
+
isItemsDragDisabled.set(true);
|
|
81
|
+
zone.destroy();
|
|
80
82
|
node.removeEventListener("consider", consider);
|
|
81
83
|
node.removeEventListener("finalize", finalize);
|
|
82
84
|
isItemsDragDisabled.unsubscribe(updateZone);
|