fix: delegate not defining Delegate props (#751)

This commit is contained in:
Wesley Luyten
2026-03-05 19:38:49 -06:00
committed by GitHub
parent 9f456f572f
commit c61fcdcc3a
4 changed files with 40 additions and 57 deletions
+6
View File
@@ -1,5 +1,7 @@
import type { Constructor } from '@videojs/utils/types';
import { defineClassPropHooks } from '../utils/define-class-prop-hooks';
export interface MediaDelegate {
attach?(target: EventTarget): void;
detach?(): void;
@@ -52,6 +54,10 @@ 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);
}
return DelegateMedia as unknown as Constructor<
InstanceType<Base> &
InstanceType<Delegate> & {
+4 -56
View File
@@ -1,13 +1,8 @@
import type { AnyConstructor, Constructor } from '@videojs/utils/types';
import { defineClassPropHooks } from '../utils/define-class-prop-hooks';
export interface MediaApiProxyTarget extends EventTarget {}
type API_TYPE = 0 | 1 | 2;
const API_METHOD: API_TYPE = 0;
const API_GET: API_TYPE = 1;
const API_GET_SET: API_TYPE = 2;
/**
* This mixin creates an API from the passed classes and proxies the methods and properties to the attached target.
*
@@ -24,32 +19,6 @@ export const MediaProxyMixin = <T extends EventTarget>(
...AdditionalClasses: AnyConstructor<EventTarget>[]
) => {
class MediaApiProxy {
static extends(...MediaApiTargetClasses: AnyConstructor<any>[]) {
const props = getClassProps(...MediaApiTargetClasses);
for (const [prop, type] of props.entries()) {
if (prop in MediaApiProxy.prototype) continue;
const config: PropertyDescriptor = {};
if (type === API_METHOD) {
config.value = function (this: MediaApiProxy, ...args: any[]) {
return this.call(prop as keyof MediaApiProxyTarget, ...args);
};
} else if (type === API_GET || type === API_GET_SET) {
config.get = function (this: MediaApiProxy) {
return this.get(prop as keyof MediaApiProxyTarget);
};
if (type === API_GET_SET) {
config.set = function (this: MediaApiProxy, val: any) {
this.set(prop as keyof MediaApiProxyTarget, val);
};
}
}
Object.defineProperty(MediaApiProxy.prototype, prop, config);
}
}
#target: MediaApiProxyTarget | null = null;
get target() {
@@ -82,30 +51,9 @@ export const MediaProxyMixin = <T extends EventTarget>(
}
}
MediaApiProxy.extends(PrimaryClass, ...AdditionalClasses);
for (const Class of [PrimaryClass, ...AdditionalClasses]) {
defineClassPropHooks(MediaApiProxy, Class.prototype);
}
return MediaApiProxy as unknown as Constructor<T>;
};
/**
* Helper function to get the methods, getters, and setters from a class prototype.
*/
export function getClassProps<T extends EventTarget>(...Classes: AnyConstructor<T>[]) {
const props = new Map<keyof T, API_TYPE>();
for (const Class of Classes) {
const names = Object.getOwnPropertyNames(Class.prototype) as (keyof T)[];
for (const name of names) {
const descriptor = Object.getOwnPropertyDescriptor(Class.prototype, name);
if (typeof descriptor?.value === 'function') {
props.set(name, API_METHOD);
} else if (typeof descriptor?.get === 'function') {
if (typeof descriptor?.set === 'function') {
props.set(name, API_GET_SET);
} else {
props.set(name, API_GET);
}
}
}
}
return props;
}
@@ -0,0 +1,29 @@
import type { Constructor } from '@videojs/utils/types';
export function defineClassPropHooks<T extends Constructor<any>>(Class: T, BaseClassProto: PropertyDescriptorMap) {
for (const prop of Object.getOwnPropertyNames(BaseClassProto)) {
if (prop in Class.prototype) continue;
const descriptor = Object.getOwnPropertyDescriptor(BaseClassProto, prop);
if (!descriptor) continue;
const config: PropertyDescriptor = {};
if (typeof descriptor.value === 'function') {
config.value = function (this: InstanceType<T>, ...args: any[]) {
return this.call?.(prop, ...args);
};
} else if (descriptor.get) {
config.get = function (this: InstanceType<T>) {
return this.get?.(prop);
};
if (descriptor.set) {
config.set = function (this: InstanceType<T>, val: any) {
this.set?.(prop, val);
};
}
}
Object.defineProperty(Class.prototype, prop, config);
}
}
+1 -1
View File
@@ -27,7 +27,7 @@ export class HlsVideo extends HlsCustomMedia {
}
disconnectedCallback(): void {
super.disconnectedCallback();
super.disconnectedCallback?.();
if (!this.hasAttribute('keep-alive')) {
this.destroy();