mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
fix(html): prevent tsdown from stripping custom element registrations (#703)
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
import { audioFeatures } from '@videojs/core/dom';
|
import { audioFeatures } from '@videojs/core/dom';
|
||||||
|
import { MediaContainerElement } from '../../media/container-element';
|
||||||
import { createPlayer } from '../../player/create-player';
|
import { createPlayer } from '../../player/create-player';
|
||||||
import { MediaElement } from '../../ui/media-element';
|
import { MediaElement } from '../../ui/media-element';
|
||||||
import '../media/container';
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
const { ProviderMixin } = createPlayer({
|
const { ProviderMixin } = createPlayer({
|
||||||
features: audioFeatures,
|
features: audioFeatures,
|
||||||
@@ -11,7 +12,9 @@ export class AudioPlayerElement extends ProviderMixin(MediaElement) {
|
|||||||
static readonly tagName = 'audio-player';
|
static readonly tagName = 'audio-player';
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define(AudioPlayerElement.tagName, AudioPlayerElement);
|
// Provider must be defined before consumer for context handshake during upgrade.
|
||||||
|
safeDefine(AudioPlayerElement);
|
||||||
|
safeDefine(MediaContainerElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { backgroundFeatures } from '@videojs/core/dom';
|
import { backgroundFeatures } from '@videojs/core/dom';
|
||||||
|
import { MediaContainerElement } from '../../media/container-element';
|
||||||
import { createPlayer } from '../../player/create-player';
|
import { createPlayer } from '../../player/create-player';
|
||||||
import { MediaElement } from '../../ui/media-element';
|
import { MediaElement } from '../../ui/media-element';
|
||||||
import '../media/container';
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
const { ProviderMixin } = createPlayer({
|
const { ProviderMixin } = createPlayer({
|
||||||
features: backgroundFeatures,
|
features: backgroundFeatures,
|
||||||
@@ -11,7 +12,9 @@ export class BackgroundVideoPlayerElement extends ProviderMixin(MediaElement) {
|
|||||||
static readonly tagName = 'background-video-player';
|
static readonly tagName = 'background-video-player';
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define(BackgroundVideoPlayerElement.tagName, BackgroundVideoPlayerElement);
|
// Provider must be defined before consumer for context handshake during upgrade.
|
||||||
|
safeDefine(BackgroundVideoPlayerElement);
|
||||||
|
safeDefine(MediaContainerElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { ReactiveElement } from '@videojs/element';
|
import { ReactiveElement } from '@videojs/element';
|
||||||
import { namedNodeMapToObject } from '@videojs/utils/dom';
|
import { namedNodeMapToObject } from '@videojs/utils/dom';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
function getTemplateHTML(_attrs: Record<string, string>) {
|
function getTemplateHTML(_attrs: Record<string, string>) {
|
||||||
return /*html*/ `
|
return /*html*/ `
|
||||||
@@ -24,7 +25,7 @@ export class BackgroundVideoSkinElement extends ReactiveElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define(BackgroundVideoSkinElement.tagName, BackgroundVideoSkinElement);
|
safeDefine(BackgroundVideoSkinElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { BackgroundVideo } from '../../media/background-video';
|
import { BackgroundVideo } from '../../media/background-video';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
export class BackgroundVideoElement extends BackgroundVideo {
|
export class BackgroundVideoElement extends BackgroundVideo {
|
||||||
static readonly tagName = 'background-video';
|
static readonly tagName = 'background-video';
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define(BackgroundVideoElement.tagName, BackgroundVideoElement);
|
safeDefine(BackgroundVideoElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
import { playerContext } from '../../player/context';
|
import { MediaContainerElement } from '../../media/container-element';
|
||||||
import { createContainerMixin } from '../../store/container-mixin';
|
import { safeDefine } from '../safe-define';
|
||||||
import { MediaElement } from '../../ui/media-element';
|
|
||||||
|
|
||||||
const ContainerMixin = createContainerMixin(playerContext);
|
safeDefine(MediaContainerElement);
|
||||||
|
|
||||||
export class MediaContainerElement extends ContainerMixin(MediaElement) {
|
|
||||||
static readonly tagName = 'media-container';
|
|
||||||
}
|
|
||||||
|
|
||||||
customElements.define(MediaContainerElement.tagName, MediaContainerElement);
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { HlsVideo } from '../../media/hls-video';
|
import { HlsVideo } from '../../media/hls-video';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
export class HlsVideoElement extends HlsVideo {
|
export class HlsVideoElement extends HlsVideo {
|
||||||
static readonly tagName = 'hls-video';
|
static readonly tagName = 'hls-video';
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define(HlsVideoElement.tagName, HlsVideoElement);
|
safeDefine(HlsVideoElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
type DefinableElement = CustomElementConstructor & { tagName: string };
|
||||||
|
|
||||||
|
/** Define a custom element only if not already registered. */
|
||||||
|
export function safeDefine(element: DefinableElement): void {
|
||||||
|
if (!customElements.get(element.tagName)) {
|
||||||
|
customElements.define(element.tagName, element);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
import { afterAll, beforeAll, describe, expect, it, type MockInstance, vi } from 'vitest';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that composite define files register all expected custom elements
|
||||||
|
* and that provider/parent elements are defined before consumer/child elements.
|
||||||
|
*
|
||||||
|
* Tests run sequentially. Each dynamically imports a composite define file and
|
||||||
|
* checks the batch of `customElements.define()` calls that resulted. Because
|
||||||
|
* modules are cached within a test file, shared sub-elements (e.g. slider parts)
|
||||||
|
* are only registered by the first composite that imports them — subsequent
|
||||||
|
* composites skip them via `safeDefine`. This is intentional and tested.
|
||||||
|
*/
|
||||||
|
describe('composite define registration', () => {
|
||||||
|
let spy: MockInstance;
|
||||||
|
|
||||||
|
/** Tag names registered since `offset` (the call count before an import). */
|
||||||
|
function batchSince(offset: number): string[] {
|
||||||
|
return spy.mock.calls.slice(offset).map((call) => call[0] as string);
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
spy = vi.spyOn(customElements, 'define');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
spy.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
// ── Player composites ────────────────────────────────────────────────
|
||||||
|
|
||||||
|
describe('video/player', () => {
|
||||||
|
it('registers video-player before media-container', async () => {
|
||||||
|
const before = spy.mock.calls.length;
|
||||||
|
await import('../video/player');
|
||||||
|
const batch = batchSince(before);
|
||||||
|
|
||||||
|
expect(batch).toContain('video-player');
|
||||||
|
expect(batch).toContain('media-container');
|
||||||
|
expect(batch.indexOf('video-player')).toBeLessThan(batch.indexOf('media-container'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('audio/player', () => {
|
||||||
|
it('registers audio-player', async () => {
|
||||||
|
const before = spy.mock.calls.length;
|
||||||
|
await import('../audio/player');
|
||||||
|
const batch = batchSince(before);
|
||||||
|
|
||||||
|
expect(batch).toContain('audio-player');
|
||||||
|
// media-container already registered by video/player — safeDefine skips it
|
||||||
|
expect(batch).not.toContain('media-container');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('background/player', () => {
|
||||||
|
it('registers background-video-player', async () => {
|
||||||
|
const before = spy.mock.calls.length;
|
||||||
|
await import('../background/player');
|
||||||
|
const batch = batchSince(before);
|
||||||
|
|
||||||
|
expect(batch).toContain('background-video-player');
|
||||||
|
expect(batch).not.toContain('media-container');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ── Slider composites ────────────────────────────────────────────────
|
||||||
|
|
||||||
|
describe('ui/time-slider', () => {
|
||||||
|
it('registers media-time-slider before sub-elements', async () => {
|
||||||
|
const before = spy.mock.calls.length;
|
||||||
|
await import('../ui/time-slider');
|
||||||
|
const batch = batchSince(before);
|
||||||
|
|
||||||
|
// Parent slider must be first (provider for sliderContext)
|
||||||
|
expect(batch[0]).toBe('media-time-slider');
|
||||||
|
|
||||||
|
// All sub-elements registered (first composite to claim them)
|
||||||
|
expect(batch).toContain('media-slider-buffer');
|
||||||
|
expect(batch).toContain('media-slider-fill');
|
||||||
|
expect(batch).toContain('media-slider-thumb');
|
||||||
|
expect(batch).toContain('media-slider-track');
|
||||||
|
expect(batch).toContain('media-slider-value');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ui/volume-slider', () => {
|
||||||
|
it('registers media-volume-slider and skips already-defined sub-elements', async () => {
|
||||||
|
const before = spy.mock.calls.length;
|
||||||
|
await import('../ui/volume-slider');
|
||||||
|
const batch = batchSince(before);
|
||||||
|
|
||||||
|
expect(batch).toContain('media-volume-slider');
|
||||||
|
|
||||||
|
// Sub-elements already registered by time-slider — safeDefine skips them
|
||||||
|
expect(batch).not.toContain('media-slider-fill');
|
||||||
|
expect(batch).not.toContain('media-slider-thumb');
|
||||||
|
expect(batch).not.toContain('media-slider-track');
|
||||||
|
expect(batch).not.toContain('media-slider-value');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ui/slider', () => {
|
||||||
|
it('registers media-slider', async () => {
|
||||||
|
const before = spy.mock.calls.length;
|
||||||
|
await import('../ui/slider');
|
||||||
|
const batch = batchSince(before);
|
||||||
|
|
||||||
|
expect(batch).toContain('media-slider');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ── Other composites ─────────────────────────────────────────────────
|
||||||
|
|
||||||
|
describe('ui/time', () => {
|
||||||
|
it('registers media-time before sub-elements', async () => {
|
||||||
|
const before = spy.mock.calls.length;
|
||||||
|
await import('../ui/time');
|
||||||
|
const batch = batchSince(before);
|
||||||
|
|
||||||
|
expect(batch[0]).toBe('media-time');
|
||||||
|
expect(batch).toContain('media-time-group');
|
||||||
|
expect(batch).toContain('media-time-separator');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ui/controls', () => {
|
||||||
|
it('registers media-controls before sub-elements', async () => {
|
||||||
|
const before = spy.mock.calls.length;
|
||||||
|
await import('../ui/controls');
|
||||||
|
const batch = batchSince(before);
|
||||||
|
|
||||||
|
expect(batch[0]).toBe('media-controls');
|
||||||
|
expect(batch).toContain('media-controls-group');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ── Final state ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
describe('registry completeness', () => {
|
||||||
|
it('all expected elements are registered after importing all composites', () => {
|
||||||
|
const expected = [
|
||||||
|
// Players + container
|
||||||
|
'video-player',
|
||||||
|
'audio-player',
|
||||||
|
'background-video-player',
|
||||||
|
'media-container',
|
||||||
|
// Sliders
|
||||||
|
'media-slider',
|
||||||
|
'media-time-slider',
|
||||||
|
'media-volume-slider',
|
||||||
|
// Slider sub-elements
|
||||||
|
'media-slider-buffer',
|
||||||
|
'media-slider-fill',
|
||||||
|
'media-slider-thumb',
|
||||||
|
'media-slider-track',
|
||||||
|
'media-slider-value',
|
||||||
|
// Time
|
||||||
|
'media-time',
|
||||||
|
'media-time-group',
|
||||||
|
'media-time-separator',
|
||||||
|
// Controls
|
||||||
|
'media-controls',
|
||||||
|
'media-controls-group',
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const tagName of expected) {
|
||||||
|
expect(customElements.get(tagName), `${tagName} should be registered`).toBeDefined();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
|
describe('safeDefine', () => {
|
||||||
|
it('registers a custom element', () => {
|
||||||
|
class TestElement extends HTMLElement {
|
||||||
|
static tagName = 'test-sd-register';
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(customElements.get('test-sd-register')).toBeUndefined();
|
||||||
|
safeDefine(TestElement);
|
||||||
|
expect(customElements.get('test-sd-register')).toBe(TestElement);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not throw when element is already registered', () => {
|
||||||
|
class TestElement extends HTMLElement {
|
||||||
|
static tagName = 'test-sd-no-throw';
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('test-sd-no-throw', TestElement);
|
||||||
|
expect(() => safeDefine(TestElement)).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not replace an existing registration', () => {
|
||||||
|
class Original extends HTMLElement {
|
||||||
|
static tagName = 'test-sd-no-replace';
|
||||||
|
}
|
||||||
|
class Replacement extends HTMLElement {
|
||||||
|
static tagName = 'test-sd-no-replace';
|
||||||
|
}
|
||||||
|
|
||||||
|
safeDefine(Original);
|
||||||
|
safeDefine(Replacement);
|
||||||
|
expect(customElements.get('test-sd-no-replace')).toBe(Original);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { BufferingIndicatorElement } from '../../ui/buffering-indicator/buffering-indicator-element';
|
import { BufferingIndicatorElement } from '../../ui/buffering-indicator/buffering-indicator-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(BufferingIndicatorElement.tagName, BufferingIndicatorElement);
|
safeDefine(BufferingIndicatorElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ControlsGroupElement } from '../../ui/controls/controls-group-element';
|
import { ControlsGroupElement } from '../../ui/controls/controls-group-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(ControlsGroupElement.tagName, ControlsGroupElement);
|
safeDefine(ControlsGroupElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { ControlsElement } from '../../ui/controls/controls-element';
|
import { ControlsElement } from '../../ui/controls/controls-element';
|
||||||
|
import { ControlsGroupElement } from '../../ui/controls/controls-group-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
import './controls-group';
|
safeDefine(ControlsElement);
|
||||||
|
safeDefine(ControlsGroupElement);
|
||||||
customElements.define(ControlsElement.tagName, ControlsElement);
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { FullscreenButtonElement } from '../../ui/fullscreen-button/fullscreen-button-element';
|
import { FullscreenButtonElement } from '../../ui/fullscreen-button/fullscreen-button-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(FullscreenButtonElement.tagName, FullscreenButtonElement);
|
safeDefine(FullscreenButtonElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { MuteButtonElement } from '../../ui/mute-button/mute-button-element';
|
import { MuteButtonElement } from '../../ui/mute-button/mute-button-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(MuteButtonElement.tagName, MuteButtonElement);
|
safeDefine(MuteButtonElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { PiPButtonElement } from '../../ui/pip-button/pip-button-element';
|
import { PiPButtonElement } from '../../ui/pip-button/pip-button-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(PiPButtonElement.tagName, PiPButtonElement);
|
safeDefine(PiPButtonElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { PlayButtonElement } from '../../ui/play-button/play-button-element';
|
import { PlayButtonElement } from '../../ui/play-button/play-button-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(PlayButtonElement.tagName, PlayButtonElement);
|
safeDefine(PlayButtonElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { PlaybackRateButtonElement } from '../../ui/playback-rate-button/playback-rate-button-element';
|
import { PlaybackRateButtonElement } from '../../ui/playback-rate-button/playback-rate-button-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(PlaybackRateButtonElement.tagName, PlaybackRateButtonElement);
|
safeDefine(PlaybackRateButtonElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { PopoverElement } from '../../ui/popover/popover-element';
|
import { PopoverElement } from '../../ui/popover/popover-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(PopoverElement.tagName, PopoverElement);
|
safeDefine(PopoverElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { PosterElement } from '../../ui/poster/poster-element';
|
import { PosterElement } from '../../ui/poster/poster-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(PosterElement.tagName, PosterElement);
|
safeDefine(PosterElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { SeekButtonElement } from '../../ui/seek-button/seek-button-element';
|
import { SeekButtonElement } from '../../ui/seek-button/seek-button-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(SeekButtonElement.tagName, SeekButtonElement);
|
safeDefine(SeekButtonElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { SliderBufferElement } from '../../ui/slider/slider-buffer-element';
|
import { SliderBufferElement } from '../../ui/slider/slider-buffer-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(SliderBufferElement.tagName, SliderBufferElement);
|
safeDefine(SliderBufferElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { SliderFillElement } from '../../ui/slider/slider-fill-element';
|
import { SliderFillElement } from '../../ui/slider/slider-fill-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(SliderFillElement.tagName, SliderFillElement);
|
safeDefine(SliderFillElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { SliderThumbElement } from '../../ui/slider/slider-thumb-element';
|
import { SliderThumbElement } from '../../ui/slider/slider-thumb-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(SliderThumbElement.tagName, SliderThumbElement);
|
safeDefine(SliderThumbElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { SliderTrackElement } from '../../ui/slider/slider-track-element';
|
import { SliderTrackElement } from '../../ui/slider/slider-track-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(SliderTrackElement.tagName, SliderTrackElement);
|
safeDefine(SliderTrackElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { SliderValueElement } from '../../ui/slider/slider-value-element';
|
import { SliderValueElement } from '../../ui/slider/slider-value-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(SliderValueElement.tagName, SliderValueElement);
|
safeDefine(SliderValueElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
import { SliderElement } from '../../ui/slider/slider-element';
|
import { SliderElement } from '../../ui/slider/slider-element';
|
||||||
|
import { SliderFillElement } from '../../ui/slider/slider-fill-element';
|
||||||
|
import { SliderThumbElement } from '../../ui/slider/slider-thumb-element';
|
||||||
|
import { SliderTrackElement } from '../../ui/slider/slider-track-element';
|
||||||
|
import { SliderValueElement } from '../../ui/slider/slider-value-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
import './slider-fill';
|
// Parent slider first — sub-elements consume its context.
|
||||||
import './slider-thumb';
|
safeDefine(SliderElement);
|
||||||
import './slider-track';
|
safeDefine(SliderFillElement);
|
||||||
import './slider-value';
|
safeDefine(SliderThumbElement);
|
||||||
|
safeDefine(SliderTrackElement);
|
||||||
customElements.define(SliderElement.tagName, SliderElement);
|
safeDefine(SliderValueElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ThumbnailElement } from '../../ui/thumbnail/thumbnail-element';
|
import { ThumbnailElement } from '../../ui/thumbnail/thumbnail-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(ThumbnailElement.tagName, ThumbnailElement);
|
safeDefine(ThumbnailElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { TimeGroupElement } from '../../ui/time/time-group-element';
|
import { TimeGroupElement } from '../../ui/time/time-group-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(TimeGroupElement.tagName, TimeGroupElement);
|
safeDefine(TimeGroupElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { TimeSeparatorElement } from '../../ui/time/time-separator-element';
|
import { TimeSeparatorElement } from '../../ui/time/time-separator-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
customElements.define(TimeSeparatorElement.tagName, TimeSeparatorElement);
|
safeDefine(TimeSeparatorElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
|
import { SliderBufferElement } from '../../ui/slider/slider-buffer-element';
|
||||||
|
import { SliderFillElement } from '../../ui/slider/slider-fill-element';
|
||||||
|
import { SliderThumbElement } from '../../ui/slider/slider-thumb-element';
|
||||||
|
import { SliderTrackElement } from '../../ui/slider/slider-track-element';
|
||||||
|
import { SliderValueElement } from '../../ui/slider/slider-value-element';
|
||||||
import { TimeSliderElement } from '../../ui/time-slider/time-slider-element';
|
import { TimeSliderElement } from '../../ui/time-slider/time-slider-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
import './slider-buffer';
|
// Parent slider first — sub-elements consume its context.
|
||||||
import './slider-fill';
|
safeDefine(TimeSliderElement);
|
||||||
import './slider-thumb';
|
safeDefine(SliderBufferElement);
|
||||||
import './slider-track';
|
safeDefine(SliderFillElement);
|
||||||
import './slider-value';
|
safeDefine(SliderThumbElement);
|
||||||
|
safeDefine(SliderTrackElement);
|
||||||
customElements.define(TimeSliderElement.tagName, TimeSliderElement);
|
safeDefine(SliderValueElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { TimeElement } from '../../ui/time/time-element';
|
import { TimeElement } from '../../ui/time/time-element';
|
||||||
|
import { TimeGroupElement } from '../../ui/time/time-group-element';
|
||||||
|
import { TimeSeparatorElement } from '../../ui/time/time-separator-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
import './time-group';
|
safeDefine(TimeElement);
|
||||||
import './time-separator';
|
safeDefine(TimeGroupElement);
|
||||||
|
safeDefine(TimeSeparatorElement);
|
||||||
customElements.define(TimeElement.tagName, TimeElement);
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
|
import { SliderFillElement } from '../../ui/slider/slider-fill-element';
|
||||||
|
import { SliderThumbElement } from '../../ui/slider/slider-thumb-element';
|
||||||
|
import { SliderTrackElement } from '../../ui/slider/slider-track-element';
|
||||||
|
import { SliderValueElement } from '../../ui/slider/slider-value-element';
|
||||||
import { VolumeSliderElement } from '../../ui/volume-slider/volume-slider-element';
|
import { VolumeSliderElement } from '../../ui/volume-slider/volume-slider-element';
|
||||||
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
import './slider-fill';
|
// Parent slider first — sub-elements consume its context.
|
||||||
import './slider-thumb';
|
safeDefine(VolumeSliderElement);
|
||||||
import './slider-track';
|
safeDefine(SliderFillElement);
|
||||||
import './slider-value';
|
safeDefine(SliderThumbElement);
|
||||||
|
safeDefine(SliderTrackElement);
|
||||||
customElements.define(VolumeSliderElement.tagName, VolumeSliderElement);
|
safeDefine(SliderValueElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { videoFeatures } from '@videojs/core/dom';
|
import { videoFeatures } from '@videojs/core/dom';
|
||||||
|
import { MediaContainerElement } from '../../media/container-element';
|
||||||
import { createPlayer } from '../../player/create-player';
|
import { createPlayer } from '../../player/create-player';
|
||||||
import { MediaElement } from '../../ui/media-element';
|
import { MediaElement } from '../../ui/media-element';
|
||||||
import '../media/container';
|
import { safeDefine } from '../safe-define';
|
||||||
|
|
||||||
const { ProviderMixin } = createPlayer({
|
const { ProviderMixin } = createPlayer({
|
||||||
features: videoFeatures,
|
features: videoFeatures,
|
||||||
@@ -11,7 +12,9 @@ export class VideoPlayerElement extends ProviderMixin(MediaElement) {
|
|||||||
static readonly tagName = 'video-player';
|
static readonly tagName = 'video-player';
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define(VideoPlayerElement.tagName, VideoPlayerElement);
|
// Provider must be defined before consumer for context handshake during upgrade.
|
||||||
|
safeDefine(VideoPlayerElement);
|
||||||
|
safeDefine(MediaContainerElement);
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ export * from '@videojs/core/dom';
|
|||||||
// Store
|
// Store
|
||||||
export type { Comparator, Selector } from '@videojs/store';
|
export type { Comparator, Selector } from '@videojs/store';
|
||||||
export { createSelector, shallowEqual } from '@videojs/store';
|
export { createSelector, shallowEqual } from '@videojs/store';
|
||||||
|
// Media
|
||||||
|
export { MediaContainerElement } from './media/container-element';
|
||||||
// Player
|
// Player
|
||||||
export * from './player/context';
|
export * from './player/context';
|
||||||
export * from './player/create-player';
|
export * from './player/create-player';
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { playerContext } from '../player/context';
|
||||||
|
import { createContainerMixin } from '../store/container-mixin';
|
||||||
|
import { MediaElement } from '../ui/media-element';
|
||||||
|
|
||||||
|
const ContainerMixin = createContainerMixin(playerContext);
|
||||||
|
|
||||||
|
export class MediaContainerElement extends ContainerMixin(MediaElement) {
|
||||||
|
static readonly tagName = 'media-container';
|
||||||
|
}
|
||||||
@@ -7,10 +7,12 @@ type BuildMode = 'dev' | 'default';
|
|||||||
const buildModes: BuildMode[] = ['dev', 'default'];
|
const buildModes: BuildMode[] = ['dev', 'default'];
|
||||||
|
|
||||||
const defineEntries = Object.fromEntries(
|
const defineEntries = Object.fromEntries(
|
||||||
globSync('src/define/**/*.ts').map((file) => {
|
globSync('src/define/**/*.ts')
|
||||||
const key = file.replace('src/', '').replace('.ts', '');
|
.filter((file) => !file.includes('.test.'))
|
||||||
return [key, file];
|
.map((file) => {
|
||||||
})
|
const key = file.replace('src/', '').replace('.ts', '');
|
||||||
|
return [key, file];
|
||||||
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const presetEntries = Object.fromEntries(
|
const presetEntries = Object.fromEntries(
|
||||||
|
|||||||
Reference in New Issue
Block a user