UNPKG

hexo-tag-youtube-responsive

Version:

Hexo tag plugin to embed a Youtube player that auto resizes with your responsive layout

192 lines (161 loc) 4.57 kB
const yaml = require('js-yaml'); const _ = require('lodash'); const validParams = [ 'allowfullscreen', 'autoplay', 'cc_lang_pref', 'cc_load_policy', 'color', 'controls', 'disablekb', 'enablejsapi', 'end', 'frameborder', 'fs', 'height', 'hl', 'iv_load_policy', 'loop', 'modestbranding', 'origin', 'playlist', 'playsinline', 'privacy_mode', 'rel', 'showinfo', 'start', 'widget_referrer', 'width', ]; if (process.env.NODE_ENV != 'test') { hexo.extend.tag.register('youtuber', youtube, { ends: true }); } function youtube(args, context) { const params = _.merge(getDefault(hexo.config.youtuber), _.merge(getParams(context), getArgs(args))); if (!_.has(params, 'type') || !_.has(params, 'id')) { return 'Must have the 2 required arguments such as {% youtuber video VIDEO_ID %}'; } if (_.has(params, 'height') || _.has(params, 'width')) { // by default it is responsive unless dimension is specified return getIframe(params); } return `${getCss()}\n\n<div class="embed-container">${getIframe(params)}</div>`; } function isFalsy(value) { const v = _.isString(value) ? value.toLowerCase() : value; return v === false || v === 'false' || v === 'f' || v === 'no' || v === 'n' || v === '0' || v === 0; } function isTruthy(value) { const v = _.isString(value) ? value.toLowerCase() : value; return v === true || v === 'true' || v === 't' || v === 'yes' || v === 'y' || v === '1' || v === 1; } function isParamFalsy(params, field) { if (!_.has(params, field)) return false; return isFalsy(params[field]); } function isParamTruthy(params, field) { if (!_.has(params, field)) return false; return isTruthy(params[field]); } const getArgs = (args) => { const params = {}; if (args.length > 0) params['type'] = args[0]; if (args.length > 1) params['id'] = args[1]; return params; } const getDefault = (config) => { const params = {}; console.log('=====', config, '-----'); if (config) { Object.keys(config).forEach(k => { if (validParams.indexOf(k) >= 0) { params[k] = config[k]; } }); } return params; } const getParams = (content) => { const params = {}; if (content && content.trim()) { const contentParams = yaml.load(content); Object.keys(contentParams).forEach(k => { if (validParams.indexOf(k) >= 0) { params[k] = contentParams[k]; } }); } return params; } const getUrl = (params) => { const url = new URL(_.has(params, 'privacy_mode') && isTruthy(params.privacy_mode) ? 'https://www.youtube-nocookie.com' : 'https://www.youtube.com'); const urlParams = new URLSearchParams(); if (params.type === 'video') { url.pathname = `/embed/${params.id}`; } else { const listTypes = { playlist: 'playlist', user: 'user_uploads', search: 'search' }; if (Object.keys(listTypes).indexOf(params.type) >= 0) { urlParams.set('listType', listTypes[params.type]); urlParams.set('list', params.id); url.pathname = '/embed'; } else { console.error('Unable to render Youtube', type, id); return null; } } const validParams = [ 'autoplay', 'cc_lang_pref', 'cc_load_policy', 'color', 'controls', 'disablekb', 'enablejsapi', 'end', 'fs', 'hl', 'iv_load_policy', 'loop', 'modestbranding', 'origin', 'playlist', 'playsinline', 'rel', 'showinfo', 'start', 'widget_referrer', ]; validParams.forEach(p => { if (_.has(params, p)) { urlParams.set(p, params[p]); } }) url.search = urlParams.toString(); return url; } const getIframe = (params) => { let options = []; if (!_.has(params, 'allowfullscreen') || isTruthy(params.allowfullscreen)) options.push(`allowfullscreen`); options.push(`frameborder="${_.has(params, 'frameborder') ? params.frameborder : 0}"`); if (_.has(params, 'height')) options.push(`height="${params.height}"`); if (_.has(params, 'width')) options.push(`width="${params.width}"`); return `<iframe src="${getUrl(params).toString()}" ${options.join(' ')} allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"></iframe>`; } const getCss = () => { return `<style>.embed-container { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; } .embed-container iframe, .embed-container object, .embed-container embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } </style>`; }