polite-media 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +78 -0
- package/README.md +109 -23
- package/dist/coordinator.d.ts +47 -1
- package/dist/coordinator.d.ts.map +1 -1
- package/dist/coordinator.js +120 -79
- package/dist/coordinator.js.map +1 -1
- package/dist/fade.d.ts +11 -0
- package/dist/fade.d.ts.map +1 -0
- package/dist/fade.js +17 -0
- package/dist/fade.js.map +1 -0
- package/dist/image.css +1 -1
- package/dist/image.d.ts.map +1 -1
- package/dist/image.js +15 -5
- package/dist/image.js.map +1 -1
- package/dist/sources.js +4 -4
- package/dist/targets.d.ts.map +1 -1
- package/dist/targets.js +0 -2
- package/dist/targets.js.map +1 -1
- package/dist/video.css +1 -1
- package/dist/warming.d.ts +4 -1
- package/dist/warming.d.ts.map +1 -1
- package/dist/warming.js +3 -0
- package/dist/warming.js.map +1 -1
- package/package.json +13 -13
- package/src/coordinator.ts +147 -83
- package/src/fade.ts +19 -0
- package/src/image.css +3 -1
- package/src/image.ts +17 -5
- package/src/sources.ts +4 -4
- package/src/targets.ts +0 -2
- package/src/video.css +13 -6
- package/src/warming.ts +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,84 @@
|
|
|
3
3
|
Notable changes, newest first. Versions follow [semver](https://semver.org); while
|
|
4
4
|
this is `0.x`, a minor bump may still break things and will say so here.
|
|
5
5
|
|
|
6
|
+
## 0.6.0 (2026-10-07)
|
|
7
|
+
|
|
8
|
+
### Breaking
|
|
9
|
+
|
|
10
|
+
- **`data-polite-active` is on `<html>` only while a registered video may play.** It used to stay
|
|
11
|
+
for as long as any video was registered, so under reduced motion, on Save-Data or a 2g connection,
|
|
12
|
+
or with `atOnce` at `0`, the README's recipe showed a pause control with nothing to stop. It now
|
|
13
|
+
follows those gates on every reconcile, and a user pause keeps it, since the control is then what
|
|
14
|
+
resumes. CSS that used the attribute to mean "a video is registered" needs another hook.
|
|
15
|
+
|
|
16
|
+
- **A revealed poster is hidden with `opacity`, so its `alt` stays in the accessibility tree.**
|
|
17
|
+
`video.css` hid it with `visibility: hidden`, which removes it from the tree, while the README
|
|
18
|
+
tells you to put the meaning in the poster's `alt` and hide the video. It now sets
|
|
19
|
+
`opacity: 0 !important` and `pointer-events: none` on the poster image, inside a `<picture>` too,
|
|
20
|
+
after the same `--polite-fade` delay. `!important` because image.css's failsafe animation would
|
|
21
|
+
otherwise keep a marked poster that nothing manages opaque. A rule of yours that changes the
|
|
22
|
+
poster's opacity after the reveal now needs `!important` as well, and a test that waited for the
|
|
23
|
+
poster with Playwright's `toBeHidden()` must wait for computed opacity `0`, since Playwright
|
|
24
|
+
counts an element at opacity 0 as visible.
|
|
25
|
+
|
|
26
|
+
- **`smallViewport` defaults to `'(max-width: 767.98px)'`**, from `'(max-width: 767px)'`. Beside a
|
|
27
|
+
`(min-width: 768px)` the old default left every width between 767px and 768px, which page zoom
|
|
28
|
+
produces, matching neither, so arbitration treated those viewports as large. The gap is now
|
|
29
|
+
0.02px. Range syntax would close it fully, but Safari before 16.4 never matches it. Pass
|
|
30
|
+
`smallViewport` yourself to keep the old value.
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- **A warning when a registered video is not decorative.** The markup contract asks for
|
|
35
|
+
`tabindex="-1" aria-hidden="true"` on the video, and nothing checked it. `register()` now warns
|
|
36
|
+
once per page, naming the video, when its `tabindex` attribute is not `-1` or no
|
|
37
|
+
`aria-hidden="true"` sits on the video or a box around it.
|
|
38
|
+
|
|
39
|
+
- **A warning when `--polite-fade` is not a CSS time.** A value such as `0.6` computes to `0s`
|
|
40
|
+
rather than to the stylesheet's default, so it silently removed the image fade. The first video
|
|
41
|
+
box and the first fading image that see such a value are named once per page. The browser parses
|
|
42
|
+
the value, so `calc(0.3s * 2)` passes, and a bare `0` stays quiet because it gives the cut it
|
|
43
|
+
looks like.
|
|
44
|
+
|
|
45
|
+
- **`register(video, { until, prefetchWhileGated: true })`** lets a gated video download while it
|
|
46
|
+
waits, so a splash buys it load time. A gate used to hold the fetch as well as playback, and that
|
|
47
|
+
stays the default, since a page may rely on a consent dialog holding the bytes too. The download
|
|
48
|
+
still waits for `startWhen`, reduced motion, Save-Data and a user pause, and starts once the video
|
|
49
|
+
is on screen or within `prefetchMargin`. A host can end its splash on the video's own
|
|
50
|
+
`canplaythrough`, which fires while the gate still holds; the README shows the recipe.
|
|
51
|
+
|
|
52
|
+
### Fixed
|
|
53
|
+
|
|
54
|
+
- **`warm()` with `sources` fetched the candidate for the full viewport width.** A `<source>`
|
|
55
|
+
without its own `sizes` is selected as if it said `100vw`, and `sizes` went on the `<img>` alone,
|
|
56
|
+
so a desktop warm could fetch a file several times the size the destination then picked. Every
|
|
57
|
+
`<source>` now carries the `sizes` it was passed.
|
|
58
|
+
|
|
59
|
+
- **A video buffered ahead through `prefetchMargin` started playing off screen when its first source
|
|
60
|
+
could not be decoded.** The source fallback revealed and played whatever came next, whether or not
|
|
61
|
+
anything had asked the video to play. It now moves to the next source and waits.
|
|
62
|
+
|
|
63
|
+
- **A lazy image still faded in under reduced motion.** `image.css`'s reduced-motion rule lost on
|
|
64
|
+
specificity to the rule that sets the fade, so the README's promise that reduced motion overrides
|
|
65
|
+
`--polite-fade` held only for eager images that opted in. Lazy images now arrive at once there.
|
|
66
|
+
|
|
67
|
+
- **A paused page still buffered videos within `prefetchMargin`.** The prefetch observer fetched
|
|
68
|
+
without asking whether the visitor had paused. It now waits, and resuming starts the fetch.
|
|
69
|
+
|
|
70
|
+
### Documentation
|
|
71
|
+
|
|
72
|
+
- **`register()` and `pauseAll()` carry their documentation in the published types.** Their doc
|
|
73
|
+
comments sat above other functions, so an editor hovering either showed nothing.
|
|
74
|
+
|
|
75
|
+
- **An `until` gate does not protect LCP**, and the README no longer says it does. The video's
|
|
76
|
+
first frame is an LCP candidate whenever it paints; only `startWhen: 'interaction'` keeps it out.
|
|
77
|
+
The poster-`load` gate example is gone for the same reason.
|
|
78
|
+
- **A gate that never settles holds its video for good.** The README shows racing it against a
|
|
79
|
+
timeout of your own.
|
|
80
|
+
- **The wrapper recipe in "Composing your own animation" gates only on images that will load.**
|
|
81
|
+
Lazy images in a horizontal scroller may never be fetched, so a wrapper waiting on all of them
|
|
82
|
+
waits for its failsafe.
|
|
83
|
+
|
|
6
84
|
## 0.5.0 (2026-09-12)
|
|
7
85
|
|
|
8
86
|
### Breaking
|
package/README.md
CHANGED
|
@@ -166,9 +166,12 @@ console names any image in that state, so widen the selector or drop the
|
|
|
166
166
|
attribute. An eager image is never hidden; give the attribute the value `eager`
|
|
167
167
|
to opt one into the fade anyway.
|
|
168
168
|
|
|
169
|
-
`data-polite-active` is on `<html>`
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
`data-polite-active` is on `<html>` while a registered video may play. It is
|
|
170
|
+
absent when nothing is registered, under reduced motion, on Save-Data or a 2g
|
|
171
|
+
connection, and where `atOnce` is `0` for the viewport; a user pause keeps it,
|
|
172
|
+
since the control is then what resumes. A pause control is markup on every page,
|
|
173
|
+
but it must not offer to stop something that cannot move, and CSS alone cannot
|
|
174
|
+
see most of those reasons:
|
|
172
175
|
|
|
173
176
|
```css
|
|
174
177
|
[data-polite-pause-control] {
|
|
@@ -207,6 +210,14 @@ bundle that never arrives leaves your wrapper hidden for good even though the
|
|
|
207
210
|
library's own failsafe fired. Give any rule of yours that hides on
|
|
208
211
|
`:not([data-polite-ready])` its own failsafe on the same delay.
|
|
209
212
|
|
|
213
|
+
**Gate a wrapper only on images that will load.** The `:has()` above waits on
|
|
214
|
+
every marked image inside the card, and lazy loading may never fetch some of
|
|
215
|
+
them. Measured in Chromium, in a 412px-wide horizontal scroller of nine lazy
|
|
216
|
+
images, only the first three loaded, and three in the middle never did, even
|
|
217
|
+
after scrolling past them. A card holding that scroller waits for your failsafe
|
|
218
|
+
and then appears unfaded. Gate it on the images in view when it appears, such as
|
|
219
|
+
the first, or leave scrollers out of the rule.
|
|
220
|
+
|
|
210
221
|
One limit worth knowing: a skipped `content-visibility: auto` subtree runs no
|
|
211
222
|
animations, so neither failsafe fires there until the section is scrolled into
|
|
212
223
|
view. It resolves itself the moment anyone looks at it, which is the only moment
|
|
@@ -249,14 +260,18 @@ it could have mattered.
|
|
|
249
260
|
6. The video carries `tabindex="-1" aria-hidden="true"`. It is decorative, and
|
|
250
261
|
without this it lands in the tab order: measured in Firefox, twelve background
|
|
251
262
|
videos sat ahead of the pause button, so a keyboard user reached it on the
|
|
252
|
-
thirteenth Tab.
|
|
263
|
+
thirteenth Tab. The console says so once per page when a registered video
|
|
264
|
+
lacks either; `aria-hidden` on a box around it counts too. Anything the
|
|
265
|
+
picture means goes in the poster's `alt`: the reveal hides the poster with
|
|
266
|
+
`opacity`, not `visibility`, so it stays in the accessibility tree while the
|
|
267
|
+
video plays.
|
|
253
268
|
|
|
254
269
|
## API
|
|
255
270
|
|
|
256
271
|
```js
|
|
257
272
|
// polite-media/video
|
|
258
|
-
register(video, { until, observe, startWhen }); // manage a video
|
|
259
|
-
registerAll(target?, { until, startWhen }); //
|
|
273
|
+
register(video, { until, observe, startWhen, prefetchWhileGated }); // manage a video
|
|
274
|
+
registerAll(target?, { until, startWhen, prefetchWhileGated }); // every [data-polite-media] video by default
|
|
260
275
|
unregister(video); // stop managing it, release everything
|
|
261
276
|
unregisterAll(); // tear down the whole page
|
|
262
277
|
configure({ ... }); // before the first register, or it throws
|
|
@@ -309,7 +324,13 @@ rather than guessed.
|
|
|
309
324
|
| option | default | reach for it when |
|
|
310
325
|
| --------------- | ---------------------------- | ---------------------------------------------------------- |
|
|
311
326
|
| `atOnce` | `{ small: 1, large: 'all' }` | a feed wants one at a time everywhere, or phones want none |
|
|
312
|
-
| `smallViewport` | `'(max-width:
|
|
327
|
+
| `smallViewport` | `'(max-width: 767.98px)'` | your breakpoint is not ours |
|
|
328
|
+
|
|
329
|
+
The `smallViewport` default meets a `(min-width: 768px)` with a 0.02px gap rather
|
|
330
|
+
than a whole pixel, so a fractional width from page zoom lands on one side. Pair
|
|
331
|
+
your own queries the same way. Range syntax, `(width < 768px)`, would close the
|
|
332
|
+
gap entirely, but Safari before 16.4 never matches it, so phones there would
|
|
333
|
+
count as large and play every visible video at once.
|
|
313
334
|
|
|
314
335
|
**When may it begin?**
|
|
315
336
|
|
|
@@ -338,30 +359,70 @@ effect on the next pass.
|
|
|
338
359
|
callers: a `2` would otherwise fall through to the single-slot branch and quietly
|
|
339
360
|
mean `1`.
|
|
340
361
|
|
|
341
|
-
**A malformed `smallViewport`
|
|
342
|
-
not throw and does not normalise to anything recognisable; Chromium echoes
|
|
343
|
-
text straight back and never matches. So `smallViewport: '(max-width: 767)'`,
|
|
362
|
+
**A malformed `smallViewport` is not checked for you.** An invalid media query
|
|
363
|
+
does not throw and does not normalise to anything recognisable; Chromium echoes
|
|
364
|
+
the text straight back and never matches. So `smallViewport: '(max-width: 767)'`,
|
|
344
365
|
missing its unit, means arbitration silently never engages and phones behave like
|
|
345
|
-
desktops. Check
|
|
366
|
+
desktops. Check it in the console on both sides of your breakpoint:
|
|
367
|
+
`matchMedia(query).matches` should be `true` below it and `false` above. A
|
|
368
|
+
malformed query is `false` on both.
|
|
346
369
|
|
|
347
370
|
### Per-video gates
|
|
348
371
|
|
|
349
372
|
`register(video, { until: promise })` holds a video back until the promise
|
|
350
|
-
settles: for a splash screen
|
|
351
|
-
|
|
352
|
-
|
|
373
|
+
settles: for a splash screen or a consent dialog. A hero at scroll-top is
|
|
374
|
+
reported visible in the observer's very first batch, so without this it starts
|
|
375
|
+
before whatever the page is waiting on has finished.
|
|
376
|
+
|
|
377
|
+
**A gate delays the video; it does not keep it out of Largest Contentful Paint.**
|
|
378
|
+
The first frame is an LCP candidate like any image, whenever it paints: measured
|
|
379
|
+
in Chromium on a real hero gated behind a splash, the video's first frame
|
|
380
|
+
replaced the poster as the LCP element just after the gate opened. Only
|
|
381
|
+
[`startWhen: 'interaction'`](#startwhen) keeps a video out of LCP.
|
|
382
|
+
|
|
383
|
+
The gate opens when the promise settles, fulfilled or rejected, and not
|
|
384
|
+
otherwise: one that never settles holds the video on its poster for the life of
|
|
385
|
+
the page. If whatever resolves it might never run, race it against a timeout of
|
|
386
|
+
your own:
|
|
353
387
|
|
|
354
388
|
```js
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
const poster = document.querySelector('img.hero-poster');
|
|
359
|
-
if (!poster || poster.complete) done();
|
|
360
|
-
else poster.addEventListener('load', () => done(), { once: true });
|
|
361
|
-
}),
|
|
362
|
-
});
|
|
389
|
+
const timeout = (ms) => new Promise((done) => setTimeout(done, ms));
|
|
390
|
+
|
|
391
|
+
register(video, { until: Promise.race([splashDone, timeout(15000)]) });
|
|
363
392
|
```
|
|
364
393
|
|
|
394
|
+
**A splash can buy the video load time.** A gate holds the download as well as
|
|
395
|
+
playback, so a hero behind a five-second splash only starts fetching once the
|
|
396
|
+
splash ends. `prefetchWhileGated: true` lets it download while it waits: only
|
|
397
|
+
playback waits for the gate, while `startWhen`, reduced motion, Save-Data and a
|
|
398
|
+
pause still hold the fetch. The browser fires `canplaythrough` once it can play
|
|
399
|
+
through, which a splash can end on, with a floor and a cap of its own:
|
|
400
|
+
|
|
401
|
+
```js
|
|
402
|
+
const wait = (ms) => new Promise((done) => setTimeout(done, ms));
|
|
403
|
+
let endSplash;
|
|
404
|
+
const splashDone = new Promise((done) => (endSplash = done));
|
|
405
|
+
|
|
406
|
+
register(hero, { until: splashDone, prefetchWhileGated: true });
|
|
407
|
+
|
|
408
|
+
// Nothing downloads where nothing will play (reduced motion, Save-Data,
|
|
409
|
+
// atOnce: 0), or while the visitor has paused.
|
|
410
|
+
const root = document.documentElement;
|
|
411
|
+
const buffered =
|
|
412
|
+
root.hasAttribute('data-polite-active') && !root.hasAttribute('data-polite-paused')
|
|
413
|
+
? new Promise((done) => hero.addEventListener('canplaythrough', done, { once: true }))
|
|
414
|
+
: Promise.resolve();
|
|
415
|
+
|
|
416
|
+
// At least 1.5s of splash, at most 4.5s, and in between until the hero can play through.
|
|
417
|
+
await Promise.race([Promise.all([buffered, wait(1500)]), wait(4500)]);
|
|
418
|
+
hideSplash();
|
|
419
|
+
endSplash();
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
Keep the cap. Whether iOS Safari buffers under `preload="auto"` before anything
|
|
423
|
+
calls `play()` is untested, and the cap is what ends the splash if the event
|
|
424
|
+
never comes.
|
|
425
|
+
|
|
365
426
|
`register(video, { observe: box })` observes a wrapper instead of the video, for
|
|
366
427
|
when the video is `inset: 0` inside the element that carries the layout.
|
|
367
428
|
|
|
@@ -562,7 +623,9 @@ Two things that surprise people:
|
|
|
562
623
|
that is invalid at computed-value time falls back to the property's initial
|
|
563
624
|
value, and the `var()` fallback only applies when the property is undefined.
|
|
564
625
|
Harmless on video, which cuts anyway; on images it silently removes the 350ms
|
|
565
|
-
fade.
|
|
626
|
+
fade. The console names the first image or video box where it is set to
|
|
627
|
+
something that is not a time. A bare `0` is left alone, since the cut it gives
|
|
628
|
+
is what it looks like it asks for.
|
|
566
629
|
|
|
567
630
|
Reduced motion overrides you either way: the stylesheet sets `transition: none`
|
|
568
631
|
there, so a fade you asked for never runs for someone who asked not to see one.
|
|
@@ -585,6 +648,11 @@ warmOnIntent('a[data-hero]', (link) => ({
|
|
|
585
648
|
}));
|
|
586
649
|
```
|
|
587
650
|
|
|
651
|
+
Give a format through `sources` with its `type`, as above, rather than as a bare `srcset`: a
|
|
652
|
+
browser that cannot decode AVIF then skips it and warms the fallback, instead of fetching a file it
|
|
653
|
+
cannot show. `sizes` goes on every `<source>` and on the image, since a `<source>` without its own
|
|
654
|
+
is chosen as if it said `100vw`.
|
|
655
|
+
|
|
588
656
|
**Nothing in this package parses a media query**, which is the point: the
|
|
589
657
|
candidates are assembled as a detached `<picture>` and the browser picks, running
|
|
590
658
|
the same algorithm it will run on the destination. Hand-rolling that selection
|
|
@@ -633,6 +701,24 @@ document.addEventListener('astro:page-load', () => registerAll('[data-polite-med
|
|
|
633
701
|
registered twice. Videos that did not survive need no cleanup: the coordinator
|
|
634
702
|
drops any entry whose element has left the document on its next pass.
|
|
635
703
|
|
|
704
|
+
## Astro
|
|
705
|
+
|
|
706
|
+
This is developed against Astro projects, and the same three things come up.
|
|
707
|
+
|
|
708
|
+
**Import each stylesheet from the component that emits its attribute.** A build folds every
|
|
709
|
+
component's CSS into one file, so a stylesheet imported anywhere covers everywhere, while a dev
|
|
710
|
+
server serves it per component and does not. Import `image.css` from some other component and the
|
|
711
|
+
fade works in the build and is missing in dev, on exactly the pages that do not render whichever
|
|
712
|
+
component happened to import it. The console says so when the stylesheet never arrives.
|
|
713
|
+
|
|
714
|
+
**Put the `<script>` in the component that renders the media**, not in the layout. Astro bundles a
|
|
715
|
+
component's script once per page, so a page that never renders that component never downloads the
|
|
716
|
+
coordinator.
|
|
717
|
+
|
|
718
|
+
**A strict CSP needs nothing from this package.** It writes attributes and never an inline `style`,
|
|
719
|
+
which the end-to-end suite asserts on every demo, so `style-src` needs no `'unsafe-inline'` on its
|
|
720
|
+
account.
|
|
721
|
+
|
|
636
722
|
## What it does
|
|
637
723
|
|
|
638
724
|
- Reveals on a genuinely presented frame, never on `playing`.
|
package/dist/coordinator.d.ts
CHANGED
|
@@ -52,8 +52,13 @@ export interface ConfigureOptions {
|
|
|
52
52
|
*/
|
|
53
53
|
prefetchMargin?: string;
|
|
54
54
|
/**
|
|
55
|
-
* Which viewports count as small. Configurable because
|
|
55
|
+
* Which viewports count as small. Configurable because 768px is one project's
|
|
56
56
|
* breakpoint, not a fact about phones.
|
|
57
|
+
*
|
|
58
|
+
* The default stops at 767.98px, leaving 0.02px beside a `(min-width: 768px)`
|
|
59
|
+
* rather than the whole pixel a zoomed page's fractional width can fall into.
|
|
60
|
+
* Range syntax would close the gap, but Safari before 16.4 never matches it, so
|
|
61
|
+
* phones there would count as large.
|
|
57
62
|
*/
|
|
58
63
|
smallViewport?: string;
|
|
59
64
|
/**
|
|
@@ -158,6 +163,9 @@ export interface RegisterOptions {
|
|
|
158
163
|
* at scroll-top is reported visible in the observer's very first batch, so
|
|
159
164
|
* without a gate it starts before whatever the page is waiting on (a splash
|
|
160
165
|
* screen, a consent dialog) has finished.
|
|
166
|
+
*
|
|
167
|
+
* Settling, fulfilled or rejected, is the only release: a promise that never
|
|
168
|
+
* settles holds the video on its poster for the life of the page.
|
|
161
169
|
*/
|
|
162
170
|
until?: Promise<unknown>;
|
|
163
171
|
/**
|
|
@@ -173,8 +181,30 @@ export interface RegisterOptions {
|
|
|
173
181
|
* the same rule buys nothing.
|
|
174
182
|
*/
|
|
175
183
|
startWhen?: StartWhen;
|
|
184
|
+
/**
|
|
185
|
+
* Let the video download while `until` holds it, so a splash buys it load time.
|
|
186
|
+
* Only playback waits for the gate; the download still waits for `startWhen`,
|
|
187
|
+
* Save-Data, reduced motion and a user pause, and starts once the video is on
|
|
188
|
+
* screen or within `prefetchMargin`.
|
|
189
|
+
*
|
|
190
|
+
* Opt-in, because a gate holding the fetch too is what `until` has always
|
|
191
|
+
* done, and a page gating a video behind a consent dialog may rely on it.
|
|
192
|
+
*/
|
|
193
|
+
prefetchWhileGated?: boolean;
|
|
176
194
|
}
|
|
177
195
|
export declare function reconcile(): void;
|
|
196
|
+
/**
|
|
197
|
+
* Starts managing a video: reveals it on its first genuinely painted frame,
|
|
198
|
+
* plays it only while it is visible, falls through its `<source>` list when one
|
|
199
|
+
* cannot be decoded, and stops it when a gate closes.
|
|
200
|
+
*
|
|
201
|
+
* The video and its poster must already share a box carrying `data-polite-media`
|
|
202
|
+
* in the authored markup, and the video should be `muted loop playsinline
|
|
203
|
+
* preload="none"`. Calling this twice on the same element is a no-op.
|
|
204
|
+
*
|
|
205
|
+
* @param video the element to manage
|
|
206
|
+
* @param options see {@link RegisterOptions}
|
|
207
|
+
*/
|
|
178
208
|
export declare function register(video: HTMLVideoElement, options?: RegisterOptions): void;
|
|
179
209
|
/** Anything that names one or more videos. See {@link Target}. */
|
|
180
210
|
export type VideoTarget = Target<HTMLVideoElement>;
|
|
@@ -199,6 +229,22 @@ export declare function registerAll(target?: VideoTarget, options?: Omit<Registe
|
|
|
199
229
|
* was the last one. Safe to call for a video that was never registered.
|
|
200
230
|
*/
|
|
201
231
|
export declare function unregister(video: HTMLVideoElement): void;
|
|
232
|
+
/**
|
|
233
|
+
* Stops every managed video and keeps them stopped.
|
|
234
|
+
*
|
|
235
|
+
* WCAG 2.2.2 applies to content that moves automatically, runs for more than
|
|
236
|
+
* five seconds, and sits alongside other content -- which a looping background
|
|
237
|
+
* video does. Honouring `prefers-reduced-motion` is necessary but, per the W3C
|
|
238
|
+
* understanding document, is not listed as satisfying the criterion, so a
|
|
239
|
+
* mechanism the user can actually operate has to exist.
|
|
240
|
+
*
|
|
241
|
+
* The host supplies the button and its styling; the library ships no markup and
|
|
242
|
+
* no CSS for it. A `<button>` carrying `data-polite-pause-control` toggles this.
|
|
243
|
+
*
|
|
244
|
+
* It has to be a real `<button>`. The binding is a delegated `click`, and a
|
|
245
|
+
* browser only synthesises that from Enter and Space for a native button, so a
|
|
246
|
+
* `div[role="button"][tabindex="0"]` responds to a mouse and not to a keyboard.
|
|
247
|
+
*/
|
|
202
248
|
export declare function pauseAll(): void;
|
|
203
249
|
/** Lets playback resume, undoing {@link pauseAll}. */
|
|
204
250
|
export declare function resumeAll(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coordinator.d.ts","sourceRoot":"","sources":["../src/coordinator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"coordinator.d.ts","sourceRoot":"","sources":["../src/coordinator.ts"],"names":[],"mappings":"AAYA,OAAO,EAAkB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3D;;;;;;;;GAQG;AAEH;;;;;GAKG;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEnC;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,aAAa,GAAG,aAAa,CAAC;AAElE;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;;;;;;;OAgBG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACnD;;;;;;;;;;;;;OAaG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;;;;;;;;;OAaG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AA4ED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAcvD;AA0DD,MAAM,WAAW,eAAe;IAC9B;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACzB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AA0lBD,wBAAgB,SAAS,IAAI,IAAI,CA4FhC;AAmOD;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,gBAAgB,EAAE,OAAO,GAAE,eAAoB,GAAG,IAAI,CAgErF;AAED,kEAAkE;AAClE,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAEnD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CACzB,MAAM,GAAE,WAAyC,EACjD,OAAO,GAAE,IAAI,CAAC,eAAe,EAAE,SAAS,CAAM,GAC7C,IAAI,CAEN;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAwBxD;AAiDD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,IAAI,IAAI,CAG/B;AAED,sDAAsD;AACtD,wBAAgB,SAAS,IAAI,IAAI,CAGhC;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAIpC;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,IAAI,IAAI,CAQpC;AAED,0EAA0E;AAC1E,wBAAgB,OAAO,IAAI;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAErF"}
|