import $ from 'jquery'; const { VPData } = window; const { settingsPopupGallery } = VPData; const templatesSupport = 'content' in document.createElement('template'); /* * Global Popup Gallery API. */ const VPPopupAPI = { vendor: false, vendors: [ { vendor: 'youtube', embedUrl: 'https://www.youtube.com/embed/{{video_id}}?{{params}}', pattern: /(https?:\/\/)?(www.)?(youtube\.com|youtu\.be|youtube-nocookie\.com)\/(?:embed\/|shorts\/|v\/|watch\?v=|watch\?list=(.*)&v=|watch\?(.*[^&]&)v=)?((\w|-){11})(&list=(\w+)&?)?(.*)/, patternIndex: 6, params: { autoplay: 1, autohide: 1, fs: 1, rel: 0, hd: 1, wmode: 'transparent', enablejsapi: 1, html5: 1, }, paramsIndex: 10, embedCallback(url, match) { let result = false; const vendorData = this; const videoId = match && match[vendorData.patternIndex] ? match[vendorData.patternIndex] : false; if (videoId) { const isShorts = /\/shorts\//.test(url); const width = isShorts ? 476 : 1920; const height = isShorts ? 847 : 1080; result = VPPopupAPI.embedCallback( { ...vendorData, width, height, }, videoId, url, match ); } return result; }, }, { vendor: 'vimeo', embedUrl: 'https://player.vimeo.com/video/{{video_id}}?{{params}}', pattern: /https?:\/\/(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|album\/(\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)(.*)/, patternIndex: 3, params: { autoplay: 1, hd: 1, show_title: 1, show_byline: 1, show_portrait: 0, fullscreen: 1, }, paramsIndex: 4, }, ], init() {}, open() {}, close() {}, /** * Parse query parameters. * Thanks to https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript * * @param {string} query - query string. * * @return {string} */ getQueryStringParams(query) { return query ? (/^[?#]/.test(query) ? query.slice(1) : query) .split('&') .reduce((params, param) => { const [key, value] = param.split('='); params[key] = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : ''; return params; }, {}) : {}; }, /** * Prepare params from parsed URL. * * @param {Object} match - url match data. * @param {Object} vendorData - vendor data. * * @return {string} */ prepareParams(match, vendorData) { let result = ''; // Prepare default params. const params = vendorData.params || {}; // Parse params from URL. if (vendorData.paramsIndex && match && match[vendorData.paramsIndex]) { const newParams = VPPopupAPI.getQueryStringParams( match[vendorData.paramsIndex] ); if (newParams && typeof newParams === 'object') { Object.keys(newParams).forEach((key) => { if (key && newParams[key]) { params[key] = newParams[key]; } }); } } if (params && Object.keys(params).length) { Object.keys(params).forEach((key) => { if (key && params[key]) { if (result) { result += '&'; } result += `${key}=${params[key]}`; } }); } return result; }, /** * Prepare data for embed. * * @param {Object} vendorData current video vendor data. * @param {string} videoId parsed video ID. * @param {string} url video URL provided. * @param {Object | boolean} match URL match data. * * @return {Object} */ embedCallback(vendorData, videoId, url, match = false) { let { embedUrl } = vendorData; embedUrl = embedUrl.replace(/{{video_id}}/g, videoId); embedUrl = embedUrl.replace(/{{video_url}}/g, url); embedUrl = embedUrl.replace( /{{video_url_encoded}}/g, encodeURIComponent(url) ); embedUrl = embedUrl.replace( /{{params}}/g, match ? VPPopupAPI.prepareParams(match, vendorData) : '' ); const width = vendorData.width || 1920; const height = vendorData.height || 1080; return { vendor: vendorData.vendor, id: videoId, embed: ``, embedUrl, url, width, height, }; }, /** * Parse video URL and return object with data * * @param {string} url - video url. * @param {string} url - optional poster url. * * @param poster * @return {object|boolean} video data */ parseVideo(url, poster) { let result = false; VPPopupAPI.vendors.forEach((vendorData) => { if (!result) { const match = url.match(vendorData.pattern); const videoId = match && match[vendorData.patternIndex] ? match[vendorData.patternIndex] : false; if (videoId) { // Custom embed callback. if (vendorData.embedCallback) { result = vendorData.embedCallback(url, match, poster); // Predefined embed callback. } else { result = VPPopupAPI.embedCallback( vendorData, videoId, url, match ); } } } }); // Unknown vendor. if (!result) { result = VPPopupAPI.embedCallback( { vendor: 'unknown', embedUrl: url, }, url, url, false ); } return result; }, /** * Parse gallery item popup data. * * @param {element} itemElement - gallery item */ parseItem(itemElement) { let result = false; const $dataElement = itemElement && itemElement.querySelector('.vp-portfolio__item-popup'); if ($dataElement) { result = { $dataElement, $content: $dataElement, data: $dataElement.dataset, }; // Support for