@jsenv/dom 0.9.2 → 0.9.4
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/jsenv_dom.js +306 -335
- package/package.json +1 -1
package/dist/jsenv_dom.js
CHANGED
|
@@ -2227,6 +2227,9 @@ const normalizeStyle = (
|
|
|
2227
2227
|
if (propertyName === "lineHeight") {
|
|
2228
2228
|
if (context === "js") {
|
|
2229
2229
|
if (typeof value === "string") {
|
|
2230
|
+
if (isCSSFunction(value)) {
|
|
2231
|
+
return value;
|
|
2232
|
+
}
|
|
2230
2233
|
const unit = getUnit(value);
|
|
2231
2234
|
if (unit === "px") {
|
|
2232
2235
|
const float = parseFloat(value);
|
|
@@ -2271,6 +2274,9 @@ const normalizeStyle = (
|
|
|
2271
2274
|
}
|
|
2272
2275
|
|
|
2273
2276
|
if (colorPropertySet.has(propertyName)) {
|
|
2277
|
+
if (typeof value === "string" && isCSSFunction(value)) {
|
|
2278
|
+
return value;
|
|
2279
|
+
}
|
|
2274
2280
|
const rgba = parseCSSColor(value, element);
|
|
2275
2281
|
if (context === "js") {
|
|
2276
2282
|
return rgba;
|
|
@@ -2287,8 +2293,15 @@ const stringifyStyle = (value, propertyName, element) => {
|
|
|
2287
2293
|
return normalizeStyle(value, propertyName, "css", element);
|
|
2288
2294
|
};
|
|
2289
2295
|
|
|
2296
|
+
const isCSSFunction = (value) => {
|
|
2297
|
+
return /^[a-z-]+\(/.test(value);
|
|
2298
|
+
};
|
|
2290
2299
|
const normalizeNumber = (value, { unit, propertyName, preferedType }) => {
|
|
2291
2300
|
if (typeof value === "string") {
|
|
2301
|
+
// CSS variables and CSS functions like calc() must be passed through as-is
|
|
2302
|
+
if (isCSSFunction(value)) {
|
|
2303
|
+
return value;
|
|
2304
|
+
}
|
|
2292
2305
|
// Keep strings as-is (including %, em, rem, auto, none, etc.)
|
|
2293
2306
|
if (preferedType === "string") {
|
|
2294
2307
|
if (unit && isUnitless(value) && !unitlessKeywordSet.has(value)) {
|
|
@@ -6325,23 +6338,52 @@ const getDragCoordinates = (
|
|
|
6325
6338
|
return [leftRelativeToScrollContainer, topRelativeToScrollContainer];
|
|
6326
6339
|
};
|
|
6327
6340
|
|
|
6328
|
-
const
|
|
6329
|
-
const
|
|
6341
|
+
const installImportMetaCssBuild = (importMeta) => {
|
|
6342
|
+
const IMPORT_META_CSS_BUILD = "jsenv_import_meta_css_build";
|
|
6343
|
+
|
|
6344
|
+
if (importMeta.css === IMPORT_META_CSS_BUILD) {
|
|
6345
|
+
return;
|
|
6346
|
+
}
|
|
6347
|
+
|
|
6348
|
+
const stylesheetMap = new Map();
|
|
6349
|
+
const adopt = (url, value) => {
|
|
6350
|
+
const stylesheet = new CSSStyleSheet({ baseUrl: importMeta.url });
|
|
6351
|
+
stylesheet.replaceSync(value);
|
|
6352
|
+
stylesheetMap.set(url, stylesheet);
|
|
6353
|
+
document.adoptedStyleSheets = [...document.adoptedStyleSheets, stylesheet];
|
|
6354
|
+
};
|
|
6355
|
+
const update = (url, value) => {
|
|
6356
|
+
stylesheetMap.get(url).replaceSync(value);
|
|
6357
|
+
};
|
|
6358
|
+
const remove = (url) => {
|
|
6359
|
+
const stylesheet = stylesheetMap.get(url);
|
|
6360
|
+
document.adoptedStyleSheets = document.adoptedStyleSheets.filter(
|
|
6361
|
+
(s) => s !== stylesheet,
|
|
6362
|
+
);
|
|
6363
|
+
stylesheetMap.delete(url);
|
|
6364
|
+
};
|
|
6330
6365
|
|
|
6331
|
-
|
|
6332
|
-
// eslint-disable-next-line accessor-pairs
|
|
6366
|
+
const currentCssSourceMap = new Map();
|
|
6333
6367
|
Object.defineProperty(importMeta, "css", {
|
|
6334
6368
|
configurable: true,
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6369
|
+
get() {
|
|
6370
|
+
return IMPORT_META_CSS_BUILD;
|
|
6371
|
+
},
|
|
6372
|
+
set([value, url]) {
|
|
6373
|
+
if (value === undefined) {
|
|
6374
|
+
if (stylesheetMap.has(url)) {
|
|
6375
|
+
remove(url);
|
|
6376
|
+
currentCssSourceMap.delete(url);
|
|
6377
|
+
}
|
|
6378
|
+
return;
|
|
6379
|
+
}
|
|
6380
|
+
if (!stylesheetMap.has(url)) {
|
|
6381
|
+
adopt(url, value);
|
|
6382
|
+
currentCssSourceMap.set(url, value);
|
|
6383
|
+
} else if (currentCssSourceMap.get(url) !== value) {
|
|
6384
|
+
update(url, value);
|
|
6385
|
+
currentCssSourceMap.set(url, value);
|
|
6386
|
+
}
|
|
6345
6387
|
},
|
|
6346
6388
|
});
|
|
6347
6389
|
};
|
|
@@ -6505,7 +6547,16 @@ const isolateInteractions = (elements) => {
|
|
|
6505
6547
|
};
|
|
6506
6548
|
};
|
|
6507
6549
|
|
|
6508
|
-
|
|
6550
|
+
installImportMetaCssBuild(import.meta);/**
|
|
6551
|
+
* Drag Gesture System
|
|
6552
|
+
*
|
|
6553
|
+
* TODO: rename moveX/moveY en juste x/y
|
|
6554
|
+
* puisque move c'est perturbant sachant que c'est drag + scroll
|
|
6555
|
+
* et que drag c'est juste la partie mouvement de la souris
|
|
6556
|
+
*
|
|
6557
|
+
* donc juste x/y ca seras surement mieux
|
|
6558
|
+
*
|
|
6559
|
+
*/
|
|
6509
6560
|
const createDragGestureController = (options = {}) => {
|
|
6510
6561
|
const {
|
|
6511
6562
|
name,
|
|
@@ -6514,17 +6565,18 @@ const createDragGestureController = (options = {}) => {
|
|
|
6514
6565
|
onDrag,
|
|
6515
6566
|
onRelease,
|
|
6516
6567
|
threshold = 5,
|
|
6517
|
-
direction: defaultDirection = {
|
|
6568
|
+
direction: defaultDirection = {
|
|
6569
|
+
x: true,
|
|
6570
|
+
y: true
|
|
6571
|
+
},
|
|
6518
6572
|
documentInteractions = "auto",
|
|
6519
6573
|
backdrop = true,
|
|
6520
|
-
backdropZIndex = 999999
|
|
6574
|
+
backdropZIndex = 999999
|
|
6521
6575
|
} = options;
|
|
6522
|
-
|
|
6523
6576
|
const dragGestureController = {
|
|
6524
6577
|
grab: null,
|
|
6525
|
-
gravViaPointer: null
|
|
6578
|
+
gravViaPointer: null
|
|
6526
6579
|
};
|
|
6527
|
-
|
|
6528
6580
|
const grab = ({
|
|
6529
6581
|
element,
|
|
6530
6582
|
direction = defaultDirection,
|
|
@@ -6534,7 +6586,7 @@ const createDragGestureController = (options = {}) => {
|
|
|
6534
6586
|
cursor = "grabbing",
|
|
6535
6587
|
scrollContainer = document.documentElement,
|
|
6536
6588
|
layoutScrollableLeft: scrollableLeftAtGrab = 0,
|
|
6537
|
-
layoutScrollableTop: scrollableTopAtGrab = 0
|
|
6589
|
+
layoutScrollableTop: scrollableTopAtGrab = 0
|
|
6538
6590
|
} = {}) => {
|
|
6539
6591
|
if (!element) {
|
|
6540
6592
|
throw new Error("element is required");
|
|
@@ -6542,7 +6594,6 @@ const createDragGestureController = (options = {}) => {
|
|
|
6542
6594
|
if (!direction.x && !direction.y) {
|
|
6543
6595
|
return null;
|
|
6544
6596
|
}
|
|
6545
|
-
|
|
6546
6597
|
const [publishBeforeDrag, addBeforeDragCallback] = createPubSub();
|
|
6547
6598
|
const [publishDrag, addDragCallback] = createPubSub();
|
|
6548
6599
|
const [publishRelease, addReleaseCallback] = createPubSub();
|
|
@@ -6552,13 +6603,15 @@ const createDragGestureController = (options = {}) => {
|
|
|
6552
6603
|
if (onRelease) {
|
|
6553
6604
|
addReleaseCallback(onRelease);
|
|
6554
6605
|
}
|
|
6555
|
-
|
|
6556
6606
|
const scrollLeftAtGrab = scrollContainer.scrollLeft;
|
|
6557
6607
|
const scrollTopAtGrab = scrollContainer.scrollTop;
|
|
6558
6608
|
const leftAtGrab = scrollLeftAtGrab + scrollableLeftAtGrab;
|
|
6559
6609
|
const topAtGrab = scrollTopAtGrab + scrollableTopAtGrab;
|
|
6560
6610
|
const createLayout = (x, y) => {
|
|
6561
|
-
const {
|
|
6611
|
+
const {
|
|
6612
|
+
scrollLeft,
|
|
6613
|
+
scrollTop
|
|
6614
|
+
} = scrollContainer;
|
|
6562
6615
|
const left = scrollableLeftAtGrab + x;
|
|
6563
6616
|
const top = scrollableTopAtGrab + y;
|
|
6564
6617
|
const scrollableLeft = left - scrollLeft;
|
|
@@ -6578,42 +6631,38 @@ const createDragGestureController = (options = {}) => {
|
|
|
6578
6631
|
top,
|
|
6579
6632
|
// Delta since grab (number representing how much we dragged)
|
|
6580
6633
|
xDelta: left - leftAtGrab,
|
|
6581
|
-
yDelta: top - topAtGrab
|
|
6634
|
+
yDelta: top - topAtGrab
|
|
6582
6635
|
};
|
|
6583
6636
|
return layoutProps;
|
|
6584
6637
|
};
|
|
6585
|
-
|
|
6586
|
-
const grabLayout = createLayout(
|
|
6587
|
-
grabX + scrollContainer.scrollLeft,
|
|
6588
|
-
grabY + scrollContainer.scrollTop,
|
|
6589
|
-
);
|
|
6638
|
+
const grabLayout = createLayout(grabX + scrollContainer.scrollLeft, grabY + scrollContainer.scrollTop);
|
|
6590
6639
|
const gestureInfo = {
|
|
6591
6640
|
name,
|
|
6592
6641
|
direction,
|
|
6593
6642
|
started: !threshold,
|
|
6594
6643
|
status: "grabbed",
|
|
6595
|
-
|
|
6596
6644
|
element,
|
|
6597
6645
|
scrollContainer,
|
|
6598
|
-
grabX,
|
|
6599
|
-
|
|
6646
|
+
grabX,
|
|
6647
|
+
// x grab coordinate (excluding scroll)
|
|
6648
|
+
grabY,
|
|
6649
|
+
// y grab coordinate (excluding scroll)
|
|
6600
6650
|
grabLayout,
|
|
6601
6651
|
leftAtGrab,
|
|
6602
6652
|
topAtGrab,
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
dragY: grabY,
|
|
6653
|
+
dragX: grabX,
|
|
6654
|
+
// coordinate of the last drag (excluding scroll of the scrollContainer)
|
|
6655
|
+
dragY: grabY,
|
|
6656
|
+
// coordinate of the last drag (excluding scroll of the scrollContainer)
|
|
6606
6657
|
layout: grabLayout,
|
|
6607
|
-
|
|
6608
6658
|
isGoingUp: undefined,
|
|
6609
6659
|
isGoingDown: undefined,
|
|
6610
6660
|
isGoingLeft: undefined,
|
|
6611
6661
|
isGoingRight: undefined,
|
|
6612
|
-
|
|
6613
6662
|
// metadata about interaction sources
|
|
6614
6663
|
grabEvent: event,
|
|
6615
6664
|
dragEvent: null,
|
|
6616
|
-
releaseEvent: null
|
|
6665
|
+
releaseEvent: null
|
|
6617
6666
|
};
|
|
6618
6667
|
definePropertyAsReadOnly(gestureInfo, "name");
|
|
6619
6668
|
definePropertyAsReadOnly(gestureInfo, "direction");
|
|
@@ -6624,7 +6673,6 @@ const createDragGestureController = (options = {}) => {
|
|
|
6624
6673
|
definePropertyAsReadOnly(gestureInfo, "leftAtGrab");
|
|
6625
6674
|
definePropertyAsReadOnly(gestureInfo, "topAtGrab");
|
|
6626
6675
|
definePropertyAsReadOnly(gestureInfo, "grabEvent");
|
|
6627
|
-
|
|
6628
6676
|
document_interactions: {
|
|
6629
6677
|
if (documentInteractions === "manual") {
|
|
6630
6678
|
break document_interactions;
|
|
@@ -6637,23 +6685,18 @@ const createDragGestureController = (options = {}) => {
|
|
|
6637
6685
|
2. Break the visual feedback (inconsistent cursors, hover states)
|
|
6638
6686
|
3. Cause unwanted scrolling (keyboard shortcuts, wheel events in restricted directions)
|
|
6639
6687
|
4. Create accessibility issues (focus jumping, screen reader confusion)
|
|
6640
|
-
|
|
6641
|
-
STRATEGY: Create a controlled interaction environment by:
|
|
6688
|
+
STRATEGY: Create a controlled interaction environment by:
|
|
6642
6689
|
1. VISUAL CONTROL: Use a backdrop to unify cursor appearance and block pointer events
|
|
6643
6690
|
2. INTERACTION ISOLATION: Make non-dragged elements inert to prevent interference
|
|
6644
6691
|
3. FOCUS MANAGEMENT: Control focus location and prevent focus changes during drag
|
|
6645
6692
|
4. SELECTIVE SCROLLING: Allow scrolling only in directions supported by the drag gesture
|
|
6646
|
-
|
|
6647
|
-
IMPLEMENTATION:
|
|
6693
|
+
IMPLEMENTATION:
|
|
6648
6694
|
*/
|
|
6649
6695
|
|
|
6650
6696
|
// 1. INTERACTION ISOLATION: Make everything except the dragged element inert
|
|
6651
6697
|
// This prevents keyboard events, pointer interactions, and screen reader navigation
|
|
6652
6698
|
// on non-relevant elements during the drag operation
|
|
6653
|
-
const cleanupInert = isolateInteractions([
|
|
6654
|
-
element,
|
|
6655
|
-
...Array.from(document.querySelectorAll("[data-droppable]")),
|
|
6656
|
-
]);
|
|
6699
|
+
const cleanupInert = isolateInteractions([element, ...Array.from(document.querySelectorAll("[data-droppable]"))]);
|
|
6657
6700
|
addReleaseCallback(() => {
|
|
6658
6701
|
cleanupInert();
|
|
6659
6702
|
});
|
|
@@ -6670,14 +6713,14 @@ const createDragGestureController = (options = {}) => {
|
|
|
6670
6713
|
// Handle wheel events on backdrop for directionally-constrained drag gestures
|
|
6671
6714
|
// (e.g., table column resize should only allow horizontal scrolling)
|
|
6672
6715
|
if (!direction.x || !direction.y) {
|
|
6673
|
-
backdropElement.onwheel =
|
|
6716
|
+
backdropElement.onwheel = e => {
|
|
6674
6717
|
e.preventDefault();
|
|
6675
6718
|
const scrollX = direction.x ? e.deltaX : 0;
|
|
6676
6719
|
const scrollY = direction.y ? e.deltaY : 0;
|
|
6677
6720
|
scrollContainer.scrollBy({
|
|
6678
6721
|
left: scrollX,
|
|
6679
6722
|
top: scrollY,
|
|
6680
|
-
behavior: "auto"
|
|
6723
|
+
behavior: "auto"
|
|
6681
6724
|
});
|
|
6682
6725
|
};
|
|
6683
6726
|
}
|
|
@@ -6688,23 +6731,25 @@ const createDragGestureController = (options = {}) => {
|
|
|
6688
6731
|
}
|
|
6689
6732
|
|
|
6690
6733
|
// 3. FOCUS MANAGEMENT: Control and stabilize focus during drag
|
|
6691
|
-
const {
|
|
6734
|
+
const {
|
|
6735
|
+
activeElement
|
|
6736
|
+
} = document;
|
|
6692
6737
|
const focusableElement = findFocusable(element);
|
|
6693
6738
|
// Focus the dragged element (or document.body as fallback) to establish clear focus context
|
|
6694
6739
|
// This also ensure any keydown event listened by the currently focused element
|
|
6695
6740
|
// won't be available during drag
|
|
6696
6741
|
const elementToFocus = focusableElement || document.body;
|
|
6697
6742
|
elementToFocus.focus({
|
|
6698
|
-
preventScroll: true
|
|
6743
|
+
preventScroll: true
|
|
6699
6744
|
});
|
|
6700
6745
|
addReleaseCallback(() => {
|
|
6701
6746
|
// Restore original focus on release
|
|
6702
6747
|
activeElement.focus({
|
|
6703
|
-
preventScroll: true
|
|
6748
|
+
preventScroll: true
|
|
6704
6749
|
});
|
|
6705
6750
|
});
|
|
6706
6751
|
// Prevent Tab navigation entirely (focus should stay stable)
|
|
6707
|
-
const onkeydown =
|
|
6752
|
+
const onkeydown = e => {
|
|
6708
6753
|
if (e.key === "Tab") {
|
|
6709
6754
|
e.preventDefault();
|
|
6710
6755
|
return;
|
|
@@ -6717,27 +6762,16 @@ const createDragGestureController = (options = {}) => {
|
|
|
6717
6762
|
|
|
6718
6763
|
// 4. SELECTIVE SCROLLING: Allow keyboard scrolling only in supported directions
|
|
6719
6764
|
{
|
|
6720
|
-
const onDocumentKeydown =
|
|
6765
|
+
const onDocumentKeydown = keyboardEvent => {
|
|
6721
6766
|
// Vertical scrolling keys - prevent if vertical movement not supported
|
|
6722
|
-
if (
|
|
6723
|
-
keyboardEvent.key === "ArrowUp" ||
|
|
6724
|
-
keyboardEvent.key === "ArrowDown" ||
|
|
6725
|
-
keyboardEvent.key === " " ||
|
|
6726
|
-
keyboardEvent.key === "PageUp" ||
|
|
6727
|
-
keyboardEvent.key === "PageDown" ||
|
|
6728
|
-
keyboardEvent.key === "Home" ||
|
|
6729
|
-
keyboardEvent.key === "End"
|
|
6730
|
-
) {
|
|
6767
|
+
if (keyboardEvent.key === "ArrowUp" || keyboardEvent.key === "ArrowDown" || keyboardEvent.key === " " || keyboardEvent.key === "PageUp" || keyboardEvent.key === "PageDown" || keyboardEvent.key === "Home" || keyboardEvent.key === "End") {
|
|
6731
6768
|
if (!direction.y) {
|
|
6732
6769
|
keyboardEvent.preventDefault();
|
|
6733
6770
|
}
|
|
6734
6771
|
return;
|
|
6735
6772
|
}
|
|
6736
6773
|
// Horizontal scrolling keys - prevent if horizontal movement not supported
|
|
6737
|
-
if (
|
|
6738
|
-
keyboardEvent.key === "ArrowLeft" ||
|
|
6739
|
-
keyboardEvent.key === "ArrowRight"
|
|
6740
|
-
) {
|
|
6774
|
+
if (keyboardEvent.key === "ArrowLeft" || keyboardEvent.key === "ArrowRight") {
|
|
6741
6775
|
if (!direction.x) {
|
|
6742
6776
|
keyboardEvent.preventDefault();
|
|
6743
6777
|
}
|
|
@@ -6754,36 +6788,38 @@ const createDragGestureController = (options = {}) => {
|
|
|
6754
6788
|
// Set up scroll event handling to adjust drag position when scrolling occurs
|
|
6755
6789
|
{
|
|
6756
6790
|
let isHandlingScroll = false;
|
|
6757
|
-
const handleScroll =
|
|
6791
|
+
const handleScroll = scrollEvent => {
|
|
6758
6792
|
if (isHandlingScroll) {
|
|
6759
6793
|
return;
|
|
6760
6794
|
}
|
|
6761
6795
|
isHandlingScroll = true;
|
|
6762
|
-
drag(gestureInfo.dragX, gestureInfo.dragY, {
|
|
6796
|
+
drag(gestureInfo.dragX, gestureInfo.dragY, {
|
|
6797
|
+
event: scrollEvent
|
|
6798
|
+
});
|
|
6763
6799
|
isHandlingScroll = false;
|
|
6764
6800
|
};
|
|
6765
|
-
const scrollEventReceiver =
|
|
6766
|
-
scrollContainer === document.documentElement
|
|
6767
|
-
? document
|
|
6768
|
-
: scrollContainer;
|
|
6801
|
+
const scrollEventReceiver = scrollContainer === document.documentElement ? document : scrollContainer;
|
|
6769
6802
|
scrollEventReceiver.addEventListener("scroll", handleScroll, {
|
|
6770
|
-
passive: true
|
|
6803
|
+
passive: true
|
|
6771
6804
|
});
|
|
6772
6805
|
addReleaseCallback(() => {
|
|
6773
6806
|
scrollEventReceiver.removeEventListener("scroll", handleScroll, {
|
|
6774
|
-
passive: true
|
|
6807
|
+
passive: true
|
|
6775
6808
|
});
|
|
6776
6809
|
});
|
|
6777
6810
|
}
|
|
6778
|
-
|
|
6779
6811
|
const determineDragData = ({
|
|
6780
6812
|
dragX,
|
|
6781
6813
|
dragY,
|
|
6782
6814
|
dragEvent,
|
|
6783
|
-
isRelease = false
|
|
6815
|
+
isRelease = false
|
|
6784
6816
|
}) => {
|
|
6785
6817
|
// === ÉTAT INITIAL (au moment du grab) ===
|
|
6786
|
-
const {
|
|
6818
|
+
const {
|
|
6819
|
+
grabX,
|
|
6820
|
+
grabY,
|
|
6821
|
+
grabLayout
|
|
6822
|
+
} = gestureInfo;
|
|
6787
6823
|
// === CE QUI EST DEMANDÉ (où on veut aller) ===
|
|
6788
6824
|
// Calcul de la direction basé sur le mouvement précédent
|
|
6789
6825
|
// (ne tient pas compte du mouvement final une fois les contraintes appliquées)
|
|
@@ -6795,56 +6831,38 @@ const createDragGestureController = (options = {}) => {
|
|
|
6795
6831
|
const isGoingRight = dragX > currentDragX;
|
|
6796
6832
|
const isGoingUp = dragY < currentDragY;
|
|
6797
6833
|
const isGoingDown = dragY > currentDragY;
|
|
6798
|
-
|
|
6799
|
-
const
|
|
6800
|
-
? scrollContainer.scrollLeft + (dragX - grabX)
|
|
6801
|
-
: grabLayout.scrollLeft;
|
|
6802
|
-
const layoutYRequested = direction.y
|
|
6803
|
-
? scrollContainer.scrollTop + (dragY - grabY)
|
|
6804
|
-
: grabLayout.scrollTop;
|
|
6834
|
+
const layoutXRequested = direction.x ? scrollContainer.scrollLeft + (dragX - grabX) : grabLayout.scrollLeft;
|
|
6835
|
+
const layoutYRequested = direction.y ? scrollContainer.scrollTop + (dragY - grabY) : grabLayout.scrollTop;
|
|
6805
6836
|
const layoutRequested = createLayout(layoutXRequested, layoutYRequested);
|
|
6806
6837
|
const currentLayout = gestureInfo.layout;
|
|
6807
6838
|
let layout;
|
|
6808
|
-
if (
|
|
6809
|
-
layoutRequested.x === currentLayout.x &&
|
|
6810
|
-
layoutRequested.y === currentLayout.y
|
|
6811
|
-
) {
|
|
6839
|
+
if (layoutRequested.x === currentLayout.x && layoutRequested.y === currentLayout.y) {
|
|
6812
6840
|
layout = currentLayout;
|
|
6813
6841
|
} else {
|
|
6814
6842
|
// === APPLICATION DES CONTRAINTES ===
|
|
6815
6843
|
let layoutConstrained = layoutRequested;
|
|
6816
6844
|
const limitLayout = (left, top) => {
|
|
6817
|
-
layoutConstrained = createLayout(
|
|
6818
|
-
left === undefined
|
|
6819
|
-
? layoutConstrained.x
|
|
6820
|
-
: left - scrollableLeftAtGrab,
|
|
6821
|
-
top === undefined ? layoutConstrained.y : top - scrollableTopAtGrab,
|
|
6822
|
-
);
|
|
6845
|
+
layoutConstrained = createLayout(left === undefined ? layoutConstrained.x : left - scrollableLeftAtGrab, top === undefined ? layoutConstrained.y : top - scrollableTopAtGrab);
|
|
6823
6846
|
};
|
|
6824
|
-
|
|
6825
6847
|
publishBeforeDrag(layoutRequested, currentLayout, limitLayout, {
|
|
6826
6848
|
dragEvent,
|
|
6827
|
-
isRelease
|
|
6849
|
+
isRelease
|
|
6828
6850
|
});
|
|
6829
6851
|
// === ÉTAT FINAL ===
|
|
6830
6852
|
layout = layoutConstrained;
|
|
6831
6853
|
}
|
|
6832
|
-
|
|
6833
6854
|
const dragData = {
|
|
6834
6855
|
dragX,
|
|
6835
6856
|
dragY,
|
|
6836
6857
|
layout,
|
|
6837
|
-
|
|
6838
6858
|
isGoingLeft,
|
|
6839
6859
|
isGoingRight,
|
|
6840
6860
|
isGoingUp,
|
|
6841
6861
|
isGoingDown,
|
|
6842
|
-
|
|
6843
6862
|
status: isRelease ? "released" : "dragging",
|
|
6844
6863
|
dragEvent: isRelease ? gestureInfo.dragEvent : dragEvent,
|
|
6845
|
-
releaseEvent: isRelease ? dragEvent : null
|
|
6864
|
+
releaseEvent: isRelease ? dragEvent : null
|
|
6846
6865
|
};
|
|
6847
|
-
|
|
6848
6866
|
if (isRelease) {
|
|
6849
6867
|
return dragData;
|
|
6850
6868
|
}
|
|
@@ -6869,18 +6887,19 @@ const createDragGestureController = (options = {}) => {
|
|
|
6869
6887
|
}
|
|
6870
6888
|
return dragData;
|
|
6871
6889
|
};
|
|
6872
|
-
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6890
|
+
const drag = (dragX = gestureInfo.dragX,
|
|
6891
|
+
// Scroll container relative X coordinate
|
|
6892
|
+
dragY = gestureInfo.dragY,
|
|
6893
|
+
// Scroll container relative Y coordinate
|
|
6894
|
+
{
|
|
6895
|
+
event = new CustomEvent("programmatic"),
|
|
6896
|
+
isRelease = false
|
|
6897
|
+
} = {}) => {
|
|
6879
6898
|
const dragData = determineDragData({
|
|
6880
6899
|
dragX,
|
|
6881
6900
|
dragY,
|
|
6882
6901
|
dragEvent: event,
|
|
6883
|
-
isRelease
|
|
6902
|
+
isRelease
|
|
6884
6903
|
});
|
|
6885
6904
|
const startedPrevious = gestureInfo.started;
|
|
6886
6905
|
const layoutPrevious = gestureInfo.layout;
|
|
@@ -6890,25 +6909,24 @@ const createDragGestureController = (options = {}) => {
|
|
|
6890
6909
|
onDragStart?.(gestureInfo);
|
|
6891
6910
|
}
|
|
6892
6911
|
const someLayoutChange = gestureInfo.layout !== layoutPrevious;
|
|
6893
|
-
publishDrag(
|
|
6894
|
-
|
|
6895
|
-
|
|
6896
|
-
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
someLayoutChange,
|
|
6900
|
-
);
|
|
6912
|
+
publishDrag(gestureInfo,
|
|
6913
|
+
// we still publish drag event even when unchanged
|
|
6914
|
+
// because UI might need to adjust when document scrolls
|
|
6915
|
+
// even if nothing truly changes visually the element
|
|
6916
|
+
// can decide to stick to the scroll for example
|
|
6917
|
+
someLayoutChange);
|
|
6901
6918
|
};
|
|
6902
|
-
|
|
6903
6919
|
const release = ({
|
|
6904
6920
|
event = new CustomEvent("programmatic"),
|
|
6905
6921
|
releaseX = gestureInfo.dragX,
|
|
6906
|
-
releaseY = gestureInfo.dragY
|
|
6922
|
+
releaseY = gestureInfo.dragY
|
|
6907
6923
|
} = {}) => {
|
|
6908
|
-
drag(releaseX, releaseY, {
|
|
6924
|
+
drag(releaseX, releaseY, {
|
|
6925
|
+
event,
|
|
6926
|
+
isRelease: true
|
|
6927
|
+
});
|
|
6909
6928
|
publishRelease(gestureInfo);
|
|
6910
6929
|
};
|
|
6911
|
-
|
|
6912
6930
|
onGrab?.(gestureInfo);
|
|
6913
6931
|
const dragGesture = {
|
|
6914
6932
|
gestureInfo,
|
|
@@ -6916,12 +6934,11 @@ const createDragGestureController = (options = {}) => {
|
|
|
6916
6934
|
addDragCallback,
|
|
6917
6935
|
addReleaseCallback,
|
|
6918
6936
|
drag,
|
|
6919
|
-
release
|
|
6937
|
+
release
|
|
6920
6938
|
};
|
|
6921
6939
|
return dragGesture;
|
|
6922
6940
|
};
|
|
6923
6941
|
dragGestureController.grab = grab;
|
|
6924
|
-
|
|
6925
6942
|
const initDragByPointer = (grabEvent, dragOptions, initializer) => {
|
|
6926
6943
|
if (grabEvent.button !== undefined && grabEvent.button !== 0) {
|
|
6927
6944
|
return null;
|
|
@@ -6931,8 +6948,11 @@ const createDragGestureController = (options = {}) => {
|
|
|
6931
6948
|
// target is a text node
|
|
6932
6949
|
return null;
|
|
6933
6950
|
}
|
|
6934
|
-
const mouseEventCoords =
|
|
6935
|
-
const {
|
|
6951
|
+
const mouseEventCoords = mouseEvent => {
|
|
6952
|
+
const {
|
|
6953
|
+
clientX,
|
|
6954
|
+
clientY
|
|
6955
|
+
} = mouseEvent;
|
|
6936
6956
|
return [clientX, clientY];
|
|
6937
6957
|
};
|
|
6938
6958
|
const [grabX, grabY] = mouseEventCoords(grabEvent);
|
|
@@ -6940,37 +6960,39 @@ const createDragGestureController = (options = {}) => {
|
|
|
6940
6960
|
grabX,
|
|
6941
6961
|
grabY,
|
|
6942
6962
|
event: grabEvent,
|
|
6943
|
-
...dragOptions
|
|
6963
|
+
...dragOptions
|
|
6944
6964
|
});
|
|
6945
|
-
const dragViaPointer =
|
|
6965
|
+
const dragViaPointer = dragEvent => {
|
|
6946
6966
|
const [mouseDragX, mouseDragY] = mouseEventCoords(dragEvent);
|
|
6947
6967
|
dragGesture.drag(mouseDragX, mouseDragY, {
|
|
6948
|
-
event: dragEvent
|
|
6968
|
+
event: dragEvent
|
|
6949
6969
|
});
|
|
6950
6970
|
};
|
|
6951
|
-
const releaseViaPointer =
|
|
6971
|
+
const releaseViaPointer = mouseupEvent => {
|
|
6952
6972
|
const [mouseReleaseX, mouseReleaseY] = mouseEventCoords(mouseupEvent);
|
|
6953
6973
|
dragGesture.release({
|
|
6954
6974
|
event: mouseupEvent,
|
|
6955
6975
|
releaseX: mouseReleaseX,
|
|
6956
|
-
releaseY: mouseReleaseY
|
|
6976
|
+
releaseY: mouseReleaseY
|
|
6957
6977
|
});
|
|
6958
6978
|
};
|
|
6959
6979
|
dragGesture.dragViaPointer = dragViaPointer;
|
|
6960
6980
|
dragGesture.releaseViaPointer = releaseViaPointer;
|
|
6961
6981
|
const cleanup = initializer({
|
|
6962
6982
|
onMove: dragViaPointer,
|
|
6963
|
-
onRelease: releaseViaPointer
|
|
6983
|
+
onRelease: releaseViaPointer
|
|
6964
6984
|
});
|
|
6965
6985
|
dragGesture.addReleaseCallback(() => {
|
|
6966
6986
|
cleanup();
|
|
6967
6987
|
});
|
|
6968
6988
|
return dragGesture;
|
|
6969
6989
|
};
|
|
6970
|
-
|
|
6971
6990
|
const grabViaPointer = (grabEvent, options) => {
|
|
6972
6991
|
if (grabEvent.type === "pointerdown") {
|
|
6973
|
-
return initDragByPointer(grabEvent, options, ({
|
|
6992
|
+
return initDragByPointer(grabEvent, options, ({
|
|
6993
|
+
onMove,
|
|
6994
|
+
onRelease
|
|
6995
|
+
}) => {
|
|
6974
6996
|
const target = grabEvent.target;
|
|
6975
6997
|
target.setPointerCapture(grabEvent.pointerId);
|
|
6976
6998
|
target.addEventListener("lostpointercapture", onRelease);
|
|
@@ -6987,11 +7009,12 @@ const createDragGestureController = (options = {}) => {
|
|
|
6987
7009
|
});
|
|
6988
7010
|
}
|
|
6989
7011
|
if (grabEvent.type === "mousedown") {
|
|
6990
|
-
console.warn(
|
|
6991
|
-
|
|
6992
|
-
|
|
6993
|
-
|
|
6994
|
-
|
|
7012
|
+
console.warn(`Received "mousedown" event, "pointerdown" events are recommended to perform drag gestures.`);
|
|
7013
|
+
return initDragByPointer(grabEvent, options, ({
|
|
7014
|
+
onMove,
|
|
7015
|
+
onRelease
|
|
7016
|
+
}) => {
|
|
7017
|
+
const onPointerUp = pointerEvent => {
|
|
6995
7018
|
// <button disabled> for example does not emit mouseup if we release mouse over it
|
|
6996
7019
|
// -> we add "pointerup" to catch mouseup occuring on disabled element
|
|
6997
7020
|
if (pointerEvent.pointerType === "mouse") {
|
|
@@ -7008,54 +7031,43 @@ const createDragGestureController = (options = {}) => {
|
|
|
7008
7031
|
};
|
|
7009
7032
|
});
|
|
7010
7033
|
}
|
|
7011
|
-
throw new Error(
|
|
7012
|
-
`Unsupported "${grabEvent.type}" evenet passed to grabViaPointer. "pointerdown" was expected.`,
|
|
7013
|
-
);
|
|
7034
|
+
throw new Error(`Unsupported "${grabEvent.type}" evenet passed to grabViaPointer. "pointerdown" was expected.`);
|
|
7014
7035
|
};
|
|
7015
7036
|
dragGestureController.grabViaPointer = grabViaPointer;
|
|
7016
|
-
|
|
7017
7037
|
return dragGestureController;
|
|
7018
7038
|
};
|
|
7019
|
-
|
|
7020
|
-
const dragAfterThreshold = (
|
|
7021
|
-
grabEvent,
|
|
7022
|
-
dragGestureInitializer,
|
|
7023
|
-
threshold,
|
|
7024
|
-
) => {
|
|
7039
|
+
const dragAfterThreshold = (grabEvent, dragGestureInitializer, threshold) => {
|
|
7025
7040
|
const significantDragGestureController = createDragGestureController({
|
|
7026
7041
|
threshold,
|
|
7027
7042
|
// allow interaction for this intermediate gesture:
|
|
7028
7043
|
// user should still be able to scroll or interact with the document
|
|
7029
7044
|
// only once the gesture is significant we take control
|
|
7030
7045
|
documentInteractions: "manual",
|
|
7031
|
-
onDragStart:
|
|
7046
|
+
onDragStart: gestureInfo => {
|
|
7032
7047
|
significantDragGesture.release(); // kill that gesture
|
|
7033
7048
|
const dragGesture = dragGestureInitializer();
|
|
7034
7049
|
dragGesture.dragViaPointer(gestureInfo.dragEvent);
|
|
7035
|
-
}
|
|
7050
|
+
}
|
|
7051
|
+
});
|
|
7052
|
+
const significantDragGesture = significantDragGestureController.grabViaPointer(grabEvent, {
|
|
7053
|
+
element: grabEvent.target
|
|
7036
7054
|
});
|
|
7037
|
-
const significantDragGesture =
|
|
7038
|
-
significantDragGestureController.grabViaPointer(grabEvent, {
|
|
7039
|
-
element: grabEvent.target,
|
|
7040
|
-
});
|
|
7041
7055
|
};
|
|
7042
|
-
|
|
7043
7056
|
const definePropertyAsReadOnly = (object, propertyName) => {
|
|
7044
7057
|
Object.defineProperty(object, propertyName, {
|
|
7045
7058
|
writable: false,
|
|
7046
|
-
value: object[propertyName]
|
|
7059
|
+
value: object[propertyName]
|
|
7047
7060
|
});
|
|
7048
7061
|
};
|
|
7049
|
-
|
|
7050
|
-
import.meta.css = /* css */ `
|
|
7062
|
+
import.meta.css = [/* css */`
|
|
7051
7063
|
.navi_drag_gesture_backdrop {
|
|
7052
7064
|
position: fixed;
|
|
7053
7065
|
inset: 0;
|
|
7054
7066
|
user-select: none;
|
|
7055
7067
|
}
|
|
7056
|
-
|
|
7068
|
+
`, "@jsenv/dom/src/interaction/drag/drag_gesture.js"];
|
|
7057
7069
|
|
|
7058
|
-
|
|
7070
|
+
installImportMetaCssBuild(import.meta);const setupConstraintFeedbackLine = () => {
|
|
7059
7071
|
const constraintFeedbackLine = createConstraintFeedbackLine();
|
|
7060
7072
|
|
|
7061
7073
|
// Track last known mouse position for constraint feedback line during scroll
|
|
@@ -7063,18 +7075,17 @@ installImportMetaCss(import.meta);const setupConstraintFeedbackLine = () => {
|
|
|
7063
7075
|
let lastMouseY = null;
|
|
7064
7076
|
|
|
7065
7077
|
// Internal function to update constraint feedback line
|
|
7066
|
-
const onDrag =
|
|
7067
|
-
const {
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
) {
|
|
7078
|
+
const onDrag = gestureInfo => {
|
|
7079
|
+
const {
|
|
7080
|
+
grabEvent,
|
|
7081
|
+
dragEvent
|
|
7082
|
+
} = gestureInfo;
|
|
7083
|
+
if (grabEvent.type === "programmatic" ||
|
|
7084
|
+
// dragEvent can be null when only mousedown without yet any mousemove
|
|
7085
|
+
!dragEvent || dragEvent.type === "programmatic") {
|
|
7074
7086
|
// programmatic drag
|
|
7075
7087
|
return;
|
|
7076
7088
|
}
|
|
7077
|
-
|
|
7078
7089
|
const mouseX = dragEvent.clientX;
|
|
7079
7090
|
const mouseY = dragEvent.clientY;
|
|
7080
7091
|
// Use last known position if current position not available (e.g., during scroll)
|
|
@@ -7087,7 +7098,6 @@ installImportMetaCss(import.meta);const setupConstraintFeedbackLine = () => {
|
|
|
7087
7098
|
// Store current mouse position for potential use during scroll
|
|
7088
7099
|
lastMouseX = mouseX;
|
|
7089
7100
|
lastMouseY = mouseY;
|
|
7090
|
-
|
|
7091
7101
|
const grabClientX = grabEvent.clientX;
|
|
7092
7102
|
const grabClientY = grabEvent.clientY;
|
|
7093
7103
|
|
|
@@ -7116,25 +7126,21 @@ installImportMetaCss(import.meta);const setupConstraintFeedbackLine = () => {
|
|
|
7116
7126
|
constraintFeedbackLine.style.opacity = `${maxOpacity * opacityFactor}`;
|
|
7117
7127
|
constraintFeedbackLine.setAttribute("data-visible", "");
|
|
7118
7128
|
};
|
|
7119
|
-
|
|
7120
7129
|
return {
|
|
7121
7130
|
onDrag,
|
|
7122
7131
|
onRelease: () => {
|
|
7123
7132
|
constraintFeedbackLine.remove();
|
|
7124
|
-
}
|
|
7133
|
+
}
|
|
7125
7134
|
};
|
|
7126
7135
|
};
|
|
7127
|
-
|
|
7128
7136
|
const createConstraintFeedbackLine = () => {
|
|
7129
7137
|
const line = document.createElement("div");
|
|
7130
7138
|
line.className = "navi_constraint_feedback_line";
|
|
7131
|
-
line.title =
|
|
7132
|
-
"Constraint feedback - shows distance between mouse and moving grab point";
|
|
7139
|
+
line.title = "Constraint feedback - shows distance between mouse and moving grab point";
|
|
7133
7140
|
document.body.appendChild(line);
|
|
7134
7141
|
return line;
|
|
7135
7142
|
};
|
|
7136
|
-
|
|
7137
|
-
import.meta.css = /* css */ `
|
|
7143
|
+
import.meta.css = [/* css */`
|
|
7138
7144
|
.navi_constraint_feedback_line {
|
|
7139
7145
|
position: fixed;
|
|
7140
7146
|
z-index: 9998;
|
|
@@ -7148,16 +7154,17 @@ import.meta.css = /* css */ `
|
|
|
7148
7154
|
.navi_constraint_feedback_line[data-visible] {
|
|
7149
7155
|
visibility: visible;
|
|
7150
7156
|
}
|
|
7151
|
-
|
|
7152
|
-
|
|
7153
|
-
installImportMetaCss(import.meta);const MARKER_SIZE = 12;
|
|
7157
|
+
`, "@jsenv/dom/src/interaction/drag/constraint_feedback_line.js"];
|
|
7154
7158
|
|
|
7159
|
+
installImportMetaCssBuild(import.meta);// Keep visual markers (debug markers, obstacle markers, constraint feedback line) in DOM after drag ends
|
|
7160
|
+
const MARKER_SIZE = 12;
|
|
7155
7161
|
let currentDebugMarkers = [];
|
|
7156
7162
|
let currentConstraintMarkers = [];
|
|
7157
7163
|
let currentReferenceElementMarker = null;
|
|
7158
7164
|
let currentElementMarker = null;
|
|
7159
|
-
|
|
7160
|
-
|
|
7165
|
+
const setupDragDebugMarkers = (dragGesture, {
|
|
7166
|
+
referenceElement
|
|
7167
|
+
}) => {
|
|
7161
7168
|
// Clean up any existing persistent markers from previous drag gestures
|
|
7162
7169
|
{
|
|
7163
7170
|
// Remove any existing markers from previous gestures
|
|
@@ -7166,29 +7173,27 @@ const setupDragDebugMarkers = (dragGesture, { referenceElement }) => {
|
|
|
7166
7173
|
container.innerHTML = ""; // Clear all markers efficiently
|
|
7167
7174
|
}
|
|
7168
7175
|
}
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
7176
|
+
const {
|
|
7177
|
+
direction,
|
|
7178
|
+
scrollContainer
|
|
7179
|
+
} = dragGesture.gestureInfo;
|
|
7172
7180
|
return {
|
|
7173
|
-
onConstraints: (
|
|
7174
|
-
|
|
7175
|
-
|
|
7176
|
-
|
|
7181
|
+
onConstraints: (constraints, {
|
|
7182
|
+
left,
|
|
7183
|
+
top,
|
|
7184
|
+
right,
|
|
7185
|
+
bottom,
|
|
7186
|
+
autoScrollArea
|
|
7187
|
+
}) => {
|
|
7177
7188
|
// Schedule removal of previous markers if they exist
|
|
7178
7189
|
const previousDebugMarkers = [...currentDebugMarkers];
|
|
7179
7190
|
const previousConstraintMarkers = [...currentConstraintMarkers];
|
|
7180
7191
|
const previousReferenceElementMarker = currentReferenceElementMarker;
|
|
7181
7192
|
const previousElementMarker = currentElementMarker;
|
|
7182
|
-
|
|
7183
|
-
if (
|
|
7184
|
-
previousDebugMarkers.length > 0 ||
|
|
7185
|
-
previousConstraintMarkers.length > 0 ||
|
|
7186
|
-
previousReferenceElementMarker ||
|
|
7187
|
-
previousElementMarker
|
|
7188
|
-
) {
|
|
7193
|
+
if (previousDebugMarkers.length > 0 || previousConstraintMarkers.length > 0 || previousReferenceElementMarker || previousElementMarker) {
|
|
7189
7194
|
setTimeout(() => {
|
|
7190
|
-
previousDebugMarkers.forEach(
|
|
7191
|
-
previousConstraintMarkers.forEach(
|
|
7195
|
+
previousDebugMarkers.forEach(marker => marker.remove());
|
|
7196
|
+
previousConstraintMarkers.forEach(marker => marker.remove());
|
|
7192
7197
|
if (previousReferenceElementMarker) {
|
|
7193
7198
|
previousReferenceElementMarker.remove();
|
|
7194
7199
|
}
|
|
@@ -7217,7 +7222,7 @@ const setupDragDebugMarkers = (dragGesture, { referenceElement }) => {
|
|
|
7217
7222
|
bottom,
|
|
7218
7223
|
scrollContainer,
|
|
7219
7224
|
label: elementLabel,
|
|
7220
|
-
color: elementColor
|
|
7225
|
+
color: elementColor
|
|
7221
7226
|
});
|
|
7222
7227
|
|
|
7223
7228
|
// Create reference element marker if reference element exists
|
|
@@ -7227,52 +7232,47 @@ const setupDragDebugMarkers = (dragGesture, { referenceElement }) => {
|
|
|
7227
7232
|
top,
|
|
7228
7233
|
right,
|
|
7229
7234
|
bottom,
|
|
7230
|
-
scrollContainer
|
|
7235
|
+
scrollContainer
|
|
7231
7236
|
});
|
|
7232
7237
|
}
|
|
7233
7238
|
|
|
7234
7239
|
// Collect all markers to be created, then merge duplicates
|
|
7235
7240
|
const markersToCreate = [];
|
|
7236
|
-
|
|
7237
7241
|
{
|
|
7238
7242
|
if (direction.x) {
|
|
7239
7243
|
markersToCreate.push({
|
|
7240
|
-
name: autoScrollArea.paddingLeft
|
|
7241
|
-
? `autoscroll.left + padding(${autoScrollArea.paddingLeft})`
|
|
7242
|
-
: "autoscroll.left",
|
|
7244
|
+
name: autoScrollArea.paddingLeft ? `autoscroll.left + padding(${autoScrollArea.paddingLeft})` : "autoscroll.left",
|
|
7243
7245
|
x: autoScrollArea.left,
|
|
7244
7246
|
y: 0,
|
|
7245
|
-
color: "0 128 0",
|
|
7246
|
-
|
|
7247
|
+
color: "0 128 0",
|
|
7248
|
+
// green
|
|
7249
|
+
side: "left"
|
|
7247
7250
|
});
|
|
7248
7251
|
markersToCreate.push({
|
|
7249
|
-
name: autoScrollArea.paddingRight
|
|
7250
|
-
? `autoscroll.right + padding(${autoScrollArea.paddingRight})`
|
|
7251
|
-
: "autoscroll.right",
|
|
7252
|
+
name: autoScrollArea.paddingRight ? `autoscroll.right + padding(${autoScrollArea.paddingRight})` : "autoscroll.right",
|
|
7252
7253
|
x: autoScrollArea.right,
|
|
7253
7254
|
y: 0,
|
|
7254
|
-
color: "0 128 0",
|
|
7255
|
-
|
|
7255
|
+
color: "0 128 0",
|
|
7256
|
+
// green
|
|
7257
|
+
side: "right"
|
|
7256
7258
|
});
|
|
7257
7259
|
}
|
|
7258
7260
|
if (direction.y) {
|
|
7259
7261
|
markersToCreate.push({
|
|
7260
|
-
name: autoScrollArea.paddingTop
|
|
7261
|
-
? `autoscroll.top + padding(${autoScrollArea.paddingTop})`
|
|
7262
|
-
: "autoscroll.top",
|
|
7262
|
+
name: autoScrollArea.paddingTop ? `autoscroll.top + padding(${autoScrollArea.paddingTop})` : "autoscroll.top",
|
|
7263
7263
|
x: 0,
|
|
7264
7264
|
y: autoScrollArea.top,
|
|
7265
|
-
color: "255 0 0",
|
|
7266
|
-
|
|
7265
|
+
color: "255 0 0",
|
|
7266
|
+
// red
|
|
7267
|
+
side: "top"
|
|
7267
7268
|
});
|
|
7268
7269
|
markersToCreate.push({
|
|
7269
|
-
name: autoScrollArea.paddingBottom
|
|
7270
|
-
? `autoscroll.bottom + padding(${autoScrollArea.paddingBottom})`
|
|
7271
|
-
: "autoscroll.bottom",
|
|
7270
|
+
name: autoScrollArea.paddingBottom ? `autoscroll.bottom + padding(${autoScrollArea.paddingBottom})` : "autoscroll.bottom",
|
|
7272
7271
|
x: 0,
|
|
7273
7272
|
y: autoScrollArea.bottom,
|
|
7274
|
-
color: "255 165 0",
|
|
7275
|
-
|
|
7273
|
+
color: "255 165 0",
|
|
7274
|
+
// orange
|
|
7275
|
+
side: "bottom"
|
|
7276
7276
|
});
|
|
7277
7277
|
}
|
|
7278
7278
|
}
|
|
@@ -7280,7 +7280,9 @@ const setupDragDebugMarkers = (dragGesture, { referenceElement }) => {
|
|
|
7280
7280
|
// Process each constraint individually to preserve names
|
|
7281
7281
|
for (const constraint of constraints) {
|
|
7282
7282
|
if (constraint.type === "bounds") {
|
|
7283
|
-
const {
|
|
7283
|
+
const {
|
|
7284
|
+
bounds
|
|
7285
|
+
} = constraint;
|
|
7284
7286
|
|
|
7285
7287
|
// Create individual markers for each bound with constraint name
|
|
7286
7288
|
if (direction.x) {
|
|
@@ -7289,8 +7291,9 @@ const setupDragDebugMarkers = (dragGesture, { referenceElement }) => {
|
|
|
7289
7291
|
name: `${constraint.name}.left`,
|
|
7290
7292
|
x: bounds.left,
|
|
7291
7293
|
y: 0,
|
|
7292
|
-
color: "128 0 128",
|
|
7293
|
-
|
|
7294
|
+
color: "128 0 128",
|
|
7295
|
+
// purple
|
|
7296
|
+
side: "left"
|
|
7294
7297
|
});
|
|
7295
7298
|
}
|
|
7296
7299
|
if (bounds.right !== undefined) {
|
|
@@ -7300,8 +7303,9 @@ const setupDragDebugMarkers = (dragGesture, { referenceElement }) => {
|
|
|
7300
7303
|
name: `${constraint.name}.right`,
|
|
7301
7304
|
x: bounds.right,
|
|
7302
7305
|
y: 0,
|
|
7303
|
-
color: "128 0 128",
|
|
7304
|
-
|
|
7306
|
+
color: "128 0 128",
|
|
7307
|
+
// purple
|
|
7308
|
+
side: "right"
|
|
7305
7309
|
});
|
|
7306
7310
|
}
|
|
7307
7311
|
}
|
|
@@ -7311,8 +7315,9 @@ const setupDragDebugMarkers = (dragGesture, { referenceElement }) => {
|
|
|
7311
7315
|
name: `${constraint.name}.top`,
|
|
7312
7316
|
x: 0,
|
|
7313
7317
|
y: bounds.top,
|
|
7314
|
-
color: "128 0 128",
|
|
7315
|
-
|
|
7318
|
+
color: "128 0 128",
|
|
7319
|
+
// purple
|
|
7320
|
+
side: "top"
|
|
7316
7321
|
});
|
|
7317
7322
|
}
|
|
7318
7323
|
if (bounds.bottom !== undefined) {
|
|
@@ -7322,37 +7327,28 @@ const setupDragDebugMarkers = (dragGesture, { referenceElement }) => {
|
|
|
7322
7327
|
name: `${constraint.name}.bottom`,
|
|
7323
7328
|
x: 0,
|
|
7324
7329
|
y: bounds.bottom,
|
|
7325
|
-
color: "128 0 128",
|
|
7326
|
-
|
|
7330
|
+
color: "128 0 128",
|
|
7331
|
+
// purple
|
|
7332
|
+
side: "bottom"
|
|
7327
7333
|
});
|
|
7328
7334
|
}
|
|
7329
7335
|
}
|
|
7330
7336
|
} else if (constraint.type === "obstacle") {
|
|
7331
|
-
const obstacleMarker = createObstacleMarker(
|
|
7332
|
-
constraint,
|
|
7333
|
-
scrollContainer,
|
|
7334
|
-
);
|
|
7337
|
+
const obstacleMarker = createObstacleMarker(constraint, scrollContainer);
|
|
7335
7338
|
currentConstraintMarkers.push(obstacleMarker);
|
|
7336
7339
|
}
|
|
7337
7340
|
}
|
|
7338
7341
|
|
|
7339
7342
|
// Create markers with merging for overlapping positions
|
|
7340
|
-
const createdMarkers = createMergedMarkers(
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
);
|
|
7344
|
-
currentDebugMarkers.push(
|
|
7345
|
-
...createdMarkers.filter((m) => m.type !== "constraint"),
|
|
7346
|
-
);
|
|
7347
|
-
currentConstraintMarkers.push(
|
|
7348
|
-
...createdMarkers.filter((m) => m.type === "constraint"),
|
|
7349
|
-
);
|
|
7343
|
+
const createdMarkers = createMergedMarkers(markersToCreate, scrollContainer);
|
|
7344
|
+
currentDebugMarkers.push(...createdMarkers.filter(m => m.type !== "constraint"));
|
|
7345
|
+
currentConstraintMarkers.push(...createdMarkers.filter(m => m.type === "constraint"));
|
|
7350
7346
|
},
|
|
7351
7347
|
onRelease: () => {
|
|
7352
7348
|
{
|
|
7353
7349
|
return;
|
|
7354
7350
|
}
|
|
7355
|
-
}
|
|
7351
|
+
}
|
|
7356
7352
|
};
|
|
7357
7353
|
};
|
|
7358
7354
|
|
|
@@ -7371,8 +7367,9 @@ const getMarkersContainer = () => {
|
|
|
7371
7367
|
// Convert document-relative coordinates to viewport coordinates for marker positioning
|
|
7372
7368
|
// Takes the scroll container into account for proper positioning relative to the container
|
|
7373
7369
|
const getDebugMarkerPos = (x, y, scrollContainer, side = null) => {
|
|
7374
|
-
const {
|
|
7375
|
-
|
|
7370
|
+
const {
|
|
7371
|
+
documentElement
|
|
7372
|
+
} = document;
|
|
7376
7373
|
const leftWithoutScroll = x - scrollContainer.scrollLeft;
|
|
7377
7374
|
const topWithoutScroll = y - scrollContainer.scrollTop;
|
|
7378
7375
|
let baseX;
|
|
@@ -7404,7 +7401,6 @@ const getDebugMarkerPos = (x, y, scrollContainer, side = null) => {
|
|
|
7404
7401
|
// For obstacles and other markers: use converted coordinates directly
|
|
7405
7402
|
return [baseX, baseY];
|
|
7406
7403
|
};
|
|
7407
|
-
|
|
7408
7404
|
const createMergedMarkers = (markersToCreate, scrollContainer) => {
|
|
7409
7405
|
const mergedMarkers = [];
|
|
7410
7406
|
const positionMap = new Map();
|
|
@@ -7412,7 +7408,6 @@ const createMergedMarkers = (markersToCreate, scrollContainer) => {
|
|
|
7412
7408
|
// Group markers by position and side
|
|
7413
7409
|
for (const marker of markersToCreate) {
|
|
7414
7410
|
const key = `${marker.x},${marker.y},${marker.side}`;
|
|
7415
|
-
|
|
7416
7411
|
if (!positionMap.has(key)) {
|
|
7417
7412
|
positionMap.set(key, []);
|
|
7418
7413
|
}
|
|
@@ -7430,43 +7425,36 @@ const createMergedMarkers = (markersToCreate, scrollContainer) => {
|
|
|
7430
7425
|
} else {
|
|
7431
7426
|
// Multiple markers at same position - merge labels
|
|
7432
7427
|
const firstMarker = markers[0];
|
|
7433
|
-
const combinedName = markers.map(
|
|
7428
|
+
const combinedName = markers.map(m => m.name).join(" + ");
|
|
7434
7429
|
|
|
7435
7430
|
// Use the first marker's color, or mix colors if needed
|
|
7436
|
-
const domMarker = createDebugMarker(
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
scrollContainer,
|
|
7442
|
-
);
|
|
7443
|
-
domMarker.type = markers.some((m) => m.name.includes("Bound"))
|
|
7444
|
-
? "constraint"
|
|
7445
|
-
: "visible";
|
|
7431
|
+
const domMarker = createDebugMarker({
|
|
7432
|
+
...firstMarker,
|
|
7433
|
+
name: combinedName
|
|
7434
|
+
}, scrollContainer);
|
|
7435
|
+
domMarker.type = markers.some(m => m.name.includes("Bound")) ? "constraint" : "visible";
|
|
7446
7436
|
mergedMarkers.push(domMarker);
|
|
7447
7437
|
}
|
|
7448
7438
|
}
|
|
7449
|
-
|
|
7450
7439
|
return mergedMarkers;
|
|
7451
7440
|
};
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
|
|
7441
|
+
const createDebugMarker = ({
|
|
7442
|
+
name,
|
|
7443
|
+
x,
|
|
7444
|
+
y,
|
|
7445
|
+
color = "255 0 0",
|
|
7446
|
+
side
|
|
7447
|
+
}, scrollContainer) => {
|
|
7457
7448
|
// Convert coordinates from document-relative to viewport
|
|
7458
7449
|
const [viewportX, viewportY] = getDebugMarkerPos(x, y, scrollContainer, side);
|
|
7459
|
-
|
|
7460
7450
|
const marker = document.createElement("div");
|
|
7461
7451
|
marker.className = `navi_debug_marker`;
|
|
7462
7452
|
marker.setAttribute(`data-${side}`, "");
|
|
7463
7453
|
// Set the color as a CSS custom property
|
|
7464
7454
|
marker.style.setProperty("--marker-color", `rgb(${color})`);
|
|
7465
7455
|
// Position markers exactly at the boundary coordinates
|
|
7466
|
-
marker.style.left =
|
|
7467
|
-
|
|
7468
|
-
marker.style.top =
|
|
7469
|
-
side === "bottom" ? `${viewportY - MARKER_SIZE}px` : `${viewportY}px`;
|
|
7456
|
+
marker.style.left = side === "right" ? `${viewportX - MARKER_SIZE}px` : `${viewportX}px`;
|
|
7457
|
+
marker.style.top = side === "bottom" ? `${viewportY - MARKER_SIZE}px` : `${viewportY}px`;
|
|
7470
7458
|
marker.title = name;
|
|
7471
7459
|
|
|
7472
7460
|
// Add label
|
|
@@ -7474,7 +7462,6 @@ const createDebugMarker = (
|
|
|
7474
7462
|
label.className = `navi_debug_marker_label`;
|
|
7475
7463
|
label.textContent = name;
|
|
7476
7464
|
marker.appendChild(label);
|
|
7477
|
-
|
|
7478
7465
|
const container = getMarkersContainer();
|
|
7479
7466
|
container.appendChild(marker);
|
|
7480
7467
|
return marker;
|
|
@@ -7484,13 +7471,7 @@ const createObstacleMarker = (obstacleObj, scrollContainer) => {
|
|
|
7484
7471
|
const height = obstacleObj.bounds.bottom - obstacleObj.bounds.top;
|
|
7485
7472
|
|
|
7486
7473
|
// Convert document-relative coordinates to viewport coordinates
|
|
7487
|
-
const [x, y] = getDebugMarkerPos(
|
|
7488
|
-
obstacleObj.bounds.left,
|
|
7489
|
-
obstacleObj.bounds.top,
|
|
7490
|
-
scrollContainer,
|
|
7491
|
-
"obstacle",
|
|
7492
|
-
);
|
|
7493
|
-
|
|
7474
|
+
const [x, y] = getDebugMarkerPos(obstacleObj.bounds.left, obstacleObj.bounds.top, scrollContainer, "obstacle");
|
|
7494
7475
|
const marker = document.createElement("div");
|
|
7495
7476
|
marker.className = "navi_obstacle_marker";
|
|
7496
7477
|
marker.style.left = `${x}px`;
|
|
@@ -7504,12 +7485,10 @@ const createObstacleMarker = (obstacleObj, scrollContainer) => {
|
|
|
7504
7485
|
label.className = "navi_obstacle_marker_label";
|
|
7505
7486
|
label.textContent = obstacleObj.name;
|
|
7506
7487
|
marker.appendChild(label);
|
|
7507
|
-
|
|
7508
7488
|
const container = getMarkersContainer();
|
|
7509
7489
|
container.appendChild(marker);
|
|
7510
7490
|
return marker;
|
|
7511
7491
|
};
|
|
7512
|
-
|
|
7513
7492
|
const createElementMarker = ({
|
|
7514
7493
|
left,
|
|
7515
7494
|
top,
|
|
@@ -7517,13 +7496,12 @@ const createElementMarker = ({
|
|
|
7517
7496
|
bottom,
|
|
7518
7497
|
scrollContainer,
|
|
7519
7498
|
label = "Element",
|
|
7520
|
-
color = "0, 200, 0"
|
|
7499
|
+
color = "0, 200, 0" // Default green color
|
|
7521
7500
|
}) => {
|
|
7522
7501
|
const width = right - left;
|
|
7523
7502
|
const height = bottom - top;
|
|
7524
7503
|
// Convert document-relative coordinates to viewport coordinates
|
|
7525
7504
|
const [x, y] = getDebugMarkerPos(left, top, scrollContainer, "element");
|
|
7526
|
-
|
|
7527
7505
|
const marker = document.createElement("div");
|
|
7528
7506
|
marker.className = "navi_element_marker";
|
|
7529
7507
|
marker.style.left = `${x}px`;
|
|
@@ -7541,24 +7519,21 @@ const createElementMarker = ({
|
|
|
7541
7519
|
labelEl.className = "navi_element_marker_label";
|
|
7542
7520
|
labelEl.textContent = label;
|
|
7543
7521
|
marker.appendChild(labelEl);
|
|
7544
|
-
|
|
7545
7522
|
const container = getMarkersContainer();
|
|
7546
7523
|
container.appendChild(marker);
|
|
7547
7524
|
return marker;
|
|
7548
7525
|
};
|
|
7549
|
-
|
|
7550
7526
|
const createReferenceElementMarker = ({
|
|
7551
7527
|
left,
|
|
7552
7528
|
top,
|
|
7553
7529
|
right,
|
|
7554
7530
|
bottom,
|
|
7555
|
-
scrollContainer
|
|
7531
|
+
scrollContainer
|
|
7556
7532
|
}) => {
|
|
7557
7533
|
const width = right - left;
|
|
7558
7534
|
const height = bottom - top;
|
|
7559
7535
|
// Convert document-relative coordinates to viewport coordinates
|
|
7560
7536
|
const [x, y] = getDebugMarkerPos(left, top, scrollContainer, "reference");
|
|
7561
|
-
|
|
7562
7537
|
const marker = document.createElement("div");
|
|
7563
7538
|
marker.className = "navi_reference_element_marker";
|
|
7564
7539
|
marker.style.left = `${x}px`;
|
|
@@ -7572,13 +7547,11 @@ const createReferenceElementMarker = ({
|
|
|
7572
7547
|
label.className = "navi_reference_element_marker_label";
|
|
7573
7548
|
label.textContent = "Reference Element";
|
|
7574
7549
|
marker.appendChild(label);
|
|
7575
|
-
|
|
7576
7550
|
const container = getMarkersContainer();
|
|
7577
7551
|
container.appendChild(marker);
|
|
7578
7552
|
return marker;
|
|
7579
7553
|
};
|
|
7580
|
-
|
|
7581
|
-
import.meta.css = /* css */ `
|
|
7554
|
+
import.meta.css = [/* css */`
|
|
7582
7555
|
.navi_debug_markers_container {
|
|
7583
7556
|
position: fixed;
|
|
7584
7557
|
top: 0;
|
|
@@ -7763,7 +7736,7 @@ import.meta.css = /* css */ `
|
|
|
7763
7736
|
border-radius: 3px;
|
|
7764
7737
|
pointer-events: none;
|
|
7765
7738
|
}
|
|
7766
|
-
|
|
7739
|
+
`, "@jsenv/dom/src/interaction/drag/drag_debug_markers.js"];
|
|
7767
7740
|
|
|
7768
7741
|
const initDragConstraints = (
|
|
7769
7742
|
dragGesture,
|
|
@@ -8927,17 +8900,37 @@ const getWidth = (element) => {
|
|
|
8927
8900
|
return width;
|
|
8928
8901
|
};
|
|
8929
8902
|
|
|
8930
|
-
|
|
8931
|
-
|
|
8903
|
+
installImportMetaCssBuild(import.meta);/**
|
|
8904
|
+
* Position Sticky Polyfill
|
|
8905
|
+
*
|
|
8906
|
+
* This module provides a workaround for position:sticky limitations when used with
|
|
8907
|
+
* overflow:auto/hidden parent elements (see https://github.com/w3c/csswg-drafts/issues/865).
|
|
8908
|
+
*
|
|
8909
|
+
* How it works:
|
|
8910
|
+
* 1. Creates a placeholder clone of the sticky element to maintain document flow
|
|
8911
|
+
* 2. Positions the real element using fixed positioning relative to viewport
|
|
8912
|
+
* 3. Adjusts position on scroll to emulate position:sticky behavior
|
|
8913
|
+
* 4. Handles parent boundary detection to keep element within its container
|
|
8914
|
+
* 5. Updates dimensions on resize and DOM changes
|
|
8915
|
+
*
|
|
8916
|
+
* Usage:
|
|
8917
|
+
* ```
|
|
8918
|
+
* const cleanup = initPositionSticky(element);
|
|
8919
|
+
* // Later when no longer needed
|
|
8920
|
+
* cleanup();
|
|
8921
|
+
* ```
|
|
8922
|
+
*
|
|
8923
|
+
* The element should have a CSS "top" value specified (e.g., top: 10px).
|
|
8924
|
+
*/
|
|
8925
|
+
import.meta.css = [/* css */`
|
|
8932
8926
|
[data-position-sticky-placeholder] {
|
|
8933
8927
|
position: static !important;
|
|
8934
8928
|
width: auto !important;
|
|
8935
8929
|
height: auto !important;
|
|
8936
8930
|
opacity: 0 !important;
|
|
8937
8931
|
}
|
|
8938
|
-
|
|
8939
|
-
|
|
8940
|
-
const initPositionSticky = (element) => {
|
|
8932
|
+
`, "@jsenv/dom/src/position/position_sticky.js"];
|
|
8933
|
+
const initPositionSticky = element => {
|
|
8941
8934
|
const computedStyle = getComputedStyle(element);
|
|
8942
8935
|
const topCssValue = computedStyle.top;
|
|
8943
8936
|
const top = parseFloat(topCssValue);
|
|
@@ -8961,20 +8954,10 @@ const initPositionSticky = (element) => {
|
|
|
8961
8954
|
break;
|
|
8962
8955
|
}
|
|
8963
8956
|
const style = getComputedStyle(scrollContainer);
|
|
8964
|
-
if (
|
|
8965
|
-
xScrollContainer === null &&
|
|
8966
|
-
(style.overflowX === "auto" ||
|
|
8967
|
-
style.overflowX === "hidden" ||
|
|
8968
|
-
style.overflowX === "scroll")
|
|
8969
|
-
) {
|
|
8957
|
+
if (xScrollContainer === null && (style.overflowX === "auto" || style.overflowX === "hidden" || style.overflowX === "scroll")) {
|
|
8970
8958
|
xScrollContainer = scrollContainer;
|
|
8971
8959
|
}
|
|
8972
|
-
if (
|
|
8973
|
-
yScrollContainer === null &&
|
|
8974
|
-
(style.overflowY === "auto" ||
|
|
8975
|
-
style.overflowY === "hidden" ||
|
|
8976
|
-
style.overflowY === "scroll")
|
|
8977
|
-
) {
|
|
8960
|
+
if (yScrollContainer === null && (style.overflowY === "auto" || style.overflowY === "hidden" || style.overflowY === "scroll")) {
|
|
8978
8961
|
yScrollContainer = scrollContainer;
|
|
8979
8962
|
}
|
|
8980
8963
|
}
|
|
@@ -8983,7 +8966,6 @@ const initPositionSticky = (element) => {
|
|
|
8983
8966
|
if (!needsPolyfillX && !needsPolyfillY) {
|
|
8984
8967
|
return () => {}; // Native sticky will work fine on both axes
|
|
8985
8968
|
}
|
|
8986
|
-
|
|
8987
8969
|
const cleanupCallbackSet = new Set();
|
|
8988
8970
|
const cleanup = () => {
|
|
8989
8971
|
for (const cleanupCallback of cleanupCallbackSet) {
|
|
@@ -8991,7 +8973,6 @@ const initPositionSticky = (element) => {
|
|
|
8991
8973
|
}
|
|
8992
8974
|
cleanupCallbackSet.clear();
|
|
8993
8975
|
};
|
|
8994
|
-
|
|
8995
8976
|
const parentElement = element.parentElement;
|
|
8996
8977
|
const createPlaceholderClone = () => {
|
|
8997
8978
|
const clone = element.cloneNode(true);
|
|
@@ -8999,16 +8980,13 @@ const initPositionSticky = (element) => {
|
|
|
8999
8980
|
clone.removeAttribute("data-sticky");
|
|
9000
8981
|
return clone;
|
|
9001
8982
|
};
|
|
9002
|
-
|
|
9003
8983
|
let placeholder = createPlaceholderClone();
|
|
9004
8984
|
parentElement.insertBefore(placeholder, element);
|
|
9005
8985
|
cleanupCallbackSet.add(() => {
|
|
9006
8986
|
placeholder.remove();
|
|
9007
8987
|
});
|
|
9008
|
-
|
|
9009
8988
|
let width = getWidth(element);
|
|
9010
8989
|
let height = getHeight(element);
|
|
9011
|
-
|
|
9012
8990
|
const updateSize = () => {
|
|
9013
8991
|
const newPlaceholder = createPlaceholderClone();
|
|
9014
8992
|
parentElement.replaceChild(newPlaceholder, placeholder);
|
|
@@ -9017,14 +8995,12 @@ const initPositionSticky = (element) => {
|
|
|
9017
8995
|
height = getHeight(placeholder);
|
|
9018
8996
|
updatePosition();
|
|
9019
8997
|
};
|
|
9020
|
-
|
|
9021
8998
|
const updatePosition = () => {
|
|
9022
8999
|
// Ensure placeholder dimensions match element
|
|
9023
9000
|
setStyles(placeholder, {
|
|
9024
9001
|
width: `${width}px`,
|
|
9025
|
-
height: `${height}px
|
|
9002
|
+
height: `${height}px`
|
|
9026
9003
|
});
|
|
9027
|
-
|
|
9028
9004
|
const placeholderRect = placeholder.getBoundingClientRect();
|
|
9029
9005
|
const parentRect = parentElement.getBoundingClientRect();
|
|
9030
9006
|
|
|
@@ -9038,12 +9014,12 @@ const initPositionSticky = (element) => {
|
|
|
9038
9014
|
// -420 <= 250 → stuck → element.style.left = 250px (main's left edge). ✓
|
|
9039
9015
|
//
|
|
9040
9016
|
// If no intermediate scroll container exists, use 0 (document/viewport edge).
|
|
9041
|
-
const yContainerRect = yScrollContainer
|
|
9042
|
-
|
|
9043
|
-
|
|
9044
|
-
const xContainerRect = xScrollContainer
|
|
9045
|
-
|
|
9046
|
-
|
|
9017
|
+
const yContainerRect = yScrollContainer ? yScrollContainer.getBoundingClientRect() : {
|
|
9018
|
+
top: 0
|
|
9019
|
+
};
|
|
9020
|
+
const xContainerRect = xScrollContainer ? xScrollContainer.getBoundingClientRect() : {
|
|
9021
|
+
left: 0
|
|
9022
|
+
};
|
|
9047
9023
|
const topThreshold = yContainerRect.top + top;
|
|
9048
9024
|
const leftThreshold = xContainerRect.left + left;
|
|
9049
9025
|
|
|
@@ -9086,7 +9062,6 @@ const initPositionSticky = (element) => {
|
|
|
9086
9062
|
} else {
|
|
9087
9063
|
leftPosition = placeholderRect.left;
|
|
9088
9064
|
}
|
|
9089
|
-
|
|
9090
9065
|
element.style.top = `${topPosition}px`;
|
|
9091
9066
|
element.style.left = `${Math.round(leftPosition)}px`;
|
|
9092
9067
|
element.style.width = `${width}px`;
|
|
@@ -9099,18 +9074,15 @@ const initPositionSticky = (element) => {
|
|
|
9099
9074
|
element.removeAttribute("data-sticky");
|
|
9100
9075
|
}
|
|
9101
9076
|
};
|
|
9102
|
-
|
|
9103
9077
|
{
|
|
9104
9078
|
const restorePositionStyle = forceStyles(element, {
|
|
9105
9079
|
"position": "fixed",
|
|
9106
9080
|
"z-index": 1,
|
|
9107
|
-
"will-change": "transform"
|
|
9081
|
+
"will-change": "transform" // Hint for hardware acceleration
|
|
9108
9082
|
});
|
|
9109
9083
|
cleanupCallbackSet.add(restorePositionStyle);
|
|
9110
9084
|
}
|
|
9111
|
-
|
|
9112
9085
|
updatePosition();
|
|
9113
|
-
|
|
9114
9086
|
{
|
|
9115
9087
|
const handleScroll = () => {
|
|
9116
9088
|
updatePosition();
|
|
@@ -9121,15 +9093,16 @@ const initPositionSticky = (element) => {
|
|
|
9121
9093
|
const listenTargets = new Set(scrollContainerSet);
|
|
9122
9094
|
listenTargets.add(document.documentElement);
|
|
9123
9095
|
for (const scrollTarget of listenTargets) {
|
|
9124
|
-
scrollTarget.addEventListener("scroll", handleScroll, {
|
|
9096
|
+
scrollTarget.addEventListener("scroll", handleScroll, {
|
|
9097
|
+
passive: true
|
|
9098
|
+
});
|
|
9125
9099
|
cleanupCallbackSet.add(() => {
|
|
9126
9100
|
scrollTarget.removeEventListener("scroll", handleScroll, {
|
|
9127
|
-
passive: true
|
|
9101
|
+
passive: true
|
|
9128
9102
|
});
|
|
9129
9103
|
});
|
|
9130
9104
|
}
|
|
9131
9105
|
}
|
|
9132
|
-
|
|
9133
9106
|
{
|
|
9134
9107
|
let animationFrame = null;
|
|
9135
9108
|
const resizeObserver = new ResizeObserver(() => {
|
|
@@ -9148,7 +9121,6 @@ const initPositionSticky = (element) => {
|
|
|
9148
9121
|
animationFrame = null;
|
|
9149
9122
|
});
|
|
9150
9123
|
}
|
|
9151
|
-
|
|
9152
9124
|
{
|
|
9153
9125
|
const mutationObserver = new MutationObserver(() => {
|
|
9154
9126
|
updateSize();
|
|
@@ -9156,13 +9128,12 @@ const initPositionSticky = (element) => {
|
|
|
9156
9128
|
mutationObserver.observe(element, {
|
|
9157
9129
|
childList: true,
|
|
9158
9130
|
subtree: true,
|
|
9159
|
-
characterData: true
|
|
9131
|
+
characterData: true
|
|
9160
9132
|
});
|
|
9161
9133
|
cleanupCallbackSet.add(() => {
|
|
9162
9134
|
mutationObserver.disconnect();
|
|
9163
9135
|
});
|
|
9164
9136
|
}
|
|
9165
|
-
|
|
9166
9137
|
return cleanup;
|
|
9167
9138
|
};
|
|
9168
9139
|
|