custom-media-element
Advanced tools
Comparing version 1.1.3 to 1.2.0
@@ -15,2 +15,3 @@ | ||
disconnectedCallback(): void; | ||
init(): void; | ||
handleEvent(event: Event): void; | ||
@@ -27,2 +28,3 @@ } | ||
disconnectedCallback(): void; | ||
init(): void; | ||
handleEvent(event: Event): void; | ||
@@ -38,6 +40,6 @@ } | ||
export function CustomMediaMixin(Base: any, options: { tag: 'video', is?: string }): | ||
export function CustomMediaMixin(superclass: any, options: { tag: 'video', is?: string }): | ||
CustomMediaElementConstructor<CustomVideoElement>; | ||
export function CustomMediaMixin(Base: any, options: { tag: 'audio', is?: string }): | ||
export function CustomMediaMixin(superclass: any, options: { tag: 'audio', is?: string }): | ||
CustomMediaElementConstructor<CustomAudioElement>; |
@@ -210,2 +210,3 @@ /** | ||
#nativeEl; | ||
#childMap = new Map(); | ||
@@ -264,3 +265,6 @@ constructor() { | ||
this.#isInit = true; | ||
this.init(); | ||
} | ||
init() { | ||
// If there is no nativeEl by now, create it. | ||
@@ -283,28 +287,4 @@ if (!this.nativeEl) { | ||
// Keep some native child elements like track and source in sync. | ||
const childMap = new Map(); | ||
// An unnamed <slot> will be filled with all of the custom element's | ||
// top-level child nodes that do not have the slot attribute. | ||
const slotEl = this.shadowRoot.querySelector('slot:not([name])'); | ||
slotEl?.addEventListener('slotchange', () => { | ||
const removeNativeChildren = new Map(childMap); | ||
slotEl | ||
.assignedElements() | ||
.filter((el) => ['track', 'source'].includes(el.localName)) | ||
.forEach((el) => { | ||
// If the source or track is still in the assigned elements keep it. | ||
removeNativeChildren.delete(el); | ||
// Re-use clones if possible. | ||
let clone = childMap.get(el); | ||
if (!clone) { | ||
clone = el.cloneNode(); | ||
childMap.set(el, clone); | ||
} | ||
this.nativeEl.append?.(clone); | ||
}); | ||
removeNativeChildren.forEach((el) => el.remove()); | ||
}); | ||
this.shadowRoot.addEventListener('slotchange', this); | ||
// The video events are dispatched on the CustomMediaElement instance. | ||
// This makes it possible to add event listeners before the element is upgraded. | ||
for (let type of this.constructor.Events) { | ||
@@ -315,7 +295,42 @@ this.shadowRoot.addEventListener?.(type, this, true); | ||
handleEvent(evt) { | ||
if (evt.target !== this.nativeEl) return; | ||
this.dispatchEvent(new CustomEvent(evt.type, { detail: evt.detail })); | ||
handleEvent(event) { | ||
if (event.type === 'slotchange') { | ||
this.#syncMediaChildren(); | ||
return; | ||
} | ||
if (event.target === this.nativeEl) { | ||
// The video events are dispatched on the CustomMediaElement instance. | ||
// This makes it possible to add event listeners before the element is upgraded. | ||
this.dispatchEvent(new CustomEvent(event.type, { detail: event.detail })); | ||
} | ||
} | ||
/** | ||
* Keep some native child elements like track and source in sync. | ||
* An unnamed <slot> will be filled with all of the custom element's | ||
* top-level child nodes that do not have the slot attribute. | ||
*/ | ||
#syncMediaChildren() { | ||
const removeNativeChildren = new Map(this.#childMap); | ||
this.shadowRoot.querySelector('slot:not([name])') | ||
.assignedElements() | ||
.filter((el) => ['track', 'source'].includes(el.localName)) | ||
.forEach((el) => { | ||
// If the source or track is still in the assigned elements keep it. | ||
removeNativeChildren.delete(el); | ||
// Re-use clones if possible. | ||
let clone = this.#childMap.get(el); | ||
if (!clone) { | ||
clone = el.cloneNode(); | ||
this.#childMap.set(el, clone); | ||
} | ||
this.nativeEl.append?.(clone); | ||
}); | ||
removeNativeChildren.forEach((el) => el.remove()); | ||
} | ||
#upgradeProperty(prop) { | ||
@@ -322,0 +337,0 @@ // Sets properties that are set before the custom element is upgraded. |
{ | ||
"name": "custom-media-element", | ||
"version": "1.1.3", | ||
"version": "1.2.0", | ||
"description": "A custom element for extending the native media elements (<audio> or <video>)", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -65,2 +65,3 @@ # Custom Media Element | ||
disconnectedCallback(): void; | ||
handleEvent(event: Event): void; | ||
} | ||
@@ -76,15 +77,16 @@ | ||
disconnectedCallback(): void; | ||
handleEvent(event: Event): void; | ||
} | ||
type CustomMediaElementConstructor<K> = { | ||
type CustomMediaElementConstructor<T> = { | ||
readonly observedAttributes: string[]; | ||
Events: string[]; | ||
template: HTMLTemplateElement; | ||
new(): K | ||
new(): T | ||
}; | ||
export function CustomMediaMixin(Base: any, options: { tag: 'video', is: string }): | ||
export function CustomMediaMixin(superclass: any, options: { tag: 'video', is?: string }): | ||
CustomMediaElementConstructor<CustomVideoElement>; | ||
export function CustomMediaMixin(Base: any, options: { tag: 'audio', is: string }): | ||
export function CustomMediaMixin(superclass: any, options: { tag: 'audio', is?: string }): | ||
CustomMediaElementConstructor<CustomAudioElement>; | ||
@@ -105,4 +107,4 @@ ``` | ||
- [`<videojs-video>`](https://github.com/luwes/videojs-video-element) A custom element for Video.js. | ||
- [`castable-video`](https://github.com/muxinc/castable-video) Cast your video element to the big screen with ease! | ||
- [`<castable-video>`](https://github.com/muxinc/castable-video) Cast your video element to the big screen with ease! | ||
- [`<mux-player>`](https://github.com/muxinc/elements/tree/main/packages/mux-player) The official Mux-flavored video player custom element. | ||
- [`<mux-video>`](https://github.com/muxinc/elements/tree/main/packages/mux-video) A Mux-flavored HTML5 video element w/ hls.js and Mux data builtin. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
19337
374
108