@12-apps/ui 6.45.5 → 6.45.6
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/_internal/components/layout/SettingsLayout/SettingsLayout.js +4 -4
- package/dist/_internal/components/layout/SettingsLayout/SettingsPanel.js +3 -3
- package/dist/_internal/components/layout/SettingsLayout/SettingsSectionChips.js +2 -2
- package/dist/_internal/components/layout/SettingsLayout/SettingsSectionChips.scroll.js +1 -1
- package/dist/{chunk-QLAFJZDS.js → chunk-AJUSBPWG.js} +5 -2
- package/dist/chunk-AJUSBPWG.js.map +1 -0
- package/dist/{chunk-FNLD2KCQ.js → chunk-EWVJJ32N.js} +2 -2
- package/dist/{chunk-YWQ7QCWR.js → chunk-F3Q4CMRB.js} +2 -2
- package/dist/{chunk-B7HYM3QB.js → chunk-RIAZPGHT.js} +2 -2
- package/dist/layout/SettingsLayout.js +4 -4
- package/dist/types/components/layout/SettingsLayout/SettingsSectionChips.scroll.d.ts +6 -7
- package/dist/types/components/layout/SettingsLayout/SettingsSectionChips.scroll.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/layout/SettingsLayout/SettingsSectionChips.scroll.ts +19 -19
- package/dist/chunk-QLAFJZDS.js.map +0 -1
- /package/dist/{chunk-FNLD2KCQ.js.map → chunk-EWVJJ32N.js.map} +0 -0
- /package/dist/{chunk-YWQ7QCWR.js.map → chunk-F3Q4CMRB.js.map} +0 -0
- /package/dist/{chunk-B7HYM3QB.js.map → chunk-RIAZPGHT.js.map} +0 -0
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
SettingsLayout
|
|
4
|
-
} from "../../../../chunk-
|
|
5
|
-
import "../../../../chunk-
|
|
4
|
+
} from "../../../../chunk-EWVJJ32N.js";
|
|
5
|
+
import "../../../../chunk-RIAZPGHT.js";
|
|
6
6
|
import "../../../../chunk-TNYKM4UU.js";
|
|
7
7
|
import "../../../../chunk-V5EWCJBT.js";
|
|
8
8
|
import "../../../../chunk-BXC6GRLE.js";
|
|
9
9
|
import "../../../../chunk-6KEXHOIF.js";
|
|
10
|
-
import "../../../../chunk-
|
|
11
|
-
import "../../../../chunk-
|
|
10
|
+
import "../../../../chunk-F3Q4CMRB.js";
|
|
11
|
+
import "../../../../chunk-AJUSBPWG.js";
|
|
12
12
|
import "../../../../chunk-DBFRCTI5.js";
|
|
13
13
|
import "../../../../chunk-NYFNF7I5.js";
|
|
14
14
|
import "../../../../chunk-HPK33ACY.js";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
SettingsPanel
|
|
4
|
-
} from "../../../../chunk-
|
|
4
|
+
} from "../../../../chunk-RIAZPGHT.js";
|
|
5
5
|
import "../../../../chunk-6KEXHOIF.js";
|
|
6
|
-
import "../../../../chunk-
|
|
7
|
-
import "../../../../chunk-
|
|
6
|
+
import "../../../../chunk-F3Q4CMRB.js";
|
|
7
|
+
import "../../../../chunk-AJUSBPWG.js";
|
|
8
8
|
import "../../../../chunk-DBFRCTI5.js";
|
|
9
9
|
import "../../../../chunk-NYFNF7I5.js";
|
|
10
10
|
import "../../../../chunk-YKCAJ2TN.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
SettingsSectionChips
|
|
4
|
-
} from "../../../../chunk-
|
|
5
|
-
import "../../../../chunk-
|
|
4
|
+
} from "../../../../chunk-F3Q4CMRB.js";
|
|
5
|
+
import "../../../../chunk-AJUSBPWG.js";
|
|
6
6
|
import "../../../../chunk-DBFRCTI5.js";
|
|
7
7
|
import "../../../../chunk-NYFNF7I5.js";
|
|
8
8
|
import "../../../../chunk-YKCAJ2TN.js";
|
|
@@ -8,6 +8,7 @@ function horizontalDelta(event) {
|
|
|
8
8
|
if (!(event instanceof WheelEvent)) return 0;
|
|
9
9
|
return event.deltaX !== 0 ? event.deltaX : event.shiftKey ? event.deltaY : 0;
|
|
10
10
|
}
|
|
11
|
+
var STRIP_SCROLLING_KEYS = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight"]);
|
|
11
12
|
var cachedRtlScrollType;
|
|
12
13
|
function detectRtlScrollType(doc) {
|
|
13
14
|
if (cachedRtlScrollType) return cachedRtlScrollType;
|
|
@@ -100,7 +101,9 @@ function createGestureListeners(state) {
|
|
|
100
101
|
nudge();
|
|
101
102
|
onPointerUp();
|
|
102
103
|
};
|
|
103
|
-
const onKeydown =
|
|
104
|
+
const onKeydown = (event) => {
|
|
105
|
+
if (event instanceof KeyboardEvent && STRIP_SCROLLING_KEYS.has(event.key)) nudge();
|
|
106
|
+
};
|
|
104
107
|
const onWheel = (event) => {
|
|
105
108
|
if (horizontalDelta(event) !== 0) nudge();
|
|
106
109
|
};
|
|
@@ -199,4 +202,4 @@ export {
|
|
|
199
202
|
toRawScrollLeft,
|
|
200
203
|
watchVisitorScroll
|
|
201
204
|
};
|
|
202
|
-
//# sourceMappingURL=chunk-
|
|
205
|
+
//# sourceMappingURL=chunk-AJUSBPWG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/layout/SettingsLayout/SettingsSectionChips.scroll.ts"],"sourcesContent":["/**\n * Telling the strip's own scrolls from the visitor's (FUT-2606). Split from\n * `SettingsSectionChips.tsx` so the chips stay a component file and the rule\n * for \"who moved the strip\" can be read in one place.\n */\n\n/**\n * How near to where the strip aimed itself it has to come to rest for the scroll\n * to count as the strip's own. A smooth scroll lands on a device pixel, and the\n * target it was given is fractional.\n */\nconst LANDED_SLACK = 1;\n\n/**\n * Where `scrollend` is missing: how long the strip goes without a `scroll`\n * before it counts as settled — generous, since a busy thread can go several\n * frames between smooth-scroll ticks and judging one mid-flight would read\n * the strip's own animation as the visitor's. Too short can latch it for good.\n */\nconst QUIET_BEFORE_SETTLED_MS = 250;\n\n/**\n * How much `scrollLeft` has to move, tick to tick, before a `scroll` event is\n * even a CANDIDATE for arming (FUT-2775). Below this, a browser's own rounding\n * or a repeated event carrying no real motion cannot arm anything by itself.\n * This alone does not stop the false latch the ticket describes: the strip's\n * own `scrollTo` produces real per-tick deltas well past this line, same as a\n * drag would. It only rules out a scroll event that moved nothing.\n */\nconst SCROLL_DELTA_EPSILON = 2;\n\n/**\n * How far a pointer/touch must travel from where it went down to count as\n * MOVED, not merely resting (FUT-2775) — below this, a held tremor isn't a drag.\n */\nconst POINTER_MOVE_EPSILON = 2;\n\n/**\n * How long a key, sideways wheel or pan stays armed through a scroll the strip\n * made itself (FUT-2848) — a busy thread can finish a re-centre before the\n * key's scroll ticks once; past this it lapses, so a later clamp isn't the visitor.\n */\nconst NUDGE_FRESH_MS = 1000;\n\ninterface VisitorScrollWatch {\n /** True once the visitor has moved the strip themselves. */\n hasScrolled: () => boolean;\n /**\n * True while a scroll the visitor MAY be making has not come to rest yet. The\n * strip must not scroll itself under it: that would yank a drag in progress.\n */\n isUndecided: () => boolean;\n /**\n * Where the strip last aimed itself, PHYSICAL pixels (see {@link physicalScrollLeft}) —\n * direction-blind, like every other geometry read in this file. `NaN` before it has.\n */\n aimedAt: () => number;\n /**\n * The strip is about to scroll itself to `left` (physical pixels). Records the\n * aim and NOTHING\n * else: it used to disarm too, and a re-centre landing between a visitor's key\n * press (or wheel, or pan) and the first tick of the scroll it causes wiped\n * the arming — their scroll went unclaimed, read as the strip's own. Left\n * armed, the worst a stale arming does is put the strip's OWN next scroll\n * under judgement, which rests on its aim, is not latched, and disarms.\n */\n beforeOwnScroll: (left: number) => void;\n /** Called once an undecided scroll has come to rest and been judged. */\n onSettled: (listener: () => void) => void;\n detach: () => void;\n}\n\ntype Listeners = Array<[string, (event: Event) => void]>;\n\n/** A wheel's sideways travel: `deltaX`, or `deltaY` with Shift held, as browsers read it. */\nfunction horizontalDelta(event: Event): number {\n if (!(event instanceof WheelEvent)) return 0;\n return event.deltaX !== 0 ? event.deltaX : event.shiftKey ? event.deltaY : 0;\n}\n\nconst STRIP_SCROLLING_KEYS = new Set(['ArrowLeft', 'ArrowRight']); // verified live in Chromium (FUT-2862)\n\ninterface WatchState {\n pointer: boolean;\n touch: boolean;\n nudged: boolean;\n /** When `nudged` was set (`Date.now()` ms), and whether it outlived an own verdict. */\n nudgedAt: number;\n nudgeKept: boolean;\n undecided: boolean;\n scrolled: boolean;\n aimed: number;\n quiet: ReturnType<typeof setTimeout> | undefined;\n settled: () => void;\n /** `scrollLeft` as of the last `scroll` tick, updated every tick regardless of arming. */\n lastScrollLeft: number;\n /** Where a `pointerdown` on the strip landed, in viewport `clientX`. `NaN` while up. */\n pointerDownAt: number;\n /** True once that pointer has travelled past {@link POINTER_MOVE_EPSILON} from `pointerDownAt`. */\n pointerMoved: boolean;\n /** Same pair, for `touchstart`/`touchmove` — a distinct event stream on some engines. */\n touchDownAt: number;\n touchMoved: boolean;\n}\n\ntype RtlScrollType = 'default' | 'negative' | 'reverse';\n\nlet cachedRtlScrollType: RtlScrollType | undefined;\n\n/**\n * Which of the three incompatible conventions this engine reports an RTL\n * scroller's `scrollLeft` in, probed once and cached (FUT-2775).\n *\n * Per the CSSOM View spec, an RTL scroller's `scrollLeft` is `0` at its\n * (right-hand) start and goes NEGATIVE toward the end — `'negative'` below,\n * what every current evergreen engine implements. Older WebKit mirrored that\n * (`'reverse'`: `0` at the start, growing toward `+max`), and older\n * Chromium/Safari ignored `dir` altogether and kept the plain left-to-right\n * numbering (`'default'`). A hidden probe, not a version sniff, tells them\n * apart — the same technique `@mui/utils`'s `detectScrollType` uses for\n * `Tabs`; reimplemented here rather than taking a new dependency for one\n * probe.\n */\nfunction detectRtlScrollType(doc: Document): RtlScrollType {\n if (cachedRtlScrollType) return cachedRtlScrollType;\n // The exact pixel values below are the probe's mechanism, not a design size:\n // what matters is only that the INNER box is wider than the OUTER one, so the\n // outer one has something to scroll — same technique `@mui/utils` uses,\n // detached and off-screen either way.\n const probe = doc.createElement('div');\n const inner = doc.createElement('div');\n inner.style.width = '10px';\n probe.appendChild(inner);\n probe.dir = 'rtl';\n probe.style.width = '4px';\n probe.style.position = 'absolute';\n probe.style.top = '-1000px';\n probe.style.overflow = 'scroll';\n doc.body.appendChild(probe);\n let type: RtlScrollType = 'reverse';\n if (probe.scrollLeft > 0) {\n type = 'default';\n } else {\n probe.scrollLeft = 1;\n if (probe.scrollLeft === 0) type = 'negative';\n }\n doc.body.removeChild(probe);\n cachedRtlScrollType = type;\n return type;\n}\n\n/** True when the strip's own computed direction is right-to-left. */\nexport function isRtlStrip(strip: HTMLElement): boolean {\n const view = strip.ownerDocument.defaultView;\n const getComputedStyle = view?.getComputedStyle ?? globalThis.getComputedStyle;\n return getComputedStyle(strip).direction === 'rtl';\n}\n\n/**\n * `strip.scrollLeft`, renumbered so `0` is always the strip's physical LEFT\n * edge and larger is always further physically right — whatever `direction`\n * and whatever convention this engine uses to report it raw (FUT-2775).\n *\n * Every geometry read in this file (`getBoundingClientRect`) is already in\n * that same physical, direction-blind coordinate space, so this is what makes\n * `scrollLeft` combinable with it at all.\n */\nexport function physicalScrollLeft(strip: HTMLElement): number {\n const raw = strip.scrollLeft;\n if (!isRtlStrip(strip)) return raw;\n const max = strip.scrollWidth - strip.clientWidth;\n const type = detectRtlScrollType(strip.ownerDocument);\n if (type === 'negative') return raw + max;\n if (type === 'reverse') return max - raw;\n return raw;\n}\n\n/** The inverse of {@link physicalScrollLeft}: a physical offset back to this engine's raw `scrollLeft`. */\nexport function toRawScrollLeft(strip: HTMLElement, physical: number): number {\n if (!isRtlStrip(strip)) return physical;\n const max = strip.scrollWidth - strip.clientWidth;\n const type = detectRtlScrollType(strip.ownerDocument);\n if (type === 'negative') return physical - max;\n if (type === 'reverse') return max - physical;\n return physical;\n}\n\n/** Whether the gesture that armed `nudged` happened within {@link NUDGE_FRESH_MS}. */\nfunction nudgeIsFresh(state: WatchState): boolean {\n return Date.now() - state.nudgedAt <= NUDGE_FRESH_MS;\n}\n\n/** Whether the strip came to rest where it last aimed itself — clamped as the browser would. */\nfunction restsOnAim(strip: HTMLElement, aimed: number): boolean {\n const reachable = Math.min(aimed, strip.scrollWidth - strip.clientWidth);\n // Written so that `NaN` — the strip never aimed — reads as \"not on aim\".\n return Math.abs(physicalScrollLeft(strip) - reachable) <= LANDED_SLACK;\n}\n\n/** The pointer/touch/keydown/wheel listeners that arm `state`, split out of `watchVisitorScroll` (line budget). */\nfunction createGestureListeners(state: WatchState): { onStrip: Listeners; onView: Listeners } {\n // `MouseEvent`, not `PointerEvent`: a real `PointerEvent` IS one (it extends\n // `MouseEvent`), so this reads `clientX` off it just the same in a browser —\n // but jsdom (this file's own test environment) has never implemented\n // `PointerEvent` at all, and the bare identifier throws a `ReferenceError`\n // the moment anything evaluates `instanceof PointerEvent`, pointer event or\n // not. Same reasoning as feature-checking `scrollTo` elsewhere in this file:\n // nothing in here is worth a crash over which constructor a probe prefers.\n const onPointerDown = (event: Event): void => {\n state.pointer = true;\n state.pointerMoved = false;\n state.pointerDownAt = event instanceof MouseEvent ? event.clientX : Number.NaN;\n };\n const onPointerMove = (event: Event): void => {\n if (!(event instanceof MouseEvent) || Number.isNaN(state.pointerDownAt)) return;\n if (Math.abs(event.clientX - state.pointerDownAt) > POINTER_MOVE_EPSILON) state.pointerMoved = true;\n };\n const onPointerUp = (): void => {\n state.pointer = false;\n state.pointerDownAt = Number.NaN;\n };\n const onTouchStart = (event: Event): void => {\n state.touch = true;\n state.touchMoved = false;\n state.touchDownAt = event instanceof TouchEvent ? (event.touches[0]?.clientX ?? Number.NaN) : Number.NaN;\n };\n const onTouchMove = (event: Event): void => {\n if (!(event instanceof TouchEvent) || Number.isNaN(state.touchDownAt)) return;\n const clientX = event.touches[0]?.clientX;\n if (clientX !== undefined && Math.abs(clientX - state.touchDownAt) > POINTER_MOVE_EPSILON) {\n state.touchMoved = true;\n }\n };\n const onTouchEnd = (): void => {\n state.touch = false;\n state.touchDownAt = Number.NaN;\n };\n const nudge = (): void => {\n state.nudged = true;\n state.nudgedAt = Date.now();\n state.nudgeKept = false;\n };\n const onPointerCancel = (): void => {\n nudge();\n onPointerUp();\n };\n const onKeydown = (event: Event): void => {\n if (event instanceof KeyboardEvent && STRIP_SCROLLING_KEYS.has(event.key)) nudge();\n };\n const onWheel = (event: Event): void => {\n if (horizontalDelta(event) !== 0) nudge();\n };\n return {\n onStrip: [\n ['pointerdown', onPointerDown],\n ['pointermove', onPointerMove],\n ['touchstart', onTouchStart],\n ['touchmove', onTouchMove],\n ['pointercancel', onPointerCancel],\n ['keydown', onKeydown],\n ['wheel', onWheel],\n ],\n // A gesture can END off the strip, so its end is heard on the window.\n onView: [\n ['pointerup', onPointerUp],\n ['pointercancel', onPointerUp],\n ['touchend', onTouchEnd],\n ['touchcancel', onTouchEnd],\n ],\n };\n}\n\n/**\n * Judge the scroll under judgement once the strip rests. Only a scroll UNDER\n * JUDGEMENT disarms: Chromium can fire `scrollend` for the strip's own scroll\n * cut off by another BEFORE that one's first `scroll`, and disarming there\n * would hand the visitor's scroll to nobody.\n */\nfunction settleJudgement(strip: HTMLElement, state: WatchState): void {\n if (!state.undecided) return;\n state.undecided = false;\n const own = restsOnAim(strip, state.aimed);\n if (!own) state.scrolled = true;\n // The strip's own scroll does not use up a gesture armed moments ago: the\n // scroll that gesture causes may still be on its way (FUT-2848).\n state.nudgeKept = own && nudgeIsFresh(state);\n if (!state.nudgeKept) state.nudged = false;\n state.settled();\n}\n\n/** A gesture kept through the strip's own scroll lapses once stale (FUT-2848). */\nfunction dropStaleNudge(state: WatchState): void {\n if (!state.nudgeKept || nudgeIsFresh(state)) return;\n state.nudged = false;\n state.nudgeKept = false;\n}\n\n/**\n * Tell a scroll the VISITOR made from every other one.\n *\n * The `scroll` event cannot say: the strip's own `scrollTo` fires it, and so does\n * the browser clamping a strip whose content shrank. So a scroll is only a\n * CANDIDATE when it arrives during something only a visitor does:\n *\n * - a finger held on the strip (`touchstart` until `touchend`) — a drag;\n * - a pointer held on it (`pointerdown` until `pointerup`);\n * - a strip-scrolling key press (`STRIP_SCROLLING_KEYS`, FUT-2862), a SIDEWAYS\n * wheel, or the browser taking a pointer over to pan it (`pointercancel`),\n * each armed until the next scroll under judgement has been judged.\n *\n * and the verdict waits until the strip comes to REST (`scrollend`, or a quiet\n * spell where the browser has no `scrollend`): it is the visitor's only if the\n * strip rests somewhere other than where it last aimed itself.\n *\n * Judged at rest rather than per `scroll` because the strip's own smooth scroll\n * fires `scroll` for a third of a second, and a visitor who presses Tab or puts\n * a finger on a chip to scroll the PAGE in that window is not scrolling the\n * strip. Every tick of that animation used to count as theirs, the strip stopped\n * re-centring for good, and the open chip could be left clipped (FUT-2606\n * again, by another door). A visitor who really drags or wheels the strip\n * mid-animation cancels it, so the strip rests where THEY left it — and that\n * still counts. The one loss: a visitor who happens to leave it within a pixel\n * of the strip's own aim is not told apart from it, and the strip there is\n * already where it would have put itself.\n *\n * A tap is a pointer held with no scroll under it, so it never counts. A\n * vertical wheel scrolls the PAGE — the strip is `overflowY: hidden` — and is\n * not armed at all.\n */\nexport function watchVisitorScroll(strip: HTMLElement): VisitorScrollWatch {\n const view = strip.ownerDocument.defaultView;\n const hasScrollEnd = 'onscrollend' in strip;\n const state: WatchState = {\n pointer: false,\n touch: false,\n nudged: false,\n nudgedAt: Number.NaN,\n nudgeKept: false,\n undecided: false,\n scrolled: false,\n aimed: Number.NaN,\n quiet: undefined,\n settled: () => undefined,\n lastScrollLeft: physicalScrollLeft(strip),\n pointerDownAt: Number.NaN,\n pointerMoved: false,\n touchDownAt: Number.NaN,\n touchMoved: false,\n };\n const settle = (): void => settleJudgement(strip, state);\n const onScroll = (): void => {\n const now = physicalScrollLeft(strip);\n const movedFarEnough = Math.abs(now - state.lastScrollLeft) > SCROLL_DELTA_EPSILON;\n state.lastScrollLeft = now;\n // Pointer/touch need BOTH signals (FUT-2775): the pointer/finger must have\n // itself MOVED since going down, AND this tick's delta must be real. Either\n // alone still latches on the other's shape — a pointer merely resting on\n // the strip while its OWN `scrollTo` produces real per-tick deltas would\n // arm under a delta-only check (`pointerMoved`/`touchMoved` rules that out);\n // a pointer that drifts a sub-epsilon amount while resting would arm under\n // a moved-only check with no delta floor (`movedFarEnough` rules that out).\n dropStaleNudge(state);\n const pointerDrag = state.pointer && state.pointerMoved && movedFarEnough;\n const touchDrag = state.touch && state.touchMoved && movedFarEnough;\n // `nudged` (a keypress, a sideways wheel, the browser taking the pointer\n // over to pan) is already a discrete, one-shot gesture with no \"resting\n // pointer coincides with an unrelated animation\" shape to rule out — unlike\n // pointer/touch, requiring a delta on the SAME tick that arms it would only\n // race the strip's own scroll ending before a qualifying tick arrives (seen:\n // it broke the existing \"keeps a wheel/drag scroll\" stories against a real\n // browser's `scrollend` timing). So it arms as it always has.\n if (pointerDrag || touchDrag || state.nudged) state.undecided = true;\n if (!state.undecided || hasScrollEnd) return;\n // Every tick while undecided, armed or not: a quiet spell that began while\n // the strip was still moving would judge it mid-flight, away from its aim.\n clearTimeout(state.quiet);\n state.quiet = setTimeout(settle, QUIET_BEFORE_SETTLED_MS);\n };\n const gestures = createGestureListeners(state);\n const onStrip: Listeners = [...gestures.onStrip, ['scroll', onScroll], ['scrollend', settle]];\n const onView = gestures.onView;\n for (const [type, listener] of onStrip) strip.addEventListener(type, listener, { passive: true });\n for (const [type, listener] of onView) view?.addEventListener(type, listener, { passive: true });\n return {\n hasScrolled: () => state.scrolled,\n isUndecided: () => state.undecided,\n aimedAt: () => state.aimed,\n beforeOwnScroll: (left) => {\n state.aimed = left;\n },\n onSettled: (listener) => {\n state.settled = listener;\n },\n detach: () => {\n clearTimeout(state.quiet);\n for (const [type, listener] of onStrip) strip.removeEventListener(type, listener);\n for (const [type, listener] of onView) view?.removeEventListener(type, listener);\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SettingsPanel
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-RIAZPGHT.js";
|
|
4
4
|
import {
|
|
5
5
|
SettingsRail
|
|
6
6
|
} from "./chunk-TNYKM4UU.js";
|
|
@@ -135,4 +135,4 @@ SettingsLayout.displayName = "SettingsLayout";
|
|
|
135
135
|
export {
|
|
136
136
|
SettingsLayout
|
|
137
137
|
};
|
|
138
|
-
//# sourceMappingURL=chunk-
|
|
138
|
+
//# sourceMappingURL=chunk-EWVJJ32N.js.map
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
physicalScrollLeft,
|
|
3
3
|
toRawScrollLeft,
|
|
4
4
|
watchVisitorScroll
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-AJUSBPWG.js";
|
|
6
6
|
import {
|
|
7
7
|
SettingsStatusMarker
|
|
8
8
|
} from "./chunk-DBFRCTI5.js";
|
|
@@ -186,4 +186,4 @@ SettingsSectionChips.displayName = "SettingsSectionChips";
|
|
|
186
186
|
export {
|
|
187
187
|
SettingsSectionChips
|
|
188
188
|
};
|
|
189
|
-
//# sourceMappingURL=chunk-
|
|
189
|
+
//# sourceMappingURL=chunk-F3Q4CMRB.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-6KEXHOIF.js";
|
|
4
4
|
import {
|
|
5
5
|
SettingsSectionChips
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-F3Q4CMRB.js";
|
|
7
7
|
import {
|
|
8
8
|
TOUCH_TARGET,
|
|
9
9
|
atLeastRail,
|
|
@@ -167,4 +167,4 @@ function SettingsPanel({
|
|
|
167
167
|
export {
|
|
168
168
|
SettingsPanel
|
|
169
169
|
};
|
|
170
|
-
//# sourceMappingURL=chunk-
|
|
170
|
+
//# sourceMappingURL=chunk-RIAZPGHT.js.map
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SettingsLayout
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-EWVJJ32N.js";
|
|
4
|
+
import "../chunk-RIAZPGHT.js";
|
|
5
5
|
import "../chunk-TNYKM4UU.js";
|
|
6
6
|
import "../chunk-V5EWCJBT.js";
|
|
7
7
|
import "../chunk-BXC6GRLE.js";
|
|
8
8
|
import "../chunk-6KEXHOIF.js";
|
|
9
9
|
import {
|
|
10
10
|
SettingsSectionChips
|
|
11
|
-
} from "../chunk-
|
|
12
|
-
import "../chunk-
|
|
11
|
+
} from "../chunk-F3Q4CMRB.js";
|
|
12
|
+
import "../chunk-AJUSBPWG.js";
|
|
13
13
|
import {
|
|
14
14
|
SettingsStatusMarker
|
|
15
15
|
} from "../chunk-DBFRCTI5.js";
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Telling the strip's own scrolls from the visitor's (FUT-2606).
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* the rule for "who moved the strip" can be read in one place.
|
|
2
|
+
* Telling the strip's own scrolls from the visitor's (FUT-2606). Split from
|
|
3
|
+
* `SettingsSectionChips.tsx` so the chips stay a component file and the rule
|
|
4
|
+
* for "who moved the strip" can be read in one place.
|
|
6
5
|
*/
|
|
7
6
|
interface VisitorScrollWatch {
|
|
8
7
|
/** True once the visitor has moved the strip themselves. */
|
|
@@ -54,9 +53,9 @@ export declare function toRawScrollLeft(strip: HTMLElement, physical: number): n
|
|
|
54
53
|
*
|
|
55
54
|
* - a finger held on the strip (`touchstart` until `touchend`) — a drag;
|
|
56
55
|
* - a pointer held on it (`pointerdown` until `pointerup`);
|
|
57
|
-
* - a key press
|
|
58
|
-
*
|
|
59
|
-
*
|
|
56
|
+
* - a strip-scrolling key press (`STRIP_SCROLLING_KEYS`, FUT-2862), a SIDEWAYS
|
|
57
|
+
* wheel, or the browser taking a pointer over to pan it (`pointercancel`),
|
|
58
|
+
* each armed until the next scroll under judgement has been judged.
|
|
60
59
|
*
|
|
61
60
|
* and the verdict waits until the strip comes to REST (`scrollend`, or a quiet
|
|
62
61
|
* spell where the browser has no `scrollend`): it is the visitor's only if the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SettingsSectionChips.scroll.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/SettingsLayout/SettingsSectionChips.scroll.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"SettingsSectionChips.scroll.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/SettingsLayout/SettingsSectionChips.scroll.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAwCH,UAAU,kBAAkB;IAC1B,4DAA4D;IAC5D,WAAW,EAAE,MAAM,OAAO,CAAC;IAC3B;;;OAGG;IACH,WAAW,EAAE,MAAM,OAAO,CAAC;IAC3B;;;OAGG;IACH,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB;;;;;;;;OAQG;IACH,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,wEAAwE;IACxE,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAC1C,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAiFD,qEAAqE;AACrE,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAItD;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAQ7D;AAED,2GAA2G;AAC3G,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO5E;AAgHD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,GAAG,kBAAkB,CAsEzE"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Telling the strip's own scrolls from the visitor's (FUT-2606).
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* the rule for "who moved the strip" can be read in one place.
|
|
2
|
+
* Telling the strip's own scrolls from the visitor's (FUT-2606). Split from
|
|
3
|
+
* `SettingsSectionChips.tsx` so the chips stay a component file and the rule
|
|
4
|
+
* for "who moved the strip" can be read in one place.
|
|
6
5
|
*/
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -13,11 +12,10 @@
|
|
|
13
12
|
const LANDED_SLACK = 1;
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
|
-
* Where `scrollend` is missing: how long the strip
|
|
17
|
-
* before it counts as settled
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* re-centre; too short can latch the strip for good.
|
|
15
|
+
* Where `scrollend` is missing: how long the strip goes without a `scroll`
|
|
16
|
+
* before it counts as settled — generous, since a busy thread can go several
|
|
17
|
+
* frames between smooth-scroll ticks and judging one mid-flight would read
|
|
18
|
+
* the strip's own animation as the visitor's. Too short can latch it for good.
|
|
21
19
|
*/
|
|
22
20
|
const QUIET_BEFORE_SETTLED_MS = 250;
|
|
23
21
|
|
|
@@ -25,7 +23,6 @@ const QUIET_BEFORE_SETTLED_MS = 250;
|
|
|
25
23
|
* How much `scrollLeft` has to move, tick to tick, before a `scroll` event is
|
|
26
24
|
* even a CANDIDATE for arming (FUT-2775). Below this, a browser's own rounding
|
|
27
25
|
* or a repeated event carrying no real motion cannot arm anything by itself.
|
|
28
|
-
*
|
|
29
26
|
* This alone does not stop the false latch the ticket describes: the strip's
|
|
30
27
|
* own `scrollTo` produces real per-tick deltas well past this line, same as a
|
|
31
28
|
* drag would. It only rules out a scroll event that moved nothing.
|
|
@@ -33,16 +30,15 @@ const QUIET_BEFORE_SETTLED_MS = 250;
|
|
|
33
30
|
const SCROLL_DELTA_EPSILON = 2;
|
|
34
31
|
|
|
35
32
|
/**
|
|
36
|
-
* How far a pointer
|
|
37
|
-
*
|
|
38
|
-
* an held-still finger's sub-pixel tremor does not count as a drag.
|
|
33
|
+
* How far a pointer/touch must travel from where it went down to count as
|
|
34
|
+
* MOVED, not merely resting (FUT-2775) — below this, a held tremor isn't a drag.
|
|
39
35
|
*/
|
|
40
36
|
const POINTER_MOVE_EPSILON = 2;
|
|
41
37
|
|
|
42
38
|
/**
|
|
43
39
|
* How long a key, sideways wheel or pan stays armed through a scroll the strip
|
|
44
|
-
* made itself (FUT-2848)
|
|
45
|
-
* scroll ticks once
|
|
40
|
+
* made itself (FUT-2848) — a busy thread can finish a re-centre before the
|
|
41
|
+
* key's scroll ticks once; past this it lapses, so a later clamp isn't the visitor.
|
|
46
42
|
*/
|
|
47
43
|
const NUDGE_FRESH_MS = 1000;
|
|
48
44
|
|
|
@@ -82,6 +78,8 @@ function horizontalDelta(event: Event): number {
|
|
|
82
78
|
return event.deltaX !== 0 ? event.deltaX : event.shiftKey ? event.deltaY : 0;
|
|
83
79
|
}
|
|
84
80
|
|
|
81
|
+
const STRIP_SCROLLING_KEYS = new Set(['ArrowLeft', 'ArrowRight']); // verified live in Chromium (FUT-2862)
|
|
82
|
+
|
|
85
83
|
interface WatchState {
|
|
86
84
|
pointer: boolean;
|
|
87
85
|
touch: boolean;
|
|
@@ -246,7 +244,9 @@ function createGestureListeners(state: WatchState): { onStrip: Listeners; onView
|
|
|
246
244
|
nudge();
|
|
247
245
|
onPointerUp();
|
|
248
246
|
};
|
|
249
|
-
const onKeydown =
|
|
247
|
+
const onKeydown = (event: Event): void => {
|
|
248
|
+
if (event instanceof KeyboardEvent && STRIP_SCROLLING_KEYS.has(event.key)) nudge();
|
|
249
|
+
};
|
|
250
250
|
const onWheel = (event: Event): void => {
|
|
251
251
|
if (horizontalDelta(event) !== 0) nudge();
|
|
252
252
|
};
|
|
@@ -304,9 +304,9 @@ function dropStaleNudge(state: WatchState): void {
|
|
|
304
304
|
*
|
|
305
305
|
* - a finger held on the strip (`touchstart` until `touchend`) — a drag;
|
|
306
306
|
* - a pointer held on it (`pointerdown` until `pointerup`);
|
|
307
|
-
* - a key press
|
|
308
|
-
*
|
|
309
|
-
*
|
|
307
|
+
* - a strip-scrolling key press (`STRIP_SCROLLING_KEYS`, FUT-2862), a SIDEWAYS
|
|
308
|
+
* wheel, or the browser taking a pointer over to pan it (`pointercancel`),
|
|
309
|
+
* each armed until the next scroll under judgement has been judged.
|
|
310
310
|
*
|
|
311
311
|
* and the verdict waits until the strip comes to REST (`scrollend`, or a quiet
|
|
312
312
|
* spell where the browser has no `scrollend`): it is the visitor's only if the
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/layout/SettingsLayout/SettingsSectionChips.scroll.ts"],"sourcesContent":["/**\n * Telling the strip's own scrolls from the visitor's (FUT-2606).\n *\n * Split from `SettingsSectionChips.tsx` so the chips stay a component file and\n * the rule for \"who moved the strip\" can be read in one place.\n */\n\n/**\n * How near to where the strip aimed itself it has to come to rest for the scroll\n * to count as the strip's own. A smooth scroll lands on a device pixel, and the\n * target it was given is fractional.\n */\nconst LANDED_SLACK = 1;\n\n/**\n * Where `scrollend` is missing: how long the strip has to go without a `scroll`\n * before it counts as settled. Generous on purpose — a busy main thread can go\n * several frames between ticks of a smooth scroll, and judging one mid-flight\n * would read the strip's own animation as the visitor's. Too long only delays a\n * re-centre; too short can latch the strip for good.\n */\nconst QUIET_BEFORE_SETTLED_MS = 250;\n\n/**\n * How much `scrollLeft` has to move, tick to tick, before a `scroll` event is\n * even a CANDIDATE for arming (FUT-2775). Below this, a browser's own rounding\n * or a repeated event carrying no real motion cannot arm anything by itself.\n *\n * This alone does not stop the false latch the ticket describes: the strip's\n * own `scrollTo` produces real per-tick deltas well past this line, same as a\n * drag would. It only rules out a scroll event that moved nothing.\n */\nconst SCROLL_DELTA_EPSILON = 2;\n\n/**\n * How far a pointer or touch has to travel from where it went down before it\n * counts as having MOVED, rather than merely resting (FUT-2775). Below this,\n * an held-still finger's sub-pixel tremor does not count as a drag.\n */\nconst POINTER_MOVE_EPSILON = 2;\n\n/**\n * How long a key, sideways wheel or pan stays armed through a scroll the strip\n * made itself (FUT-2848): a busy thread can finish a re-centre before the key's\n * scroll ticks once. Past this it lapses, so a later clamp is not the visitor.\n */\nconst NUDGE_FRESH_MS = 1000;\n\ninterface VisitorScrollWatch {\n /** True once the visitor has moved the strip themselves. */\n hasScrolled: () => boolean;\n /**\n * True while a scroll the visitor MAY be making has not come to rest yet. The\n * strip must not scroll itself under it: that would yank a drag in progress.\n */\n isUndecided: () => boolean;\n /**\n * Where the strip last aimed itself, PHYSICAL pixels (see {@link physicalScrollLeft}) —\n * direction-blind, like every other geometry read in this file. `NaN` before it has.\n */\n aimedAt: () => number;\n /**\n * The strip is about to scroll itself to `left` (physical pixels). Records the\n * aim and NOTHING\n * else: it used to disarm too, and a re-centre landing between a visitor's key\n * press (or wheel, or pan) and the first tick of the scroll it causes wiped\n * the arming — their scroll went unclaimed, read as the strip's own. Left\n * armed, the worst a stale arming does is put the strip's OWN next scroll\n * under judgement, which rests on its aim, is not latched, and disarms.\n */\n beforeOwnScroll: (left: number) => void;\n /** Called once an undecided scroll has come to rest and been judged. */\n onSettled: (listener: () => void) => void;\n detach: () => void;\n}\n\ntype Listeners = Array<[string, (event: Event) => void]>;\n\n/** A wheel's sideways travel: `deltaX`, or `deltaY` with Shift held, as browsers read it. */\nfunction horizontalDelta(event: Event): number {\n if (!(event instanceof WheelEvent)) return 0;\n return event.deltaX !== 0 ? event.deltaX : event.shiftKey ? event.deltaY : 0;\n}\n\ninterface WatchState {\n pointer: boolean;\n touch: boolean;\n nudged: boolean;\n /** When `nudged` was set (`Date.now()` ms), and whether it outlived an own verdict. */\n nudgedAt: number;\n nudgeKept: boolean;\n undecided: boolean;\n scrolled: boolean;\n aimed: number;\n quiet: ReturnType<typeof setTimeout> | undefined;\n settled: () => void;\n /** `scrollLeft` as of the last `scroll` tick, updated every tick regardless of arming. */\n lastScrollLeft: number;\n /** Where a `pointerdown` on the strip landed, in viewport `clientX`. `NaN` while up. */\n pointerDownAt: number;\n /** True once that pointer has travelled past {@link POINTER_MOVE_EPSILON} from `pointerDownAt`. */\n pointerMoved: boolean;\n /** Same pair, for `touchstart`/`touchmove` — a distinct event stream on some engines. */\n touchDownAt: number;\n touchMoved: boolean;\n}\n\ntype RtlScrollType = 'default' | 'negative' | 'reverse';\n\nlet cachedRtlScrollType: RtlScrollType | undefined;\n\n/**\n * Which of the three incompatible conventions this engine reports an RTL\n * scroller's `scrollLeft` in, probed once and cached (FUT-2775).\n *\n * Per the CSSOM View spec, an RTL scroller's `scrollLeft` is `0` at its\n * (right-hand) start and goes NEGATIVE toward the end — `'negative'` below,\n * what every current evergreen engine implements. Older WebKit mirrored that\n * (`'reverse'`: `0` at the start, growing toward `+max`), and older\n * Chromium/Safari ignored `dir` altogether and kept the plain left-to-right\n * numbering (`'default'`). A hidden probe, not a version sniff, tells them\n * apart — the same technique `@mui/utils`'s `detectScrollType` uses for\n * `Tabs`; reimplemented here rather than taking a new dependency for one\n * probe.\n */\nfunction detectRtlScrollType(doc: Document): RtlScrollType {\n if (cachedRtlScrollType) return cachedRtlScrollType;\n // The exact pixel values below are the probe's mechanism, not a design size:\n // what matters is only that the INNER box is wider than the OUTER one, so the\n // outer one has something to scroll — same technique `@mui/utils` uses,\n // detached and off-screen either way.\n const probe = doc.createElement('div');\n const inner = doc.createElement('div');\n inner.style.width = '10px';\n probe.appendChild(inner);\n probe.dir = 'rtl';\n probe.style.width = '4px';\n probe.style.position = 'absolute';\n probe.style.top = '-1000px';\n probe.style.overflow = 'scroll';\n doc.body.appendChild(probe);\n let type: RtlScrollType = 'reverse';\n if (probe.scrollLeft > 0) {\n type = 'default';\n } else {\n probe.scrollLeft = 1;\n if (probe.scrollLeft === 0) type = 'negative';\n }\n doc.body.removeChild(probe);\n cachedRtlScrollType = type;\n return type;\n}\n\n/** True when the strip's own computed direction is right-to-left. */\nexport function isRtlStrip(strip: HTMLElement): boolean {\n const view = strip.ownerDocument.defaultView;\n const getComputedStyle = view?.getComputedStyle ?? globalThis.getComputedStyle;\n return getComputedStyle(strip).direction === 'rtl';\n}\n\n/**\n * `strip.scrollLeft`, renumbered so `0` is always the strip's physical LEFT\n * edge and larger is always further physically right — whatever `direction`\n * and whatever convention this engine uses to report it raw (FUT-2775).\n *\n * Every geometry read in this file (`getBoundingClientRect`) is already in\n * that same physical, direction-blind coordinate space, so this is what makes\n * `scrollLeft` combinable with it at all.\n */\nexport function physicalScrollLeft(strip: HTMLElement): number {\n const raw = strip.scrollLeft;\n if (!isRtlStrip(strip)) return raw;\n const max = strip.scrollWidth - strip.clientWidth;\n const type = detectRtlScrollType(strip.ownerDocument);\n if (type === 'negative') return raw + max;\n if (type === 'reverse') return max - raw;\n return raw;\n}\n\n/** The inverse of {@link physicalScrollLeft}: a physical offset back to this engine's raw `scrollLeft`. */\nexport function toRawScrollLeft(strip: HTMLElement, physical: number): number {\n if (!isRtlStrip(strip)) return physical;\n const max = strip.scrollWidth - strip.clientWidth;\n const type = detectRtlScrollType(strip.ownerDocument);\n if (type === 'negative') return physical - max;\n if (type === 'reverse') return max - physical;\n return physical;\n}\n\n/** Whether the gesture that armed `nudged` happened within {@link NUDGE_FRESH_MS}. */\nfunction nudgeIsFresh(state: WatchState): boolean {\n return Date.now() - state.nudgedAt <= NUDGE_FRESH_MS;\n}\n\n/** Whether the strip came to rest where it last aimed itself — clamped as the browser would. */\nfunction restsOnAim(strip: HTMLElement, aimed: number): boolean {\n const reachable = Math.min(aimed, strip.scrollWidth - strip.clientWidth);\n // Written so that `NaN` — the strip never aimed — reads as \"not on aim\".\n return Math.abs(physicalScrollLeft(strip) - reachable) <= LANDED_SLACK;\n}\n\n/** The pointer/touch/keydown/wheel listeners that arm `state`, split out of `watchVisitorScroll` (line budget). */\nfunction createGestureListeners(state: WatchState): { onStrip: Listeners; onView: Listeners } {\n // `MouseEvent`, not `PointerEvent`: a real `PointerEvent` IS one (it extends\n // `MouseEvent`), so this reads `clientX` off it just the same in a browser —\n // but jsdom (this file's own test environment) has never implemented\n // `PointerEvent` at all, and the bare identifier throws a `ReferenceError`\n // the moment anything evaluates `instanceof PointerEvent`, pointer event or\n // not. Same reasoning as feature-checking `scrollTo` elsewhere in this file:\n // nothing in here is worth a crash over which constructor a probe prefers.\n const onPointerDown = (event: Event): void => {\n state.pointer = true;\n state.pointerMoved = false;\n state.pointerDownAt = event instanceof MouseEvent ? event.clientX : Number.NaN;\n };\n const onPointerMove = (event: Event): void => {\n if (!(event instanceof MouseEvent) || Number.isNaN(state.pointerDownAt)) return;\n if (Math.abs(event.clientX - state.pointerDownAt) > POINTER_MOVE_EPSILON) state.pointerMoved = true;\n };\n const onPointerUp = (): void => {\n state.pointer = false;\n state.pointerDownAt = Number.NaN;\n };\n const onTouchStart = (event: Event): void => {\n state.touch = true;\n state.touchMoved = false;\n state.touchDownAt = event instanceof TouchEvent ? (event.touches[0]?.clientX ?? Number.NaN) : Number.NaN;\n };\n const onTouchMove = (event: Event): void => {\n if (!(event instanceof TouchEvent) || Number.isNaN(state.touchDownAt)) return;\n const clientX = event.touches[0]?.clientX;\n if (clientX !== undefined && Math.abs(clientX - state.touchDownAt) > POINTER_MOVE_EPSILON) {\n state.touchMoved = true;\n }\n };\n const onTouchEnd = (): void => {\n state.touch = false;\n state.touchDownAt = Number.NaN;\n };\n const nudge = (): void => {\n state.nudged = true;\n state.nudgedAt = Date.now();\n state.nudgeKept = false;\n };\n const onPointerCancel = (): void => {\n nudge();\n onPointerUp();\n };\n const onKeydown = nudge;\n const onWheel = (event: Event): void => {\n if (horizontalDelta(event) !== 0) nudge();\n };\n return {\n onStrip: [\n ['pointerdown', onPointerDown],\n ['pointermove', onPointerMove],\n ['touchstart', onTouchStart],\n ['touchmove', onTouchMove],\n ['pointercancel', onPointerCancel],\n ['keydown', onKeydown],\n ['wheel', onWheel],\n ],\n // A gesture can END off the strip, so its end is heard on the window.\n onView: [\n ['pointerup', onPointerUp],\n ['pointercancel', onPointerUp],\n ['touchend', onTouchEnd],\n ['touchcancel', onTouchEnd],\n ],\n };\n}\n\n/**\n * Judge the scroll under judgement once the strip rests. Only a scroll UNDER\n * JUDGEMENT disarms: Chromium can fire `scrollend` for the strip's own scroll\n * cut off by another BEFORE that one's first `scroll`, and disarming there\n * would hand the visitor's scroll to nobody.\n */\nfunction settleJudgement(strip: HTMLElement, state: WatchState): void {\n if (!state.undecided) return;\n state.undecided = false;\n const own = restsOnAim(strip, state.aimed);\n if (!own) state.scrolled = true;\n // The strip's own scroll does not use up a gesture armed moments ago: the\n // scroll that gesture causes may still be on its way (FUT-2848).\n state.nudgeKept = own && nudgeIsFresh(state);\n if (!state.nudgeKept) state.nudged = false;\n state.settled();\n}\n\n/** A gesture kept through the strip's own scroll lapses once stale (FUT-2848). */\nfunction dropStaleNudge(state: WatchState): void {\n if (!state.nudgeKept || nudgeIsFresh(state)) return;\n state.nudged = false;\n state.nudgeKept = false;\n}\n\n/**\n * Tell a scroll the VISITOR made from every other one.\n *\n * The `scroll` event cannot say: the strip's own `scrollTo` fires it, and so does\n * the browser clamping a strip whose content shrank. So a scroll is only a\n * CANDIDATE when it arrives during something only a visitor does:\n *\n * - a finger held on the strip (`touchstart` until `touchend`) — a drag;\n * - a pointer held on it (`pointerdown` until `pointerup`);\n * - a key press, a SIDEWAYS wheel, or the browser taking a pointer over to pan\n * it (`pointercancel`), each armed until the next scroll under judgement has\n * been judged — whoever's it turns out to be.\n *\n * and the verdict waits until the strip comes to REST (`scrollend`, or a quiet\n * spell where the browser has no `scrollend`): it is the visitor's only if the\n * strip rests somewhere other than where it last aimed itself.\n *\n * Judged at rest rather than per `scroll` because the strip's own smooth scroll\n * fires `scroll` for a third of a second, and a visitor who presses Tab or puts\n * a finger on a chip to scroll the PAGE in that window is not scrolling the\n * strip. Every tick of that animation used to count as theirs, the strip stopped\n * re-centring for good, and the open chip could be left clipped (FUT-2606\n * again, by another door). A visitor who really drags or wheels the strip\n * mid-animation cancels it, so the strip rests where THEY left it — and that\n * still counts. The one loss: a visitor who happens to leave it within a pixel\n * of the strip's own aim is not told apart from it, and the strip there is\n * already where it would have put itself.\n *\n * A tap is a pointer held with no scroll under it, so it never counts. A\n * vertical wheel scrolls the PAGE — the strip is `overflowY: hidden` — and is\n * not armed at all.\n */\nexport function watchVisitorScroll(strip: HTMLElement): VisitorScrollWatch {\n const view = strip.ownerDocument.defaultView;\n const hasScrollEnd = 'onscrollend' in strip;\n const state: WatchState = {\n pointer: false,\n touch: false,\n nudged: false,\n nudgedAt: Number.NaN,\n nudgeKept: false,\n undecided: false,\n scrolled: false,\n aimed: Number.NaN,\n quiet: undefined,\n settled: () => undefined,\n lastScrollLeft: physicalScrollLeft(strip),\n pointerDownAt: Number.NaN,\n pointerMoved: false,\n touchDownAt: Number.NaN,\n touchMoved: false,\n };\n const settle = (): void => settleJudgement(strip, state);\n const onScroll = (): void => {\n const now = physicalScrollLeft(strip);\n const movedFarEnough = Math.abs(now - state.lastScrollLeft) > SCROLL_DELTA_EPSILON;\n state.lastScrollLeft = now;\n // Pointer/touch need BOTH signals (FUT-2775): the pointer/finger must have\n // itself MOVED since going down, AND this tick's delta must be real. Either\n // alone still latches on the other's shape — a pointer merely resting on\n // the strip while its OWN `scrollTo` produces real per-tick deltas would\n // arm under a delta-only check (`pointerMoved`/`touchMoved` rules that out);\n // a pointer that drifts a sub-epsilon amount while resting would arm under\n // a moved-only check with no delta floor (`movedFarEnough` rules that out).\n dropStaleNudge(state);\n const pointerDrag = state.pointer && state.pointerMoved && movedFarEnough;\n const touchDrag = state.touch && state.touchMoved && movedFarEnough;\n // `nudged` (a keypress, a sideways wheel, the browser taking the pointer\n // over to pan) is already a discrete, one-shot gesture with no \"resting\n // pointer coincides with an unrelated animation\" shape to rule out — unlike\n // pointer/touch, requiring a delta on the SAME tick that arms it would only\n // race the strip's own scroll ending before a qualifying tick arrives (seen:\n // it broke the existing \"keeps a wheel/drag scroll\" stories against a real\n // browser's `scrollend` timing). So it arms as it always has.\n if (pointerDrag || touchDrag || state.nudged) state.undecided = true;\n if (!state.undecided || hasScrollEnd) return;\n // Every tick while undecided, armed or not: a quiet spell that began while\n // the strip was still moving would judge it mid-flight, away from its aim.\n clearTimeout(state.quiet);\n state.quiet = setTimeout(settle, QUIET_BEFORE_SETTLED_MS);\n };\n const gestures = createGestureListeners(state);\n const onStrip: Listeners = [...gestures.onStrip, ['scroll', onScroll], ['scrollend', settle]];\n const onView = gestures.onView;\n for (const [type, listener] of onStrip) strip.addEventListener(type, listener, { passive: true });\n for (const [type, listener] of onView) view?.addEventListener(type, listener, { passive: true });\n return {\n hasScrolled: () => state.scrolled,\n isUndecided: () => state.undecided,\n aimedAt: () => state.aimed,\n beforeOwnScroll: (left) => {\n state.aimed = left;\n },\n onSettled: (listener) => {\n state.settled = listener;\n },\n detach: () => {\n clearTimeout(state.quiet);\n for (const [type, listener] of onStrip) strip.removeEventListener(type, listener);\n for (const [type, listener] of onView) view?.removeEventListener(type, listener);\n },\n };\n}\n"],"mappings":";AAYA,IAAM,eAAe;AASrB,IAAM,0BAA0B;AAWhC,IAAM,uBAAuB;AAO7B,IAAM,uBAAuB;AAO7B,IAAM,iBAAiB;AAiCvB,SAAS,gBAAgB,OAAsB;AAC7C,MAAI,EAAE,iBAAiB,YAAa,QAAO;AAC3C,SAAO,MAAM,WAAW,IAAI,MAAM,SAAS,MAAM,WAAW,MAAM,SAAS;AAC7E;AA2BA,IAAI;AAgBJ,SAAS,oBAAoB,KAA8B;AACzD,MAAI,oBAAqB,QAAO;AAKhC,QAAM,QAAQ,IAAI,cAAc,KAAK;AACrC,QAAM,QAAQ,IAAI,cAAc,KAAK;AACrC,QAAM,MAAM,QAAQ;AACpB,QAAM,YAAY,KAAK;AACvB,QAAM,MAAM;AACZ,QAAM,MAAM,QAAQ;AACpB,QAAM,MAAM,WAAW;AACvB,QAAM,MAAM,MAAM;AAClB,QAAM,MAAM,WAAW;AACvB,MAAI,KAAK,YAAY,KAAK;AAC1B,MAAI,OAAsB;AAC1B,MAAI,MAAM,aAAa,GAAG;AACxB,WAAO;AAAA,EACT,OAAO;AACL,UAAM,aAAa;AACnB,QAAI,MAAM,eAAe,EAAG,QAAO;AAAA,EACrC;AACA,MAAI,KAAK,YAAY,KAAK;AAC1B,wBAAsB;AACtB,SAAO;AACT;AAGO,SAAS,WAAW,OAA6B;AACtD,QAAM,OAAO,MAAM,cAAc;AACjC,QAAM,mBAAmB,MAAM,oBAAoB,WAAW;AAC9D,SAAO,iBAAiB,KAAK,EAAE,cAAc;AAC/C;AAWO,SAAS,mBAAmB,OAA4B;AAC7D,QAAM,MAAM,MAAM;AAClB,MAAI,CAAC,WAAW,KAAK,EAAG,QAAO;AAC/B,QAAM,MAAM,MAAM,cAAc,MAAM;AACtC,QAAM,OAAO,oBAAoB,MAAM,aAAa;AACpD,MAAI,SAAS,WAAY,QAAO,MAAM;AACtC,MAAI,SAAS,UAAW,QAAO,MAAM;AACrC,SAAO;AACT;AAGO,SAAS,gBAAgB,OAAoB,UAA0B;AAC5E,MAAI,CAAC,WAAW,KAAK,EAAG,QAAO;AAC/B,QAAM,MAAM,MAAM,cAAc,MAAM;AACtC,QAAM,OAAO,oBAAoB,MAAM,aAAa;AACpD,MAAI,SAAS,WAAY,QAAO,WAAW;AAC3C,MAAI,SAAS,UAAW,QAAO,MAAM;AACrC,SAAO;AACT;AAGA,SAAS,aAAa,OAA4B;AAChD,SAAO,KAAK,IAAI,IAAI,MAAM,YAAY;AACxC;AAGA,SAAS,WAAW,OAAoB,OAAwB;AAC9D,QAAM,YAAY,KAAK,IAAI,OAAO,MAAM,cAAc,MAAM,WAAW;AAEvE,SAAO,KAAK,IAAI,mBAAmB,KAAK,IAAI,SAAS,KAAK;AAC5D;AAGA,SAAS,uBAAuB,OAA8D;AAQ5F,QAAM,gBAAgB,CAAC,UAAuB;AAC5C,UAAM,UAAU;AAChB,UAAM,eAAe;AACrB,UAAM,gBAAgB,iBAAiB,aAAa,MAAM,UAAU,OAAO;AAAA,EAC7E;AACA,QAAM,gBAAgB,CAAC,UAAuB;AAC5C,QAAI,EAAE,iBAAiB,eAAe,OAAO,MAAM,MAAM,aAAa,EAAG;AACzE,QAAI,KAAK,IAAI,MAAM,UAAU,MAAM,aAAa,IAAI,qBAAsB,OAAM,eAAe;AAAA,EACjG;AACA,QAAM,cAAc,MAAY;AAC9B,UAAM,UAAU;AAChB,UAAM,gBAAgB,OAAO;AAAA,EAC/B;AACA,QAAM,eAAe,CAAC,UAAuB;AAC3C,UAAM,QAAQ;AACd,UAAM,aAAa;AACnB,UAAM,cAAc,iBAAiB,aAAc,MAAM,QAAQ,CAAC,GAAG,WAAW,OAAO,MAAO,OAAO;AAAA,EACvG;AACA,QAAM,cAAc,CAAC,UAAuB;AAC1C,QAAI,EAAE,iBAAiB,eAAe,OAAO,MAAM,MAAM,WAAW,EAAG;AACvE,UAAM,UAAU,MAAM,QAAQ,CAAC,GAAG;AAClC,QAAI,YAAY,UAAa,KAAK,IAAI,UAAU,MAAM,WAAW,IAAI,sBAAsB;AACzF,YAAM,aAAa;AAAA,IACrB;AAAA,EACF;AACA,QAAM,aAAa,MAAY;AAC7B,UAAM,QAAQ;AACd,UAAM,cAAc,OAAO;AAAA,EAC7B;AACA,QAAM,QAAQ,MAAY;AACxB,UAAM,SAAS;AACf,UAAM,WAAW,KAAK,IAAI;AAC1B,UAAM,YAAY;AAAA,EACpB;AACA,QAAM,kBAAkB,MAAY;AAClC,UAAM;AACN,gBAAY;AAAA,EACd;AACA,QAAM,YAAY;AAClB,QAAM,UAAU,CAAC,UAAuB;AACtC,QAAI,gBAAgB,KAAK,MAAM,EAAG,OAAM;AAAA,EAC1C;AACA,SAAO;AAAA,IACL,SAAS;AAAA,MACP,CAAC,eAAe,aAAa;AAAA,MAC7B,CAAC,eAAe,aAAa;AAAA,MAC7B,CAAC,cAAc,YAAY;AAAA,MAC3B,CAAC,aAAa,WAAW;AAAA,MACzB,CAAC,iBAAiB,eAAe;AAAA,MACjC,CAAC,WAAW,SAAS;AAAA,MACrB,CAAC,SAAS,OAAO;AAAA,IACnB;AAAA;AAAA,IAEA,QAAQ;AAAA,MACN,CAAC,aAAa,WAAW;AAAA,MACzB,CAAC,iBAAiB,WAAW;AAAA,MAC7B,CAAC,YAAY,UAAU;AAAA,MACvB,CAAC,eAAe,UAAU;AAAA,IAC5B;AAAA,EACF;AACF;AAQA,SAAS,gBAAgB,OAAoB,OAAyB;AACpE,MAAI,CAAC,MAAM,UAAW;AACtB,QAAM,YAAY;AAClB,QAAM,MAAM,WAAW,OAAO,MAAM,KAAK;AACzC,MAAI,CAAC,IAAK,OAAM,WAAW;AAG3B,QAAM,YAAY,OAAO,aAAa,KAAK;AAC3C,MAAI,CAAC,MAAM,UAAW,OAAM,SAAS;AACrC,QAAM,QAAQ;AAChB;AAGA,SAAS,eAAe,OAAyB;AAC/C,MAAI,CAAC,MAAM,aAAa,aAAa,KAAK,EAAG;AAC7C,QAAM,SAAS;AACf,QAAM,YAAY;AACpB;AAkCO,SAAS,mBAAmB,OAAwC;AACzE,QAAM,OAAO,MAAM,cAAc;AACjC,QAAM,eAAe,iBAAiB;AACtC,QAAM,QAAoB;AAAA,IACxB,SAAS;AAAA,IACT,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,UAAU,OAAO;AAAA,IACjB,WAAW;AAAA,IACX,WAAW;AAAA,IACX,UAAU;AAAA,IACV,OAAO,OAAO;AAAA,IACd,OAAO;AAAA,IACP,SAAS,MAAM;AAAA,IACf,gBAAgB,mBAAmB,KAAK;AAAA,IACxC,eAAe,OAAO;AAAA,IACtB,cAAc;AAAA,IACd,aAAa,OAAO;AAAA,IACpB,YAAY;AAAA,EACd;AACA,QAAM,SAAS,MAAY,gBAAgB,OAAO,KAAK;AACvD,QAAM,WAAW,MAAY;AAC3B,UAAM,MAAM,mBAAmB,KAAK;AACpC,UAAM,iBAAiB,KAAK,IAAI,MAAM,MAAM,cAAc,IAAI;AAC9D,UAAM,iBAAiB;AAQvB,mBAAe,KAAK;AACpB,UAAM,cAAc,MAAM,WAAW,MAAM,gBAAgB;AAC3D,UAAM,YAAY,MAAM,SAAS,MAAM,cAAc;AAQrD,QAAI,eAAe,aAAa,MAAM,OAAQ,OAAM,YAAY;AAChE,QAAI,CAAC,MAAM,aAAa,aAAc;AAGtC,iBAAa,MAAM,KAAK;AACxB,UAAM,QAAQ,WAAW,QAAQ,uBAAuB;AAAA,EAC1D;AACA,QAAM,WAAW,uBAAuB,KAAK;AAC7C,QAAM,UAAqB,CAAC,GAAG,SAAS,SAAS,CAAC,UAAU,QAAQ,GAAG,CAAC,aAAa,MAAM,CAAC;AAC5F,QAAM,SAAS,SAAS;AACxB,aAAW,CAAC,MAAM,QAAQ,KAAK,QAAS,OAAM,iBAAiB,MAAM,UAAU,EAAE,SAAS,KAAK,CAAC;AAChG,aAAW,CAAC,MAAM,QAAQ,KAAK,OAAQ,OAAM,iBAAiB,MAAM,UAAU,EAAE,SAAS,KAAK,CAAC;AAC/F,SAAO;AAAA,IACL,aAAa,MAAM,MAAM;AAAA,IACzB,aAAa,MAAM,MAAM;AAAA,IACzB,SAAS,MAAM,MAAM;AAAA,IACrB,iBAAiB,CAAC,SAAS;AACzB,YAAM,QAAQ;AAAA,IAChB;AAAA,IACA,WAAW,CAAC,aAAa;AACvB,YAAM,UAAU;AAAA,IAClB;AAAA,IACA,QAAQ,MAAM;AACZ,mBAAa,MAAM,KAAK;AACxB,iBAAW,CAAC,MAAM,QAAQ,KAAK,QAAS,OAAM,oBAAoB,MAAM,QAAQ;AAChF,iBAAW,CAAC,MAAM,QAAQ,KAAK,OAAQ,OAAM,oBAAoB,MAAM,QAAQ;AAAA,IACjF;AAAA,EACF;AACF;","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|