All files / media-loader/src/MediaLoader/audio index.ts

100% Statements 25/25
92.3% Branches 24/26
100% Functions 5/5
100% Lines 24/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63              1x     1x   4x 4x 4x 2x 2x       2x           2x 2x               4x       2x 2x 2x 1x 1x     1x         2x 2x 2x 2x 1x 1x 1x          
/**
 * Copyright (c) 2024-present, Matti Bar-Zeev.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
 
import {Children, ReactElement, RefObject, cloneElement, createRef} from 'react';
import {MediaProcessor} from '../types';
 
export class AudioProcessor implements MediaProcessor {
    getProcessedChildren(child: ReactElement): [ReactElement, RefObject<HTMLAudioElement>] {
        const audioRef = createRef<HTMLAudioElement>();
        let audioElement = child;
        if (child?.props?.children) {
            const sourceChildren = Children.toArray(child.props.children) as ReactElement[];
            audioElement = cloneElement(child, {
                style: {visibility: 'hidden'},
                ref: audioRef,
                children: sourceChildren.map((sourceChild) => {
                    return cloneElement(sourceChild, {
                        'data-src': sourceChild.props.src,
                        src: null,
                    });
                }),
            });
        } else if (child?.props?.src) {
            audioElement = cloneElement(child, {
                style: {visibility: 'hidden'},
                ref: audioRef,
                'data-src': child.props.src,
                src: null,
            });
        }
 
        return [audioElement, audioRef];
    }
 
    loadMedia(htmlAudioElement: HTMLAudioElement): void {
        htmlAudioElement.setAttribute('style', 'visibility: "visible"');
        const audioElementChildren = Array.from(htmlAudioElement.children);
        if (Array.isArray(audioElementChildren) && audioElementChildren.length) {
            for (const child of audioElementChildren) {
                if (child instanceof HTMLSourceElement) this.enableMediaByElement(child);
            }
        } else {
            this.enableMediaByElement(htmlAudioElement);
        }
    }
 
    enableMediaByElement(element: HTMLAudioElement | HTMLSourceElement) {
        if (element.hasAttribute('data-src')) {
            element.setAttribute('src', element.getAttribute('data-src') as string);
            element.removeAttribute('data-src');
            if (element instanceof HTMLAudioElement) {
                element.load();
            } else if (element instanceof HTMLSourceElement && element.parentElement instanceof HTMLAudioElement) {
                element.parentElement.load();
            }
        }
    }
}