Merge branch 'develop' into a11y-improvements
# Conflicts: # demo/dist/demo.css # dist/plyr.css # dist/plyr.js.map # dist/plyr.min.js # dist/plyr.min.js.map # dist/plyr.polyfilled.js # dist/plyr.polyfilled.js.map # dist/plyr.polyfilled.min.js # dist/plyr.polyfilled.min.js.map # src/js/captions.js # src/js/plyr.js
This commit is contained in:
		@ -16,28 +16,6 @@ const captions = {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Set default language if not set
 | 
			
		||||
        const stored = this.storage.get('language');
 | 
			
		||||
 | 
			
		||||
        if (!utils.is.empty(stored)) {
 | 
			
		||||
            this.captions.language = stored;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (utils.is.empty(this.captions.language)) {
 | 
			
		||||
            this.captions.language = this.config.captions.language.toLowerCase();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Set captions enabled state if not set
 | 
			
		||||
        if (!utils.is.boolean(this.captions.active)) {
 | 
			
		||||
            const active = this.storage.get('captions');
 | 
			
		||||
 | 
			
		||||
            if (utils.is.boolean(active)) {
 | 
			
		||||
                this.captions.active = active;
 | 
			
		||||
            } else {
 | 
			
		||||
                this.captions.active = this.config.captions.active;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Only Vimeo and HTML5 video supported at this point
 | 
			
		||||
        if (!this.isVideo || this.isYouTube || (this.isHTML5 && !support.textTracks)) {
 | 
			
		||||
            // Clear menu and hide
 | 
			
		||||
@ -55,17 +33,6 @@ const captions = {
 | 
			
		||||
            utils.insertAfter(this.elements.captions, this.elements.wrapper);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Set the class hook
 | 
			
		||||
        utils.toggleClass(this.elements.container, this.config.classNames.captions.enabled, !utils.is.empty(captions.getTracks.call(this)));
 | 
			
		||||
 | 
			
		||||
        // Get tracks
 | 
			
		||||
        const tracks = captions.getTracks.call(this);
 | 
			
		||||
 | 
			
		||||
        // If no caption file exists, hide container for caption text
 | 
			
		||||
        if (utils.is.empty(tracks)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Get browser info
 | 
			
		||||
        const browser = utils.getBrowser();
 | 
			
		||||
 | 
			
		||||
@ -94,14 +61,45 @@ const captions = {
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Set language
 | 
			
		||||
        captions.setLanguage.call(this);
 | 
			
		||||
        // Try to load the value from storage
 | 
			
		||||
        let active = this.storage.get('captions');
 | 
			
		||||
 | 
			
		||||
        // Enable UI
 | 
			
		||||
        captions.show.call(this);
 | 
			
		||||
        // Otherwise fall back to the default config
 | 
			
		||||
        if (!utils.is.boolean(active)) {
 | 
			
		||||
            ({ active } = this.config.captions);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Set available languages in list
 | 
			
		||||
        if (utils.is.array(this.config.controls) && this.config.controls.includes('settings') && this.config.settings.includes('captions')) {
 | 
			
		||||
        // Set toggled state
 | 
			
		||||
        this.toggleCaptions(active);
 | 
			
		||||
 | 
			
		||||
        // Watch changes to textTracks and update captions menu
 | 
			
		||||
        if (this.config.captions.update) {
 | 
			
		||||
            utils.on(this.media.textTracks, 'addtrack removetrack', captions.update.bind(this));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Update available languages in list next tick (the event must not be triggered before the listeners)
 | 
			
		||||
        setTimeout(captions.update.bind(this), 0);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    update() {
 | 
			
		||||
        // Update tracks
 | 
			
		||||
        const tracks = captions.getTracks.call(this);
 | 
			
		||||
        this.options.captions = tracks.map(({ language }) => language);
 | 
			
		||||
 | 
			
		||||
        // Set language if it hasn't been set already
 | 
			
		||||
        if (!this.language) {
 | 
			
		||||
            let { language } = this.config.captions;
 | 
			
		||||
            if (language === 'auto') {
 | 
			
		||||
                [language] = (navigator.language || navigator.userLanguage).split('-');
 | 
			
		||||
            }
 | 
			
		||||
            this.language = this.storage.get('language') || (language || '').toLowerCase();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Toggle the class hooks
 | 
			
		||||
        utils.toggleClass(this.elements.container, this.config.classNames.captions.enabled, !utils.is.empty(captions.getTracks.call(this)));
 | 
			
		||||
 | 
			
		||||
        // Update available languages in list
 | 
			
		||||
        if ((this.config.controls || []).includes('settings') && this.config.settings.includes('captions')) {
 | 
			
		||||
            controls.setCaptionsMenu.call(this);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
@ -247,24 +245,6 @@ const captions = {
 | 
			
		||||
            this.debug.warn('No captions element to render to');
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Display captions container and button (for initialization)
 | 
			
		||||
    show() {
 | 
			
		||||
        // Try to load the value from storage
 | 
			
		||||
        let active = this.storage.get('captions');
 | 
			
		||||
 | 
			
		||||
        // Otherwise fall back to the default config
 | 
			
		||||
        if (!utils.is.boolean(active)) {
 | 
			
		||||
            ({ active } = this.config.captions);
 | 
			
		||||
        } else {
 | 
			
		||||
            this.captions.active = active;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (active) {
 | 
			
		||||
            utils.toggleClass(this.elements.container, this.config.classNames.captions.active, true);
 | 
			
		||||
            this.elements.buttons.captions.pressed = true;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default captions;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										36
									
								
								src/js/controls.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								src/js/controls.js
									
									
									
									
										vendored
									
									
								
							@ -659,27 +659,7 @@ const controls = {
 | 
			
		||||
 | 
			
		||||
        // Get the badge HTML for HD, 4K etc
 | 
			
		||||
        const getBadge = quality => {
 | 
			
		||||
            let label = '';
 | 
			
		||||
 | 
			
		||||
            switch (quality) {
 | 
			
		||||
                case 2160:
 | 
			
		||||
                    label = '4K';
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 1440:
 | 
			
		||||
                case 1080:
 | 
			
		||||
                case 720:
 | 
			
		||||
                    label = 'HD';
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 576:
 | 
			
		||||
                case 480:
 | 
			
		||||
                    label = 'SD';
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            const label = i18n.get(`qualityBadge.${quality}`, this.config);
 | 
			
		||||
 | 
			
		||||
            if (!label.length) {
 | 
			
		||||
                return null;
 | 
			
		||||
@ -703,7 +683,6 @@ const controls = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Translate a value into a nice label
 | 
			
		||||
    // TODO: Localisation
 | 
			
		||||
    getLabel(setting, value) {
 | 
			
		||||
        switch (setting) {
 | 
			
		||||
            case 'speed':
 | 
			
		||||
@ -711,7 +690,13 @@ const controls = {
 | 
			
		||||
 | 
			
		||||
            case 'quality':
 | 
			
		||||
                if (utils.is.number(value)) {
 | 
			
		||||
                    return `${value}p`;
 | 
			
		||||
                    const label = i18n.get(`qualityLabel.${value}`, this.config);
 | 
			
		||||
 | 
			
		||||
                    if (!label.length) {
 | 
			
		||||
                        return `${value}p`;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    return label;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return utils.toTitleCase(value);
 | 
			
		||||
@ -878,13 +863,10 @@ const controls = {
 | 
			
		||||
                'language',
 | 
			
		||||
                track.label,
 | 
			
		||||
                track.language !== 'enabled' ? controls.createBadge.call(this, track.language.toUpperCase()) : null,
 | 
			
		||||
                track.language.toLowerCase() === this.captions.language.toLowerCase(),
 | 
			
		||||
                track.language.toLowerCase() === this.language,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Store reference
 | 
			
		||||
        this.options.captions = tracks.map(track => track.language);
 | 
			
		||||
 | 
			
		||||
        controls.updateSetting.call(this, type, list);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -60,7 +60,7 @@ const defaults = {
 | 
			
		||||
    // Sprite (for icons)
 | 
			
		||||
    loadSprite: true,
 | 
			
		||||
    iconPrefix: 'plyr',
 | 
			
		||||
    iconUrl: 'https://cdn.plyr.io/3.3.8/plyr.svg',
 | 
			
		||||
    iconUrl: 'https://cdn.plyr.io/3.3.10/plyr.svg',
 | 
			
		||||
 | 
			
		||||
    // Blank video (used to prevent errors on source change)
 | 
			
		||||
    blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
 | 
			
		||||
@ -119,7 +119,10 @@ const defaults = {
 | 
			
		||||
    // Captions settings
 | 
			
		||||
    captions: {
 | 
			
		||||
        active: false,
 | 
			
		||||
        language: (navigator.language || navigator.userLanguage).split('-')[0],
 | 
			
		||||
        language: 'auto',
 | 
			
		||||
        // Listen to new tracks added after Plyr is initialized.
 | 
			
		||||
        // This is needed for streaming captions, but may result in unselectable options
 | 
			
		||||
        update: false,
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Fullscreen settings
 | 
			
		||||
@ -191,6 +194,14 @@ const defaults = {
 | 
			
		||||
        disabled: 'Disabled',
 | 
			
		||||
        enabled: 'Enabled',
 | 
			
		||||
        advertisement: 'Ad',
 | 
			
		||||
        qualityBadge: {
 | 
			
		||||
            2160: '4K',
 | 
			
		||||
            1440: 'HD',
 | 
			
		||||
            1080: 'HD',
 | 
			
		||||
            720: 'HD',
 | 
			
		||||
            576: 'SD',
 | 
			
		||||
            480: 'SD',
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // URLs
 | 
			
		||||
@ -315,9 +326,8 @@ const defaults = {
 | 
			
		||||
        display: {
 | 
			
		||||
            currentTime: '.plyr__time--current',
 | 
			
		||||
            duration: '.plyr__time--duration',
 | 
			
		||||
            buffer: '.plyr__progress--buffer',
 | 
			
		||||
            played: '.plyr__progress--played',
 | 
			
		||||
            loop: '.plyr__progress--loop',
 | 
			
		||||
            buffer: '.plyr__progress__buffer',
 | 
			
		||||
            loop: '.plyr__progress__loop', // Used later
 | 
			
		||||
            volume: '.plyr__volume--display',
 | 
			
		||||
        },
 | 
			
		||||
        progress: '.plyr__progress',
 | 
			
		||||
 | 
			
		||||
@ -99,6 +99,13 @@ const html5 = {
 | 
			
		||||
                // Set new source
 | 
			
		||||
                player.media.src = supported[0].getAttribute('src');
 | 
			
		||||
 | 
			
		||||
                // Restore time
 | 
			
		||||
                const onLoadedMetaData = () => {
 | 
			
		||||
                    player.currentTime = currentTime;
 | 
			
		||||
                    player.off('loadedmetadata', onLoadedMetaData);
 | 
			
		||||
                };
 | 
			
		||||
                player.on('loadedmetadata', onLoadedMetaData);
 | 
			
		||||
 | 
			
		||||
                // Load new source
 | 
			
		||||
                player.media.load();
 | 
			
		||||
 | 
			
		||||
@ -107,9 +114,6 @@ const html5 = {
 | 
			
		||||
                    player.play();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Restore time
 | 
			
		||||
                player.currentTime = currentTime;
 | 
			
		||||
 | 
			
		||||
                // Trigger change event
 | 
			
		||||
                utils.dispatchEvent.call(player, player.media, 'qualitychange', false, {
 | 
			
		||||
                    quality: input,
 | 
			
		||||
 | 
			
		||||
@ -6,11 +6,15 @@ import utils from './utils';
 | 
			
		||||
 | 
			
		||||
const i18n = {
 | 
			
		||||
    get(key = '', config = {}) {
 | 
			
		||||
        if (utils.is.empty(key) || utils.is.empty(config) || !Object.keys(config.i18n).includes(key)) {
 | 
			
		||||
        if (utils.is.empty(key) || utils.is.empty(config)) {
 | 
			
		||||
            return '';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let string = config.i18n[key];
 | 
			
		||||
        let string = utils.getDeep(config.i18n, key);
 | 
			
		||||
 | 
			
		||||
        if (utils.is.empty(string)) {
 | 
			
		||||
            return '';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const replace = {
 | 
			
		||||
            '{seektime}': config.seekTime,
 | 
			
		||||
 | 
			
		||||
@ -74,7 +74,10 @@ class Listeners {
 | 
			
		||||
            // and if the focused element is not editable (e.g. text input)
 | 
			
		||||
            // and any that accept key input http://webaim.org/techniques/keyboard/
 | 
			
		||||
            const focused = utils.getFocusElement();
 | 
			
		||||
            if (utils.is.element(focused) && utils.matches(focused, this.player.config.selectors.editable)) {
 | 
			
		||||
            if (utils.is.element(focused) && (
 | 
			
		||||
                focused !== this.player.elements.inputs.seek &&
 | 
			
		||||
                utils.matches(focused, this.player.config.selectors.editable))
 | 
			
		||||
            ) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -560,6 +563,12 @@ class Listeners {
 | 
			
		||||
        on(this.player.elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', event => {
 | 
			
		||||
            const seek = event.currentTarget;
 | 
			
		||||
 | 
			
		||||
            const code = event.keyCode ? event.keyCode : event.which;
 | 
			
		||||
            const eventType = event.type;
 | 
			
		||||
 | 
			
		||||
            if ((eventType === 'keydown' || eventType === 'keyup') && (code !== 39 && code !== 37)) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            // Was playing before?
 | 
			
		||||
            const play = seek.hasAttribute('play-on-seeked');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
// ==========================================================================
 | 
			
		||||
// Plyr
 | 
			
		||||
// plyr.js v3.3.8
 | 
			
		||||
// plyr.js v3.3.10
 | 
			
		||||
// https://github.com/sampotts/plyr
 | 
			
		||||
// License: The MIT License (MIT)
 | 
			
		||||
// ==========================================================================
 | 
			
		||||
@ -432,21 +432,16 @@ class Plyr {
 | 
			
		||||
     * @param {number} input - where to seek to in seconds. Defaults to 0 (the start)
 | 
			
		||||
     */
 | 
			
		||||
    set currentTime(input) {
 | 
			
		||||
        let targetTime = 0;
 | 
			
		||||
 | 
			
		||||
        if (utils.is.number(input)) {
 | 
			
		||||
            targetTime = input;
 | 
			
		||||
        // Bail if media duration isn't available yet
 | 
			
		||||
        if (!this.duration) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Normalise targetTime
 | 
			
		||||
        if (targetTime < 0) {
 | 
			
		||||
            targetTime = 0;
 | 
			
		||||
        } else if (targetTime > this.duration) {
 | 
			
		||||
            targetTime = this.duration;
 | 
			
		||||
        }
 | 
			
		||||
        // Validate input
 | 
			
		||||
        const inputIsValid = utils.is.number(input) && input > 0;
 | 
			
		||||
 | 
			
		||||
        // Set
 | 
			
		||||
        this.media.currentTime = targetTime;
 | 
			
		||||
        this.media.currentTime = inputIsValid ? Math.min(input, this.duration) : 0;
 | 
			
		||||
 | 
			
		||||
        // Logging
 | 
			
		||||
        this.debug.log(`Seeking to ${this.currentTime} seconds`);
 | 
			
		||||
@ -494,11 +489,11 @@ class Plyr {
 | 
			
		||||
        // Faux duration set via config
 | 
			
		||||
        const fauxDuration = parseFloat(this.config.duration);
 | 
			
		||||
 | 
			
		||||
        // True duration
 | 
			
		||||
        const realDuration = this.media ? Number(this.media.duration) : 0;
 | 
			
		||||
        // Media duration can be NaN before the media has loaded
 | 
			
		||||
        const duration = (this.media || {}).duration || 0;
 | 
			
		||||
 | 
			
		||||
        // If custom duration is funky, use regular duration
 | 
			
		||||
        return !Number.isNaN(fauxDuration) ? fauxDuration : realDuration;
 | 
			
		||||
        // If config duration is funky, use regular duration
 | 
			
		||||
        return fauxDuration || duration;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -680,7 +675,7 @@ class Plyr {
 | 
			
		||||
            quality = Number(input);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!utils.is.number(quality) || quality === 0) {
 | 
			
		||||
        if (!utils.is.number(quality)) {
 | 
			
		||||
            quality = this.storage.get('quality');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -843,24 +838,19 @@ class Plyr {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If the method is called without parameter, toggle based on current value
 | 
			
		||||
        const show = utils.is.boolean(input) ? input : !this.elements.container.classList.contains(this.config.classNames.captions.active);
 | 
			
		||||
 | 
			
		||||
        // Nothing to change...
 | 
			
		||||
        if (this.captions.active === show) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Set global
 | 
			
		||||
        this.captions.active = show;
 | 
			
		||||
        const active = utils.is.boolean(input) ? input : !this.elements.container.classList.contains(this.config.classNames.captions.active);
 | 
			
		||||
 | 
			
		||||
        // Toggle state
 | 
			
		||||
        this.elements.buttons.captions.pressed = this.captions.active;
 | 
			
		||||
        this.elements.buttons.captions.pressed = active;
 | 
			
		||||
 | 
			
		||||
        // Add class hook
 | 
			
		||||
        utils.toggleClass(this.elements.container, this.config.classNames.captions.active, this.captions.active);
 | 
			
		||||
        utils.toggleClass(this.elements.container, this.config.classNames.captions.active, active);
 | 
			
		||||
 | 
			
		||||
        // Trigger an event
 | 
			
		||||
        // Update state and trigger event
 | 
			
		||||
        if (active !== this.captions.active) {
 | 
			
		||||
            this.captions.active = active;
 | 
			
		||||
        utils.dispatchEvent.call(this, this.media, this.captions.active ? 'captionsenabled' : 'captionsdisabled');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
// ==========================================================================
 | 
			
		||||
// Plyr Polyfilled Build
 | 
			
		||||
// plyr.js v3.3.8
 | 
			
		||||
// plyr.js v3.3.10
 | 
			
		||||
// https://github.com/sampotts/plyr
 | 
			
		||||
// License: The MIT License (MIT)
 | 
			
		||||
// ==========================================================================
 | 
			
		||||
 | 
			
		||||
@ -31,7 +31,7 @@ class Storage {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get(key) {
 | 
			
		||||
        if (!Storage.supported) {
 | 
			
		||||
        if (!Storage.supported || !this.enabled) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								src/js/ui.js
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/js/ui.js
									
									
									
									
									
								
							@ -55,8 +55,10 @@ const ui = {
 | 
			
		||||
        // Remove native controls
 | 
			
		||||
        ui.toggleNativeControls.call(this);
 | 
			
		||||
 | 
			
		||||
        // Captions
 | 
			
		||||
        captions.setup.call(this);
 | 
			
		||||
        // Setup captions for HTML5
 | 
			
		||||
        if (this.isHTML5) {
 | 
			
		||||
            captions.setup.call(this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Reset volume
 | 
			
		||||
        this.volume = null;
 | 
			
		||||
@ -109,6 +111,12 @@ const ui = {
 | 
			
		||||
        if (this.poster && this.elements.poster && !this.elements.poster.style.backgroundImage) {
 | 
			
		||||
            ui.setPoster.call(this, this.poster);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Manually set the duration if user has overridden it.
 | 
			
		||||
        // The event listeners for it doesn't get called if preload is disabled (#701)
 | 
			
		||||
        if (this.config.duration) {
 | 
			
		||||
            controls.durationUpdate.call(this);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Setup aria attribute for play and iframe title
 | 
			
		||||
 | 
			
		||||
@ -44,7 +44,7 @@ const utils = {
 | 
			
		||||
            return this.instanceof(input, Event);
 | 
			
		||||
        },
 | 
			
		||||
        cue(input) {
 | 
			
		||||
            return this.instanceof(input, TextTrackCue) || this.instanceof(input, VTTCue);
 | 
			
		||||
            return this.instanceof(input, window.TextTrackCue) || this.instanceof(input, window.VTTCue);
 | 
			
		||||
        },
 | 
			
		||||
        track(input) {
 | 
			
		||||
            return this.instanceof(input, TextTrack) || (!this.nullOrUndefined(input) && this.string(input.kind));
 | 
			
		||||
@ -151,24 +151,23 @@ const utils = {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const prefix = 'cache-';
 | 
			
		||||
        const prefix = 'cache';
 | 
			
		||||
        const hasId = utils.is.string(id);
 | 
			
		||||
        let isCached = false;
 | 
			
		||||
 | 
			
		||||
        const exists = () => document.querySelectorAll(`#${id}`).length;
 | 
			
		||||
        const exists = () => document.getElementById(id) !== null;
 | 
			
		||||
 | 
			
		||||
        const update = (container, data) => {
 | 
			
		||||
            container.innerHTML = data;
 | 
			
		||||
 | 
			
		||||
        function injectSprite(data) {
 | 
			
		||||
            // Check again incase of race condition
 | 
			
		||||
            if (hasId && exists()) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Inject content
 | 
			
		||||
            this.innerHTML = data;
 | 
			
		||||
 | 
			
		||||
            // Inject the SVG to the body
 | 
			
		||||
            document.body.insertBefore(this, document.body.childNodes[0]);
 | 
			
		||||
        }
 | 
			
		||||
            document.body.insertAdjacentElement('afterbegin', container);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Only load once if ID set
 | 
			
		||||
        if (!hasId || !exists()) {
 | 
			
		||||
@ -184,13 +183,12 @@ const utils = {
 | 
			
		||||
 | 
			
		||||
            // Check in cache
 | 
			
		||||
            if (useStorage) {
 | 
			
		||||
                const cached = window.localStorage.getItem(prefix + id);
 | 
			
		||||
                const cached = window.localStorage.getItem(`${prefix}-${id}`);
 | 
			
		||||
                isCached = cached !== null;
 | 
			
		||||
 | 
			
		||||
                if (isCached) {
 | 
			
		||||
                    const data = JSON.parse(cached);
 | 
			
		||||
                    injectSprite.call(container, data.content);
 | 
			
		||||
                    return;
 | 
			
		||||
                    update(container, data.content);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -204,14 +202,14 @@ const utils = {
 | 
			
		||||
 | 
			
		||||
                    if (useStorage) {
 | 
			
		||||
                        window.localStorage.setItem(
 | 
			
		||||
                            prefix + id,
 | 
			
		||||
                            `${prefix}-${id}`,
 | 
			
		||||
                            JSON.stringify({
 | 
			
		||||
                                content: result,
 | 
			
		||||
                            }),
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    injectSprite.call(container, result);
 | 
			
		||||
                    update(container, result);
 | 
			
		||||
                })
 | 
			
		||||
                .catch(() => {});
 | 
			
		||||
        }
 | 
			
		||||
@ -706,6 +704,11 @@ const utils = {
 | 
			
		||||
        return JSON.parse(JSON.stringify(object));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Get a nested value in an object
 | 
			
		||||
    getDeep(object, path) {
 | 
			
		||||
        return path.split('.').reduce((obj, key) => obj && obj[key], object);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Get the closest value in an array
 | 
			
		||||
    closest(array, value) {
 | 
			
		||||
        if (!utils.is.array(array) || !array.length) {
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user