@mattebox/player-cast 0.1.0 → 0.3.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 +22 -16
- package/dist/cast-button.js +58 -64
- package/dist/cast-button.js.map +1 -1
- package/dist/cast-screen.d.ts.map +1 -1
- package/dist/cast-screen.js +113 -145
- package/dist/cast-screen.js.map +1 -1
- package/dist/cast.js +258 -311
- package/dist/cast.js.map +1 -1
- package/dist/cdn/mattebox-player-cast.min.js +1 -91
- package/dist/component.js +85 -88
- package/dist/component.js.map +1 -1
- package/dist/es2015/cast-screen.js +2 -34
- package/dist/es2015/icons.js +4 -4
- package/dist/es2015/shared.js +4 -59
- package/dist/host.js +15 -13
- package/dist/host.js.map +1 -1
- package/dist/icons.d.ts +3 -27
- package/dist/icons.d.ts.map +1 -1
- package/dist/icons.js +19 -46
- package/dist/icons.js.map +1 -1
- package/dist/index.js +17 -19
- package/dist/index.js.map +1 -1
- package/dist/shared.d.ts +2 -10
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +54 -107
- package/dist/shared.js.map +1 -1
- package/dist/slider.js +151 -160
- package/dist/slider.js.map +1 -1
- package/package.json +6 -7
- package/NOTICE +0 -24
package/dist/host.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.js","
|
|
1
|
+
{"version":3,"file":"host.js","names":[],"sources":["../src/host.ts"],"sourcesContent":["/**\n * The contract of a control of the page's own, as guide chapter 03 of the\n * player states it: the nearest <mattebox-player> above, through shadow\n * hosts, then read for `video`, `engine`, `player` and `error`, with\n * `sourcechange` heard on it. This package implements the contract from\n * outside, on purpose: the player exports no base class, and a control that\n * needs more than this surface has found a gap in the player's API.\n */\nimport type { PlayerHost } from '@mattebox/player';\n\nexport type { PlayerHost };\n\nexport const PLAYER = 'mattebox-player';\n\n/** The parent, or the host of the shadow root `node` sits in, or null at the document. */\nfunction above(node: Node): Node | null {\n const parent = node.parentNode;\n if (parent !== null) return parent;\n return node instanceof ShadowRoot ? node.host : null;\n}\n\n/** The nearest player above `node`, or null outside one. It may not be upgraded yet. */\nexport function findPlayer(node: Node): HTMLElement | null {\n let current: Node | null = node;\n while (current !== null) {\n if (current instanceof HTMLElement && current.localName === PLAYER) return current;\n current = above(current);\n }\n return null;\n}\n"],"mappings":";AAYA,MAAa,SAAS;;AAGtB,SAAS,MAAM,MAAyB;CACtC,MAAM,SAAS,KAAK;CACpB,IAAI,WAAW,MAAM,OAAO;CAC5B,OAAO,gBAAgB,aAAa,KAAK,OAAO;AAClD;;AAGA,SAAgB,WAAW,MAAgC;CACzD,IAAI,UAAuB;CAC3B,OAAO,YAAY,MAAM;EACvB,IAAI,mBAAmB,eAAe,QAAQ,cAAA,mBAAsB,OAAO;EAC3E,UAAU,MAAM,OAAO;CACzB;CACA,OAAO;AACT"}
|
package/dist/icons.d.ts
CHANGED
|
@@ -1,31 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The play and
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Copied, not depended on. The notice below is the license's one condition,
|
|
6
|
-
* and packages/player/NOTICE repeats it for the published tarball.
|
|
7
|
-
*
|
|
8
|
-
* MIT License
|
|
9
|
-
*
|
|
10
|
-
* Copyright (c) 2023 Rahim Alwer
|
|
11
|
-
*
|
|
12
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
14
|
-
* in the Software without restriction, including without limitation the rights
|
|
15
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
17
|
-
* furnished to do so, subject to the following conditions:
|
|
18
|
-
*
|
|
19
|
-
* The above copyright notice and this permission notice shall be included in all
|
|
20
|
-
* copies or substantial portions of the Software.
|
|
21
|
-
*
|
|
22
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
-
* SOFTWARE.
|
|
2
|
+
* The play, pause and cast glyphs, Mattebox's own drawings and the same
|
|
3
|
+
* ones the player draws: filled paths on a 32-unit viewBox. The cast glyph
|
|
4
|
+
* is a screen with a corner open for three arcs, filled while casting.
|
|
29
5
|
*/
|
|
30
6
|
export type IconName = 'play' | 'pause' | 'cast' | 'cast-active';
|
|
31
7
|
/** A glyph, hidden from the accessibility tree: the button it sits in carries the name. */
|
package/dist/icons.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../src/icons.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../src/icons.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,aAAa,CAAC;AAajE,2FAA2F;AAC3F,wBAAgB,IAAI,CAAC,IAAI,EAAE,QAAQ,GAAG,aAAa,CAUlD"}
|
package/dist/icons.js
CHANGED
|
@@ -1,52 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
* The play and pause glyphs, copied from Vidstack's media-icons 0.10.0
|
|
3
|
-
* (https://github.com/vidstack/media-icons): filled paths on a 32-unit
|
|
4
|
-
* viewBox, drawn for a control bar, one visual weight across the set.
|
|
5
|
-
* Copied, not depended on. The notice below is the license's one condition,
|
|
6
|
-
* and packages/player/NOTICE repeats it for the published tarball.
|
|
7
|
-
*
|
|
8
|
-
* MIT License
|
|
9
|
-
*
|
|
10
|
-
* Copyright (c) 2023 Rahim Alwer
|
|
11
|
-
*
|
|
12
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
14
|
-
* in the Software without restriction, including without limitation the rights
|
|
15
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
17
|
-
* furnished to do so, subject to the following conditions:
|
|
18
|
-
*
|
|
19
|
-
* The above copyright notice and this permission notice shall be included in all
|
|
20
|
-
* copies or substantial portions of the Software.
|
|
21
|
-
*
|
|
22
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
-
* SOFTWARE.
|
|
29
|
-
*/
|
|
1
|
+
//#region src/icons.ts
|
|
30
2
|
/** Each glyph's subpaths joined into one `d`, drawn even-odd like the player's. */
|
|
31
3
|
const PATHS = {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
cast: 'M4 6h24v18H20v-2h6V8H6v1H4V6zM4 21a3 3 0 0 1 3 3H4zM4 15a9 9 0 0 1 9 9h-2a7 7 0 0 0-7-7zM4 10a14 14 0 0 1 14 14h-2A12 12 0 0 0 4 12z',
|
|
37
|
-
'cast-active': 'M4 6h24v18H20A16 16 0 0 0 4 8zM4 21a3 3 0 0 1 3 3H4zM4 15a9 9 0 0 1 9 9h-2a7 7 0 0 0-7-7zM4 10a14 14 0 0 1 14 14h-2A12 12 0 0 0 4 12z',
|
|
4
|
+
play: "M9 5L26 16L9 27z",
|
|
5
|
+
pause: "M8 6h5.5v20h-5.5zM18.5 6h5.5v20h-5.5z",
|
|
6
|
+
cast: "M4 6H28V26H20V23.5H25.5V8.5H6.5V11H4zM4 23h3v3h-3zM4 17.5A8.5 8.5 0 0 1 12.5 26L10 26A6 6 0 0 0 4 20zM4 12A14 14 0 0 1 18 26L15.5 26A11.5 11.5 0 0 0 4 14.5z",
|
|
7
|
+
"cast-active": "M4 6H28V26H20A16 16 0 0 0 4 10zM4 23h3v3h-3zM4 17.5A8.5 8.5 0 0 1 12.5 26L10 26A6 6 0 0 0 4 20zM4 12A14 14 0 0 1 18 26L15.5 26A11.5 11.5 0 0 0 4 14.5z"
|
|
38
8
|
};
|
|
39
|
-
const SVG =
|
|
9
|
+
const SVG = "http://www.w3.org/2000/svg";
|
|
40
10
|
/** A glyph, hidden from the accessibility tree: the button it sits in carries the name. */
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
11
|
+
function icon(name) {
|
|
12
|
+
const svg = document.createElementNS(SVG, "svg");
|
|
13
|
+
svg.setAttribute("viewBox", "0 0 32 32");
|
|
14
|
+
svg.setAttribute("aria-hidden", "true");
|
|
15
|
+
svg.setAttribute("part", "icon");
|
|
16
|
+
const path = document.createElementNS(SVG, "path");
|
|
17
|
+
path.setAttribute("fill-rule", "evenodd");
|
|
18
|
+
path.setAttribute("d", PATHS[name]);
|
|
19
|
+
svg.append(path);
|
|
20
|
+
return svg;
|
|
51
21
|
}
|
|
22
|
+
//#endregion
|
|
23
|
+
export { icon };
|
|
24
|
+
|
|
52
25
|
//# sourceMappingURL=icons.js.map
|
package/dist/icons.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icons.js","
|
|
1
|
+
{"version":3,"file":"icons.js","names":[],"sources":["../src/icons.ts"],"sourcesContent":["/**\n * The play, pause and cast glyphs, Mattebox's own drawings and the same\n * ones the player draws: filled paths on a 32-unit viewBox. The cast glyph\n * is a screen with a corner open for three arcs, filled while casting.\n */\n\nexport type IconName = 'play' | 'pause' | 'cast' | 'cast-active';\n\n/** Each glyph's subpaths joined into one `d`, drawn even-odd like the player's. */\nconst PATHS: Readonly<Record<IconName, string>> = {\n play: 'M9 5L26 16L9 27z',\n pause: 'M8 6h5.5v20h-5.5zM18.5 6h5.5v20h-5.5z',\n cast: 'M4 6H28V26H20V23.5H25.5V8.5H6.5V11H4zM4 23h3v3h-3zM4 17.5A8.5 8.5 0 0 1 12.5 26L10 26A6 6 0 0 0 4 20zM4 12A14 14 0 0 1 18 26L15.5 26A11.5 11.5 0 0 0 4 14.5z',\n 'cast-active':\n 'M4 6H28V26H20A16 16 0 0 0 4 10zM4 23h3v3h-3zM4 17.5A8.5 8.5 0 0 1 12.5 26L10 26A6 6 0 0 0 4 20zM4 12A14 14 0 0 1 18 26L15.5 26A11.5 11.5 0 0 0 4 14.5z',\n};\n\nconst SVG = 'http://www.w3.org/2000/svg';\n\n/** A glyph, hidden from the accessibility tree: the button it sits in carries the name. */\nexport function icon(name: IconName): SVGSVGElement {\n const svg = document.createElementNS(SVG, 'svg');\n svg.setAttribute('viewBox', '0 0 32 32');\n svg.setAttribute('aria-hidden', 'true');\n svg.setAttribute('part', 'icon');\n const path = document.createElementNS(SVG, 'path');\n path.setAttribute('fill-rule', 'evenodd');\n path.setAttribute('d', PATHS[name]);\n svg.append(path);\n return svg;\n}\n"],"mappings":";;AASA,MAAM,QAA4C;CAChD,MAAM;CACN,OAAO;CACP,MAAM;CACN,eACE;AACJ;AAEA,MAAM,MAAM;;AAGZ,SAAgB,KAAK,MAA+B;CAClD,MAAM,MAAM,SAAS,gBAAgB,KAAK,KAAK;CAC/C,IAAI,aAAa,WAAW,WAAW;CACvC,IAAI,aAAa,eAAe,MAAM;CACtC,IAAI,aAAa,QAAQ,MAAM;CAC/B,MAAM,OAAO,SAAS,gBAAgB,KAAK,MAAM;CACjD,KAAK,aAAa,aAAa,SAAS;CACxC,KAAK,aAAa,KAAK,MAAM,KAAK;CAClC,IAAI,OAAO,IAAI;CACf,OAAO;AACT"}
|
package/dist/index.js
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
|
+
import { MbxCastButton } from "./cast-button.js";
|
|
2
|
+
import { MbxCastScreen } from "./cast-screen.js";
|
|
3
|
+
//#region src/index.ts
|
|
1
4
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export
|
|
15
|
-
|
|
16
|
-
customElements.define(CAST_BUTTON, MbxCastButton);
|
|
17
|
-
}
|
|
18
|
-
if (customElements.get(CAST_SCREEN) === undefined) {
|
|
19
|
-
customElements.define(CAST_SCREEN, MbxCastScreen);
|
|
20
|
-
}
|
|
5
|
+
* @mattebox/player-cast: <mbx-cast-button> and <mbx-cast-screen>, Chromecast
|
|
6
|
+
* from the player over Google's sender SDK. Importing this module registers
|
|
7
|
+
* both elements; that is the package's one side effect. It is a package of
|
|
8
|
+
* its own because the button loads Google's script onto the page, which the
|
|
9
|
+
* player never does on an integrator's behalf: the AirPlay button, over
|
|
10
|
+
* Safari's own API, ships with the player.
|
|
11
|
+
*/
|
|
12
|
+
const CAST_BUTTON = "mbx-cast-button";
|
|
13
|
+
const CAST_SCREEN = "mbx-cast-screen";
|
|
14
|
+
if (customElements.get("mbx-cast-button") === void 0) customElements.define(CAST_BUTTON, MbxCastButton);
|
|
15
|
+
if (customElements.get("mbx-cast-screen") === void 0) customElements.define(CAST_SCREEN, MbxCastScreen);
|
|
16
|
+
//#endregion
|
|
17
|
+
export { CAST_BUTTON, CAST_SCREEN, MbxCastButton, MbxCastScreen };
|
|
18
|
+
|
|
21
19
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @mattebox/player-cast: <mbx-cast-button> and <mbx-cast-screen>, Chromecast\n * from the player over Google's sender SDK. Importing this module registers\n * both elements; that is the package's one side effect. It is a package of\n * its own because the button loads Google's script onto the page, which the\n * player never does on an integrator's behalf: the AirPlay button, over\n * Safari's own API, ships with the player.\n */\nimport { MbxCastButton } from './cast-button.js';\nimport { MbxCastScreen } from './cast-screen.js';\n\nexport type { CastState, LoadRequest as CastLoadRequest, MediaInfo, Track } from './cast.js';\nexport { MbxCastButton } from './cast-button.js';\nexport { MbxCastScreen } from './cast-screen.js';\n\nexport const CAST_BUTTON = 'mbx-cast-button';\nexport const CAST_SCREEN = 'mbx-cast-screen';\n\nif (customElements.get(CAST_BUTTON) === undefined) {\n customElements.define(CAST_BUTTON, MbxCastButton);\n}\nif (customElements.get(CAST_SCREEN) === undefined) {\n customElements.define(CAST_SCREEN, MbxCastScreen);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mbx-cast-button': MbxCastButton;\n 'mbx-cast-screen': MbxCastScreen;\n }\n}\n"],"mappings":";;;;;;;;;;;AAeA,MAAa,cAAc;AAC3B,MAAa,cAAc;AAE3B,IAAI,eAAe,IAAA,iBAAe,MAAM,KAAA,GACtC,eAAe,OAAO,aAAa,aAAa;AAElD,IAAI,eAAe,IAAA,iBAAe,MAAM,KAAA,GACtC,eAAe,OAAO,aAAa,aAAa"}
|
package/dist/shared.d.ts
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
* The styles and helpers the two elements share, copied from the player:
|
|
3
|
-
* the button and slider styles, the glyph slots, the part helper, the label
|
|
4
|
-
* template, and the time format. The player exports none of them, on
|
|
5
|
-
* purpose: a control of the page's own carries its own, and so does this
|
|
6
|
-
* package. The tokens come through the `--mbx-*` custom properties the
|
|
7
|
-
* player sets, which inherit into every control.
|
|
8
|
-
*/
|
|
9
|
-
export declare const BUTTON_STYLE = "\n:host { display: inline-flex; }\n:host([hidden]) { display: none; }\n[part~=\"button\"] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: 40px;\n height: 40px;\n padding: 0;\n font: inherit;\n color: inherit;\n background: transparent;\n border: 0;\n border-radius: var(--mbx-radius);\n cursor: pointer;\n opacity: 0.9;\n}\n[part~=\"button\"]:hover { opacity: 1; }\n[part~=\"button\"]:focus-visible { outline: 2px solid var(--mbx-accent); outline-offset: -2px; }\n[part~=\"icon\"], ::slotted(*) { width: 1.75em; height: 1.75em; fill: currentColor; }\nslot[hidden] { display: none; }\n";
|
|
1
|
+
export declare const BUTTON_STYLE: string;
|
|
10
2
|
/** The style of a slider: the rail, the track with its fill, and the thumb. */
|
|
11
3
|
/** The style of a slider: the rail, the track with its fill, and the thumb. */
|
|
12
|
-
export declare const SLIDER_STYLE
|
|
4
|
+
export declare const SLIDER_STYLE: string;
|
|
13
5
|
/** A `<style>` with `text`, for a shadow root. */
|
|
14
6
|
export declare function style(text: string): HTMLStyleElement;
|
|
15
7
|
/**
|
package/dist/shared.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,YAAY,QAAmB,CAAC;AAE7C,+EAA+E;AAE/E,+EAA+E;AAC/E,eAAO,MAAM,YAAY,QAAmB,CAAC;AAE7C,kDAAkD;AAClD,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAIpD;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,EACxC,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,aAAa,GACpC,MAAM,CAAC,CAAC,EAAE,eAAe,CAAC,CAU5B;AAED,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,EAAE,eAAe,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAExF;AAED,oEAAoE;AACpE,wBAAgB,EAAE,CAAC,CAAC,SAAS,MAAM,qBAAqB,EACtD,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,qBAAqB,CAAC,CAAC,CAAC,CAK1B;AAED,wBAAgB,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAKhG;AAMD,iGAAiG;AACjG,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAM9C;AAED,iIAAiI;AACjI,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAElE"}
|
package/dist/shared.js
CHANGED
|
@@ -1,125 +1,72 @@
|
|
|
1
|
+
//#region src/shared.ts
|
|
1
2
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
:host
|
|
11
|
-
|
|
12
|
-
[part~="button"] {
|
|
13
|
-
display: inline-flex;
|
|
14
|
-
align-items: center;
|
|
15
|
-
justify-content: center;
|
|
16
|
-
flex: none;
|
|
17
|
-
width: 40px;
|
|
18
|
-
height: 40px;
|
|
19
|
-
padding: 0;
|
|
20
|
-
font: inherit;
|
|
21
|
-
color: inherit;
|
|
22
|
-
background: transparent;
|
|
23
|
-
border: 0;
|
|
24
|
-
border-radius: var(--mbx-radius);
|
|
25
|
-
cursor: pointer;
|
|
26
|
-
opacity: 0.9;
|
|
27
|
-
}
|
|
28
|
-
[part~="button"]:hover { opacity: 1; }
|
|
29
|
-
[part~="button"]:focus-visible { outline: 2px solid var(--mbx-accent); outline-offset: -2px; }
|
|
30
|
-
[part~="icon"], ::slotted(*) { width: 1.75em; height: 1.75em; fill: currentColor; }
|
|
31
|
-
slot[hidden] { display: none; }
|
|
32
|
-
`;
|
|
3
|
+
* The styles and helpers the two elements share, copied from the player:
|
|
4
|
+
* the button and slider styles, the glyph slots, the part helper, the label
|
|
5
|
+
* template, and the time format. The player exports none of them, on
|
|
6
|
+
* purpose: a control of the page's own carries its own, and so does this
|
|
7
|
+
* package. The tokens come through the `--mbx-*` custom properties the
|
|
8
|
+
* player sets, which inherit into every control.
|
|
9
|
+
*/
|
|
10
|
+
const BUTTON_STYLE_CSS = ":host{display:inline-flex}:host([hidden]){display:none}[part~=button]{width:2.5em;height:2.5em;font:inherit;color:inherit;border-radius:var(--mbx-radius);cursor:pointer;opacity:.9;background:0 0;border:0;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}[part~=button]:hover{opacity:1}[part~=button]:focus{outline:2px solid var(--mbx-accent);outline-offset:-2px}[part~=button]:focus:not(:focus-visible){outline:none}[part~=icon],::slotted(*){fill:currentColor;width:1.75em;height:1.75em}slot[hidden]{display:none}";
|
|
11
|
+
const SLIDER_STYLE_CSS = ":host{display:block}:host([hidden]){display:none}[part~=slider]{border-radius:var(--mbx-radius);cursor:pointer;touch-action:none;height:2.6667em;position:relative}[part~=slider]:focus{outline:2px solid var(--mbx-accent);outline-offset:-2px}[part~=slider]:focus:not(:focus-visible){outline:none}[part~=rail]{position:absolute;top:0;bottom:0;left:.5333em;right:.5333em}[part~=track]{background:#ffffff59;border-radius:2px;height:.2667em;position:absolute;top:50%;left:0;right:0;overflow:hidden;transform:translateY(-50%)}[part~=fill]{background:var(--mbx-accent);position:absolute;top:0;bottom:0;left:0}[part~=thumb]{background:var(--mbx-text);pointer-events:none;border-radius:50%;width:.8em;height:.8em;margin:-.4em 0 0 -.4em;position:absolute;top:50%}";
|
|
12
|
+
const BUTTON_STYLE = BUTTON_STYLE_CSS;
|
|
33
13
|
/** The style of a slider: the rail, the track with its fill, and the thumb. */
|
|
34
14
|
/** The style of a slider: the rail, the track with its fill, and the thumb. */
|
|
35
|
-
|
|
36
|
-
:host { display: block; }
|
|
37
|
-
:host([hidden]) { display: none; }
|
|
38
|
-
[part~="slider"] {
|
|
39
|
-
position: relative;
|
|
40
|
-
height: 40px;
|
|
41
|
-
border-radius: var(--mbx-radius);
|
|
42
|
-
cursor: pointer;
|
|
43
|
-
touch-action: none;
|
|
44
|
-
}
|
|
45
|
-
[part~="slider"]:focus-visible { outline: 2px solid var(--mbx-accent); outline-offset: -2px; }
|
|
46
|
-
[part~="rail"] { position: absolute; top: 0; bottom: 0; left: 8px; right: 8px; }
|
|
47
|
-
[part~="track"] {
|
|
48
|
-
position: absolute;
|
|
49
|
-
top: 50%;
|
|
50
|
-
left: 0;
|
|
51
|
-
right: 0;
|
|
52
|
-
height: 4px;
|
|
53
|
-
transform: translateY(-50%);
|
|
54
|
-
background: rgba(255, 255, 255, 0.35);
|
|
55
|
-
border-radius: 2px;
|
|
56
|
-
overflow: hidden;
|
|
57
|
-
}
|
|
58
|
-
[part~="fill"] { position: absolute; top: 0; bottom: 0; left: 0; background: var(--mbx-accent); }
|
|
59
|
-
[part~="thumb"] {
|
|
60
|
-
position: absolute;
|
|
61
|
-
top: 50%;
|
|
62
|
-
width: 12px;
|
|
63
|
-
height: 12px;
|
|
64
|
-
margin: -6px 0 0 -6px;
|
|
65
|
-
border-radius: 50%;
|
|
66
|
-
background: var(--mbx-text);
|
|
67
|
-
pointer-events: none;
|
|
68
|
-
}
|
|
69
|
-
`;
|
|
15
|
+
const SLIDER_STYLE = SLIDER_STYLE_CSS;
|
|
70
16
|
/** A `<style>` with `text`, for a shadow root. */
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
17
|
+
function style(text) {
|
|
18
|
+
const node = document.createElement("style");
|
|
19
|
+
node.textContent = text;
|
|
20
|
+
return node;
|
|
75
21
|
}
|
|
76
22
|
/**
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
23
|
+
* A named slot per state with the default glyph as its fallback, so a page
|
|
24
|
+
* drops its own SVG into `slot="icon-<state>"` and the button keeps the
|
|
25
|
+
* name. Returns the slots by state; `show` hides all but one.
|
|
26
|
+
*/
|
|
27
|
+
function iconSlots(states, fallback) {
|
|
28
|
+
const out = {};
|
|
29
|
+
for (const state of states) {
|
|
30
|
+
const slot = document.createElement("slot");
|
|
31
|
+
slot.name = `icon-${state}`;
|
|
32
|
+
slot.append(fallback(state));
|
|
33
|
+
slot.hidden = true;
|
|
34
|
+
out[state] = slot;
|
|
35
|
+
}
|
|
36
|
+
return out;
|
|
91
37
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
slots[key].hidden = key !== state;
|
|
38
|
+
function show(slots, state) {
|
|
39
|
+
for (const key of Object.keys(slots)) slots[key].hidden = key !== state;
|
|
95
40
|
}
|
|
96
41
|
/** An element with its part names, and its text when it has any. */
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return node;
|
|
42
|
+
function el(tag, part, text) {
|
|
43
|
+
const node = document.createElement(tag);
|
|
44
|
+
node.setAttribute("part", part);
|
|
45
|
+
if (text !== void 0) node.textContent = text;
|
|
46
|
+
return node;
|
|
103
47
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
48
|
+
function fill(template, values) {
|
|
49
|
+
return template.replace(/\{(\w+)\}/g, (match, name) => {
|
|
50
|
+
const value = values[name];
|
|
51
|
+
return value === void 0 ? match : String(value);
|
|
52
|
+
});
|
|
109
53
|
}
|
|
110
54
|
function pad(n) {
|
|
111
|
-
|
|
55
|
+
return n < 10 ? `0${n}` : `${n}`;
|
|
112
56
|
}
|
|
113
57
|
/** `m:ss`, or `h:mm:ss` from an hour up. Anything not a finite positive number reads as zero. */
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
58
|
+
function format(seconds) {
|
|
59
|
+
const total = Number.isFinite(seconds) && seconds > 0 ? Math.floor(seconds) : 0;
|
|
60
|
+
const hours = Math.floor(total / 3600);
|
|
61
|
+
const minutes = Math.floor(total % 3600 / 60);
|
|
62
|
+
const rest = total % 60;
|
|
63
|
+
return hours > 0 ? `${hours}:${pad(minutes)}:${pad(rest)}` : `${minutes}:${pad(rest)}`;
|
|
120
64
|
}
|
|
121
65
|
/** What a screen reader hears for a position: "1:23 of 4:56", or the position alone when the duration is unknown or infinite. */
|
|
122
|
-
|
|
123
|
-
|
|
66
|
+
function describe(current, duration) {
|
|
67
|
+
return Number.isFinite(duration) ? `${format(current)} of ${format(duration)}` : format(current);
|
|
124
68
|
}
|
|
69
|
+
//#endregion
|
|
70
|
+
export { BUTTON_STYLE, SLIDER_STYLE, describe, el, fill, format, iconSlots, show, style };
|
|
71
|
+
|
|
125
72
|
//# sourceMappingURL=shared.js.map
|
package/dist/shared.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","
|
|
1
|
+
{"version":3,"file":"shared.js","names":[],"sources":["../src/shared.ts"],"sourcesContent":["/**\n * The styles and helpers the two elements share, copied from the player:\n * the button and slider styles, the glyph slots, the part helper, the label\n * template, and the time format. The player exports none of them, on\n * purpose: a control of the page's own carries its own, and so does this\n * package. The tokens come through the `--mbx-*` custom properties the\n * player sets, which inherit into every control.\n */\nimport BUTTON_STYLE_CSS from './button.css?inline';\nimport SLIDER_STYLE_CSS from './slider.css?inline';\n\nexport const BUTTON_STYLE = BUTTON_STYLE_CSS;\n\n/** The style of a slider: the rail, the track with its fill, and the thumb. */\n\n/** The style of a slider: the rail, the track with its fill, and the thumb. */\nexport const SLIDER_STYLE = SLIDER_STYLE_CSS;\n\n/** A `<style>` with `text`, for a shadow root. */\nexport function style(text: string): HTMLStyleElement {\n const node = document.createElement('style');\n node.textContent = text;\n return node;\n}\n\n/**\n * A named slot per state with the default glyph as its fallback, so a page\n * drops its own SVG into `slot=\"icon-<state>\"` and the button keeps the\n * name. Returns the slots by state; `show` hides all but one.\n */\nexport function iconSlots<S extends string>(\n states: readonly S[],\n fallback: (state: S) => SVGSVGElement,\n): Record<S, HTMLSlotElement> {\n const out = {} as Record<S, HTMLSlotElement>;\n for (const state of states) {\n const slot = document.createElement('slot');\n slot.name = `icon-${state}`;\n slot.append(fallback(state));\n slot.hidden = true;\n out[state] = slot;\n }\n return out;\n}\n\nexport function show<S extends string>(slots: Record<S, HTMLSlotElement>, state: S): void {\n for (const key of Object.keys(slots) as S[]) slots[key].hidden = key !== state;\n}\n\n/** An element with its part names, and its text when it has any. */\nexport function el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n part: string,\n text?: string,\n): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag);\n node.setAttribute('part', part);\n if (text !== undefined) node.textContent = text;\n return node;\n}\n\nexport function fill(template: string, values: Readonly<Record<string, string | number>>): string {\n return template.replace(/\\{(\\w+)\\}/g, (match: string, name: string) => {\n const value = values[name];\n return value === undefined ? match : String(value);\n });\n}\n\nfunction pad(n: number): string {\n return n < 10 ? `0${n}` : `${n}`;\n}\n\n/** `m:ss`, or `h:mm:ss` from an hour up. Anything not a finite positive number reads as zero. */\nexport function format(seconds: number): string {\n const total = Number.isFinite(seconds) && seconds > 0 ? Math.floor(seconds) : 0;\n const hours = Math.floor(total / 3600);\n const minutes = Math.floor((total % 3600) / 60);\n const rest = total % 60;\n return hours > 0 ? `${hours}:${pad(minutes)}:${pad(rest)}` : `${minutes}:${pad(rest)}`;\n}\n\n/** What a screen reader hears for a position: \"1:23 of 4:56\", or the position alone when the duration is unknown or infinite. */\nexport function describe(current: number, duration: number): string {\n return Number.isFinite(duration) ? `${format(current)} of ${format(duration)}` : format(current);\n}\n"],"mappings":";;;;;;;;;AAQA,MAAA,mBAAA;AACA,MAAA,mBAAA;AAEA,MAAA,eAAA;;;AAKA,MAAA,eAAA;;AAGA,SAAA,MAAA,MAAA;CACA,MAAA,OAAA,SAAA,cAAA,OAAA;CACA,KAAA,cAAA;CACA,OAAA;AACA;;;;;;AAOA,SAAA,UACA,QACA,UACA;CACA,MAAA,MAAA,CAAA;CACA,KAAA,MAAA,SAAA,QAAA;EACA,MAAA,OAAA,SAAA,cAAA,MAAA;EACA,KAAA,OAAA,QAAA;EACA,KAAA,OAAA,SAAA,KAAA,CAAA;EACA,KAAA,SAAA;EACA,IAAA,SAAA;CACA;CACA,OAAA;AACA;AAEA,SAAA,KAAA,OAAA,OAAA;CACA,KAAA,MAAA,OAAA,OAAA,KAAA,KAAA,GAAA,MAAA,IAAA,CAAA,SAAA,QAAA;AACA;;AAGA,SAAA,GACA,KACA,MACA,MACA;CACA,MAAA,OAAA,SAAA,cAAA,GAAA;CACA,KAAA,aAAA,QAAA,IAAA;CACA,IAAA,SAAA,KAAA,GAAA,KAAA,cAAA;CACA,OAAA;AACA;AAEA,SAAA,KAAA,UAAA,QAAA;CACA,OAAA,SAAA,QAAA,eAAA,OAAA,SAAA;EACA,MAAA,QAAA,OAAA;EACA,OAAA,UAAA,KAAA,IAAA,QAAA,OAAA,KAAA;CACA,CAAA;AACA;AAEA,SAAA,IAAA,GAAA;CACA,OAAA,IAAA,KAAA,IAAA,MAAA,GAAA;AACA;;AAGA,SAAA,OAAA,SAAA;CACA,MAAA,QAAA,OAAA,SAAA,OAAA,KAAA,UAAA,IAAA,KAAA,MAAA,OAAA,IAAA;CACA,MAAA,QAAA,KAAA,MAAA,QAAA,IAAA;CACA,MAAA,UAAA,KAAA,MAAA,QAAA,OAAA,EAAA;CACA,MAAA,OAAA,QAAA;CACA,OAAA,QAAA,IAAA,GAAA,MAAA,GAAA,IAAA,OAAA,EAAA,GAAA,IAAA,IAAA,MAAA,GAAA,QAAA,GAAA,IAAA,IAAA;AACA;;AAGA,SAAA,SAAA,SAAA,UAAA;CACA,OAAA,OAAA,SAAA,QAAA,IAAA,GAAA,OAAA,OAAA,EAAA,MAAA,OAAA,QAAA,MAAA,OAAA,OAAA;AACA"}
|