fix(core): rename MediaDelegateMixin and MediaProxyMixin (#976)

This commit is contained in:
Wesley Luyten
2026-03-16 18:32:00 -05:00
committed by GitHub
parent c8bba26fb3
commit 561d03eb5a
7 changed files with 39 additions and 55 deletions
@@ -35,7 +35,7 @@ Composes `DestroyMixin(ReactiveElement)` and bridges `destroyCallback()` to
### HlsCustomMedia
Uses `DestroyMixin(HTMLElement)` as the base for `CustomMediaMixin`. The `DelegateMedia`
class (from `MediaDelegateMixin`) overrides `destroyCallback()` to call
class (from `DelegateMixin`) overrides `destroyCallback()` to call
`this.#delegate.destroy?.()`, which destroys the HLS engine.
## Why a Mixin
+8 -8
View File
@@ -2,7 +2,7 @@ import type { Constructor } from '@videojs/utils/types';
import { defineClassPropHooks } from '../utils/define-class-prop-hooks';
export interface MediaDelegate {
export interface Delegate {
attach?(target: EventTarget): void;
detach?(): void;
}
@@ -12,13 +12,13 @@ export interface MediaDelegate {
* and method calls to an instance of `DelegateClass` before falling through
* to the base class implementation.
*
* Works with both `CustomMediaMixin` and `MediaProxyMixin`.
* Works with both `CustomMediaMixin` and `ProxyMixin`.
*/
export function MediaDelegateMixin<Base extends Constructor<any>, Delegate extends Constructor<MediaDelegate>>(
export function DelegateMixin<Base extends Constructor<any>, D extends Constructor<Delegate>>(
BaseClass: Base,
DelegateClass: Delegate
DelegateClass: D
) {
class DelegateMedia extends (BaseClass as Constructor<any>) {
class DelegateImpl extends (BaseClass as Constructor<any>) {
#delegate = new DelegateClass();
get(prop: string): any {
@@ -55,12 +55,12 @@ export function MediaDelegateMixin<Base extends Constructor<any>, Delegate exten
}
for (let proto = DelegateClass.prototype; proto && proto !== Object.prototype; proto = Object.getPrototypeOf(proto)) {
defineClassPropHooks(DelegateMedia, proto);
defineClassPropHooks(DelegateImpl, proto);
}
return DelegateMedia as unknown as Constructor<
return DelegateImpl as unknown as Constructor<
InstanceType<Base> &
InstanceType<Delegate> & {
InstanceType<D> & {
attach(target: EventTarget): void;
detach(): void;
}
+9 -11
View File
@@ -1,8 +1,6 @@
import type { AnyConstructor, Constructor } from '@videojs/utils/types';
import { defineClassPropHooks } from '../utils/define-class-prop-hooks';
export interface MediaApiProxyTarget extends EventTarget {}
/**
* This mixin creates an API from the passed classes and proxies the methods and properties to the attached target.
*
@@ -14,33 +12,33 @@ export interface MediaApiProxyTarget extends EventTarget {}
*
* The `get`, `set`, and `call` methods can be overridden to provide catch-all custom behavior.
*/
export const MediaProxyMixin = <T extends EventTarget>(
export const ProxyMixin = <T extends EventTarget>(
PrimaryClass: AnyConstructor<T>,
...AdditionalClasses: AnyConstructor<EventTarget>[]
) => {
class MediaApiProxy {
#target: MediaApiProxyTarget | null = null;
class MediaProxy {
#target: EventTarget | null = null;
get target() {
return this.#target;
}
get(prop: keyof MediaApiProxyTarget): any {
get(prop: keyof EventTarget): any {
return this.target?.[prop];
}
set(prop: keyof MediaApiProxyTarget, val: any): void {
set(prop: keyof EventTarget, val: any): void {
if (this.target) {
this.target[prop] = val;
}
}
call(prop: keyof MediaApiProxyTarget, ...args: any[]): any {
call(prop: keyof EventTarget, ...args: any[]): any {
const nativeFn = this.target?.[prop] as ((...args: any[]) => any) | undefined;
return nativeFn?.apply(this.target, args);
}
attach(target: MediaApiProxyTarget): void {
attach(target: EventTarget): void {
if (!target || this.#target === target) return;
this.#target = target;
}
@@ -52,8 +50,8 @@ export const MediaProxyMixin = <T extends EventTarget>(
}
for (const Class of [PrimaryClass, ...AdditionalClasses]) {
defineClassPropHooks(MediaApiProxy, Class.prototype);
defineClassPropHooks(MediaProxy, Class.prototype);
}
return MediaApiProxy as unknown as Constructor<T>;
return MediaProxy as unknown as Constructor<T>;
};
+5 -12
View File
@@ -1,10 +1,10 @@
import * as dashjs from 'dashjs';
import { type MediaDelegate, MediaDelegateMixin } from '../../../core/media/delegate';
import { MediaProxyMixin } from '../../../core/media/proxy';
import { type Delegate, DelegateMixin } from '../../../core/media/delegate';
import { CustomMediaMixin } from '../custom-media-element';
import { MediaProxyMixin } from '../proxy';
export class DashMediaDelegateBase implements MediaDelegate {
export class DashMediaDelegateBase implements Delegate {
#engine: dashjs.MediaPlayerClass;
constructor() {
@@ -39,17 +39,10 @@ export class DashMediaDelegateBase implements MediaDelegate {
}
// This is used by the web component because it needs to extend HTMLElement!
export class DashCustomMedia extends MediaDelegateMixin(
export class DashCustomMedia extends DelegateMixin(
CustomMediaMixin(globalThis.HTMLElement ?? class {}, { tag: 'video' }),
DashMediaDelegateBase
) {}
// This is used by the React component.
export class DashMedia extends MediaDelegateMixin(
MediaProxyMixin(
globalThis.HTMLVideoElement ?? class {},
globalThis.HTMLMediaElement ?? class {},
globalThis.EventTarget ?? class {}
),
DashMediaDelegateBase
) {}
export class DashMedia extends DelegateMixin(MediaProxyMixin, DashMediaDelegateBase) {}
+5 -12
View File
@@ -1,8 +1,8 @@
import Hls from 'hls.js';
import { type MediaDelegate, MediaDelegateMixin } from '../../../core/media/delegate';
import { MediaProxyMixin } from '../../../core/media/proxy';
import { type Delegate, DelegateMixin } from '../../../core/media/delegate';
import { CustomMediaMixin } from '../custom-media-element';
import { MediaProxyMixin } from '../proxy';
import { HlsMediaTextTracksMixin } from './text-tracks';
const defaultConfig = {
@@ -13,7 +13,7 @@ const defaultConfig = {
capLevelOnFPSDrop: true,
};
export class HlsMediaDelegateBase implements MediaDelegate {
export class HlsMediaDelegateBase implements Delegate {
#engine = Hls.isSupported() ? new Hls(defaultConfig) : null;
get engine(): Hls | null {
@@ -44,17 +44,10 @@ export class HlsMediaDelegateBase implements MediaDelegate {
const HlsMediaDelegate = HlsMediaTextTracksMixin(HlsMediaDelegateBase);
// This is used by the web component because it needs to extend HTMLElement!
export class HlsCustomMedia extends MediaDelegateMixin(
export class HlsCustomMedia extends DelegateMixin(
CustomMediaMixin(globalThis.HTMLElement ?? class {}, { tag: 'video' }),
HlsMediaDelegate
) {}
// This is used by the React component.
export class HlsMedia extends MediaDelegateMixin(
MediaProxyMixin(
globalThis.HTMLVideoElement ?? class {},
globalThis.HTMLMediaElement ?? class {},
globalThis.EventTarget ?? class {}
),
HlsMediaDelegate
) {}
export class HlsMedia extends DelegateMixin(MediaProxyMixin, HlsMediaDelegate) {}
+7
View File
@@ -0,0 +1,7 @@
import { ProxyMixin } from '../../core/media/proxy';
export const MediaProxyMixin = ProxyMixin(
globalThis.HTMLVideoElement ?? class {},
globalThis.HTMLMediaElement ?? class {},
globalThis.EventTarget ?? class {}
);
@@ -1,20 +1,13 @@
import { SpfMedia as SpfMediaDelegate } from '@videojs/spf/dom';
import { MediaDelegateMixin } from '../../../core/media/delegate';
import { MediaProxyMixin } from '../../../core/media/proxy';
import { DelegateMixin } from '../../../core/media/delegate';
import { CustomMediaMixin } from '../custom-media-element';
import { MediaProxyMixin } from '../proxy';
// This is used by the web component because it needs to extend HTMLElement!
export class SimpleHlsCustomMedia extends MediaDelegateMixin(
export class SimpleHlsCustomMedia extends DelegateMixin(
CustomMediaMixin(globalThis.HTMLElement ?? class {}, { tag: 'video' }),
SpfMediaDelegate
) {}
// This is used by the React component.
export class SimpleHlsMedia extends MediaDelegateMixin(
MediaProxyMixin(
globalThis.HTMLVideoElement ?? class {},
globalThis.HTMLMediaElement ?? class {},
globalThis.EventTarget ?? class {}
),
SpfMediaDelegate
) {}
export class SimpleHlsMedia extends DelegateMixin(MediaProxyMixin, SpfMediaDelegate) {}