// ========================================================================== // YouTube plugin // ========================================================================== import ui from '../ui'; import { createElement, replaceElement, toggleClass } from '../utils/elements'; import { triggerEvent } from '../utils/events'; import fetch from '../utils/fetch'; import is from '../utils/is'; import loadImage from '../utils/load-image'; import loadScript from '../utils/load-script'; import { extend } from '../utils/objects'; import { format, generateId } from '../utils/strings'; import { setAspectRatio } from '../utils/style'; // Parse YouTube ID from URL function parseId(url) { if (is.empty(url)) { return null; } const regex = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/; return url.match(regex) ? RegExp.$2 : url; } // Set playback state and trigger change (only on actual change) function assurePlaybackState(play) { if (play && !this.embed.hasPlayed) { this.embed.hasPlayed = true; } if (this.media.paused === play) { this.media.paused = !play; triggerEvent.call(this, this.media, play ? 'play' : 'pause'); } } function getHost(config) { if (config.noCookie) { return 'https://www.youtube-nocookie.com'; } if (window.location.protocol === 'http:') { return 'http://www.youtube.com'; } // Use YouTube's default return undefined; } const youtube = { setup() { // Add embed class for responsive toggleClass(this.elements.wrapper, this.config.classNames.embed, true); // Setup API if (is.object(window.YT) && is.function(window.YT.Player)) { youtube.ready.call(this); } else { // Reference current global callback const callback = window.onYouTubeIframeAPIReady; // Set callback to process queue window.onYouTubeIframeAPIReady = () => { // Call global callback if set if (is.function(callback)) { callback(); } youtube.ready.call(this); }; // Load the SDK loadScript(this.config.urls.youtube.sdk).catch((error) => { this.debug.warn('YouTube API failed to load', error); }); } }, // Get the media title getTitle(videoId) { const url = format(this.config.urls.youtube.api, videoId); fetch(url) .then((data) => { if (is.object(data)) { const { title, height, width } = data; // Set title this.config.title = title; ui.setTitle.call(this); // Set aspect ratio this.embed.ratio = [width, height]; } setAspectRatio.call(this); }) .catch(() => { // Set aspect ratio setAspectRatio.call(this); }); }, // API ready ready() { const player = this; const config = player.config.youtube; // Ignore already setup (race condition) const currentId = player.media && player.media.getAttribute('id'); if (!is.empty(currentId) && currentId.startsWith('youtube-')) { return; } // Get the source URL or ID let source = player.media.getAttribute('src'); // Get from
if needed if (is.empty(source)) { source = player.media.getAttribute(this.config.attributes.embed.id); } // Replace the