@fusion.dev/helix-headless 0.0.0-dev → 0.0.3
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/custom-elements.json +4513 -4483
- package/dist/accordion/item/accordion-item.d.ts +13 -15
- package/dist/accordion/item/accordion-item.js +15 -17
- package/dist/announcement/root/announcement-root.d.ts +7 -25
- package/dist/announcement/root/announcement-root.js +7 -20
- package/dist/app-header/root/app-header-root.d.ts +10 -17
- package/dist/app-header/root/app-header-root.js +9 -18
- package/dist/avatar/group/avatar-group.d.ts +10 -19
- package/dist/avatar/group/avatar-group.js +12 -17
- package/dist/avatar/root/avatar-root.d.ts +8 -8
- package/dist/avatar/root/avatar-root.js +19 -20
- package/dist/badge/root/badge-root.d.ts +6 -6
- package/dist/badge/root/badge-root.js +13 -13
- package/dist/bar-chart/root/bar-chart-root.d.ts +21 -29
- package/dist/bar-chart/root/bar-chart-root.js +42 -57
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +12 -18
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +13 -16
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +9 -28
- package/dist/breadcrumbs/root/breadcrumbs-root.js +9 -28
- package/dist/button/root/button-root.d.ts +84 -94
- package/dist/button/root/button-root.js +82 -92
- package/dist/callout/root/callout-root.d.ts +4 -5
- package/dist/carousel/root/carousel-root.d.ts +59 -71
- package/dist/carousel/root/carousel-root.js +73 -101
- package/dist/chat/composer/chat-composer.d.ts +29 -33
- package/dist/chat/composer/chat-composer.js +40 -44
- package/dist/chat/message/chat-message.d.ts +25 -25
- package/dist/chat/message/chat-message.js +26 -26
- package/dist/chat/root/chat-root.d.ts +28 -41
- package/dist/chat/root/chat-root.js +27 -40
- package/dist/checkbox/root/checkbox-root.d.ts +10 -12
- package/dist/checkbox/root/checkbox-root.js +29 -35
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +32 -45
- package/dist/checkbox-group/root/checkbox-group-root.js +53 -79
- package/dist/code-block/root/code-block-root.d.ts +3 -4
- package/dist/code-block/root/code-block-root.js +8 -12
- package/dist/color-input/root/color-input-root.d.ts +36 -37
- package/dist/color-input/root/color-input-root.js +29 -34
- package/dist/color-picker/color.d.ts +7 -8
- package/dist/color-picker/color.js +7 -8
- package/dist/color-picker/root/color-picker-root.d.ts +55 -57
- package/dist/color-picker/root/color-picker-root.js +60 -64
- package/dist/combobox/root/combobox-root.d.ts +53 -58
- package/dist/combobox/root/combobox-root.js +85 -94
- package/dist/command/root/command-root.d.ts +8 -8
- package/dist/command/root/command-root.js +29 -33
- package/dist/copy-button/root/copy-button-root.d.ts +21 -24
- package/dist/copy-button/root/copy-button-root.js +25 -35
- package/dist/data-table/root/data-table-root.d.ts +77 -76
- package/dist/data-table/root/data-table-root.js +95 -84
- package/dist/data-table/root/order.d.ts +2 -2
- package/dist/data-table/root/order.js +1 -3
- package/dist/date-input/root/date-input-root.d.ts +88 -93
- package/dist/date-input/root/date-input-root.js +147 -158
- package/dist/date-picker/root/date-picker-root.d.ts +75 -83
- package/dist/date-picker/root/date-picker-root.js +120 -143
- package/dist/dialog/root/dialog-root.d.ts +41 -24
- package/dist/dialog/root/dialog-root.js +47 -24
- package/dist/divider/root/divider-root.d.ts +5 -6
- package/dist/divider/root/divider-root.js +4 -5
- package/dist/donut-chart/root/donut-chart-root.d.ts +22 -25
- package/dist/donut-chart/root/donut-chart-root.js +37 -51
- package/dist/drawer/root/drawer-root.d.ts +24 -29
- package/dist/drawer/root/drawer-root.js +15 -22
- package/dist/drilldown/item/drilldown-item.d.ts +14 -14
- package/dist/drilldown/item/drilldown-item.js +24 -26
- package/dist/drilldown/root/drilldown-root.d.ts +8 -10
- package/dist/drilldown/root/drilldown-root.js +6 -7
- package/dist/element-events.generated.js +1 -1
- package/dist/file-input/root/file-input-root.d.ts +20 -24
- package/dist/file-input/root/file-input-root.js +42 -57
- package/dist/format-date/root/format-date-root.js +1 -1
- package/dist/heatmap/root/buckets.d.ts +8 -8
- package/dist/heatmap/root/buckets.js +8 -8
- package/dist/heatmap/root/heatmap-root.d.ts +57 -63
- package/dist/heatmap/root/heatmap-root.js +72 -83
- package/dist/icon/root/icon-root.d.ts +4 -4
- package/dist/icon/root/icon-root.js +9 -9
- package/dist/icon-button/root/icon-button-root.d.ts +4 -6
- package/dist/icon-button/root/icon-button-root.js +4 -6
- package/dist/image/root/image-root.d.ts +49 -59
- package/dist/image/root/image-root.js +55 -65
- package/dist/index.d.ts +5 -5
- package/dist/index.js +5 -5
- package/dist/input/root/input-root.d.ts +61 -85
- package/dist/input/root/input-root.js +79 -106
- package/dist/kbd/root/kbd-root.d.ts +8 -7
- package/dist/kbd/root/kbd-root.js +71 -11
- package/dist/legend/root/legend-root.d.ts +1 -1
- package/dist/legend/root/legend-root.js +4 -5
- package/dist/line-chart/root/line-chart-root.d.ts +26 -30
- package/dist/line-chart/root/line-chart-root.js +10 -10
- package/dist/list/item/list-item.d.ts +14 -18
- package/dist/list/item/list-item.js +18 -22
- package/dist/list/root/list-root.d.ts +4 -4
- package/dist/list/root/list-root.js +3 -3
- package/dist/listbox/root/listbox-root.d.ts +31 -58
- package/dist/listbox/root/listbox-root.js +66 -109
- package/dist/megamenu/root/megamenu-root.d.ts +34 -35
- package/dist/megamenu/root/megamenu-root.js +53 -58
- package/dist/menu/item/menu-item.d.ts +39 -53
- package/dist/menu/item/menu-item.js +50 -64
- package/dist/menu/root/menu-root.d.ts +30 -40
- package/dist/menu/root/menu-root.js +49 -82
- package/dist/meter/root/meter-root.d.ts +49 -53
- package/dist/meter/root/meter-root.js +22 -27
- package/dist/navigation/root/navigation-root.js +11 -19
- package/dist/notifications/notification/notification.d.ts +16 -22
- package/dist/notifications/notification/notification.js +21 -27
- package/dist/notifications/root/notifications-root.d.ts +31 -39
- package/dist/notifications/root/notifications-root.js +41 -52
- package/dist/number-input/root/number-input-root.d.ts +31 -33
- package/dist/number-input/root/number-input-root.js +37 -39
- package/dist/option/root/option-root.d.ts +73 -74
- package/dist/option/root/option-root.js +62 -64
- package/dist/outline/root/outline-root.d.ts +38 -44
- package/dist/outline/root/outline-root.js +66 -82
- package/dist/pagination/root/pagination-root.d.ts +87 -92
- package/dist/pagination/root/pagination-root.js +116 -123
- package/dist/pagination/size/pagination-size.d.ts +31 -50
- package/dist/pagination/size/pagination-size.js +35 -55
- package/dist/pagination/summary/pagination-summary.d.ts +12 -12
- package/dist/pagination/summary/pagination-summary.js +18 -18
- package/dist/pin-input/root/pin-input-root.d.ts +53 -70
- package/dist/pin-input/root/pin-input-root.js +74 -94
- package/dist/popover/root/popover-root.d.ts +15 -20
- package/dist/popover/root/popover-root.js +19 -36
- package/dist/progress/root/progress-root.d.ts +12 -14
- package/dist/progress/root/progress-root.js +22 -25
- package/dist/qr-code/root/qr-code-root.d.ts +11 -11
- package/dist/qr-code/root/qr-code-root.js +12 -14
- package/dist/radio/group/radio-group.js +19 -26
- package/dist/radio/root/radio-root.d.ts +12 -13
- package/dist/radio/root/radio-root.js +12 -13
- package/dist/rating/root/rating-root.d.ts +25 -30
- package/dist/rating/root/rating-root.js +43 -50
- package/dist/scroll-area/root/scroll-area-root.d.ts +11 -14
- package/dist/scroll-area/root/scroll-area-root.js +39 -33
- package/dist/select/root/select-root.d.ts +7 -12
- package/dist/select/root/select-root.js +40 -55
- package/dist/slider/root/slider-root.d.ts +53 -60
- package/dist/slider/root/slider-root.js +74 -85
- package/dist/sparkline/root/sparkline-root.d.ts +43 -47
- package/dist/sparkline/root/sparkline-root.js +23 -32
- package/dist/speed-dial/item/speed-dial-item.d.ts +6 -6
- package/dist/speed-dial/item/speed-dial-item.js +9 -9
- package/dist/speed-dial/root/speed-dial-root.d.ts +21 -25
- package/dist/speed-dial/root/speed-dial-root.js +32 -40
- package/dist/splitter/root/splitter-root.d.ts +98 -111
- package/dist/splitter/root/splitter-root.js +96 -123
- package/dist/stat/root/stat-root.d.ts +2 -7
- package/dist/stat/root/stat-root.js +0 -5
- package/dist/steps/step/step.d.ts +19 -24
- package/dist/steps/step/step.js +27 -32
- package/dist/switch/root/switch-root.js +2 -2
- package/dist/table/column/table-column.d.ts +54 -60
- package/dist/table/column/table-column.js +95 -68
- package/dist/table/root/table-root.d.ts +5 -6
- package/dist/table/root/table-root.js +7 -10
- package/dist/tabs/panel/tab-panel.d.ts +21 -25
- package/dist/tabs/panel/tab-panel.js +25 -29
- package/dist/tabs/root/tabs-root.d.ts +25 -34
- package/dist/tabs/root/tabs-root.js +22 -28
- package/dist/tabs/tab/tab.d.ts +12 -12
- package/dist/tabs/tab/tab.js +19 -20
- package/dist/textarea/root/textarea-root.d.ts +36 -36
- package/dist/textarea/root/textarea-root.js +43 -47
- package/dist/time-input/root/time-input-root.d.ts +58 -68
- package/dist/time-input/root/time-input-root.js +62 -77
- package/dist/time-picker/root/time-picker-root.d.ts +73 -79
- package/dist/time-picker/root/time-picker-root.js +72 -84
- package/dist/timeline/item/timeline-item.d.ts +8 -11
- package/dist/timeline/item/timeline-item.js +8 -11
- package/dist/timeline/root/timeline-root.d.ts +5 -7
- package/dist/timeline/root/timeline-root.js +5 -7
- package/dist/toast/item/toast-item.d.ts +9 -27
- package/dist/toast/item/toast-item.js +19 -41
- package/dist/toast/root/toast-root.d.ts +10 -14
- package/dist/toast/root/toast-root.js +4 -5
- package/dist/toggle/group/toggle-group.d.ts +6 -15
- package/dist/toggle/group/toggle-group.js +21 -36
- package/dist/toggle/root/toggle-root.d.ts +26 -27
- package/dist/toggle/root/toggle-root.js +30 -31
- package/dist/toolbar/root/toolbar-root.d.ts +7 -10
- package/dist/toolbar/root/toolbar-root.js +10 -14
- package/dist/tooltip/root/tooltip-root.d.ts +52 -59
- package/dist/tooltip/root/tooltip-root.js +98 -93
- package/dist/tour/root/tour-root.d.ts +19 -23
- package/dist/tour/root/tour-root.js +31 -41
- package/dist/tour/stop/tour-stop.d.ts +14 -15
- package/dist/tour/stop/tour-stop.js +31 -34
- package/dist/tree/item/tree-item.d.ts +30 -35
- package/dist/tree/item/tree-item.js +43 -55
- package/dist/tree/root/tree-root.d.ts +7 -10
- package/dist/tree/root/tree-root.js +33 -42
- package/dist/trend/root/trend-root.d.ts +3 -5
- package/dist/trend/root/trend-root.js +5 -9
- package/dist/video/root/video-root.d.ts +100 -124
- package/dist/video/root/video-root.js +142 -176
- package/dist/video-playlist/item/video-playlist-item.d.ts +16 -16
- package/dist/video-playlist/item/video-playlist-item.js +24 -24
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +5 -8
- package/dist/video-playlist/menu/video-playlist-menu.js +20 -29
- package/dist/video-playlist/root/video-playlist-root.d.ts +16 -11
- package/dist/video-playlist/root/video-playlist-root.js +21 -25
- package/dist/virtual-list/root/virtual-list-root.d.ts +8 -12
- package/dist/virtual-list/root/virtual-list-root.js +11 -16
- package/jsx.d.ts +9797 -12561
- package/package.json +6 -6
- package/vue.d.ts +2684 -3228
|
@@ -129,11 +129,11 @@ const SKIP_SECONDS = 10;
|
|
|
129
129
|
* @slot controls - Added to the control bar, before fullscreen.
|
|
130
130
|
* @slot poster - Shown over the video until it starts.
|
|
131
131
|
*
|
|
132
|
-
* @event {Event} ended - Relayed
|
|
132
|
+
* @event {Event} ended - Relayed, because it does not cross a shadow boundary.
|
|
133
133
|
* @event {HelixNextEvent} helix-next - Fired when the reader asks for the next item.
|
|
134
134
|
* @event {HelixPreviousEvent} helix-previous - Fired when they ask for the previous one.
|
|
135
135
|
* @event {Event} pause - Relayed for the same reason.
|
|
136
|
-
* @event {Event} play - Relayed
|
|
136
|
+
* @event {Event} play - Relayed for the same reason.
|
|
137
137
|
*
|
|
138
138
|
* @csspart back - The region top left, for a way out of a set.
|
|
139
139
|
* @csspart captions - Subtitles on and off.
|
|
@@ -155,7 +155,6 @@ const SKIP_SECONDS = 10;
|
|
|
155
155
|
* @csspart failure - What is said when the source will not play.
|
|
156
156
|
* @csspart forward - The control that goes on ten seconds.
|
|
157
157
|
* @csspart fullscreen - The whole screen, and back.
|
|
158
|
-
* @csspart icon - A glyph this component draws.
|
|
159
158
|
* @csspart loading - What is said while the picture waits for more of itself.
|
|
160
159
|
* @csspart loading-mark - The part of that which spins.
|
|
161
160
|
* @csspart more - The button that opens it.
|
|
@@ -193,39 +192,14 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
193
192
|
constructor() {
|
|
194
193
|
super(...arguments);
|
|
195
194
|
/**
|
|
196
|
-
*
|
|
197
|
-
*/
|
|
198
|
-
this.src = '';
|
|
199
|
-
/**
|
|
200
|
-
* A still shown before it plays, which the platform draws itself.
|
|
201
|
-
*/
|
|
202
|
-
this.poster = '';
|
|
203
|
-
/**
|
|
204
|
-
* Accessible name, since a video is not described by its filename.
|
|
205
|
-
*/
|
|
206
|
-
this.label = '';
|
|
207
|
-
/**
|
|
208
|
-
* Whether it starts again at the end.
|
|
209
|
-
*/
|
|
210
|
-
this.loop = false;
|
|
211
|
-
/**
|
|
212
|
-
* Whether it *starts* silent, which is what an autoplaying video must do.
|
|
195
|
+
* Whether it starts on its own, which a browser only allows while silent.
|
|
213
196
|
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
* bound it to the attribute, and tracked the live state privately as
|
|
219
|
-
* `silent`, so `<helix-video>.muted` answered what the author wrote rather
|
|
220
|
-
* than whether there was sound. A name matching the platform's while meaning
|
|
221
|
-
* something else is worse than a name the platform does not have, and
|
|
222
|
-
* `check:platform-fidelity` could not see it: it compares names.
|
|
223
|
-
*/
|
|
224
|
-
this.defaultMuted = false;
|
|
225
|
-
/**
|
|
226
|
-
* Whether it plays where it sits rather than taking over the screen.
|
|
197
|
+
* Forwarded rather than acted on. Whether an unprompted play is permitted is
|
|
198
|
+
* the browser's policy and not this element's, and `play()` already swallows
|
|
199
|
+
* the refusal: what follows a refused autoplay is a paused player showing its
|
|
200
|
+
* start control, which is the correct thing to be looking at.
|
|
227
201
|
*/
|
|
228
|
-
this.
|
|
202
|
+
this.autoplay = false;
|
|
229
203
|
/**
|
|
230
204
|
* Whether the browser draws the controls instead of this element.
|
|
231
205
|
*
|
|
@@ -233,24 +207,22 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
233
207
|
* either alone, so this one is not drawn at all when it is set.
|
|
234
208
|
*/
|
|
235
209
|
this.controls = false;
|
|
236
|
-
/**
|
|
237
|
-
* How much to fetch before anything is asked for.
|
|
238
|
-
*/
|
|
239
|
-
this.preload = 'metadata';
|
|
240
|
-
/**
|
|
241
|
-
* Whether it starts on its own, which a browser only allows while silent.
|
|
242
|
-
*
|
|
243
|
-
* Forwarded rather than acted on. Whether an unprompted play is permitted is
|
|
244
|
-
* the browser's policy and not this element's, and `play()` already swallows
|
|
245
|
-
* the refusal: what follows a refused autoplay is a paused player showing its
|
|
246
|
-
* start control, which is the correct thing to be looking at.
|
|
247
|
-
*/
|
|
248
|
-
this.autoplay = false;
|
|
249
210
|
/**
|
|
250
211
|
* How the media is fetched across origins, which decides whether a track can
|
|
251
212
|
* be read.
|
|
252
213
|
*/
|
|
253
214
|
this.crossOrigin = null;
|
|
215
|
+
/**
|
|
216
|
+
* Whether it *starts* silent, which is what an autoplaying video must do.
|
|
217
|
+
*
|
|
218
|
+
* **Named for the platform's split, which is real.** The `muted` content
|
|
219
|
+
* attribute reflects to `defaultMuted`; the `muted` property is live state a
|
|
220
|
+
* reader's click moves without touching the attribute. One property called
|
|
221
|
+
* `muted` bound to the attribute answers what the author wrote rather than
|
|
222
|
+
* whether there is sound, which is a name matching the platform's while
|
|
223
|
+
* meaning something else.
|
|
224
|
+
*/
|
|
225
|
+
this.defaultMuted = false;
|
|
254
226
|
/**
|
|
255
227
|
* Whether the browser may offer picture in picture.
|
|
256
228
|
*/
|
|
@@ -259,13 +231,17 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
259
231
|
* Whether the browser may offer playback on a remote device.
|
|
260
232
|
*/
|
|
261
233
|
this.disableRemotePlayback = false;
|
|
234
|
+
/**
|
|
235
|
+
* And what they are told when it will not play at all.
|
|
236
|
+
*/
|
|
237
|
+
this.errorLabel = 'This video could not be played';
|
|
262
238
|
/**
|
|
263
239
|
* Controls beyond the ones every player has, named in the order they appear.
|
|
264
240
|
*
|
|
265
241
|
* A list rather than a property apiece. A bar is a row with a budget, and a
|
|
266
242
|
* boolean per feature invites a consumer to switch all of them on: naming
|
|
267
243
|
* them makes the row a decision, and makes the order theirs. Anything
|
|
268
|
-
*
|
|
244
|
+
* unrecognized is skipped rather than throwing, since the list is markup and
|
|
269
245
|
* a typo should cost a control, not a page.
|
|
270
246
|
*
|
|
271
247
|
* `pip` is offered only where the platform has it, checked rather than
|
|
@@ -282,6 +258,30 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
282
258
|
* and not something a player can work around.
|
|
283
259
|
*/
|
|
284
260
|
this.extraControls = '';
|
|
261
|
+
/**
|
|
262
|
+
* How long the bar waits after the pointer stops before it goes, in ms.
|
|
263
|
+
*
|
|
264
|
+
* A wait rather than leaving with the pointer, or a reader moving across the
|
|
265
|
+
* picture to reach a control watches the bar vanish under them. Zero turns
|
|
266
|
+
* the wait off and the bar goes immediately; a large number keeps it up for
|
|
267
|
+
* as long as anyone is likely to look.
|
|
268
|
+
*
|
|
269
|
+
* The wait is only ever about *idling*. A video that is paused keeps its bar
|
|
270
|
+
* regardless, because a reader who stopped it is deciding what to do next.
|
|
271
|
+
*/
|
|
272
|
+
this.idleDelay = 2500;
|
|
273
|
+
/**
|
|
274
|
+
* Accessible name, since a video is not described by its filename.
|
|
275
|
+
*/
|
|
276
|
+
this.label = '';
|
|
277
|
+
/**
|
|
278
|
+
* What a reader is told while the picture is waiting for more of itself.
|
|
279
|
+
*/
|
|
280
|
+
this.loadingLabel = 'Loading';
|
|
281
|
+
/**
|
|
282
|
+
* Whether it starts again at the end.
|
|
283
|
+
*/
|
|
284
|
+
this.loop = false;
|
|
285
285
|
/**
|
|
286
286
|
* Controls that go behind one button instead of onto the bar, named the same
|
|
287
287
|
* way.
|
|
@@ -301,37 +301,33 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
301
301
|
*/
|
|
302
302
|
this.overflowControls = '';
|
|
303
303
|
/**
|
|
304
|
-
*
|
|
305
|
-
*/
|
|
306
|
-
this.speeds = '0.5 1 1.5 2';
|
|
307
|
-
/**
|
|
308
|
-
* How long the bar waits after the pointer stops before it goes, in ms.
|
|
309
|
-
*
|
|
310
|
-
* It used to leave the moment the pointer did, which is not how a player
|
|
311
|
-
* behaves: a reader moving across the picture to reach a control watched it
|
|
312
|
-
* vanish under them. Zero turns the wait off and the bar goes immediately;
|
|
313
|
-
* a large number keeps it up for as long as anyone is likely to look.
|
|
314
|
-
*
|
|
315
|
-
* The wait is only ever about *idling*. A video that is paused keeps its bar
|
|
316
|
-
* regardless, because a reader who stopped it is deciding what to do next.
|
|
304
|
+
* And while it would stop it.
|
|
317
305
|
*/
|
|
318
|
-
this.
|
|
306
|
+
this.pauseLabel = 'Pause';
|
|
319
307
|
/**
|
|
320
308
|
* What the play control is called while it would start the video.
|
|
321
309
|
*/
|
|
322
310
|
this.playLabel = 'Play';
|
|
323
311
|
/**
|
|
324
|
-
*
|
|
312
|
+
* Whether it plays where it sits rather than taking over the screen.
|
|
325
313
|
*/
|
|
326
|
-
this.
|
|
314
|
+
this.playsInline = true;
|
|
327
315
|
/**
|
|
328
|
-
*
|
|
316
|
+
* A still shown before it plays, which the platform draws itself.
|
|
329
317
|
*/
|
|
330
|
-
this.
|
|
318
|
+
this.poster = '';
|
|
331
319
|
/**
|
|
332
|
-
*
|
|
320
|
+
* How much to fetch before anything is asked for.
|
|
333
321
|
*/
|
|
334
|
-
this.
|
|
322
|
+
this.preload = 'metadata';
|
|
323
|
+
/**
|
|
324
|
+
* The speeds offered, slowest first, as multipliers of normal.
|
|
325
|
+
*/
|
|
326
|
+
this.speeds = '0.5 1 1.5 2';
|
|
327
|
+
/**
|
|
328
|
+
* Where the video is, for the common case of one file.
|
|
329
|
+
*/
|
|
330
|
+
this.src = '';
|
|
335
331
|
/**
|
|
336
332
|
* Whether playback has stopped to wait for data.
|
|
337
333
|
*
|
|
@@ -368,12 +364,11 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
368
364
|
/**
|
|
369
365
|
* How many caption tracks there are, which decides which control is drawn.
|
|
370
366
|
*
|
|
371
|
-
* A count and not a boolean
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
* the videos it exists for.
|
|
367
|
+
* A count and not a boolean. Tracks resolve after the element renders, so
|
|
368
|
+
* this is what schedules the update that draws the control at all, and a
|
|
369
|
+
* boolean goes false to true when the first track arrives and then never
|
|
370
|
+
* moves again: a second one landing leaves the toggle in place and the
|
|
371
|
+
* language menu unreachable on exactly the videos it exists for.
|
|
377
372
|
*/
|
|
378
373
|
this.captionCount = 0;
|
|
379
374
|
this.rate = 1;
|
|
@@ -471,13 +466,10 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
471
466
|
this.handleTime = () => {
|
|
472
467
|
this.position = this.video?.currentTime ?? 0;
|
|
473
468
|
};
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
* the element they wrote hears nothing at all without this. Input relays
|
|
479
|
-
* `change` for the same reason.
|
|
480
|
-
*/
|
|
469
|
+
/* Relayed, because none of these cross a shadow boundary on their own. The
|
|
470
|
+
video is inside this element's shadow root, so a consumer listening on the
|
|
471
|
+
element they wrote hears nothing at all without this. Input relays `change`
|
|
472
|
+
for the same reason. */
|
|
481
473
|
/* `emptied` is in the list for a reason worth keeping. Assigning `src` runs
|
|
482
474
|
the media load algorithm, which stops playback and sets `paused` without
|
|
483
475
|
firing `pause`: the only events are `emptied` and `loadstart`. Listening for
|
|
@@ -742,13 +734,9 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
742
734
|
/**
|
|
743
735
|
* The media's own state, under the platform's own names.
|
|
744
736
|
*
|
|
745
|
-
* **
|
|
746
|
-
*
|
|
747
|
-
*
|
|
748
|
-
* them, and published none of them, so a consumer asking where the video had
|
|
749
|
-
* reached had nowhere to ask: the `<video>` is inside this shadow root and
|
|
750
|
-
* `querySelector` does not cross it. 295 is that finding across the library
|
|
751
|
-
* and this is its clearest case.
|
|
737
|
+
* **Published because there is no other way in.** The `<video>` is inside
|
|
738
|
+
* this shadow root and `querySelector` does not cross it, so a consumer
|
|
739
|
+
* asking where the video has reached has nowhere else to ask.
|
|
752
740
|
*
|
|
753
741
|
* **Read from the element, with the mirror as the fallback.** The element is
|
|
754
742
|
* the truth and the mirror is a render cache that a media event refreshes, so
|
|
@@ -911,10 +899,9 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
911
899
|
* name Video never promised, carrying a seconds count or a level between zero
|
|
912
900
|
* and one rather than anything about the element.
|
|
913
901
|
*
|
|
914
|
-
*
|
|
915
|
-
*
|
|
916
|
-
* control
|
|
917
|
-
* chrome is neither a form control nor exempt from the mechanism. See 308.
|
|
902
|
+
* Every family that renders a native control needs this, not only the form
|
|
903
|
+
* controls: a media component with two rails in its chrome is neither a form
|
|
904
|
+
* control nor exempt from the mechanism.
|
|
918
905
|
*/
|
|
919
906
|
takeScrub(event) {
|
|
920
907
|
event.stopPropagation();
|
|
@@ -955,12 +942,6 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
955
942
|
});
|
|
956
943
|
session.setActionHandler('play', () => this.toggle());
|
|
957
944
|
session.setActionHandler('pause', () => this.toggle());
|
|
958
|
-
session.setActionHandler('seekbackward', (details) => {
|
|
959
|
-
this.seek((this.video?.currentTime ?? 0) - (details.seekOffset ?? 10));
|
|
960
|
-
});
|
|
961
|
-
session.setActionHandler('seekforward', (details) => {
|
|
962
|
-
this.seek((this.video?.currentTime ?? 0) + (details.seekOffset ?? 10));
|
|
963
|
-
});
|
|
964
945
|
session.setActionHandler('seekto', (details) => {
|
|
965
946
|
if (details.seekTime !== undefined && details.seekTime !== null) {
|
|
966
947
|
this.seek(details.seekTime);
|
|
@@ -1130,11 +1111,11 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
1130
1111
|
* user activation. Both are `TypeError: Permissions check failed`, which is
|
|
1131
1112
|
* the same message for two different causes.
|
|
1132
1113
|
*
|
|
1133
|
-
*
|
|
1134
|
-
*
|
|
1135
|
-
*
|
|
1136
|
-
*
|
|
1137
|
-
*
|
|
1114
|
+
* Caught rather than `void`ed, or a refusal becomes an unhandled rejection
|
|
1115
|
+
* naming neither the element nor the reason. The state stays honest either
|
|
1116
|
+
* way, because `aria-pressed` follows `fullscreenchange` rather than this
|
|
1117
|
+
* call, so a refused request leaves a button that correctly reports "not
|
|
1118
|
+
* fullscreen".
|
|
1138
1119
|
*/
|
|
1139
1120
|
async toggleFullscreen() {
|
|
1140
1121
|
try {
|
|
@@ -1193,9 +1174,8 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
1193
1174
|
*
|
|
1194
1175
|
* Because CSS cannot ask. `paused` is a property of a `<video>` and never an
|
|
1195
1176
|
* attribute, so `video:not([paused])` matches every video that has ever
|
|
1196
|
-
* existed
|
|
1197
|
-
*
|
|
1198
|
-
* was written to keep it in.
|
|
1177
|
+
* existed and a rule written on it hides the bar always, including on the
|
|
1178
|
+
* paused video it was written to keep the bar up for.
|
|
1199
1179
|
*
|
|
1200
1180
|
* **A `data-` attribute is right here because of when it is written.** A fact
|
|
1201
1181
|
* that can be true on the first update mirrors to a custom state instead, or
|
|
@@ -1203,9 +1183,8 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
1203
1183
|
* React reports a mismatch it will not patch up. Nothing plays until somebody
|
|
1204
1184
|
* presses play, so this one is written long past hydration and there is
|
|
1205
1185
|
* nothing for it to disagree with. `data-closed` on `Toast.Item` and
|
|
1206
|
-
* `data-
|
|
1207
|
-
* `:state(checked)` are the other one
|
|
1208
|
-
* 27 Aug 2026.
|
|
1186
|
+
* `data-scrolled` on `AppHeader` are the same case; `:state(open)` and
|
|
1187
|
+
* `:state(checked)` are the other one.
|
|
1209
1188
|
*/
|
|
1210
1189
|
updated(changed) {
|
|
1211
1190
|
super.updated?.(changed);
|
|
@@ -1231,8 +1210,6 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
1231
1210
|
* two lists that have to stay in step is how a control ends up offered in one
|
|
1232
1211
|
* place and not the other.
|
|
1233
1212
|
*/
|
|
1234
|
-
/* `protected` rather than `private`: the method was already the seam and a
|
|
1235
|
-
tier above simply could not reach it. */
|
|
1236
1213
|
renderExtra(one) {
|
|
1237
1214
|
if (one === 'remote') {
|
|
1238
1215
|
return html `<button
|
|
@@ -1246,10 +1223,8 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
1246
1223
|
</button>`;
|
|
1247
1224
|
}
|
|
1248
1225
|
/* Two templates rather than one with the name bound in, for the reason
|
|
1249
|
-
written under `previous` below: a part is read from the source
|
|
1250
|
-
`part=${one}` is a part no check can prove anything about.
|
|
1251
|
-
left bound when that pair was split, and `check:parts` had them exactly
|
|
1252
|
-
right: both were documented and neither could be found. */
|
|
1226
|
+
written under `previous` below: a part is read from the source as a
|
|
1227
|
+
literal, so `part=${one}` is a part no check can prove anything about. */
|
|
1253
1228
|
if (one === 'rewind') {
|
|
1254
1229
|
return html `<button
|
|
1255
1230
|
part="rewind"
|
|
@@ -1281,10 +1256,9 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
1281
1256
|
</button>`;
|
|
1282
1257
|
}
|
|
1283
1258
|
/* Two templates rather than one with the name bound in, because a part is
|
|
1284
|
-
read from the source: `
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
either. It reported both of these as matching nothing. */
|
|
1259
|
+
read from the source as a literal: `part=${one}` is a part no stylesheet
|
|
1260
|
+
can be proved to reach, and nothing can match it against the
|
|
1261
|
+
documentation either. */
|
|
1288
1262
|
if (one === 'previous') {
|
|
1289
1263
|
return html `<button
|
|
1290
1264
|
part="previous"
|
|
@@ -1309,7 +1283,7 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
1309
1283
|
/* A real anchor, because saving a file is the browser's job and there is
|
|
1310
1284
|
no scripted version of it worth having.
|
|
1311
1285
|
*
|
|
1312
|
-
* **`download` only where it means something.** The attribute is
|
|
1286
|
+
* **`download` only where it means something.** The attribute is honored
|
|
1313
1287
|
* for a same-origin file and ignored for any other, whatever headers come
|
|
1314
1288
|
* back, so on a video served from a CDN it does nothing and the press
|
|
1315
1289
|
* *navigates*: measured, clicking it took the whole page to the mp4, which
|
|
@@ -1340,14 +1314,6 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
1340
1314
|
${drawIcon(pictureInPicture)}
|
|
1341
1315
|
</button>`;
|
|
1342
1316
|
}
|
|
1343
|
-
/*
|
|
1344
|
-
* The same control as a row in the overflow menu.
|
|
1345
|
-
*
|
|
1346
|
-
* The label is words rather than a mark, which is the difference between a
|
|
1347
|
-
* bar and a menu: a row has the width for a name and a reader scanning one is
|
|
1348
|
-
* reading rather than recognising. `download` is a linked row, which is what
|
|
1349
|
-
* `Menu.Item`'s `href` is for.
|
|
1350
|
-
*/
|
|
1351
1317
|
/**
|
|
1352
1318
|
* A toggle for one track, a menu for several, and nothing for none.
|
|
1353
1319
|
*
|
|
@@ -1361,8 +1327,6 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
1361
1327
|
* nobody can choose between and that is the markup's fault to fix, not this
|
|
1362
1328
|
* component's to paper over with "Track 2".
|
|
1363
1329
|
*/
|
|
1364
|
-
/* `protected` rather than `private`: the method was already the seam and a
|
|
1365
|
-
tier above simply could not reach it. */
|
|
1366
1330
|
renderCaptions() {
|
|
1367
1331
|
/* Branched on the state rather than on the getter, so the render that draws
|
|
1368
1332
|
this is one the state scheduled. Reading the tracks for their labels is
|
|
@@ -1411,8 +1375,14 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
1411
1375
|
</${this.tag('menu-item')}>`)}
|
|
1412
1376
|
</${this.tag('menu')}>`;
|
|
1413
1377
|
}
|
|
1414
|
-
/*
|
|
1415
|
-
|
|
1378
|
+
/*
|
|
1379
|
+
* The same control as a row in the overflow menu.
|
|
1380
|
+
*
|
|
1381
|
+
* The label is words rather than a mark, which is the difference between a
|
|
1382
|
+
* bar and a menu: a row has the width for a name and a reader scanning one is
|
|
1383
|
+
* reading rather than recognizing. `download` is a linked row, which is what
|
|
1384
|
+
* `Menu.Item`'s `href` is for.
|
|
1385
|
+
*/
|
|
1416
1386
|
renderOverflowItem(one) {
|
|
1417
1387
|
if (one === 'remote') {
|
|
1418
1388
|
return html `<${this.tag('menu-item')} part="entry"
|
|
@@ -1476,8 +1446,6 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
1476
1446
|
Picture in picture
|
|
1477
1447
|
</${this.tag('menu-item')}>`;
|
|
1478
1448
|
}
|
|
1479
|
-
/* `protected` rather than `private`: the method was already the seam and a
|
|
1480
|
-
tier above simply could not reach it. */
|
|
1481
1449
|
renderBar() {
|
|
1482
1450
|
const done = this.knownDuration > 0 ? this.position / this.knownDuration : 0;
|
|
1483
1451
|
return html `<div part="controls">
|
|
@@ -1674,12 +1642,10 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
1674
1642
|
: nothing}
|
|
1675
1643
|
${
|
|
1676
1644
|
/* Whenever it is not playing, which is what the mark means: press this
|
|
1677
|
-
to play.
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
it on pause, and the one who paused to study a frame clears it by
|
|
1682
|
-
pressing the thing in the way.
|
|
1645
|
+
to play. Not only before the first play, which would make the mark
|
|
1646
|
+
mean two different things at two moments that are the same state.
|
|
1647
|
+
Every player a reader has used shows it on pause, and the one who
|
|
1648
|
+
paused to study a frame clears it by pressing the thing in the way.
|
|
1683
1649
|
|
|
1684
1650
|
Not drawn at all where the browser draws its own controls, since that
|
|
1685
1651
|
bar has a play button and two would be two. */
|
|
@@ -1701,69 +1667,69 @@ let HelixHeadlessVideo = class HelixHeadlessVideo extends HelixElement {
|
|
|
1701
1667
|
</div>`;
|
|
1702
1668
|
}
|
|
1703
1669
|
};
|
|
1704
|
-
__decorate([
|
|
1705
|
-
property()
|
|
1706
|
-
], HelixHeadlessVideo.prototype, "src", void 0);
|
|
1707
|
-
__decorate([
|
|
1708
|
-
property()
|
|
1709
|
-
], HelixHeadlessVideo.prototype, "poster", void 0);
|
|
1710
|
-
__decorate([
|
|
1711
|
-
property()
|
|
1712
|
-
], HelixHeadlessVideo.prototype, "label", void 0);
|
|
1713
1670
|
__decorate([
|
|
1714
1671
|
property({ reflect: true, type: Boolean })
|
|
1715
|
-
], HelixHeadlessVideo.prototype, "
|
|
1716
|
-
__decorate([
|
|
1717
|
-
property({ attribute: 'muted', reflect: true, type: Boolean })
|
|
1718
|
-
], HelixHeadlessVideo.prototype, "defaultMuted", void 0);
|
|
1719
|
-
__decorate([
|
|
1720
|
-
property({ attribute: 'playsinline', converter: onUnlessFalse })
|
|
1721
|
-
], HelixHeadlessVideo.prototype, "playsInline", void 0);
|
|
1672
|
+
], HelixHeadlessVideo.prototype, "autoplay", void 0);
|
|
1722
1673
|
__decorate([
|
|
1723
1674
|
property({ reflect: true, type: Boolean })
|
|
1724
1675
|
], HelixHeadlessVideo.prototype, "controls", void 0);
|
|
1725
|
-
__decorate([
|
|
1726
|
-
property()
|
|
1727
|
-
], HelixHeadlessVideo.prototype, "preload", void 0);
|
|
1728
|
-
__decorate([
|
|
1729
|
-
property({ reflect: true, type: Boolean })
|
|
1730
|
-
], HelixHeadlessVideo.prototype, "autoplay", void 0);
|
|
1731
1676
|
__decorate([
|
|
1732
1677
|
property({ attribute: 'crossorigin' })
|
|
1733
1678
|
], HelixHeadlessVideo.prototype, "crossOrigin", void 0);
|
|
1679
|
+
__decorate([
|
|
1680
|
+
property({ attribute: 'muted', reflect: true, type: Boolean })
|
|
1681
|
+
], HelixHeadlessVideo.prototype, "defaultMuted", void 0);
|
|
1734
1682
|
__decorate([
|
|
1735
1683
|
property({ attribute: 'disablepictureinpicture', reflect: true, type: Boolean })
|
|
1736
1684
|
], HelixHeadlessVideo.prototype, "disablePictureInPicture", void 0);
|
|
1737
1685
|
__decorate([
|
|
1738
1686
|
property({ attribute: 'disableremoteplayback', reflect: true, type: Boolean })
|
|
1739
1687
|
], HelixHeadlessVideo.prototype, "disableRemotePlayback", void 0);
|
|
1688
|
+
__decorate([
|
|
1689
|
+
property({ attribute: 'error-label' })
|
|
1690
|
+
], HelixHeadlessVideo.prototype, "errorLabel", void 0);
|
|
1740
1691
|
__decorate([
|
|
1741
1692
|
property({ attribute: 'extra-controls' })
|
|
1742
1693
|
], HelixHeadlessVideo.prototype, "extraControls", void 0);
|
|
1743
1694
|
__decorate([
|
|
1744
|
-
property({ attribute: '
|
|
1745
|
-
], HelixHeadlessVideo.prototype, "
|
|
1695
|
+
property({ attribute: 'idle-delay', type: Number })
|
|
1696
|
+
], HelixHeadlessVideo.prototype, "idleDelay", void 0);
|
|
1746
1697
|
__decorate([
|
|
1747
|
-
property(
|
|
1748
|
-
], HelixHeadlessVideo.prototype, "
|
|
1698
|
+
property()
|
|
1699
|
+
], HelixHeadlessVideo.prototype, "label", void 0);
|
|
1749
1700
|
__decorate([
|
|
1750
|
-
property({ attribute: '
|
|
1751
|
-
], HelixHeadlessVideo.prototype, "
|
|
1701
|
+
property({ attribute: 'loading-label' })
|
|
1702
|
+
], HelixHeadlessVideo.prototype, "loadingLabel", void 0);
|
|
1752
1703
|
__decorate([
|
|
1753
|
-
property({
|
|
1754
|
-
], HelixHeadlessVideo.prototype, "
|
|
1704
|
+
property({ reflect: true, type: Boolean })
|
|
1705
|
+
], HelixHeadlessVideo.prototype, "loop", void 0);
|
|
1755
1706
|
__decorate([
|
|
1756
|
-
property({ attribute: '
|
|
1757
|
-
], HelixHeadlessVideo.prototype, "
|
|
1707
|
+
property({ attribute: 'overflow-controls' })
|
|
1708
|
+
], HelixHeadlessVideo.prototype, "overflowControls", void 0);
|
|
1758
1709
|
__decorate([
|
|
1759
1710
|
property({ attribute: 'pause-label' })
|
|
1760
1711
|
], HelixHeadlessVideo.prototype, "pauseLabel", void 0);
|
|
1761
1712
|
__decorate([
|
|
1762
|
-
property({ attribute: '
|
|
1763
|
-
], HelixHeadlessVideo.prototype, "
|
|
1713
|
+
property({ attribute: 'play-label' })
|
|
1714
|
+
], HelixHeadlessVideo.prototype, "playLabel", void 0);
|
|
1764
1715
|
__decorate([
|
|
1765
|
-
property({ attribute: '
|
|
1766
|
-
], HelixHeadlessVideo.prototype, "
|
|
1716
|
+
property({ attribute: 'playsinline', converter: onUnlessFalse })
|
|
1717
|
+
], HelixHeadlessVideo.prototype, "playsInline", void 0);
|
|
1718
|
+
__decorate([
|
|
1719
|
+
property()
|
|
1720
|
+
], HelixHeadlessVideo.prototype, "poster", void 0);
|
|
1721
|
+
__decorate([
|
|
1722
|
+
property()
|
|
1723
|
+
], HelixHeadlessVideo.prototype, "preload", void 0);
|
|
1724
|
+
__decorate([
|
|
1725
|
+
property({ attribute: 'speeds' })
|
|
1726
|
+
], HelixHeadlessVideo.prototype, "speeds", void 0);
|
|
1727
|
+
__decorate([
|
|
1728
|
+
property()
|
|
1729
|
+
], HelixHeadlessVideo.prototype, "src", void 0);
|
|
1730
|
+
__decorate([
|
|
1731
|
+
property({ attribute: 'start-control' })
|
|
1732
|
+
], HelixHeadlessVideo.prototype, "startControl", void 0);
|
|
1767
1733
|
__decorate([
|
|
1768
1734
|
state()
|
|
1769
1735
|
], HelixHeadlessVideo.prototype, "buffering", void 0);
|
|
@@ -41,13 +41,17 @@ import { type TemplateResult } from 'lit';
|
|
|
41
41
|
*/
|
|
42
42
|
export declare class HelixHeadlessVideoPlaylistItem extends HelixElement {
|
|
43
43
|
/**
|
|
44
|
-
*
|
|
44
|
+
* Whether the player is on this entry.
|
|
45
|
+
*
|
|
46
|
+
* Written by the playlist rather than by the entry, the way an option's
|
|
47
|
+
* selection is: an entry that made itself current would be a second answer to
|
|
48
|
+
* which one is playing.
|
|
45
49
|
*/
|
|
46
|
-
|
|
50
|
+
current: boolean;
|
|
47
51
|
/**
|
|
48
|
-
*
|
|
52
|
+
* Whether the entry can be chosen.
|
|
49
53
|
*/
|
|
50
|
-
|
|
54
|
+
disabled: boolean;
|
|
51
55
|
/**
|
|
52
56
|
* What covers the picture before this entry plays, and the row's thumbnail.
|
|
53
57
|
*
|
|
@@ -59,24 +63,20 @@ export declare class HelixHeadlessVideoPlaylistItem extends HelixElement {
|
|
|
59
63
|
*/
|
|
60
64
|
poster: string;
|
|
61
65
|
/**
|
|
62
|
-
*
|
|
66
|
+
* The file this entry plays.
|
|
63
67
|
*/
|
|
64
|
-
|
|
68
|
+
src: string;
|
|
65
69
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* Written by the playlist rather than by the entry, the way an option's
|
|
69
|
-
* selection is: an entry that made itself current would be a second answer to
|
|
70
|
-
* which one is playing.
|
|
70
|
+
* What identifies the entry, and what `active` is compared against.
|
|
71
71
|
*/
|
|
72
|
-
|
|
72
|
+
value: string;
|
|
73
73
|
/**
|
|
74
74
|
* The entry's name, which is the words and not everything in it.
|
|
75
75
|
*
|
|
76
|
-
* `textContent`
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
76
|
+
* `textContent` takes the whole subtree: a row with a duration in `meta`
|
|
77
|
+
* reads as "His Girl Friday0:06", and that string reaches the player and the
|
|
78
|
+
* lock screen. Only the nodes the consumer left unslotted are the name;
|
|
79
|
+
* anything named is a column beside it.
|
|
80
80
|
*
|
|
81
81
|
* Light DOM rather than `assignedNodes`, so it answers on the server too,
|
|
82
82
|
* where there is no slot to ask. `Option.text` reads its own the same way.
|