@mattebox/player 0.4.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/README.md +9 -6
- package/dist/cdn/mattebox-player.min.js +105 -34
- package/dist/element.d.ts +17 -21
- package/dist/element.d.ts.map +1 -1
- package/dist/element.js +59 -41
- package/dist/element.js.map +1 -1
- package/dist/elements/spinner.d.ts +25 -0
- package/dist/elements/spinner.d.ts.map +1 -0
- package/dist/elements/spinner.js +80 -0
- package/dist/elements/spinner.js.map +1 -0
- package/dist/elements/start-button.d.ts.map +1 -1
- package/dist/elements/start-button.js +3 -2
- package/dist/elements/start-button.js.map +1 -1
- package/dist/elements/title.d.ts +19 -0
- package/dist/elements/title.d.ts.map +1 -0
- package/dist/elements/title.js +139 -0
- package/dist/elements/title.js.map +1 -0
- package/dist/entries/spinner.d.ts +5 -0
- package/dist/entries/spinner.d.ts.map +1 -0
- package/dist/entries/spinner.js +9 -0
- package/dist/entries/spinner.js.map +1 -0
- package/dist/entries/title.d.ts +5 -0
- package/dist/entries/title.d.ts.map +1 -0
- package/dist/entries/title.js +9 -0
- package/dist/entries/title.js.map +1 -0
- package/dist/es2015/_virtual/{_@oxc-project_runtime@0.149.0 → _@oxc-project_runtime@0.150.0}/helpers/esm/asyncToGenerator.js +1 -1
- package/dist/es2015/_virtual/{_@oxc-project_runtime@0.149.0 → _@oxc-project_runtime@0.150.0}/helpers/esm/defineProperty.js +1 -1
- package/dist/es2015/_virtual/{_@oxc-project_runtime@0.149.0 → _@oxc-project_runtime@0.150.0}/helpers/esm/objectSpread2.js +1 -1
- package/dist/es2015/_virtual/{_@oxc-project_runtime@0.149.0 → _@oxc-project_runtime@0.150.0}/helpers/esm/toPrimitive.js +1 -1
- package/dist/es2015/_virtual/{_@oxc-project_runtime@0.149.0 → _@oxc-project_runtime@0.150.0}/helpers/esm/toPropertyKey.js +1 -1
- package/dist/es2015/_virtual/{_@oxc-project_runtime@0.149.0 → _@oxc-project_runtime@0.150.0}/helpers/esm/typeof.js +1 -1
- package/dist/es2015/controls/menu.js +1 -1
- package/dist/es2015/element.js +47 -33
- package/dist/es2015/elements/spinner.js +84 -0
- package/dist/es2015/elements/start-button.js +6 -3
- package/dist/es2015/elements/title.js +151 -0
- package/dist/es2015/entries/spinner.js +7 -0
- package/dist/es2015/entries/title.js +7 -0
- package/dist/es2015/index.js +5 -3
- package/dist/es2015/presets.js +1 -1
- package/dist/es2015/style.js +13 -5
- package/dist/es2015/tags.js +3 -2
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/namespaces.d.ts +1 -1
- package/dist/style.d.ts +1 -1
- package/dist/style.d.ts.map +1 -1
- package/dist/style.js +13 -5
- package/dist/style.js.map +1 -1
- package/dist/tags.d.ts +2 -1
- package/dist/tags.d.ts.map +1 -1
- package/dist/tags.js +2 -1
- package/dist/tags.js.map +1 -1
- package/package.json +3 -3
- package/dist/compose.d.ts +0 -5
- package/dist/compose.d.ts.map +0 -1
- package/dist/compose.js +0 -31
- package/dist/compose.js.map +0 -1
- package/dist/elements/panels.d.ts +0 -15
- package/dist/elements/panels.d.ts.map +0 -1
- package/dist/elements/panels.js +0 -55
- package/dist/elements/panels.js.map +0 -1
- package/dist/entries/panels.d.ts +0 -5
- package/dist/entries/panels.d.ts.map +0 -1
- package/dist/entries/panels.js +0 -8
- package/dist/entries/panels.js.map +0 -1
- package/dist/es2015/compose.js +0 -33
- package/dist/es2015/elements/panels.js +0 -52
- package/dist/es2015/entries/panels.js +0 -7
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <mbx-title>: the heading, the subheading and the artwork of what plays,
|
|
3
|
+
* as a lower third across the picture above the bar: a scrim that fades
|
|
4
|
+
* upward, the artwork in the first column, the two lines in the second,
|
|
5
|
+
* so a heading alone sits on a band and never floats. The content comes
|
|
6
|
+
* from attributes, `heading`,
|
|
7
|
+
* `subheading` and `artwork`, because the stream carries none of it: a page
|
|
8
|
+
* writes what it knows, and a Cast receiver writes what the sender said.
|
|
9
|
+
* With none of the three the element draws nothing.
|
|
10
|
+
*
|
|
11
|
+
* Shown while the video is paused, which includes before the first play,
|
|
12
|
+
* and hidden while it plays. The element carries `playing` for that rule,
|
|
13
|
+
* so a page changes it in CSS: `mattebox-player[started] mbx-title
|
|
14
|
+
* { display: none }` keeps it to the time before the first play, like the
|
|
15
|
+
* poster, and `mattebox-player:hover mbx-title { display: flex }` brings it
|
|
16
|
+
* back on hover. The height of the bar's rows, its box less the fade it
|
|
17
|
+
* pads itself with, goes on the host as `--mbx-bar-rows`, so the text sits
|
|
18
|
+
* just above the seek row while the band runs under the bar to the bottom
|
|
19
|
+
* edge, one ramp with the bar's own fade. The scrim is the page's to
|
|
20
|
+
* override. Placed first among the screens, so the start button, the
|
|
21
|
+
* error screen and the spinner paint over its band.
|
|
22
|
+
*/
|
|
23
|
+
import { el } from '../dom.js';
|
|
24
|
+
import { Component } from './component.js';
|
|
25
|
+
import { style } from './shared.js';
|
|
26
|
+
const STYLE = `
|
|
27
|
+
:host {
|
|
28
|
+
position: absolute;
|
|
29
|
+
left: 0;
|
|
30
|
+
right: 0;
|
|
31
|
+
bottom: 0;
|
|
32
|
+
display: flex;
|
|
33
|
+
align-items: flex-end;
|
|
34
|
+
gap: 14px;
|
|
35
|
+
/* The band runs under the bar to the bottom edge, one ramp with the
|
|
36
|
+
bar's own fade, so there is no seam where the bar begins; the text
|
|
37
|
+
sits 12px above the bar's rows, inside the bar's fade. */
|
|
38
|
+
padding: 72px calc(var(--mbx-pad) + 8px) calc(var(--mbx-bar-rows, 0px) + 12px);
|
|
39
|
+
background: linear-gradient(to top, rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0.3) 45%, rgba(0, 0, 0, 0));
|
|
40
|
+
color: var(--mbx-text);
|
|
41
|
+
font: 400 14px/1.35 var(--mbx-font);
|
|
42
|
+
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
|
|
43
|
+
pointer-events: none;
|
|
44
|
+
}
|
|
45
|
+
:host([playing]) { display: none; }
|
|
46
|
+
:host([empty]) { display: none; }
|
|
47
|
+
:host([hidden]) { display: none; }
|
|
48
|
+
[part~="artwork"] {
|
|
49
|
+
flex: none;
|
|
50
|
+
height: 72px;
|
|
51
|
+
width: auto;
|
|
52
|
+
max-width: 128px;
|
|
53
|
+
border-radius: var(--mbx-radius);
|
|
54
|
+
object-fit: cover;
|
|
55
|
+
box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.14);
|
|
56
|
+
}
|
|
57
|
+
[part~="artwork"][hidden] { display: none; }
|
|
58
|
+
[part~="text"] { display: flex; flex-direction: column; gap: 2px; min-width: 0; max-width: 60ch; }
|
|
59
|
+
[part~="heading"] {
|
|
60
|
+
font-size: 20px;
|
|
61
|
+
font-weight: 600;
|
|
62
|
+
letter-spacing: -0.01em;
|
|
63
|
+
line-height: 1.2;
|
|
64
|
+
white-space: nowrap;
|
|
65
|
+
overflow: hidden;
|
|
66
|
+
text-overflow: ellipsis;
|
|
67
|
+
}
|
|
68
|
+
[part~="subheading"] { color: rgba(255, 255, 255, 0.78); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
69
|
+
[part~="heading"]:empty, [part~="subheading"]:empty { display: none; }
|
|
70
|
+
`;
|
|
71
|
+
export class MbxTitle extends Component {
|
|
72
|
+
static get observedAttributes() {
|
|
73
|
+
return ['heading', 'subheading', 'artwork'];
|
|
74
|
+
}
|
|
75
|
+
constructor() {
|
|
76
|
+
super();
|
|
77
|
+
this.resizer = null;
|
|
78
|
+
const root = this.attachShadow({ mode: 'open' });
|
|
79
|
+
this.artwork = el('img', 'artwork');
|
|
80
|
+
this.artwork.alt = '';
|
|
81
|
+
this.artwork.hidden = true;
|
|
82
|
+
const text = el('div', 'text');
|
|
83
|
+
this.heading = el('div', 'heading');
|
|
84
|
+
this.subheading = el('div', 'subheading');
|
|
85
|
+
text.append(this.heading, this.subheading);
|
|
86
|
+
root.append(style(STYLE), this.artwork, text);
|
|
87
|
+
}
|
|
88
|
+
attach(player) {
|
|
89
|
+
this.listen(player.video, ['play', 'pause', 'ended', 'emptied'], () => {
|
|
90
|
+
this.state(player);
|
|
91
|
+
});
|
|
92
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
93
|
+
this.resizer = new ResizeObserver(() => {
|
|
94
|
+
this.fit(player);
|
|
95
|
+
});
|
|
96
|
+
this.resizer.observe(player);
|
|
97
|
+
}
|
|
98
|
+
this.fit(player);
|
|
99
|
+
this.state(player);
|
|
100
|
+
this.render();
|
|
101
|
+
}
|
|
102
|
+
detach() {
|
|
103
|
+
this.resizer?.disconnect();
|
|
104
|
+
this.resizer = null;
|
|
105
|
+
this.removeAttribute('playing');
|
|
106
|
+
this.style.removeProperty('--mbx-bar-rows');
|
|
107
|
+
}
|
|
108
|
+
/** `playing` on the element, for its own stylesheet and the page's. */
|
|
109
|
+
state(player) {
|
|
110
|
+
this.toggleAttribute('playing', !player.video.paused);
|
|
111
|
+
}
|
|
112
|
+
/** The height of the bar's rows: its box less the padding above them, which is its fade. Zero without a bar. */
|
|
113
|
+
fit(player) {
|
|
114
|
+
const bar = player.querySelector('mbx-control-bar');
|
|
115
|
+
let rows = 0;
|
|
116
|
+
if (bar !== null) {
|
|
117
|
+
const top = Number.parseFloat(getComputedStyle(bar).paddingTop) || 0;
|
|
118
|
+
rows = Math.max(0, bar.getBoundingClientRect().height - top);
|
|
119
|
+
}
|
|
120
|
+
this.style.setProperty('--mbx-bar-rows', `${rows}px`);
|
|
121
|
+
}
|
|
122
|
+
render() {
|
|
123
|
+
const heading = this.getAttribute('heading') ?? '';
|
|
124
|
+
const subheading = this.getAttribute('subheading') ?? '';
|
|
125
|
+
const artwork = this.getAttribute('artwork');
|
|
126
|
+
this.heading.textContent = heading;
|
|
127
|
+
this.subheading.textContent = subheading;
|
|
128
|
+
if (artwork === null) {
|
|
129
|
+
this.artwork.removeAttribute('src');
|
|
130
|
+
this.artwork.hidden = true;
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
this.artwork.src = artwork;
|
|
134
|
+
this.artwork.hidden = false;
|
|
135
|
+
}
|
|
136
|
+
this.toggleAttribute('empty', heading === '' && subheading === '' && artwork === null);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=title.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"title.js","sourceRoot":"","sources":["../../src/elements/title.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/entries/spinner.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,OAAO,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAOpD,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** `@mattebox/player/elements/spinner`: registers <mbx-spinner>, and the player with it. */
|
|
2
|
+
import '../element-entry.js';
|
|
3
|
+
import { MbxSpinner } from '../elements/spinner.js';
|
|
4
|
+
import { SPINNER } from '../tags.js';
|
|
5
|
+
if (customElements.get(SPINNER) === undefined) {
|
|
6
|
+
customElements.define(SPINNER, MbxSpinner);
|
|
7
|
+
}
|
|
8
|
+
export { MbxSpinner };
|
|
9
|
+
//# sourceMappingURL=spinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/entries/spinner.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,OAAO,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,IAAI,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;IAC9C,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAC7C,CAAC;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"title.d.ts","sourceRoot":"","sources":["../../src/entries/title.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,OAAO,qBAAqB,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAOhD,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** `@mattebox/player/elements/title`: registers <mbx-title>, and the player with it. */
|
|
2
|
+
import '../element-entry.js';
|
|
3
|
+
import { MbxTitle } from '../elements/title.js';
|
|
4
|
+
import { TITLE } from '../tags.js';
|
|
5
|
+
if (customElements.get(TITLE) === undefined) {
|
|
6
|
+
customElements.define(TITLE, MbxTitle);
|
|
7
|
+
}
|
|
8
|
+
export { MbxTitle };
|
|
9
|
+
//# sourceMappingURL=title.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"title.js","sourceRoot":"","sources":["../../src/entries/title.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,OAAO,qBAAqB,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,IAAI,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;IAC5C,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AACzC,CAAC;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import toPropertyKey from "./toPropertyKey.js";
|
|
2
|
-
//#region \0@oxc-project+runtime@0.
|
|
2
|
+
//#region \0@oxc-project+runtime@0.150.0/helpers/esm/defineProperty.js
|
|
3
3
|
function _defineProperty(e, r, t) {
|
|
4
4
|
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
5
5
|
value: t,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _defineProperty from "./defineProperty.js";
|
|
2
|
-
//#region \0@oxc-project+runtime@0.
|
|
2
|
+
//#region \0@oxc-project+runtime@0.150.0/helpers/esm/objectSpread2.js
|
|
3
3
|
function ownKeys(e, r) {
|
|
4
4
|
var t = Object.keys(e);
|
|
5
5
|
if (Object.getOwnPropertySymbols) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _typeof from "./typeof.js";
|
|
2
|
-
//#region \0@oxc-project+runtime@0.
|
|
2
|
+
//#region \0@oxc-project+runtime@0.150.0/helpers/esm/toPrimitive.js
|
|
3
3
|
function toPrimitive(t, r) {
|
|
4
4
|
if ("object" != _typeof(t) || !t) return t;
|
|
5
5
|
var e = t[Symbol.toPrimitive];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _typeof from "./typeof.js";
|
|
2
2
|
import toPrimitive from "./toPrimitive.js";
|
|
3
|
-
//#region \0@oxc-project+runtime@0.
|
|
3
|
+
//#region \0@oxc-project+runtime@0.150.0/helpers/esm/toPropertyKey.js
|
|
4
4
|
function toPropertyKey(t) {
|
|
5
5
|
var i = toPrimitive(t, "string");
|
|
6
6
|
return "symbol" == _typeof(i) ? i : i + "";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region \0@oxc-project+runtime@0.
|
|
1
|
+
//#region \0@oxc-project+runtime@0.150.0/helpers/esm/typeof.js
|
|
2
2
|
function _typeof(o) {
|
|
3
3
|
"@babel/helpers - typeof";
|
|
4
4
|
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { el, state } from "../dom.js";
|
|
2
|
-
import _objectSpread2 from "../_virtual/_@oxc-project_runtime@0.
|
|
2
|
+
import _objectSpread2 from "../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/objectSpread2.js";
|
|
3
3
|
//#region src/controls/menu.ts
|
|
4
4
|
/**
|
|
5
5
|
* The menu primitive the quality, audio, subtitles and speed menus share: a
|
package/dist/es2015/element.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { CONTROL_BAR, PANELS, PLAYER } from "./tags.js";
|
|
2
|
-
import { composeBar, composePanels } from "./compose.js";
|
|
3
1
|
import { namespaces } from "./namespaces.js";
|
|
4
|
-
import _asyncToGenerator from "./_virtual/_@oxc-project_runtime@0.
|
|
2
|
+
import _asyncToGenerator from "./_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/asyncToGenerator.js";
|
|
5
3
|
import { drmGuard, resolvePreset } from "./presets.js";
|
|
6
4
|
import { STYLE } from "./style.js";
|
|
7
5
|
import { errorSurface } from "./surface.js";
|
|
8
|
-
import
|
|
6
|
+
import { PLAYER } from "./tags.js";
|
|
7
|
+
import _objectSpread2 from "./_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/objectSpread2.js";
|
|
9
8
|
import { createPlayer, inferType, matteboxHandler, nativeHandler } from "@mattebox/player-core";
|
|
10
9
|
//#region src/element.ts
|
|
11
10
|
/** Attributes forwarded onto the video as attributes, never as properties. */
|
|
@@ -33,11 +32,19 @@ const OWN = [
|
|
|
33
32
|
const CHAPTERS = "chapters";
|
|
34
33
|
/**
|
|
35
34
|
* The one attribute whose meaning the element owns: `native` keeps the
|
|
36
|
-
* browser's controls on the video, `custom` swaps them for the
|
|
37
|
-
*
|
|
38
|
-
* `native`. Changing it
|
|
35
|
+
* browser's controls on the video, `custom` swaps them for the controls the
|
|
36
|
+
* page placed inside, `none` takes the browser's off and hides every child
|
|
37
|
+
* but the video. Anything else is `native`. Changing it never touches the
|
|
38
|
+
* session.
|
|
39
39
|
*/
|
|
40
40
|
const CONTROLS = "controls";
|
|
41
|
+
/**
|
|
42
|
+
* Inline playback, on until the page writes `playsinline="false"`, the way
|
|
43
|
+
* `spellcheck` and `draggable` are on until told otherwise. An iPhone takes
|
|
44
|
+
* a video without `playsinline` to its own fullscreen on play, where no
|
|
45
|
+
* control the page placed shows. Changing it never reloads.
|
|
46
|
+
*/
|
|
47
|
+
const PLAYSINLINE = "playsinline";
|
|
41
48
|
/** The video's state, as attributes on the element, read on the events the video fires for it. */
|
|
42
49
|
const STATE_EVENTS = [
|
|
43
50
|
"play",
|
|
@@ -46,7 +53,11 @@ const STATE_EVENTS = [
|
|
|
46
53
|
"emptied",
|
|
47
54
|
"volumechange",
|
|
48
55
|
"loadedmetadata",
|
|
49
|
-
"resize"
|
|
56
|
+
"resize",
|
|
57
|
+
"playing",
|
|
58
|
+
"waiting",
|
|
59
|
+
"stalled",
|
|
60
|
+
"canplay"
|
|
50
61
|
];
|
|
51
62
|
/** Every stage the engine ships. A narrower preset is optimization. */
|
|
52
63
|
const DEFAULT_PRESET = "full";
|
|
@@ -68,7 +79,8 @@ var MatteboxPlayerElement = class MatteboxPlayerElement extends HTMLElement {
|
|
|
68
79
|
...FORWARDED,
|
|
69
80
|
...OWN,
|
|
70
81
|
CONTROLS,
|
|
71
|
-
CHAPTERS
|
|
82
|
+
CHAPTERS,
|
|
83
|
+
PLAYSINLINE
|
|
72
84
|
];
|
|
73
85
|
}
|
|
74
86
|
/**
|
|
@@ -84,20 +96,22 @@ var MatteboxPlayerElement = class MatteboxPlayerElement extends HTMLElement {
|
|
|
84
96
|
constructor(options) {
|
|
85
97
|
super();
|
|
86
98
|
this.options = options !== null && options !== void 0 ? options : defaults;
|
|
87
|
-
this.composed = [];
|
|
88
|
-
this.settled = false;
|
|
89
99
|
this.focusable = false;
|
|
90
100
|
this.track = null;
|
|
91
101
|
this.core = null;
|
|
92
102
|
this.current = null;
|
|
93
103
|
this.failure = null;
|
|
94
104
|
this.reflecting = false;
|
|
105
|
+
this.started = false;
|
|
106
|
+
this.waiting = false;
|
|
95
107
|
this.offs = [];
|
|
96
108
|
this.queue = Promise.resolve();
|
|
97
109
|
this.pending = false;
|
|
98
110
|
this.media = document.createElement("video");
|
|
99
111
|
this.media.controls = true;
|
|
112
|
+
this.media.setAttribute(PLAYSINLINE, "");
|
|
100
113
|
for (const name of STATE_EVENTS) this.media.addEventListener(name, () => {
|
|
114
|
+
this.note(name);
|
|
101
115
|
this.reflect();
|
|
102
116
|
});
|
|
103
117
|
this.media.addEventListener("playing", () => {
|
|
@@ -130,8 +144,8 @@ var MatteboxPlayerElement = class MatteboxPlayerElement extends HTMLElement {
|
|
|
130
144
|
/**
|
|
131
145
|
* The fatal error of the current load, or null once a load starts or
|
|
132
146
|
* playback resumes. The `error` event says when; this says what, for a
|
|
133
|
-
* control that attaches after the event, such as
|
|
134
|
-
*
|
|
147
|
+
* control that attaches after the event, such as an error screen parsed
|
|
148
|
+
* after a source that failed while the page was still loading.
|
|
135
149
|
*/
|
|
136
150
|
get error() {
|
|
137
151
|
return this.failure;
|
|
@@ -140,17 +154,19 @@ var MatteboxPlayerElement = class MatteboxPlayerElement extends HTMLElement {
|
|
|
140
154
|
if (this.media.parentNode !== this) this.append(this.media);
|
|
141
155
|
for (const name of FORWARDED) this.forward(name);
|
|
142
156
|
this.reflect();
|
|
143
|
-
if (!this.settled) this.settle();
|
|
144
157
|
this.reload();
|
|
145
158
|
}
|
|
146
|
-
/**
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
this.
|
|
150
|
-
this.
|
|
151
|
-
};
|
|
152
|
-
if (
|
|
153
|
-
else
|
|
159
|
+
/** The two states the video does not hold: whether it has played once, and whether it waits for data. */
|
|
160
|
+
note(event) {
|
|
161
|
+
if (event === "playing") {
|
|
162
|
+
this.started = true;
|
|
163
|
+
this.waiting = false;
|
|
164
|
+
} else if (event === "waiting" || event === "stalled") this.waiting = true;
|
|
165
|
+
else if (event === "canplay") this.waiting = false;
|
|
166
|
+
else if (event === "emptied") {
|
|
167
|
+
this.started = false;
|
|
168
|
+
this.waiting = false;
|
|
169
|
+
}
|
|
154
170
|
}
|
|
155
171
|
/** The video's state on the element, for `mattebox-player[paused]` and the like. */
|
|
156
172
|
reflect() {
|
|
@@ -161,6 +177,8 @@ var MatteboxPlayerElement = class MatteboxPlayerElement extends HTMLElement {
|
|
|
161
177
|
this.toggleAttribute("ended", video.ended);
|
|
162
178
|
this.toggleAttribute("muted", video.muted);
|
|
163
179
|
this.toggleAttribute("audio", this.audio());
|
|
180
|
+
this.toggleAttribute("started", this.started);
|
|
181
|
+
this.toggleAttribute("waiting", this.waiting);
|
|
164
182
|
this.reflecting = false;
|
|
165
183
|
}
|
|
166
184
|
/**
|
|
@@ -194,14 +212,18 @@ var MatteboxPlayerElement = class MatteboxPlayerElement extends HTMLElement {
|
|
|
194
212
|
this.chapters();
|
|
195
213
|
return;
|
|
196
214
|
}
|
|
215
|
+
if (name === PLAYSINLINE) {
|
|
216
|
+
this.media.toggleAttribute(PLAYSINLINE, this.getAttribute(PLAYSINLINE) !== "false");
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
197
219
|
if (name === "preset") this.enqueue(() => this.discard());
|
|
198
220
|
if (name === "src" || name === "type") this.toggleAttribute("audio", this.audio());
|
|
199
221
|
this.reload();
|
|
200
222
|
}
|
|
201
223
|
/**
|
|
202
|
-
* Applies the `controls` attribute: the video's own controls
|
|
203
|
-
* tabindex
|
|
204
|
-
*
|
|
224
|
+
* Applies the `controls` attribute: the video's own controls and the
|
|
225
|
+
* tabindex. The controls themselves are elements the page placed, and
|
|
226
|
+
* they attach on their own; the element appends none.
|
|
205
227
|
*/
|
|
206
228
|
mode() {
|
|
207
229
|
const value = this.getAttribute(CONTROLS);
|
|
@@ -215,14 +237,6 @@ var MatteboxPlayerElement = class MatteboxPlayerElement extends HTMLElement {
|
|
|
215
237
|
this.tabIndex = 0;
|
|
216
238
|
this.focusable = true;
|
|
217
239
|
}
|
|
218
|
-
if (!this.settled) return;
|
|
219
|
-
for (const node of this.composed) node.remove();
|
|
220
|
-
this.composed = [];
|
|
221
|
-
const own = custom ? CONTROL_BAR : PANELS;
|
|
222
|
-
if (this.querySelector(`:scope > ${own}`) === null) {
|
|
223
|
-
this.composed = custom ? composeBar() : composePanels();
|
|
224
|
-
this.append(...this.composed);
|
|
225
|
-
}
|
|
226
240
|
}
|
|
227
241
|
/** Keeps a hidden chapters track on the video for the `chapters` attribute, or none. */
|
|
228
242
|
chapters() {
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Component } from "./component.js";
|
|
2
|
+
import { style } from "./shared.js";
|
|
3
|
+
//#region src/elements/spinner.ts
|
|
4
|
+
const STYLE = `
|
|
5
|
+
:host {
|
|
6
|
+
position: absolute;
|
|
7
|
+
top: 50%;
|
|
8
|
+
left: 50%;
|
|
9
|
+
width: 44px;
|
|
10
|
+
height: 44px;
|
|
11
|
+
margin: -22px 0 0 -22px;
|
|
12
|
+
display: none;
|
|
13
|
+
pointer-events: none;
|
|
14
|
+
color: var(--mbx-text);
|
|
15
|
+
filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.5));
|
|
16
|
+
}
|
|
17
|
+
:host([waiting]) { display: block; }
|
|
18
|
+
:host([hidden]) { display: none; }
|
|
19
|
+
[part~="ring"] {
|
|
20
|
+
box-sizing: border-box;
|
|
21
|
+
width: 100%;
|
|
22
|
+
height: 100%;
|
|
23
|
+
border: 3px solid rgba(255, 255, 255, 0.22);
|
|
24
|
+
border-top-color: currentColor;
|
|
25
|
+
border-radius: 50%;
|
|
26
|
+
animation: mbx-turn 0.8s linear infinite;
|
|
27
|
+
}
|
|
28
|
+
[part~="ring"][hidden] { display: none; }
|
|
29
|
+
slot[hidden] { display: none; }
|
|
30
|
+
::slotted(*) { width: 100%; height: 100%; }
|
|
31
|
+
@keyframes mbx-turn { to { transform: rotate(360deg); } }
|
|
32
|
+
@media (prefers-reduced-motion: reduce) {
|
|
33
|
+
[part~="ring"] { animation: none; }
|
|
34
|
+
}
|
|
35
|
+
`;
|
|
36
|
+
/** What the video fires as it waits and as it goes on. */
|
|
37
|
+
const EVENTS = [
|
|
38
|
+
"waiting",
|
|
39
|
+
"stalled",
|
|
40
|
+
"playing",
|
|
41
|
+
"canplay",
|
|
42
|
+
"emptied"
|
|
43
|
+
];
|
|
44
|
+
var MbxSpinner = class extends Component {
|
|
45
|
+
static get observedAttributes() {
|
|
46
|
+
return ["label"];
|
|
47
|
+
}
|
|
48
|
+
constructor() {
|
|
49
|
+
super();
|
|
50
|
+
const root = this.attachShadow({ mode: "open" });
|
|
51
|
+
this.ring = document.createElement("div");
|
|
52
|
+
this.ring.setAttribute("part", "ring");
|
|
53
|
+
this.slot_ = document.createElement("slot");
|
|
54
|
+
this.slot_.name = "icon";
|
|
55
|
+
this.slot_.addEventListener("slotchange", () => {
|
|
56
|
+
this.ring.hidden = this.slot_.assignedNodes().length > 0;
|
|
57
|
+
});
|
|
58
|
+
root.append(style(STYLE), this.ring, this.slot_);
|
|
59
|
+
}
|
|
60
|
+
/** Named before attaching: a constructor must not add attributes. */
|
|
61
|
+
connectedCallback() {
|
|
62
|
+
if (!this.hasAttribute("role")) this.setAttribute("role", "status");
|
|
63
|
+
super.connectedCallback();
|
|
64
|
+
}
|
|
65
|
+
attach(player) {
|
|
66
|
+
const video = player.video;
|
|
67
|
+
this.listen(video, EVENTS, () => {
|
|
68
|
+
this.render();
|
|
69
|
+
});
|
|
70
|
+
this.render();
|
|
71
|
+
}
|
|
72
|
+
detach() {
|
|
73
|
+
this.removeAttribute("waiting");
|
|
74
|
+
}
|
|
75
|
+
render() {
|
|
76
|
+
var _this$getAttribute;
|
|
77
|
+
const player = this.player;
|
|
78
|
+
if (player === null) return;
|
|
79
|
+
this.setAttribute("aria-label", (_this$getAttribute = this.getAttribute("label")) !== null && _this$getAttribute !== void 0 ? _this$getAttribute : "Loading");
|
|
80
|
+
this.toggleAttribute("waiting", player.hasAttribute("waiting"));
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
//#endregion
|
|
84
|
+
export { MbxSpinner };
|
|
@@ -52,7 +52,10 @@ var MbxStartButton = class extends Component {
|
|
|
52
52
|
this.listen(video, [
|
|
53
53
|
"play",
|
|
54
54
|
"pause",
|
|
55
|
-
"ended"
|
|
55
|
+
"ended",
|
|
56
|
+
"waiting",
|
|
57
|
+
"stalled",
|
|
58
|
+
"canplay"
|
|
56
59
|
], () => {
|
|
57
60
|
this.render();
|
|
58
61
|
});
|
|
@@ -111,13 +114,13 @@ var MbxStartButton = class extends Component {
|
|
|
111
114
|
if (cramped !== wasCramped) this.render();
|
|
112
115
|
}
|
|
113
116
|
render() {
|
|
114
|
-
var _this$player2, _this$getAttribute;
|
|
117
|
+
var _this$player2, _this$getAttribute, _this$player3;
|
|
115
118
|
const video = (_this$player2 = this.player) === null || _this$player2 === void 0 ? void 0 : _this$player2.video;
|
|
116
119
|
if (video === void 0) return;
|
|
117
120
|
const state = video.ended ? "replay" : "play";
|
|
118
121
|
show(this.slots, state);
|
|
119
122
|
this.button.setAttribute("aria-label", (_this$getAttribute = this.getAttribute(`label-${state}`)) !== null && _this$getAttribute !== void 0 ? _this$getAttribute : state === "play" ? "Play" : "Replay");
|
|
120
|
-
this.hidden = this.failed || !video.paused;
|
|
123
|
+
this.hidden = this.failed || !video.paused || ((_this$player3 = this.player) === null || _this$player3 === void 0 ? void 0 : _this$player3.hasAttribute("waiting")) === true;
|
|
121
124
|
}
|
|
122
125
|
};
|
|
123
126
|
//#endregion
|