From 2bba1f30e28f402ef96b5f5181dd75788b0e25c9 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sun, 3 Sep 2017 14:36:55 +1000 Subject: Fixing Vimeo captions, WIP on settings menu, prettier and VS code settings --- src/js/plyr.js | 1160 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 749 insertions(+), 411 deletions(-) (limited to 'src/js') diff --git a/src/js/plyr.js b/src/js/plyr.js index 22f07788..db17ad00 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -16,7 +16,7 @@ } else { context[name] = definition(); } -}).call(this, 'Plyr', this, function() { +}.call(this, 'Plyr', this, function() { 'use strict'; /* global jQuery, console */ @@ -36,7 +36,6 @@ // Logging to console debug: false, - logPrefix: '', // Auto play (if supported) autoplay: false, @@ -135,12 +134,7 @@ 'airplay', 'fullscreen' ], - settings: [ - 'captions', - 'quality', - 'speed', - 'loop' - ], + settings: ['captions', 'quality', 'speed', 'loop'], // Localisation i18n: { @@ -168,13 +162,14 @@ end: 'End', all: 'All', reset: 'Reset', - none: 'None' + none: 'None', + disabled: 'Disabled' }, // URLs urls: { vimeo: { - api: 'https://player.vimeo.com/api/player.js', + api: 'https://player.vimeo.com/api/player.js' }, youtube: { api: 'https://www.youtube.com/iframe_api' @@ -227,19 +222,21 @@ 'seeked', 'emptied', 'ratechange', + 'cuechange', // Custom events 'enterfullscreen', 'exitfullscreen', 'captionsenabled', 'captionsdisabled', - 'qualitychange', - 'qualityrequested', + 'captionchange', 'controlshidden', 'controlsshown', // YouTube - 'statechange' + 'statechange', + 'qualitychange', + 'qualityrequested' ], // Selectors @@ -279,7 +276,7 @@ buffer: '.plyr__progress--buffer', played: '.plyr__progress--played', loop: '.plyr__progress--loop', - volume: '.plyr__volume--display', + volume: '.plyr__volume--display' }, progress: '.plyr__progress', captions: '.plyr__captions', @@ -289,7 +286,7 @@ }, // Class hooks added to the player in different states - classes: { + classNames: { video: 'plyr__video-wrapper', embed: 'plyr__video-embed', control: 'plyr__control', @@ -345,10 +342,17 @@ return input !== null && Array.isArray(input); }, number: function(input) { - return input !== null && (typeof input === 'number' && !isNaN(input - 0) || (typeof input === 'object' && input.constructor === Number)); + return ( + input !== null && + ((typeof input === 'number' && !isNaN(input - 0)) || + (typeof input === 'object' && input.constructor === Number)) + ); }, string: function(input) { - return input !== null && (typeof input === 'string' || (typeof input === 'object' && input.constructor === String)); + return ( + input !== null && + (typeof input === 'string' || (typeof input === 'object' && input.constructor === String)) + ); }, boolean: function(input) { return input !== null && typeof input === 'boolean'; @@ -369,13 +373,18 @@ return input !== null && (input instanceof window.TextTrackCue || input instanceof window.VTTCue); }, track: function(input) { - return input !== null && input instanceof window.TextTrack; + return input !== null && (input instanceof window.TextTrack || typeof input.kind === 'string'); }, undefined: function(input) { return input !== null && typeof input === 'undefined'; }, empty: function(input) { - return input === null || this.undefined(input) || ((this.string(input) || this.array(input) || this.nodeList(input)) && input.length === 0) || (this.object(input) && Object.keys(input).length === 0); + return ( + input === null || + this.undefined(input) || + ((this.string(input) || this.array(input) || this.nodeList(input)) && input.length === 0) || + (this.object(input) && Object.keys(input).length === 0) + ); } }, @@ -394,7 +403,7 @@ var isChrome = false; var isSafari = false; - if ((navigator.appVersion.indexOf('Windows NT') !== -1) && (navigator.appVersion.indexOf('rv:11') !== -1)) { + if (navigator.appVersion.indexOf('Windows NT') !== -1 && navigator.appVersion.indexOf('rv:11') !== -1) { // MSIE 11 isIE = true; name = 'IE'; @@ -453,7 +462,7 @@ name: name, version: majorVersion, isIE: isIE, - isOldIE: (isIE && majorVersion <= 9), + isOldIE: isIE && majorVersion <= 9, isFirefox: isFirefox, isChrome: isChrome, isSafari: isSafari, @@ -468,7 +477,7 @@ var basic = false; var full = false; var browser = utils.getBrowser(); - var playsInline = (browser.isIPhone && inline && support.inline); + var playsInline = browser.isIPhone && inline && support.inline; switch (type) { case 'video': @@ -489,12 +498,12 @@ case 'vimeo': case 'soundcloud': basic = true; - full = (!browser.isOldIE && !browser.isIos); + full = !browser.isOldIE && !browser.isIos; break; default: - basic = (support.audio && support.video); - full = (basic && !browser.isOldIE); + basic = support.audio && support.video; + full = basic && !browser.isOldIE; } return { @@ -546,7 +555,7 @@ // Loops backwards to prevent having to clone the wrapper on the // first element (see `child` below). for (var i = elements.length - 1; i >= 0; i--) { - var child = (i > 0) ? wrapper.cloneNode(true) : wrapper; + var child = i > 0 ? wrapper.cloneNode(true) : wrapper; var element = elements[i]; // Cache the current parent and sibling. @@ -572,19 +581,13 @@ // Remove an element removeElement: function(element) { - if (!utils.is.htmlElement(element) || - !utils.is.htmlElement(element.parentNode)) { + if (!utils.is.htmlElement(element) || !utils.is.htmlElement(element.parentNode)) { return; } element.parentNode.removeChild(element); }, - // Prepend child - prependChild: function(parent, element) { - parent.insertBefore(element, parent.firstChild); - }, - // Inaert an element after another insertAfter: function(element, target) { target.parentNode.insertBefore(element, target.nextSibling); @@ -611,16 +614,14 @@ // Insert a DocumentFragment insertElement: function(type, parent, attributes, text) { - // Create a new - var element = utils.createElement(type, attributes, text); - - // Inject the new element - utils.prependChild(parent, element); + // Inject the new + parent.appendChild(utils.createElement(type, attributes, text)); }, // Remove all child elements emptyElement: function(element) { var length = element.childNodes.length; + while (length--) { element.removeChild(element.lastChild); } @@ -706,7 +707,7 @@ element.className = name + (toggle ? ' ' + className : ''); } - return toggle && !contains || !toggle && contains; + return (toggle && !contains) || (!toggle && contains); } return null; @@ -728,7 +729,8 @@ matches: function(element, selector) { var prototype = Element.prototype; - var matches = prototype.matches || + var matches = + prototype.matches || prototype.webkitMatchesSelector || prototype.mozMatchesSelector || prototype.msMatchesSelector || @@ -754,12 +756,18 @@ // Bind along with custom handler proxy: function(element, eventName, customListener, defaultListener, passive, capture) { - utils.on(element, eventName, function(event) { - if (customListener) { - customListener.apply(element, [event]); - } - defaultListener.apply(element, [event]); - }, passive, capture); + utils.on( + element, + eventName, + function(event) { + if (customListener) { + customListener.apply(element, [event]); + } + defaultListener.apply(element, [event]); + }, + passive, + capture + ); }, // Toggle event listener @@ -832,7 +840,7 @@ }, // Trigger event - event: function(element, type, bubbles, properties) { + dispatchEvent: function(element, type, bubbles, properties) { // Bail if no element if (!element || !type) { return; @@ -882,7 +890,7 @@ } // Get state - state = (utils.is.boolean(state) ? state : !target.getAttribute('aria-pressed')); + state = utils.is.boolean(state) ? state : !target.getAttribute('aria-pressed'); // Set the attribute on target target.setAttribute('aria-pressed', state); @@ -895,7 +903,7 @@ if (current === 0 || max === 0 || isNaN(current) || isNaN(max)) { return 0; } - return ((current / max) * 100).toFixed(2); + return (current / max * 100).toFixed(2); }, // Deep extend/merge destination object with N more objects @@ -1011,9 +1019,12 @@ // Once loaded, inject to container and body xhr.onload = function() { if (support.storage) { - window.localStorage.setItem(prefix + id, JSON.stringify({ - content: xhr.responseText - })); + window.localStorage.setItem( + prefix + id, + JSON.stringify({ + content: xhr.responseText + }) + ); } updateSprite(container, xhr.responseText); @@ -1073,7 +1084,7 @@ prefix: prefix, // Yet again Microsoft awesomeness, // Sometimes the prefix is 'ms', sometimes 'MS' to keep you on your toes - eventType: (prefix === 'ms' ? 'MSFullscreenChange' : prefix + 'fullscreenchange'), + eventType: prefix === 'ms' ? 'MSFullscreenChange' : prefix + 'fullscreenchange', // Is an element fullscreen isFullScreen: function(element) { @@ -1105,14 +1116,18 @@ element = document.body; } - return !prefix.length ? element.requestFullScreen() : element[prefix + (prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen')](); + return !prefix.length + ? element.requestFullScreen() + : element[prefix + (prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen')](); }, cancelFullScreen: function() { if (!support.fullscreen) { return false; } - return !prefix.length ? document.cancelFullScreen() : document[prefix + (prefix === 'ms' ? 'ExitFullscreen' : 'CancelFullScreen')](); + return !prefix.length + ? document.cancelFullScreen() + : document[prefix + (prefix === 'ms' ? 'ExitFullscreen' : 'CancelFullScreen')](); }, element: function() { if (!support.fullscreen) { @@ -1255,18 +1270,25 @@ } // jQuery, NodeList or Array passed, use first element - if ((window.jQuery && player.media instanceof jQuery) || + if ( + (window.jQuery && player.media instanceof jQuery) || utils.is.nodeList(player.media) || - utils.is.array(player.media)) { + utils.is.array(player.media) + ) { player.media = player.media[0]; } // Set config - player.config = utils.extend({}, defaults, options, (function() { - try { - return JSON.parse(player.media.getAttribute('data-plyr')); - } catch (e) {} - })()); + player.config = utils.extend( + {}, + defaults, + options, + (function() { + try { + return JSON.parse(player.media.getAttribute('data-plyr')); + } catch (e) {} + })() + ); // Elements cache player.elements = { @@ -1285,9 +1307,8 @@ // Captions player.captions = { - enabled: false, - captions: [], - tracks: [], + enabled: null, + tracks: null, currentTrack: null }; @@ -1333,9 +1354,14 @@ // Trigger events, with plyr instance passed function trigger(element, type, bubbles, properties) { - utils.event(element, type, bubbles, utils.extend({}, properties, { - plyr: player - })); + utils.dispatchEvent( + element, + type, + bubbles, + utils.extend({}, properties, { + plyr: player + }) + ); } // Trap focus inside container @@ -1391,6 +1417,8 @@ src: attributes }); } else if (utils.is.array(attributes)) { + warn(attributes); + attributes.forEach(function(attribute) { utils.insertElement(type, player.media, attribute); }); @@ -1401,7 +1429,7 @@ function getIconUrl() { return { url: player.config.iconUrl, - absolute: (player.config.iconUrl.indexOf('http') === 0) || player.browser.isIE + absolute: player.config.iconUrl.indexOf('http') === 0 || player.browser.isIE }; } @@ -1413,9 +1441,12 @@ // Create var icon = document.createElementNS(namespace, 'svg'); - utils.setAttributes(icon, utils.extend(attributes, { - role: 'presentation' - })); + utils.setAttributes( + icon, + utils.extend(attributes, { + role: 'presentation' + }) + ); // Create the to reference sprite var use = document.createElementNS(namespace, 'use'); @@ -1441,20 +1472,30 @@ break; } - return utils.createElement('span', { - class: player.config.classes.hidden - }, text); + return utils.createElement( + 'span', + { + class: player.config.classNames.hidden + }, + text + ); } // Create a badge function createBadge(text) { var badge = utils.createElement('span', { - class: player.config.classes.menu.value + class: player.config.classNames.menu.value }); - badge.appendChild(utils.createElement('span', { - class: player.config.classes.menu.badge - }, text)); + badge.appendChild( + utils.createElement( + 'span', + { + class: player.config.classNames.menu.badge + }, + text + ) + ); return badge; } @@ -1471,11 +1512,11 @@ } if ('class' in attributes) { - if (attributes.class.indexOf(player.config.classes.control) === -1) { - attributes.class += ' ' + player.config.classes.control; + if (attributes.class.indexOf(player.config.classNames.control) === -1) { + attributes.class += ' ' + player.config.classNames.control; } } else { - attributes.class = player.config.classes.control; + attributes.class = player.config.classNames.control; } // Large play button @@ -1511,13 +1552,18 @@ } // Merge attributes - utils.extend(attributes, utils.getAttributesFromSelector(player.config.selectors.buttons[type], attributes)); + utils.extend( + attributes, + utils.getAttributesFromSelector(player.config.selectors.buttons[type], attributes) + ); // Add toggle icon if needed if (utils.is.string(iconToggled)) { - button.appendChild(createIcon(iconToggled, { - class: 'icon--' + iconToggled - })); + button.appendChild( + createIcon(iconToggled, { + class: 'icon--' + iconToggled + }) + ); } button.appendChild(createIcon(iconDefault)); @@ -1533,20 +1579,31 @@ // Create an