Function
The player whose element every pointer event on the chrome bubbles to. Its element is read when the listeners are attached, not while rendering, and the player itself must keep its identity between renders — a fresh object each render re-attaches the listeners and drops a hold in flight
true while a hold is armed
The hold is timed here because the library has no event for it.
Vidstack's Gesture knows pointerup, dblpointerup and the provider's
media events; the nearest it offers is an action on the release, which
would speed the video up at the moment the finger lifts — the opposite of
the gesture. So the press is timed against the player element, the same
node PlaybackGestures already listens on for a seek run's taps.
The hook says when, not what. It reports a boolean and changes no playback rate: the rate to apply, and the rate to put back, belong to the caller that holds the player and the remote. That keeps everything here testable without a media provider.
A press that drifts is a swipe, not a hold. Enlarged, the player
deliberately never locks the page's scroll, because on an iPhone only a real
swipe travelling through the pinned player hides Safari's toolbar. A finger
resting there on its way to that swipe is a frequent, ordinary event, so a
press that moves past HOLD_MOVE_TOLERANCE_PX before the delay arms
nothing. Once armed, movement is ignored — the finger is deliberately down —
and the browser's own pointercancel ends the hold when it claims the touch
for the scroll.
Releases are heard on the document rather than on the player: a finger that wandered off the player before lifting would otherwise leave a hold armed with nothing left to end it.
The play/pause key is taken from the library in the capture phase.
Vidstack binds Space and K to togglePaused and acts on keydown, so
a learner who held the key would have the lesson paused half a second before
the hold could arm. Its listener is on the player element and it stops the
event there, so the only place left to intercept is the document, capturing —
which also means the library never sees the key at all and cannot toggle
twice. The tap it used to handle is reported back through onKeyTap.
The library does offer a shortcut table that can carry a handler, and it was
tried first. It cannot be relied on: the chrome's play button registers the
same shortcut through aria-keyshortcuts, and that registration is a plain
key list that overrides whatever the table holds — so the handler is skipped
and the library toggles anyway.
A release is reported one frame late, on purpose. The browser delivers a
touch release as pointerup and then touchend, and Vidstack's tap gesture
listens for the second of those on a coarse pointer. Ending the hold between
the two would re-enable that gesture in time for it to read the release as a
tap — which is exactly how releasing a hold used to pause the lesson on an
iPhone while leaving a mouse unaffected. Waiting for the next animation frame
puts the whole release behind us before the caller is told.
contextmenu is suppressed while a press is in flight, so a desktop press
does not raise a menu over the indicator it just drew. Its touch counterpart
— iOS Safari's callout — is not an event and is turned off in the player's
stylesheet instead.
Reports whether the learner is pressing and holding the video.