chore: update packages and linting

This commit is contained in:
Sam Potts
2020-08-30 16:10:15 +10:00
parent 11e48b0181
commit 18b3f23c69
43 changed files with 3334 additions and 1986 deletions
+2 -14
View File
@@ -1,7 +1,6 @@
{ {
"parser": "babel-eslint", "parser": "babel-eslint",
"extends": ["airbnb-base", "prettier"], "extends": "@sampotts/eslint-config/es6",
"plugins": ["simple-import-sort", "import"],
"env": { "env": {
"browser": true, "browser": true,
"es6": true "es6": true
@@ -11,18 +10,7 @@
"jQuery": false "jQuery": false
}, },
"rules": { "rules": {
"import/no-cycle": "warn", "import/no-cycle": "warn"
"padding-line-between-statements": [
"error",
{
"blankLine": "never",
"prev": ["singleline-const", "singleline-let", "singleline-var"],
"next": ["singleline-const", "singleline-let", "singleline-var"]
}
],
"sort-imports": "off",
"import/order": "off",
"simple-import-sort/sort": "error"
}, },
"parserOptions": { "parserOptions": {
"sourceType": "module" "sourceType": "module"
+1 -1
View File
File diff suppressed because one or more lines are too long
+1213 -852
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -5,10 +5,10 @@
"homepage": "https://plyr.io", "homepage": "https://plyr.io",
"author": "Sam Potts <sam@potts.es>", "author": "Sam Potts <sam@potts.es>",
"dependencies": { "dependencies": {
"@sentry/browser": "^5.15.5", "@sentry/browser": "^5.22.3",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"custom-event-polyfill": "^1.0.7", "custom-event-polyfill": "^1.0.7",
"shr-buttons": "2.0.3", "shr-buttons": "2.0.3",
"url-polyfill": "^1.1.8" "url-polyfill": "^1.1.10"
} }
} }
+40 -40
View File
@@ -2,56 +2,56 @@
# yarn lockfile v1 # yarn lockfile v1
"@sentry/browser@^5.15.5": "@sentry/browser@^5.22.3":
version "5.15.5" version "5.22.3"
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.15.5.tgz#d9a51f1388581067b50d30ed9b1aed2cbb333a36" resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.22.3.tgz#7a64bd1cf01bf393741a3e4bf35f82aa927f5b4e"
integrity sha512-rqDvjk/EvogfdbZ4TiEpxM/lwpPKmq23z9YKEO4q81+1SwJNua53H60dOk9HpRU8nOJ1g84TMKT2Ov8H7sqDWA== integrity sha512-2TzE/CoBa5ZkvxJizDdi1Iz1ldmXSJpFQ1mL07PIXBjCt0Wxf+WOuFSj5IP4L40XHfJE5gU8wEvSH0VDR8nXtA==
dependencies: dependencies:
"@sentry/core" "5.15.5" "@sentry/core" "5.22.3"
"@sentry/types" "5.15.5" "@sentry/types" "5.22.3"
"@sentry/utils" "5.15.5" "@sentry/utils" "5.22.3"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/core@5.15.5": "@sentry/core@5.22.3":
version "5.15.5" version "5.22.3"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.15.5.tgz#40ea79bff5272d3fbbeeb4a98cdc59e1adbd2c92" resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.22.3.tgz#030f435f2b518f282ba8bd954dac90cd70888bd7"
integrity sha512-enxBLv5eibBMqcWyr+vApqeix8uqkfn0iGsD3piKvoMXCgKsrfMwlb/qo9Ox0lKr71qIlZVt+9/A2vZohdgnlg== integrity sha512-eGL5uUarw3o4i9QUb9JoFHnhriPpWCaqeaIBB06HUpdcvhrjoowcKZj1+WPec5lFg5XusE35vez7z/FPzmJUDw==
dependencies: dependencies:
"@sentry/hub" "5.15.5" "@sentry/hub" "5.22.3"
"@sentry/minimal" "5.15.5" "@sentry/minimal" "5.22.3"
"@sentry/types" "5.15.5" "@sentry/types" "5.22.3"
"@sentry/utils" "5.15.5" "@sentry/utils" "5.22.3"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/hub@5.15.5": "@sentry/hub@5.22.3":
version "5.15.5" version "5.22.3"
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.15.5.tgz#f5abbcdbe656a70e2ff02c02a5a4cffa0f125935" resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.22.3.tgz#08309a70d2ea8d5e313d05840c1711f34f2fffe5"
integrity sha512-zX9o49PcNIVMA4BZHe//GkbQ4Jx+nVofqU/Il32/IbwKhcpPlhGX3c1sOVQo4uag3cqd/JuQsk+DML9TKkN0Lw== integrity sha512-INo47m6N5HFEs/7GMP9cqxOIt7rmRxdERunA3H2L37owjcr77MwHVeeJ9yawRS6FMtbWXplgWTyTIWIYOuqVbw==
dependencies: dependencies:
"@sentry/types" "5.15.5" "@sentry/types" "5.22.3"
"@sentry/utils" "5.15.5" "@sentry/utils" "5.22.3"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/minimal@5.15.5": "@sentry/minimal@5.22.3":
version "5.15.5" version "5.22.3"
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.15.5.tgz#a0e4e071f01d9c4d808094ae7203f6c4cca9348a" resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.22.3.tgz#706e4029ae5494123d3875c658ba8911aa5cc440"
integrity sha512-zQkkJ1l9AjmU/Us5IrOTzu7bic4sTPKCatptXvLSTfyKW7N6K9MPIIFeSpZf9o1yM2sRYdK7GV08wS2eCT3JYw== integrity sha512-HoINpYnVYCpNjn2XIPIlqH5o4BAITpTljXjtAftOx6Hzj+Opjg8tR8PWliyKDvkXPpc4kXK9D6TpEDw8MO0wZA==
dependencies: dependencies:
"@sentry/hub" "5.15.5" "@sentry/hub" "5.22.3"
"@sentry/types" "5.15.5" "@sentry/types" "5.22.3"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/types@5.15.5": "@sentry/types@5.22.3":
version "5.15.5" version "5.22.3"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.15.5.tgz#16c97e464cf09bbd1d2e8ce90d130e781709076e" resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.22.3.tgz#d1d547b30ee8bd7771fa893af74c4f3d71f0fd18"
integrity sha512-F9A5W7ucgQLJUG4LXw1ZIy4iLevrYZzbeZ7GJ09aMlmXH9PqGThm1t5LSZlVpZvUfQ2rYA8NU6BdKJSt7B5LPw== integrity sha512-cv+VWK0YFgCVDvD1/HrrBWOWYG3MLuCUJRBTkV/Opdy7nkdNjhCAJQrEyMM9zX0sac8FKWKOHT0sykNh8KgmYw==
"@sentry/utils@5.15.5": "@sentry/utils@5.22.3":
version "5.15.5" version "5.22.3"
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.15.5.tgz#dec1d4c79037c4da08b386f5d34409234dcbfb15" resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.22.3.tgz#e3bda3e789239eb16d436f768daa12829f33d18f"
integrity sha512-Nl9gl/MGnzSkuKeo3QaefoD/OJrFLB8HmwQ7HUbTXb6E7yyEzNKAQMHXGkwNAjbdYyYbd42iABP6Y5F/h39NtA== integrity sha512-AHNryXMBvIkIE+GQxTlmhBXD0Ksh+5w1SwM5qi6AttH+1qjWLvV6WB4+4pvVvEoS8t5F+WaVUZPQLmCCWp6zKw==
dependencies: dependencies:
"@sentry/types" "5.15.5" "@sentry/types" "5.22.3"
tslib "^1.9.3" tslib "^1.9.3"
core-js@^3.6.5: core-js@^3.6.5:
@@ -74,7 +74,7 @@ tslib@^1.9.3:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==
url-polyfill@^1.1.8: url-polyfill@^1.1.10:
version "1.1.8" version "1.1.10"
resolved "https://registry.yarnpkg.com/url-polyfill/-/url-polyfill-1.1.8.tgz#21eb58ad61192f52b77dcac8ab5293ae7bc67060" resolved "https://registry.yarnpkg.com/url-polyfill/-/url-polyfill-1.1.10.tgz#fd5bbcf66c9491fa682b0cb6d6a855e1643a9281"
integrity sha512-Ey61F4FEqhcu1vHSOMmjl0Vd/RPRLEjMj402qszD/dhMBrVfoUsnIj8KSZo2yj+eIlxJGKFdnm6ES+7UzMgZ3Q== integrity sha512-vSaPpaRgBrf41+Uky1myiSh6gpcbw8FpwHYnEy0abxndojOBnIs+yh/49gKYFLtUMP9qoNWjn6j9aUVy23Ie2A==
+1 -1
View File
File diff suppressed because one or more lines are too long
+22 -15
View File
@@ -1,7 +1,7 @@
typeof navigator === "object" && (function (global, factory) { typeof navigator === "object" && (function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define('Plyr', factory) : typeof define === 'function' && define.amd ? define('Plyr', factory) :
(global = global || self, global.Plyr = factory()); (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Plyr = factory());
}(this, (function () { 'use strict'; }(this, (function () { 'use strict';
function _classCallCheck(instance, Constructor) { function _classCallCheck(instance, Constructor) {
@@ -163,7 +163,7 @@ typeof navigator === "object" && (function (global, factory) {
if (typeof o === "string") return _arrayLikeToArray(o, minLen); if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1); var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(n); if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
} }
@@ -1084,7 +1084,7 @@ typeof navigator === "object" && (function (global, factory) {
var event = new CustomEvent(type, { var event = new CustomEvent(type, {
bubbles: bubbles, bubbles: bubbles,
detail: _objectSpread2({}, detail, { detail: _objectSpread2(_objectSpread2({}, detail), {}, {
plyr: this plyr: this
}) })
}); // Dispatch the event }); // Dispatch the event
@@ -1197,7 +1197,12 @@ typeof navigator === "object" && (function (global, factory) {
if (this.isVimeo && !this.config.vimeo.premium && this.supported.ui) { if (this.isVimeo && !this.config.vimeo.premium && this.supported.ui) {
var height = 100 / this.media.offsetWidth * parseInt(window.getComputedStyle(this.media).paddingBottom, 10); var height = 100 / this.media.offsetWidth * parseInt(window.getComputedStyle(this.media).paddingBottom, 10);
var offset = (height - padding) / (height / 50); var offset = (height - padding) / (height / 50);
if (this.fullscreen.active) {
wrapper.style.paddingBottom = null;
} else {
this.media.style.transform = "translateY(-".concat(offset, "%)"); this.media.style.transform = "translateY(-".concat(offset, "%)");
}
} else if (this.isHTML5) { } else if (this.isHTML5) {
wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null); wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null);
} }
@@ -1786,7 +1791,7 @@ typeof navigator === "object" && (function (global, factory) {
var attr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var attr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var text = i18n.get(key, this.config); var text = i18n.get(key, this.config);
var attributes = _objectSpread2({}, attr, { var attributes = _objectSpread2(_objectSpread2({}, attr), {}, {
class: [attr.class, this.config.classNames.hidden].filter(Boolean).join(' ') class: [attr.class, this.config.classNames.hidden].filter(Boolean).join(' ')
}); });
@@ -2786,7 +2791,7 @@ typeof navigator === "object" && (function (global, factory) {
showMenuPanel = controls.showMenuPanel; showMenuPanel = controls.showMenuPanel;
this.elements.controls = null; // Larger overlaid play button this.elements.controls = null; // Larger overlaid play button
if (this.config.controls.includes('play-large')) { if (is$1.array(this.config.controls) && this.config.controls.includes('play-large')) {
this.elements.container.appendChild(createButton.call(this, 'play-large')); this.elements.container.appendChild(createButton.call(this, 'play-large'));
} // Create the container } // Create the container
@@ -2798,7 +2803,7 @@ typeof navigator === "object" && (function (global, factory) {
class: 'plyr__controls__item' class: 'plyr__controls__item'
}; // Loop through controls in order }; // Loop through controls in order
dedupe(this.config.controls).forEach(function (control) { dedupe(is$1.array(this.config.controls) ? this.config.controls : []).forEach(function (control) {
// Restart button // Restart button
if (control === 'restart') { if (control === 'restart') {
container.appendChild(createButton.call(_this10, 'restart', defaultAttributes)); container.appendChild(createButton.call(_this10, 'restart', defaultAttributes));
@@ -3117,8 +3122,6 @@ typeof navigator === "object" && (function (global, factory) {
if (update) { if (update) {
if (is$1.string(this.config.controls)) { if (is$1.string(this.config.controls)) {
container = replace(container); container = replace(container);
} else if (is$1.element(container)) {
container.innerHTML = replace(container.innerHTML);
} }
} // Controls container } // Controls container
@@ -4103,10 +4106,12 @@ typeof navigator === "object" && (function (global, factory) {
if (is$1.element(button)) { if (is$1.element(button)) {
button.pressed = this.active; button.pressed = this.active;
} // Trigger an event } // Always trigger events on the plyr / media element (not a fullscreen container) and let them bubble up
triggerEvent.call(this.player, this.target, this.active ? 'enterfullscreen' : 'exitfullscreen', true); var target = this.target === this.player.media ? this.target : this.player.elements.container; // Trigger an event
triggerEvent.call(this.player, target, this.active ? 'enterfullscreen' : 'exitfullscreen', true);
} }
}, { }, {
key: "toggleFallback", key: "toggleFallback",
@@ -4572,7 +4577,7 @@ typeof navigator === "object" && (function (global, factory) {
// Loop through values (as they are the keys when the object is spread 🤔) // Loop through values (as they are the keys when the object is spread 🤔)
Object.values(_objectSpread2({}, this.media.style)) // We're only fussed about Plyr specific properties Object.values(_objectSpread2({}, this.media.style)) // We're only fussed about Plyr specific properties
.filter(function (key) { .filter(function (key) {
return !is$1.empty(key) && key.startsWith('--plyr'); return !is$1.empty(key) && is$1.string(key) && key.startsWith('--plyr');
}).forEach(function (key) { }).forEach(function (key) {
// Set on the container // Set on the container
_this5.elements.container.style.setProperty(key, _this5.media.style.getPropertyValue(key)); // Clean up from media element _this5.elements.container.style.setProperty(key, _this5.media.style.getPropertyValue(key)); // Clean up from media element
@@ -8293,9 +8298,9 @@ typeof navigator === "object" && (function (global, factory) {
if (this.isHTML5 && this.config.autoplay) { if (this.isHTML5 && this.config.autoplay) {
setTimeout(function () { this.once('canplay', function () {
return silencePromise(_this.play()); return silencePromise(_this.play());
}, 10); });
} // Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek } // Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek
@@ -8491,7 +8496,7 @@ typeof navigator === "object" && (function (global, factory) {
var hiding = toggleClass(this.elements.container, this.config.classNames.hideControls, force); // Close menu var hiding = toggleClass(this.elements.container, this.config.classNames.hideControls, force); // Close menu
if (hiding && this.config.controls.includes('settings') && !is$1.empty(this.config.settings)) { if (hiding && is$1.array(this.config.controls) && this.config.controls.includes('settings') && !is$1.empty(this.config.settings)) {
controls.toggleMenu.call(this, false); controls.toggleMenu.call(this, false);
} // Trigger event on change } // Trigger event on change
@@ -8584,7 +8589,9 @@ typeof navigator === "object" && (function (global, factory) {
} }
} else { } else {
// Unbind listeners // Unbind listeners
unbindListeners.call(_this3); // Replace the container with the original element provided unbindListeners.call(_this3); // Cancel current network requests
html5.cancelRequests.call(_this3); // Replace the container with the original element provided
replaceElement(_this3.elements.original, _this3.elements.container); // Event replaceElement(_this3.elements.original, _this3.elements.container); // Event
+2 -2
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+2 -2
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+22 -15
View File
@@ -1,4 +1,4 @@
typeof navigator === "object" && function _classCallCheck(instance, Constructor) { function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) { if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function"); throw new TypeError("Cannot call a class as a function");
} }
@@ -157,7 +157,7 @@ function _unsupportedIterableToArray(o, minLen) {
if (typeof o === "string") return _arrayLikeToArray(o, minLen); if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1); var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(n); if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
} }
@@ -1078,7 +1078,7 @@ function triggerEvent(element) {
var event = new CustomEvent(type, { var event = new CustomEvent(type, {
bubbles: bubbles, bubbles: bubbles,
detail: _objectSpread2({}, detail, { detail: _objectSpread2(_objectSpread2({}, detail), {}, {
plyr: this plyr: this
}) })
}); // Dispatch the event }); // Dispatch the event
@@ -1191,7 +1191,12 @@ function setAspectRatio(input) {
if (this.isVimeo && !this.config.vimeo.premium && this.supported.ui) { if (this.isVimeo && !this.config.vimeo.premium && this.supported.ui) {
var height = 100 / this.media.offsetWidth * parseInt(window.getComputedStyle(this.media).paddingBottom, 10); var height = 100 / this.media.offsetWidth * parseInt(window.getComputedStyle(this.media).paddingBottom, 10);
var offset = (height - padding) / (height / 50); var offset = (height - padding) / (height / 50);
if (this.fullscreen.active) {
wrapper.style.paddingBottom = null;
} else {
this.media.style.transform = "translateY(-".concat(offset, "%)"); this.media.style.transform = "translateY(-".concat(offset, "%)");
}
} else if (this.isHTML5) { } else if (this.isHTML5) {
wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null); wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null);
} }
@@ -1780,7 +1785,7 @@ var controls = {
var attr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var attr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var text = i18n.get(key, this.config); var text = i18n.get(key, this.config);
var attributes = _objectSpread2({}, attr, { var attributes = _objectSpread2(_objectSpread2({}, attr), {}, {
class: [attr.class, this.config.classNames.hidden].filter(Boolean).join(' ') class: [attr.class, this.config.classNames.hidden].filter(Boolean).join(' ')
}); });
@@ -2780,7 +2785,7 @@ var controls = {
showMenuPanel = controls.showMenuPanel; showMenuPanel = controls.showMenuPanel;
this.elements.controls = null; // Larger overlaid play button this.elements.controls = null; // Larger overlaid play button
if (this.config.controls.includes('play-large')) { if (is$1.array(this.config.controls) && this.config.controls.includes('play-large')) {
this.elements.container.appendChild(createButton.call(this, 'play-large')); this.elements.container.appendChild(createButton.call(this, 'play-large'));
} // Create the container } // Create the container
@@ -2792,7 +2797,7 @@ var controls = {
class: 'plyr__controls__item' class: 'plyr__controls__item'
}; // Loop through controls in order }; // Loop through controls in order
dedupe(this.config.controls).forEach(function (control) { dedupe(is$1.array(this.config.controls) ? this.config.controls : []).forEach(function (control) {
// Restart button // Restart button
if (control === 'restart') { if (control === 'restart') {
container.appendChild(createButton.call(_this10, 'restart', defaultAttributes)); container.appendChild(createButton.call(_this10, 'restart', defaultAttributes));
@@ -3111,8 +3116,6 @@ var controls = {
if (update) { if (update) {
if (is$1.string(this.config.controls)) { if (is$1.string(this.config.controls)) {
container = replace(container); container = replace(container);
} else if (is$1.element(container)) {
container.innerHTML = replace(container.innerHTML);
} }
} // Controls container } // Controls container
@@ -4097,10 +4100,12 @@ var Fullscreen = /*#__PURE__*/function () {
if (is$1.element(button)) { if (is$1.element(button)) {
button.pressed = this.active; button.pressed = this.active;
} // Trigger an event } // Always trigger events on the plyr / media element (not a fullscreen container) and let them bubble up
triggerEvent.call(this.player, this.target, this.active ? 'enterfullscreen' : 'exitfullscreen', true); var target = this.target === this.player.media ? this.target : this.player.elements.container; // Trigger an event
triggerEvent.call(this.player, target, this.active ? 'enterfullscreen' : 'exitfullscreen', true);
} }
}, { }, {
key: "toggleFallback", key: "toggleFallback",
@@ -4566,7 +4571,7 @@ var ui = {
// Loop through values (as they are the keys when the object is spread 🤔) // Loop through values (as they are the keys when the object is spread 🤔)
Object.values(_objectSpread2({}, this.media.style)) // We're only fussed about Plyr specific properties Object.values(_objectSpread2({}, this.media.style)) // We're only fussed about Plyr specific properties
.filter(function (key) { .filter(function (key) {
return !is$1.empty(key) && key.startsWith('--plyr'); return !is$1.empty(key) && is$1.string(key) && key.startsWith('--plyr');
}).forEach(function (key) { }).forEach(function (key) {
// Set on the container // Set on the container
_this5.elements.container.style.setProperty(key, _this5.media.style.getPropertyValue(key)); // Clean up from media element _this5.elements.container.style.setProperty(key, _this5.media.style.getPropertyValue(key)); // Clean up from media element
@@ -8287,9 +8292,9 @@ var Plyr = /*#__PURE__*/function () {
if (this.isHTML5 && this.config.autoplay) { if (this.isHTML5 && this.config.autoplay) {
setTimeout(function () { this.once('canplay', function () {
return silencePromise(_this.play()); return silencePromise(_this.play());
}, 10); });
} // Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek } // Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek
@@ -8485,7 +8490,7 @@ var Plyr = /*#__PURE__*/function () {
var hiding = toggleClass(this.elements.container, this.config.classNames.hideControls, force); // Close menu var hiding = toggleClass(this.elements.container, this.config.classNames.hideControls, force); // Close menu
if (hiding && this.config.controls.includes('settings') && !is$1.empty(this.config.settings)) { if (hiding && is$1.array(this.config.controls) && this.config.controls.includes('settings') && !is$1.empty(this.config.settings)) {
controls.toggleMenu.call(this, false); controls.toggleMenu.call(this, false);
} // Trigger event on change } // Trigger event on change
@@ -8578,7 +8583,9 @@ var Plyr = /*#__PURE__*/function () {
} }
} else { } else {
// Unbind listeners // Unbind listeners
unbindListeners.call(_this3); // Replace the container with the original element provided unbindListeners.call(_this3); // Cancel current network requests
html5.cancelRequests.call(_this3); // Replace the container with the original element provided
replaceElement(_this3.elements.original, _this3.elements.container); // Event replaceElement(_this3.elements.original, _this3.elements.container); // Event
+28 -17
View File
@@ -1,7 +1,7 @@
typeof navigator === "object" && (function (global, factory) { typeof navigator === "object" && (function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define('Plyr', factory) : typeof define === 'function' && define.amd ? define('Plyr', factory) :
(global = global || self, global.Plyr = factory()); (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Plyr = factory());
}(this, (function () { 'use strict'; }(this, (function () { 'use strict';
// Polyfill for creating CustomEvents on IE9/10/11 // Polyfill for creating CustomEvents on IE9/10/11
@@ -4211,7 +4211,7 @@ typeof navigator === "object" && (function (global, factory) {
if (typeof o === "string") return _arrayLikeToArray(o, minLen); if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1); var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(n); if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
} }
@@ -4408,7 +4408,7 @@ typeof navigator === "object" && (function (global, factory) {
var checkIfURLSearchParamsSupported = function checkIfURLSearchParamsSupported() { var checkIfURLSearchParamsSupported = function checkIfURLSearchParamsSupported() {
try { try {
var URLSearchParams = global.URLSearchParams; var URLSearchParams = global.URLSearchParams;
return new URLSearchParams('?a=1').toString() === 'a=1' && typeof URLSearchParams.prototype.set === 'function'; return new URLSearchParams('?a=1').toString() === 'a=1' && typeof URLSearchParams.prototype.set === 'function' && typeof URLSearchParams.prototype.entries === 'function';
} catch (e) { } catch (e) {
return false; return false;
} }
@@ -4532,7 +4532,11 @@ typeof navigator === "object" && (function (global, factory) {
anchorElement.href = anchorElement.href; // force href to refresh anchorElement.href = anchorElement.href; // force href to refresh
} }
if (anchorElement.protocol === ':' || !/:/.test(anchorElement.href)) { var inputElement = doc.createElement('input');
inputElement.type = 'url';
inputElement.value = url;
if (anchorElement.protocol === ':' || !/:/.test(anchorElement.href) || !inputElement.checkValidity() && !base) {
throw new TypeError('Invalid URL'); throw new TypeError('Invalid URL');
} }
@@ -7320,7 +7324,7 @@ typeof navigator === "object" && (function (global, factory) {
var event = new CustomEvent(type, { var event = new CustomEvent(type, {
bubbles: bubbles, bubbles: bubbles,
detail: _objectSpread2({}, detail, { detail: _objectSpread2(_objectSpread2({}, detail), {}, {
plyr: this plyr: this
}) })
}); // Dispatch the event }); // Dispatch the event
@@ -7433,7 +7437,12 @@ typeof navigator === "object" && (function (global, factory) {
if (this.isVimeo && !this.config.vimeo.premium && this.supported.ui) { if (this.isVimeo && !this.config.vimeo.premium && this.supported.ui) {
var height = 100 / this.media.offsetWidth * parseInt(window.getComputedStyle(this.media).paddingBottom, 10); var height = 100 / this.media.offsetWidth * parseInt(window.getComputedStyle(this.media).paddingBottom, 10);
var offset = (height - padding) / (height / 50); var offset = (height - padding) / (height / 50);
if (this.fullscreen.active) {
wrapper.style.paddingBottom = null;
} else {
this.media.style.transform = "translateY(-".concat(offset, "%)"); this.media.style.transform = "translateY(-".concat(offset, "%)");
}
} else if (this.isHTML5) { } else if (this.isHTML5) {
wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null); wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null);
} }
@@ -8107,7 +8116,7 @@ typeof navigator === "object" && (function (global, factory) {
var attr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var attr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var text = i18n.get(key, this.config); var text = i18n.get(key, this.config);
var attributes = _objectSpread2({}, attr, { var attributes = _objectSpread2(_objectSpread2({}, attr), {}, {
class: [attr.class, this.config.classNames.hidden].filter(Boolean).join(' ') class: [attr.class, this.config.classNames.hidden].filter(Boolean).join(' ')
}); });
@@ -9107,7 +9116,7 @@ typeof navigator === "object" && (function (global, factory) {
showMenuPanel = controls.showMenuPanel; showMenuPanel = controls.showMenuPanel;
this.elements.controls = null; // Larger overlaid play button this.elements.controls = null; // Larger overlaid play button
if (this.config.controls.includes('play-large')) { if (is$1.array(this.config.controls) && this.config.controls.includes('play-large')) {
this.elements.container.appendChild(createButton.call(this, 'play-large')); this.elements.container.appendChild(createButton.call(this, 'play-large'));
} // Create the container } // Create the container
@@ -9119,7 +9128,7 @@ typeof navigator === "object" && (function (global, factory) {
class: 'plyr__controls__item' class: 'plyr__controls__item'
}; // Loop through controls in order }; // Loop through controls in order
dedupe(this.config.controls).forEach(function (control) { dedupe(is$1.array(this.config.controls) ? this.config.controls : []).forEach(function (control) {
// Restart button // Restart button
if (control === 'restart') { if (control === 'restart') {
container.appendChild(createButton.call(_this10, 'restart', defaultAttributes)); container.appendChild(createButton.call(_this10, 'restart', defaultAttributes));
@@ -9438,8 +9447,6 @@ typeof navigator === "object" && (function (global, factory) {
if (update) { if (update) {
if (is$1.string(this.config.controls)) { if (is$1.string(this.config.controls)) {
container = replace(container); container = replace(container);
} else if (is$1.element(container)) {
container.innerHTML = replace(container.innerHTML);
} }
} // Controls container } // Controls container
@@ -10424,10 +10431,12 @@ typeof navigator === "object" && (function (global, factory) {
if (is$1.element(button)) { if (is$1.element(button)) {
button.pressed = this.active; button.pressed = this.active;
} // Trigger an event } // Always trigger events on the plyr / media element (not a fullscreen container) and let them bubble up
triggerEvent.call(this.player, this.target, this.active ? 'enterfullscreen' : 'exitfullscreen', true); var target = this.target === this.player.media ? this.target : this.player.elements.container; // Trigger an event
triggerEvent.call(this.player, target, this.active ? 'enterfullscreen' : 'exitfullscreen', true);
} }
}, { }, {
key: "toggleFallback", key: "toggleFallback",
@@ -10906,7 +10915,7 @@ typeof navigator === "object" && (function (global, factory) {
// Loop through values (as they are the keys when the object is spread 🤔) // Loop through values (as they are the keys when the object is spread 🤔)
Object.values(_objectSpread2({}, this.media.style)) // We're only fussed about Plyr specific properties Object.values(_objectSpread2({}, this.media.style)) // We're only fussed about Plyr specific properties
.filter(function (key) { .filter(function (key) {
return !is$1.empty(key) && key.startsWith('--plyr'); return !is$1.empty(key) && is$1.string(key) && key.startsWith('--plyr');
}).forEach(function (key) { }).forEach(function (key) {
// Set on the container // Set on the container
_this5.elements.container.style.setProperty(key, _this5.media.style.getPropertyValue(key)); // Clean up from media element _this5.elements.container.style.setProperty(key, _this5.media.style.getPropertyValue(key)); // Clean up from media element
@@ -14728,9 +14737,9 @@ typeof navigator === "object" && (function (global, factory) {
if (this.isHTML5 && this.config.autoplay) { if (this.isHTML5 && this.config.autoplay) {
setTimeout(function () { this.once('canplay', function () {
return silencePromise(_this.play()); return silencePromise(_this.play());
}, 10); });
} // Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek } // Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek
@@ -14926,7 +14935,7 @@ typeof navigator === "object" && (function (global, factory) {
var hiding = toggleClass(this.elements.container, this.config.classNames.hideControls, force); // Close menu var hiding = toggleClass(this.elements.container, this.config.classNames.hideControls, force); // Close menu
if (hiding && this.config.controls.includes('settings') && !is$1.empty(this.config.settings)) { if (hiding && is$1.array(this.config.controls) && this.config.controls.includes('settings') && !is$1.empty(this.config.settings)) {
controls.toggleMenu.call(this, false); controls.toggleMenu.call(this, false);
} // Trigger event on change } // Trigger event on change
@@ -15019,7 +15028,9 @@ typeof navigator === "object" && (function (global, factory) {
} }
} else { } else {
// Unbind listeners // Unbind listeners
unbindListeners.call(_this3); // Replace the container with the original element provided unbindListeners.call(_this3); // Cancel current network requests
html5.cancelRequests.call(_this3); // Replace the container with the original element provided
replaceElement(_this3.elements.original, _this3.elements.container); // Event replaceElement(_this3.elements.original, _this3.elements.container); // Event
+2 -2
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+2 -2
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+28 -17
View File
@@ -1,4 +1,4 @@
typeof navigator === "object" && // Polyfill for creating CustomEvents on IE9/10/11 // Polyfill for creating CustomEvents on IE9/10/11
// code pulled from: // code pulled from:
// https://github.com/d4tocchini/customevent-polyfill // https://github.com/d4tocchini/customevent-polyfill
// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent#Polyfill // https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent#Polyfill
@@ -4205,7 +4205,7 @@ function _unsupportedIterableToArray(o, minLen) {
if (typeof o === "string") return _arrayLikeToArray(o, minLen); if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1); var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(n); if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
} }
@@ -4402,7 +4402,7 @@ function _nonIterableRest() {
var checkIfURLSearchParamsSupported = function checkIfURLSearchParamsSupported() { var checkIfURLSearchParamsSupported = function checkIfURLSearchParamsSupported() {
try { try {
var URLSearchParams = global.URLSearchParams; var URLSearchParams = global.URLSearchParams;
return new URLSearchParams('?a=1').toString() === 'a=1' && typeof URLSearchParams.prototype.set === 'function'; return new URLSearchParams('?a=1').toString() === 'a=1' && typeof URLSearchParams.prototype.set === 'function' && typeof URLSearchParams.prototype.entries === 'function';
} catch (e) { } catch (e) {
return false; return false;
} }
@@ -4526,7 +4526,11 @@ function _nonIterableRest() {
anchorElement.href = anchorElement.href; // force href to refresh anchorElement.href = anchorElement.href; // force href to refresh
} }
if (anchorElement.protocol === ':' || !/:/.test(anchorElement.href)) { var inputElement = doc.createElement('input');
inputElement.type = 'url';
inputElement.value = url;
if (anchorElement.protocol === ':' || !/:/.test(anchorElement.href) || !inputElement.checkValidity() && !base) {
throw new TypeError('Invalid URL'); throw new TypeError('Invalid URL');
} }
@@ -7314,7 +7318,7 @@ function triggerEvent(element) {
var event = new CustomEvent(type, { var event = new CustomEvent(type, {
bubbles: bubbles, bubbles: bubbles,
detail: _objectSpread2({}, detail, { detail: _objectSpread2(_objectSpread2({}, detail), {}, {
plyr: this plyr: this
}) })
}); // Dispatch the event }); // Dispatch the event
@@ -7427,7 +7431,12 @@ function setAspectRatio(input) {
if (this.isVimeo && !this.config.vimeo.premium && this.supported.ui) { if (this.isVimeo && !this.config.vimeo.premium && this.supported.ui) {
var height = 100 / this.media.offsetWidth * parseInt(window.getComputedStyle(this.media).paddingBottom, 10); var height = 100 / this.media.offsetWidth * parseInt(window.getComputedStyle(this.media).paddingBottom, 10);
var offset = (height - padding) / (height / 50); var offset = (height - padding) / (height / 50);
if (this.fullscreen.active) {
wrapper.style.paddingBottom = null;
} else {
this.media.style.transform = "translateY(-".concat(offset, "%)"); this.media.style.transform = "translateY(-".concat(offset, "%)");
}
} else if (this.isHTML5) { } else if (this.isHTML5) {
wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null); wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null);
} }
@@ -8101,7 +8110,7 @@ var controls = {
var attr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var attr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var text = i18n.get(key, this.config); var text = i18n.get(key, this.config);
var attributes = _objectSpread2({}, attr, { var attributes = _objectSpread2(_objectSpread2({}, attr), {}, {
class: [attr.class, this.config.classNames.hidden].filter(Boolean).join(' ') class: [attr.class, this.config.classNames.hidden].filter(Boolean).join(' ')
}); });
@@ -9101,7 +9110,7 @@ var controls = {
showMenuPanel = controls.showMenuPanel; showMenuPanel = controls.showMenuPanel;
this.elements.controls = null; // Larger overlaid play button this.elements.controls = null; // Larger overlaid play button
if (this.config.controls.includes('play-large')) { if (is$1.array(this.config.controls) && this.config.controls.includes('play-large')) {
this.elements.container.appendChild(createButton.call(this, 'play-large')); this.elements.container.appendChild(createButton.call(this, 'play-large'));
} // Create the container } // Create the container
@@ -9113,7 +9122,7 @@ var controls = {
class: 'plyr__controls__item' class: 'plyr__controls__item'
}; // Loop through controls in order }; // Loop through controls in order
dedupe(this.config.controls).forEach(function (control) { dedupe(is$1.array(this.config.controls) ? this.config.controls : []).forEach(function (control) {
// Restart button // Restart button
if (control === 'restart') { if (control === 'restart') {
container.appendChild(createButton.call(_this10, 'restart', defaultAttributes)); container.appendChild(createButton.call(_this10, 'restart', defaultAttributes));
@@ -9432,8 +9441,6 @@ var controls = {
if (update) { if (update) {
if (is$1.string(this.config.controls)) { if (is$1.string(this.config.controls)) {
container = replace(container); container = replace(container);
} else if (is$1.element(container)) {
container.innerHTML = replace(container.innerHTML);
} }
} // Controls container } // Controls container
@@ -10418,10 +10425,12 @@ var Fullscreen = /*#__PURE__*/function () {
if (is$1.element(button)) { if (is$1.element(button)) {
button.pressed = this.active; button.pressed = this.active;
} // Trigger an event } // Always trigger events on the plyr / media element (not a fullscreen container) and let them bubble up
triggerEvent.call(this.player, this.target, this.active ? 'enterfullscreen' : 'exitfullscreen', true); var target = this.target === this.player.media ? this.target : this.player.elements.container; // Trigger an event
triggerEvent.call(this.player, target, this.active ? 'enterfullscreen' : 'exitfullscreen', true);
} }
}, { }, {
key: "toggleFallback", key: "toggleFallback",
@@ -10900,7 +10909,7 @@ var ui = {
// Loop through values (as they are the keys when the object is spread 🤔) // Loop through values (as they are the keys when the object is spread 🤔)
Object.values(_objectSpread2({}, this.media.style)) // We're only fussed about Plyr specific properties Object.values(_objectSpread2({}, this.media.style)) // We're only fussed about Plyr specific properties
.filter(function (key) { .filter(function (key) {
return !is$1.empty(key) && key.startsWith('--plyr'); return !is$1.empty(key) && is$1.string(key) && key.startsWith('--plyr');
}).forEach(function (key) { }).forEach(function (key) {
// Set on the container // Set on the container
_this5.elements.container.style.setProperty(key, _this5.media.style.getPropertyValue(key)); // Clean up from media element _this5.elements.container.style.setProperty(key, _this5.media.style.getPropertyValue(key)); // Clean up from media element
@@ -14722,9 +14731,9 @@ var Plyr = /*#__PURE__*/function () {
if (this.isHTML5 && this.config.autoplay) { if (this.isHTML5 && this.config.autoplay) {
setTimeout(function () { this.once('canplay', function () {
return silencePromise(_this.play()); return silencePromise(_this.play());
}, 10); });
} // Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek } // Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek
@@ -14920,7 +14929,7 @@ var Plyr = /*#__PURE__*/function () {
var hiding = toggleClass(this.elements.container, this.config.classNames.hideControls, force); // Close menu var hiding = toggleClass(this.elements.container, this.config.classNames.hideControls, force); // Close menu
if (hiding && this.config.controls.includes('settings') && !is$1.empty(this.config.settings)) { if (hiding && is$1.array(this.config.controls) && this.config.controls.includes('settings') && !is$1.empty(this.config.settings)) {
controls.toggleMenu.call(this, false); controls.toggleMenu.call(this, false);
} // Trigger event on change } // Trigger event on change
@@ -15013,7 +15022,9 @@ var Plyr = /*#__PURE__*/function () {
} }
} else { } else {
// Unbind listeners // Unbind listeners
unbindListeners.call(_this3); // Replace the container with the original element provided unbindListeners.call(_this3); // Cancel current network requests
html5.cancelRequests.call(_this3); // Replace the container with the original element provided
replaceElement(_this3.elements.original, _this3.elements.container); // Event replaceElement(_this3.elements.original, _this3.elements.container); // Event
+20 -23
View File
@@ -35,27 +35,25 @@
"lint:fix": "eslint --fix src/js", "lint:fix": "eslint --fix src/js",
"remark": "remark -f --use 'validate-links=repository:\"sampotts/plyr\"' '{,!(node_modules),.?**/}*.md'", "remark": "remark -f --use 'validate-links=repository:\"sampotts/plyr\"' '{,!(node_modules),.?**/}*.md'",
"deploy": "yarn lint && gulp version && gulp build && gulp deploy", "deploy": "yarn lint && gulp version && gulp build && gulp deploy",
"format": "prettier --write \"./{src,demo/src}/**/*.{js,scss}\"" "format": "prettier --write \"./{src,demo/src}/**/*.{js,scss}\"",
"start": "gulp"
}, },
"devDependencies": { "devDependencies": {
"@sampotts/eslint-config": "1.0.0",
"ansi-colors": "^4.1.1", "ansi-colors": "^4.1.1",
"autoprefixer": "^9.7.6", "autoprefixer": "^9.8.6",
"aws-sdk": "^2.668.0", "aws-sdk": "^2.742.0",
"@babel/core": "^7.9.6", "@babel/core": "^7.11.4",
"@babel/preset-env": "^7.9.6", "@babel/preset-env": "^7.11.0",
"babel-eslint": "^10.1.0", "babel-eslint": "^10.1.0",
"browser-sync": "^2.26.7", "browser-sync": "^2.26.12",
"del": "^5.1.0", "del": "^5.1.0",
"eslint": "^6.8.0", "eslint": "^7.7.0",
"eslint-config-airbnb-base": "^14.1.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-simple-import-sort": "^5.0.3",
"fancy-log": "^1.3.3", "fancy-log": "^1.3.3",
"fastly-purge": "^1.0.1", "fastly-purge": "^1.0.1",
"git-branch": "^2.0.1", "git-branch": "^2.0.1",
"gulp": "^4.0.2", "gulp": "^4.0.2",
"gulp-awspublish": "^4.1.1", "gulp-awspublish": "^4.1.2",
"gulp-better-rollup": "^4.0.1", "gulp-better-rollup": "^4.0.1",
"gulp-filter": "^6.0.0", "gulp-filter": "^6.0.0",
"gulp-header": "^2.0.9", "gulp-header": "^2.0.9",
@@ -71,31 +69,30 @@
"gulp-size": "^3.0.0", "gulp-size": "^3.0.0",
"gulp-sourcemaps": "^2.6.5", "gulp-sourcemaps": "^2.6.5",
"gulp-svgstore": "^7.0.1", "gulp-svgstore": "^7.0.1",
"gulp-terser": "^1.2.0", "gulp-terser": "^1.4.0",
"postcss-clean": "^1.1.0", "postcss-clean": "^1.1.0",
"postcss-custom-properties": "^9.1.1", "postcss-custom-properties": "^9.1.1",
"prettier-eslint": "^9.0.1",
"prettier-stylelint": "^0.4.2", "prettier-stylelint": "^0.4.2",
"remark-cli": "^8.0.0", "remark-cli": "^8.0.1",
"remark-validate-links": "^10.0.0", "remark-validate-links": "^10.0.2",
"rollup": "^2.7.6", "rollup": "^2.26.8",
"rollup-plugin-babel": "^4.4.0", "rollup-plugin-babel": "^4.4.0",
"rollup-plugin-commonjs": "^10.1.0", "rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0", "rollup-plugin-node-resolve": "^5.2.0",
"stylelint": "^13.3.3", "stylelint": "^13.6.1",
"stylelint-config-prettier": "^8.0.1", "stylelint-config-prettier": "^8.0.2",
"stylelint-config-recommended": "^3.0.0", "stylelint-config-recommended": "^3.0.0",
"stylelint-config-sass-guidelines": "^7.0.0", "stylelint-config-sass-guidelines": "^7.0.0",
"stylelint-order": "^4.0.0", "stylelint-order": "^4.1.0",
"stylelint-scss": "^3.17.1", "stylelint-scss": "^3.18.0",
"stylelint-selector-bem-pattern": "^2.1.0", "stylelint-selector-bem-pattern": "^2.1.0",
"through2": "^3.0.1" "through2": "^4.0.2"
}, },
"dependencies": { "dependencies": {
"core-js": "^3.6.5", "core-js": "^3.6.5",
"custom-event-polyfill": "^1.0.7", "custom-event-polyfill": "^1.0.7",
"loadjs": "^4.2.0", "loadjs": "^4.2.0",
"rangetouch": "^2.0.1", "rangetouch": "^2.0.1",
"url-polyfill": "^1.1.8" "url-polyfill": "^1.1.10"
} }
} }
+13 -13
View File
@@ -56,7 +56,7 @@ const captions = {
if (browser.isIE && window.URL) { if (browser.isIE && window.URL) {
const elements = this.media.querySelectorAll('track'); const elements = this.media.querySelectorAll('track');
Array.from(elements).forEach(track => { Array.from(elements).forEach((track) => {
const src = track.getAttribute('src'); const src = track.getAttribute('src');
const url = parseUrl(src); const url = parseUrl(src);
@@ -66,7 +66,7 @@ const captions = {
['http:', 'https:'].includes(url.protocol) ['http:', 'https:'].includes(url.protocol)
) { ) {
fetch(src, 'blob') fetch(src, 'blob')
.then(blob => { .then((blob) => {
track.setAttribute('src', window.URL.createObjectURL(blob)); track.setAttribute('src', window.URL.createObjectURL(blob));
}) })
.catch(() => { .catch(() => {
@@ -84,7 +84,7 @@ const captions = {
// * toggled: The real captions state // * toggled: The real captions state
const browserLanguages = navigator.languages || [navigator.language || navigator.userLanguage || 'en']; const browserLanguages = navigator.languages || [navigator.language || navigator.userLanguage || 'en'];
const languages = dedupe(browserLanguages.map(language => language.split('-')[0])); const languages = dedupe(browserLanguages.map((language) => language.split('-')[0]));
let language = (this.storage.get('language') || this.config.captions.language || 'auto').toLowerCase(); let language = (this.storage.get('language') || this.config.captions.language || 'auto').toLowerCase();
// Use first browser language when language is 'auto' // Use first browser language when language is 'auto'
@@ -119,13 +119,13 @@ const captions = {
const tracks = captions.getTracks.call(this, true); const tracks = captions.getTracks.call(this, true);
// Get the wanted language // Get the wanted language
const { active, language, meta, currentTrackNode } = this.captions; const { active, language, meta, currentTrackNode } = this.captions;
const languageExists = Boolean(tracks.find(track => track.language === language)); const languageExists = Boolean(tracks.find((track) => track.language === language));
// Handle tracks (add event listener and "pseudo"-default) // Handle tracks (add event listener and "pseudo"-default)
if (this.isHTML5 && this.isVideo) { if (this.isHTML5 && this.isVideo) {
tracks tracks
.filter(track => !meta.get(track)) .filter((track) => !meta.get(track))
.forEach(track => { .forEach((track) => {
this.debug.log('Track added', track); this.debug.log('Track added', track);
// Attempt to store if the original dom element was "default" // Attempt to store if the original dom element was "default"
@@ -309,19 +309,19 @@ const captions = {
// For HTML5, use cache instead of current tracks when it exists (if captions.update is false) // For HTML5, use cache instead of current tracks when it exists (if captions.update is false)
// Filter out removed tracks and tracks that aren't captions/subtitles (for example metadata) // Filter out removed tracks and tracks that aren't captions/subtitles (for example metadata)
return tracks return tracks
.filter(track => !this.isHTML5 || update || this.captions.meta.has(track)) .filter((track) => !this.isHTML5 || update || this.captions.meta.has(track))
.filter(track => ['captions', 'subtitles'].includes(track.kind)); .filter((track) => ['captions', 'subtitles'].includes(track.kind));
}, },
// Match tracks based on languages and get the first // Match tracks based on languages and get the first
findTrack(languages, force = false) { findTrack(languages, force = false) {
const tracks = captions.getTracks.call(this); const tracks = captions.getTracks.call(this);
const sortIsDefault = track => Number((this.captions.meta.get(track) || {}).default); const sortIsDefault = (track) => Number((this.captions.meta.get(track) || {}).default);
const sorted = Array.from(tracks).sort((a, b) => sortIsDefault(b) - sortIsDefault(a)); const sorted = Array.from(tracks).sort((a, b) => sortIsDefault(b) - sortIsDefault(a));
let track; let track;
languages.every(language => { languages.every((language) => {
track = sorted.find(t => t.language === language); track = sorted.find((t) => t.language === language);
return !track; // Break iteration if there is a match return !track; // Break iteration if there is a match
}); });
@@ -383,12 +383,12 @@ const captions = {
const track = captions.getCurrentTrack.call(this); const track = captions.getCurrentTrack.call(this);
cues = Array.from((track || {}).activeCues || []) cues = Array.from((track || {}).activeCues || [])
.map(cue => cue.getCueAsHTML()) .map((cue) => cue.getCueAsHTML())
.map(getHTML); .map(getHTML);
} }
// Set new caption text // Set new caption text
const content = cues.map(cueText => cueText.trim()).join('\n'); const content = cues.map((cueText) => cueText.trim()).join('\n');
const changed = content !== this.elements.captions.innerHTML; const changed = content !== this.elements.captions.innerHTML;
if (changed) { if (changed) {
+25 -27
View File
@@ -179,7 +179,7 @@ const controls = {
iconPressed: null, iconPressed: null,
}; };
['element', 'icon', 'label'].forEach(key => { ['element', 'icon', 'label'].forEach((key) => {
if (Object.keys(attributes).includes(key)) { if (Object.keys(attributes).includes(key)) {
props[key] = attributes[key]; props[key] = attributes[key];
delete attributes[key]; delete attributes[key];
@@ -193,7 +193,7 @@ const controls = {
// Set class name // Set class name
if (Object.keys(attributes).includes('class')) { if (Object.keys(attributes).includes('class')) {
if (!attributes.class.split(' ').some(c => c === this.config.classNames.control)) { if (!attributes.class.split(' ').some((c) => c === this.config.classNames.control)) {
extend(attributes, { extend(attributes, {
class: `${attributes.class} ${this.config.classNames.control}`, class: `${attributes.class} ${this.config.classNames.control}`,
}); });
@@ -401,7 +401,7 @@ const controls = {
this, this,
menuItem, menuItem,
'keydown keyup', 'keydown keyup',
event => { (event) => {
// We only care about space and ⬆️ ⬇️ ➡️ // We only care about space and ⬆️ ⬇️ ➡️
if (![32, 38, 39, 40].includes(event.which)) { if (![32, 38, 39, 40].includes(event.which)) {
return; return;
@@ -448,7 +448,7 @@ const controls = {
// Enter will fire a `click` event but we still need to manage focus // Enter will fire a `click` event but we still need to manage focus
// So we bind to keyup which fires after and set focus here // So we bind to keyup which fires after and set focus here
on.call(this, menuItem, 'keyup', event => { on.call(this, menuItem, 'keyup', (event) => {
if (event.which !== 13) { if (event.which !== 13) {
return; return;
} }
@@ -493,8 +493,8 @@ const controls = {
// Ensure exclusivity // Ensure exclusivity
if (check) { if (check) {
Array.from(menuItem.parentNode.children) Array.from(menuItem.parentNode.children)
.filter(node => matches(node, '[role="menuitemradio"]')) .filter((node) => matches(node, '[role="menuitemradio"]'))
.forEach(node => node.setAttribute('aria-checked', 'false')); .forEach((node) => node.setAttribute('aria-checked', 'false'));
} }
menuItem.setAttribute('aria-checked', check ? 'true' : 'false'); menuItem.setAttribute('aria-checked', check ? 'true' : 'false');
@@ -504,7 +504,7 @@ const controls = {
this.listeners.bind( this.listeners.bind(
menuItem, menuItem,
'click keyup', 'click keyup',
event => { (event) => {
if (is.keyboardEvent(event) && event.which !== 32) { if (is.keyboardEvent(event) && event.which !== 32) {
return; return;
} }
@@ -698,7 +698,7 @@ const controls = {
} }
const visible = `${this.config.classNames.tooltip}--visible`; const visible = `${this.config.classNames.tooltip}--visible`;
const toggle = show => toggleClass(this.elements.display.seekTooltip, visible, show); const toggle = (show) => toggleClass(this.elements.display.seekTooltip, visible, show);
// Hide on touch // Hide on touch
if (this.touch) { if (this.touch) {
@@ -894,7 +894,7 @@ const controls = {
// Set options if passed and filter based on uniqueness and config // Set options if passed and filter based on uniqueness and config
if (is.array(options)) { if (is.array(options)) {
this.options.quality = dedupe(options).filter(quality => this.config.quality.options.includes(quality)); this.options.quality = dedupe(options).filter((quality) => this.config.quality.options.includes(quality));
} }
// Toggle the pane and tab // Toggle the pane and tab
@@ -913,7 +913,7 @@ const controls = {
} }
// Get the badge HTML for HD, 4K etc // Get the badge HTML for HD, 4K etc
const getBadge = quality => { const getBadge = (quality) => {
const label = i18n.get(`qualityBadge.${quality}`, this.config); const label = i18n.get(`qualityBadge.${quality}`, this.config);
if (!label.length) { if (!label.length) {
@@ -929,7 +929,7 @@ const controls = {
const sorting = this.config.quality.options; const sorting = this.config.quality.options;
return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1; return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1;
}) })
.forEach(quality => { .forEach((quality) => {
controls.createMenuItem.call(this, { controls.createMenuItem.call(this, {
value: quality, value: quality,
list, list,
@@ -1052,7 +1052,7 @@ const controls = {
const list = this.elements.settings.panels.speed.querySelector('[role="menu"]'); const list = this.elements.settings.panels.speed.querySelector('[role="menu"]');
// Filter out invalid speeds // Filter out invalid speeds
this.options.speed = this.options.speed.filter(o => o >= this.minimumSpeed && o <= this.maximumSpeed); this.options.speed = this.options.speed.filter((o) => o >= this.minimumSpeed && o <= this.maximumSpeed);
// Toggle the pane and tab // Toggle the pane and tab
const toggle = !is.empty(this.options.speed) && this.options.speed.length > 1; const toggle = !is.empty(this.options.speed) && this.options.speed.length > 1;
@@ -1070,7 +1070,7 @@ const controls = {
} }
// Create items // Create items
this.options.speed.forEach(speed => { this.options.speed.forEach((speed) => {
controls.createMenuItem.call(this, { controls.createMenuItem.call(this, {
value: speed, value: speed,
list, list,
@@ -1085,7 +1085,7 @@ const controls = {
// Check if we need to hide/show the settings menu // Check if we need to hide/show the settings menu
checkMenu() { checkMenu() {
const { buttons } = this.elements.settings; const { buttons } = this.elements.settings;
const visible = !is.empty(buttons) && Object.values(buttons).some(button => !button.hidden); const visible = !is.empty(buttons) && Object.values(buttons).some((button) => !button.hidden);
toggleHidden(this.elements.settings.menu, !visible); toggleHidden(this.elements.settings.menu, !visible);
}, },
@@ -1099,7 +1099,7 @@ const controls = {
let target = pane; let target = pane;
if (!is.element(target)) { if (!is.element(target)) {
target = Object.values(this.elements.settings.panels).find(p => !p.hidden); target = Object.values(this.elements.settings.panels).find((p) => !p.hidden);
} }
const firstItem = target.querySelector('[role^="menuitem"]'); const firstItem = target.querySelector('[role^="menuitem"]');
@@ -1191,7 +1191,7 @@ const controls = {
// Hide all other panels // Hide all other panels
const container = target.parentNode; const container = target.parentNode;
const current = Array.from(container.children).find(node => !node.hidden); const current = Array.from(container.children).find((node) => !node.hidden);
// If we can do fancy animations, we'll animate the height/width // If we can do fancy animations, we'll animate the height/width
if (support.transitions && !support.reducedMotion) { if (support.transitions && !support.reducedMotion) {
@@ -1203,7 +1203,7 @@ const controls = {
const size = controls.getMenuSize.call(this, target); const size = controls.getMenuSize.call(this, target);
// Restore auto height/width // Restore auto height/width
const restore = event => { const restore = (event) => {
// We're only bothered about height and width on the container // We're only bothered about height and width on the container
if (event.target !== container || !['width', 'height'].includes(event.propertyName)) { if (event.target !== container || !['width', 'height'].includes(event.propertyName)) {
return; return;
@@ -1275,7 +1275,7 @@ const controls = {
const defaultAttributes = { class: 'plyr__controls__item' }; const defaultAttributes = { class: 'plyr__controls__item' };
// Loop through controls in order // Loop through controls in order
dedupe(is.array(this.config.controls) ? this.config.controls: []).forEach(control => { dedupe(is.array(this.config.controls) ? this.config.controls : []).forEach((control) => {
// Restart button // Restart button
if (control === 'restart') { if (control === 'restart') {
container.appendChild(createButton.call(this, 'restart', defaultAttributes)); container.appendChild(createButton.call(this, 'restart', defaultAttributes));
@@ -1437,7 +1437,7 @@ const controls = {
this.elements.settings.panels.home = home; this.elements.settings.panels.home = home;
// Build the menu items // Build the menu items
this.config.settings.forEach(type => { this.config.settings.forEach((type) => {
// TODO: bundle this with the createMenuItem helper and bindings // TODO: bundle this with the createMenuItem helper and bindings
const menuItem = createElement( const menuItem = createElement(
'button', 'button',
@@ -1510,7 +1510,7 @@ const controls = {
this, this,
pane, pane,
'keydown', 'keydown',
event => { (event) => {
// We only care about <- // We only care about <-
if (event.which !== 37) { if (event.which !== 37) {
return; return;
@@ -1661,7 +1661,7 @@ const controls = {
} }
// Replace props with their value // Replace props with their value
const replace = input => { const replace = (input) => {
let result = input; let result = input;
Object.entries(props).forEach(([key, value]) => { Object.entries(props).forEach(([key, value]) => {
@@ -1702,7 +1702,7 @@ const controls = {
// Add pressed property to buttons // Add pressed property to buttons
if (!is.empty(this.elements.buttons)) { if (!is.empty(this.elements.buttons)) {
const addProperty = button => { const addProperty = (button) => {
const className = this.config.classNames.controlPressed; const className = this.config.classNames.controlPressed;
Object.defineProperty(button, 'pressed', { Object.defineProperty(button, 'pressed', {
enumerable: true, enumerable: true,
@@ -1718,11 +1718,9 @@ const controls = {
// Toggle classname when pressed property is set // Toggle classname when pressed property is set
Object.values(this.elements.buttons) Object.values(this.elements.buttons)
.filter(Boolean) .filter(Boolean)
.forEach(button => { .forEach((button) => {
if (is.array(button) || is.nodeList(button)) { if (is.array(button) || is.nodeList(button)) {
Array.from(button) Array.from(button).filter(Boolean).forEach(addProperty);
.filter(Boolean)
.forEach(addProperty);
} else { } else {
addProperty(button); addProperty(button);
} }
@@ -1740,7 +1738,7 @@ const controls = {
const selector = `${selectors.controls.wrapper} ${selectors.labels} .${classNames.hidden}`; const selector = `${selectors.controls.wrapper} ${selectors.labels} .${classNames.hidden}`;
const labels = getElements.call(this, selector); const labels = getElements.call(this, selector);
Array.from(labels).forEach(label => { Array.from(labels).forEach((label) => {
toggleClass(label, this.config.classNames.hidden, false); toggleClass(label, this.config.classNames.hidden, false);
toggleClass(label, this.config.classNames.tooltip, true); toggleClass(label, this.config.classNames.tooltip, true);
}); });
+5 -5
View File
@@ -5,7 +5,7 @@
// ========================================================================== // ==========================================================================
import browser from './utils/browser'; import browser from './utils/browser';
import { closest,getElements, hasClass, toggleClass } from './utils/elements'; import { closest, getElements, hasClass, toggleClass } from './utils/elements';
import { on, triggerEvent } from './utils/events'; import { on, triggerEvent } from './utils/events';
import is from './utils/is'; import is from './utils/is';
import { silencePromise } from './utils/promise'; import { silencePromise } from './utils/promise';
@@ -43,7 +43,7 @@ class Fullscreen {
); );
// Fullscreen toggle on double click // Fullscreen toggle on double click
on.call(this.player, this.player.elements.container, 'dblclick', event => { on.call(this.player, this.player.elements.container, 'dblclick', (event) => {
// Ignore double click in controls // Ignore double click in controls
if (is.element(this.player.elements.controls) && this.player.elements.controls.contains(event.target)) { if (is.element(this.player.elements.controls) && this.player.elements.controls.contains(event.target)) {
return; return;
@@ -53,7 +53,7 @@ class Fullscreen {
}); });
// Tap focus when in fullscreen // Tap focus when in fullscreen
on.call(this, this.player.elements.container, 'keydown', event => this.trapFocus(event)); on.call(this, this.player.elements.container, 'keydown', (event) => this.trapFocus(event));
// Update the UI // Update the UI
this.update(); this.update();
@@ -85,7 +85,7 @@ class Fullscreen {
let value = ''; let value = '';
const prefixes = ['webkit', 'moz', 'ms']; const prefixes = ['webkit', 'moz', 'ms'];
prefixes.some(pre => { prefixes.some((pre) => {
if (is.function(document[`${pre}ExitFullscreen`]) || is.function(document[`${pre}CancelFullScreen`])) { if (is.function(document[`${pre}ExitFullscreen`]) || is.function(document[`${pre}CancelFullScreen`])) {
value = pre; value = pre;
return true; return true;
@@ -191,7 +191,7 @@ class Fullscreen {
} else if (this.cleanupViewport) { } else if (this.cleanupViewport) {
viewport.content = viewport.content viewport.content = viewport.content
.split(',') .split(',')
.filter(part => part.trim() !== property) .filter((part) => part.trim() !== property)
.join(','); .join(',');
} }
} }
+4 -4
View File
@@ -18,7 +18,7 @@ const html5 = {
const sources = Array.from(this.media.querySelectorAll('source')); const sources = Array.from(this.media.querySelectorAll('source'));
// Filter out unsupported sources (if type is specified) // Filter out unsupported sources (if type is specified)
return sources.filter(source => { return sources.filter((source) => {
const type = source.getAttribute('type'); const type = source.getAttribute('type');
if (is.empty(type)) { if (is.empty(type)) {
@@ -39,7 +39,7 @@ const html5 = {
// Get sizes from <source> elements // Get sizes from <source> elements
return html5.getSources return html5.getSources
.call(this) .call(this)
.map(source => Number(source.getAttribute('size'))) .map((source) => Number(source.getAttribute('size')))
.filter(Boolean); .filter(Boolean);
}, },
@@ -63,7 +63,7 @@ const html5 = {
get() { get() {
// Get sources // Get sources
const sources = html5.getSources.call(player); const sources = html5.getSources.call(player);
const source = sources.find(s => s.getAttribute('src') === player.source); const source = sources.find((s) => s.getAttribute('src') === player.source);
// Return size, if match is found // Return size, if match is found
return source && Number(source.getAttribute('size')); return source && Number(source.getAttribute('size'));
@@ -80,7 +80,7 @@ const html5 = {
// Get sources // Get sources
const sources = html5.getSources.call(player); const sources = html5.getSources.call(player);
// Get first match for requested size // Get first match for requested size
const source = sources.find(s => Number(s.getAttribute('size')) === input); const source = sources.find((s) => Number(s.getAttribute('size')) === input);
// No matching source found // No matching source found
if (!source) { if (!source) {
+36 -36
View File
@@ -277,7 +277,7 @@ class Listeners {
player, player,
elements.container, elements.container,
'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen', 'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen',
event => { (event) => {
const { controls: controlsElement } = elements; const { controls: controlsElement } = elements;
// Remove button states for fullscreen // Remove button states for fullscreen
@@ -319,7 +319,7 @@ class Listeners {
}; };
// Resize on fullscreen change // Resize on fullscreen change
const setPlayerSize = measure => { const setPlayerSize = (measure) => {
// If we don't need to measure the viewport // If we don't need to measure the viewport
if (!measure) { if (!measure) {
return setAspectRatio.call(player); return setAspectRatio.call(player);
@@ -336,7 +336,7 @@ class Listeners {
timers.resized = setTimeout(setPlayerSize, 50); timers.resized = setTimeout(setPlayerSize, 50);
}; };
on.call(player, elements.container, 'enterfullscreen exitfullscreen', event => { on.call(player, elements.container, 'enterfullscreen exitfullscreen', (event) => {
const { target, usingNative } = player.fullscreen; const { target, usingNative } = player.fullscreen;
// Ignore events not from target // Ignore events not from target
@@ -373,10 +373,10 @@ class Listeners {
const { elements } = player; const { elements } = player;
// Time change on media // Time change on media
on.call(player, player.media, 'timeupdate seeking seeked', event => controls.timeUpdate.call(player, event)); on.call(player, player.media, 'timeupdate seeking seeked', (event) => controls.timeUpdate.call(player, event));
// Display duration // Display duration
on.call(player, player.media, 'durationchange loadeddata loadedmetadata', event => on.call(player, player.media, 'durationchange loadeddata loadedmetadata', (event) =>
controls.durationUpdate.call(player, event), controls.durationUpdate.call(player, event),
); );
@@ -393,20 +393,20 @@ class Listeners {
}); });
// Check for buffer progress // Check for buffer progress
on.call(player, player.media, 'progress playing seeking seeked', event => on.call(player, player.media, 'progress playing seeking seeked', (event) =>
controls.updateProgress.call(player, event), controls.updateProgress.call(player, event),
); );
// Handle volume changes // Handle volume changes
on.call(player, player.media, 'volumechange', event => controls.updateVolume.call(player, event)); on.call(player, player.media, 'volumechange', (event) => controls.updateVolume.call(player, event));
// Handle play/pause // Handle play/pause
on.call(player, player.media, 'playing play pause ended emptied timeupdate', event => on.call(player, player.media, 'playing play pause ended emptied timeupdate', (event) =>
ui.checkPlaying.call(player, event), ui.checkPlaying.call(player, event),
); );
// Loading state // Loading state
on.call(player, player.media, 'waiting canplay seeked playing', event => ui.checkLoading.call(player, event)); on.call(player, player.media, 'waiting canplay seeked playing', (event) => ui.checkLoading.call(player, event));
// Click video // Click video
if (player.supported.ui && player.config.clickToPlay && !player.isAudio) { if (player.supported.ui && player.config.clickToPlay && !player.isAudio) {
@@ -419,7 +419,7 @@ class Listeners {
} }
// On click play, pause or restart // On click play, pause or restart
on.call(player, elements.container, 'click', event => { on.call(player, elements.container, 'click', (event) => {
const targets = [elements.container, wrapper]; const targets = [elements.container, wrapper];
// Ignore if click if not container or in video wrapper // Ignore if click if not container or in video wrapper
@@ -459,7 +459,7 @@ class Listeners {
player, player,
elements.wrapper, elements.wrapper,
'contextmenu', 'contextmenu',
event => { (event) => {
event.preventDefault(); event.preventDefault();
}, },
false, false,
@@ -485,7 +485,7 @@ class Listeners {
}); });
// Quality change // Quality change
on.call(player, player.media, 'qualitychange', event => { on.call(player, player.media, 'qualitychange', (event) => {
// Update UI // Update UI
controls.updateSetting.call(player, 'quality', null, event.detail.quality); controls.updateSetting.call(player, 'quality', null, event.detail.quality);
}); });
@@ -499,7 +499,7 @@ class Listeners {
// Bubble up key events for Edge // Bubble up key events for Edge
const proxyEvents = player.config.events.concat(['keyup', 'keydown']).join(' '); const proxyEvents = player.config.events.concat(['keyup', 'keydown']).join(' ');
on.call(player, player.media, proxyEvents, event => { on.call(player, player.media, proxyEvents, (event) => {
let { detail = {} } = event; let { detail = {} } = event;
// Get error details from media // Get error details from media
@@ -539,7 +539,7 @@ class Listeners {
player, player,
element, element,
type, type,
event => this.proxy(event, defaultHandler, customHandlerKey), (event) => this.proxy(event, defaultHandler, customHandlerKey),
passive && !hasCustomHandler, passive && !hasCustomHandler,
); );
} }
@@ -553,7 +553,7 @@ class Listeners {
// Play/pause toggle // Play/pause toggle
if (elements.buttons.play) { if (elements.buttons.play) {
Array.from(elements.buttons.play).forEach(button => { Array.from(elements.buttons.play).forEach((button) => {
this.bind( this.bind(
button, button,
'click', 'click',
@@ -624,7 +624,7 @@ class Listeners {
this.bind( this.bind(
elements.buttons.settings, elements.buttons.settings,
'click', 'click',
event => { (event) => {
// Prevent the document click listener closing the menu // Prevent the document click listener closing the menu
event.stopPropagation(); event.stopPropagation();
event.preventDefault(); event.preventDefault();
@@ -641,7 +641,7 @@ class Listeners {
this.bind( this.bind(
elements.buttons.settings, elements.buttons.settings,
'keyup', 'keyup',
event => { (event) => {
const code = event.which; const code = event.which;
// We only care about space and return // We only care about space and return
@@ -669,21 +669,21 @@ class Listeners {
); );
// Escape closes menu // Escape closes menu
this.bind(elements.settings.menu, 'keydown', event => { this.bind(elements.settings.menu, 'keydown', (event) => {
if (event.which === 27) { if (event.which === 27) {
controls.toggleMenu.call(player, event); controls.toggleMenu.call(player, event);
} }
}); });
// Set range input alternative "value", which matches the tooltip time (#954) // Set range input alternative "value", which matches the tooltip time (#954)
this.bind(elements.inputs.seek, 'mousedown mousemove', event => { this.bind(elements.inputs.seek, 'mousedown mousemove', (event) => {
const rect = elements.progress.getBoundingClientRect(); const rect = elements.progress.getBoundingClientRect();
const percent = (100 / rect.width) * (event.pageX - rect.left); const percent = (100 / rect.width) * (event.pageX - rect.left);
event.currentTarget.setAttribute('seek-value', percent); event.currentTarget.setAttribute('seek-value', percent);
}); });
// Pause while seeking // Pause while seeking
this.bind(elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', event => { this.bind(elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', (event) => {
const seek = event.currentTarget; const seek = event.currentTarget;
const code = event.keyCode ? event.keyCode : event.which; const code = event.keyCode ? event.keyCode : event.which;
const attribute = 'play-on-seeked'; const attribute = 'play-on-seeked';
@@ -715,14 +715,14 @@ class Listeners {
// it takes over further interactions on the page. This is a hack // it takes over further interactions on the page. This is a hack
if (browser.isIos) { if (browser.isIos) {
const inputs = getElements.call(player, 'input[type="range"]'); const inputs = getElements.call(player, 'input[type="range"]');
Array.from(inputs).forEach(input => this.bind(input, inputEvent, event => repaint(event.target))); Array.from(inputs).forEach((input) => this.bind(input, inputEvent, (event) => repaint(event.target)));
} }
// Seek // Seek
this.bind( this.bind(
elements.inputs.seek, elements.inputs.seek,
inputEvent, inputEvent,
event => { (event) => {
const seek = event.currentTarget; const seek = event.currentTarget;
// If it exists, use seek-value instead of "value" for consistency with tooltip time (#954) // If it exists, use seek-value instead of "value" for consistency with tooltip time (#954)
let seekTo = seek.getAttribute('seek-value'); let seekTo = seek.getAttribute('seek-value');
@@ -739,13 +739,13 @@ class Listeners {
); );
// Seek tooltip // Seek tooltip
this.bind(elements.progress, 'mouseenter mouseleave mousemove', event => this.bind(elements.progress, 'mouseenter mouseleave mousemove', (event) =>
controls.updateSeekTooltip.call(player, event), controls.updateSeekTooltip.call(player, event),
); );
// Preview thumbnails plugin // Preview thumbnails plugin
// TODO: Really need to work on some sort of plug-in wide event bus or pub-sub for this // TODO: Really need to work on some sort of plug-in wide event bus or pub-sub for this
this.bind(elements.progress, 'mousemove touchmove', event => { this.bind(elements.progress, 'mousemove touchmove', (event) => {
const { previewThumbnails } = player; const { previewThumbnails } = player;
if (previewThumbnails && previewThumbnails.loaded) { if (previewThumbnails && previewThumbnails.loaded) {
@@ -763,7 +763,7 @@ class Listeners {
}); });
// Show scrubbing preview // Show scrubbing preview
this.bind(elements.progress, 'mousedown touchstart', event => { this.bind(elements.progress, 'mousedown touchstart', (event) => {
const { previewThumbnails } = player; const { previewThumbnails } = player;
if (previewThumbnails && previewThumbnails.loaded) { if (previewThumbnails && previewThumbnails.loaded) {
@@ -771,7 +771,7 @@ class Listeners {
} }
}); });
this.bind(elements.progress, 'mouseup touchend', event => { this.bind(elements.progress, 'mouseup touchend', (event) => {
const { previewThumbnails } = player; const { previewThumbnails } = player;
if (previewThumbnails && previewThumbnails.loaded) { if (previewThumbnails && previewThumbnails.loaded) {
@@ -781,8 +781,8 @@ class Listeners {
// Polyfill for lower fill in <input type="range"> for webkit // Polyfill for lower fill in <input type="range"> for webkit
if (browser.isWebkit) { if (browser.isWebkit) {
Array.from(getElements.call(player, 'input[type="range"]')).forEach(element => { Array.from(getElements.call(player, 'input[type="range"]')).forEach((element) => {
this.bind(element, 'input', event => controls.updateRangeFill.call(player, event.target)); this.bind(element, 'input', (event) => controls.updateRangeFill.call(player, event.target));
}); });
} }
@@ -805,30 +805,30 @@ class Listeners {
this.bind( this.bind(
elements.inputs.volume, elements.inputs.volume,
inputEvent, inputEvent,
event => { (event) => {
player.volume = event.target.value; player.volume = event.target.value;
}, },
'volume', 'volume',
); );
// Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting) // Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting)
this.bind(elements.controls, 'mouseenter mouseleave', event => { this.bind(elements.controls, 'mouseenter mouseleave', (event) => {
elements.controls.hover = !player.touch && event.type === 'mouseenter'; elements.controls.hover = !player.touch && event.type === 'mouseenter';
}); });
// Also update controls.hover state for any non-player children of fullscreen element (as above) // Also update controls.hover state for any non-player children of fullscreen element (as above)
if (elements.fullscreen) { if (elements.fullscreen) {
Array.from(elements.fullscreen.children) Array.from(elements.fullscreen.children)
.filter(c => !c.contains(elements.container)) .filter((c) => !c.contains(elements.container))
.forEach(child => { .forEach((child) => {
this.bind(child, 'mouseenter mouseleave', event => { this.bind(child, 'mouseenter mouseleave', (event) => {
elements.controls.hover = !player.touch && event.type === 'mouseenter'; elements.controls.hover = !player.touch && event.type === 'mouseenter';
}); });
}); });
} }
// Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting) // Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)
this.bind(elements.controls, 'mousedown mouseup touchstart touchend touchcancel', event => { this.bind(elements.controls, 'mousedown mouseup touchstart touchend touchcancel', (event) => {
elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type); elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);
}); });
@@ -861,12 +861,12 @@ class Listeners {
this.bind( this.bind(
elements.inputs.volume, elements.inputs.volume,
'wheel', 'wheel',
event => { (event) => {
// Detect "natural" scroll - suppored on OS X Safari only // Detect "natural" scroll - suppored on OS X Safari only
// Other browsers on OS X will be inverted until support improves // Other browsers on OS X will be inverted until support improves
const inverted = event.webkitDirectionInvertedFromDevice; const inverted = event.webkitDirectionInvertedFromDevice;
// Get delta from event. Invert if `inverted` is true // Get delta from event. Invert if `inverted` is true
const [x, y] = [event.deltaX, -event.deltaY].map(value => (inverted ? -value : value)); const [x, y] = [event.deltaX, -event.deltaY].map((value) => (inverted ? -value : value));
// Using the biggest delta, normalize to 1 or -1 (or 0 if no delta) // Using the biggest delta, normalize to 1 or -1 (or 0 if no delta)
const direction = Math.sign(Math.abs(x) > Math.abs(y) ? x : y); const direction = Math.sign(Math.abs(x) > Math.abs(y) ? x : y);
+10 -10
View File
@@ -15,7 +15,7 @@ import { silencePromise } from '../utils/promise';
import { formatTime } from '../utils/time'; import { formatTime } from '../utils/time';
import { buildUrlParams } from '../utils/urls'; import { buildUrlParams } from '../utils/urls';
const destroy = instance => { const destroy = (instance) => {
// Destroy our adsManager // Destroy our adsManager
if (instance.manager) { if (instance.manager) {
instance.manager.destroy(); instance.manager.destroy();
@@ -179,10 +179,10 @@ class Ads {
// Listen and respond to ads loaded and error events // Listen and respond to ads loaded and error events
this.loader.addEventListener( this.loader.addEventListener(
google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
event => this.onAdsManagerLoaded(event), (event) => this.onAdsManagerLoaded(event),
false, false,
); );
this.loader.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, error => this.onAdError(error), false); this.loader.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, (error) => this.onAdError(error), false);
// Request video ads to be pre-loaded // Request video ads to be pre-loaded
this.requestAds(); this.requestAds();
@@ -264,11 +264,11 @@ class Ads {
// Add listeners to the required events // Add listeners to the required events
// Advertisement error events // Advertisement error events
this.manager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, error => this.onAdError(error)); this.manager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, (error) => this.onAdError(error));
// Advertisement regular events // Advertisement regular events
Object.keys(google.ima.AdEvent.Type).forEach(type => { Object.keys(google.ima.AdEvent.Type).forEach((type) => {
this.manager.addEventListener(google.ima.AdEvent.Type[type], e => this.onAdEvent(e)); this.manager.addEventListener(google.ima.AdEvent.Type[type], (e) => this.onAdEvent(e));
}); });
// Resolve our adsManager // Resolve our adsManager
@@ -278,7 +278,7 @@ class Ads {
addCuePoints() { addCuePoints() {
// Add advertisement cue's within the time line if available // Add advertisement cue's within the time line if available
if (!is.empty(this.cuePoints)) { if (!is.empty(this.cuePoints)) {
this.cuePoints.forEach(cuePoint => { this.cuePoints.forEach((cuePoint) => {
if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < this.player.duration) { if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < this.player.duration) {
const seekElement = this.player.elements.progress; const seekElement = this.player.elements.progress;
@@ -310,7 +310,7 @@ class Ads {
const adData = event.getAdData(); const adData = event.getAdData();
// Proxy event // Proxy event
const dispatchEvent = type => { const dispatchEvent = (type) => {
triggerEvent.call(this.player, this.player.media, `ads${type.replace(/_/g, '').toLowerCase()}`); triggerEvent.call(this.player, this.player.media, `ads${type.replace(/_/g, '').toLowerCase()}`);
}; };
@@ -565,7 +565,7 @@ class Ads {
} }
// Re-set our adsManager promises // Re-set our adsManager promises
this.managerPromise = new Promise(resolve => { this.managerPromise = new Promise((resolve) => {
this.on('loaded', resolve); this.on('loaded', resolve);
this.player.debug.log(this.manager); this.player.debug.log(this.manager);
}); });
@@ -586,7 +586,7 @@ class Ads {
const handlers = this.events[event]; const handlers = this.events[event];
if (is.array(handlers)) { if (is.array(handlers)) {
handlers.forEach(handler => { handlers.forEach((handler) => {
if (is.function(handler)) { if (is.function(handler)) {
handler.apply(this, args); handler.apply(this, args);
} }
+12 -12
View File
@@ -5,15 +5,15 @@ import is from '../utils/is';
import { formatTime } from '../utils/time'; import { formatTime } from '../utils/time';
// Arg: vttDataString example: "WEBVTT\n\n1\n00:00:05.000 --> 00:00:10.000\n1080p-00001.jpg" // Arg: vttDataString example: "WEBVTT\n\n1\n00:00:05.000 --> 00:00:10.000\n1080p-00001.jpg"
const parseVtt = vttDataString => { const parseVtt = (vttDataString) => {
const processedList = []; const processedList = [];
const frames = vttDataString.split(/\r\n\r\n|\n\n|\r\r/); const frames = vttDataString.split(/\r\n\r\n|\n\n|\r\r/);
frames.forEach(frame => { frames.forEach((frame) => {
const result = {}; const result = {};
const lines = frame.split(/\r\n|\n|\r/); const lines = frame.split(/\r\n|\n|\r/);
lines.forEach(line => { lines.forEach((line) => {
if (!is.number(result.startTime)) { if (!is.number(result.startTime)) {
// The line with start and end times on it is the first line of interest // The line with start and end times on it is the first line of interest
const matchTimes = line.match( const matchTimes = line.match(
@@ -130,7 +130,7 @@ class PreviewThumbnails {
// Download VTT files and parse them // Download VTT files and parse them
getThumbnails() { getThumbnails() {
return new Promise(resolve => { return new Promise((resolve) => {
const { src } = this.player.config.previewThumbnails; const { src } = this.player.config.previewThumbnails;
if (is.empty(src)) { if (is.empty(src)) {
@@ -149,7 +149,7 @@ class PreviewThumbnails {
// Via callback() // Via callback()
if (is.function(src)) { if (is.function(src)) {
src(thumbnails => { src((thumbnails) => {
this.thumbnails = thumbnails; this.thumbnails = thumbnails;
sortAndResolve(); sortAndResolve();
}); });
@@ -159,7 +159,7 @@ class PreviewThumbnails {
// If string, convert into single-element list // If string, convert into single-element list
const urls = is.string(src) ? [src] : src; const urls = is.string(src) ? [src] : src;
// Loop through each src URL. Download and process the VTT file, storing the resulting data in this.thumbnails // Loop through each src URL. Download and process the VTT file, storing the resulting data in this.thumbnails
const promises = urls.map(u => this.getThumbnail(u)); const promises = urls.map((u) => this.getThumbnail(u));
// Resolve // Resolve
Promise.all(promises).then(sortAndResolve); Promise.all(promises).then(sortAndResolve);
} }
@@ -168,8 +168,8 @@ class PreviewThumbnails {
// Process individual VTT file // Process individual VTT file
getThumbnail(url) { getThumbnail(url) {
return new Promise(resolve => { return new Promise((resolve) => {
fetch(url).then(response => { fetch(url).then((response) => {
const thumbnail = { const thumbnail = {
frames: parseVtt(response), frames: parseVtt(response),
height: null, height: null,
@@ -360,7 +360,7 @@ class PreviewThumbnails {
// Find the desired thumbnail index // Find the desired thumbnail index
// TODO: Handle a video longer than the thumbs where thumbNum is null // TODO: Handle a video longer than the thumbs where thumbNum is null
const thumbNum = this.thumbnails[0].frames.findIndex( const thumbNum = this.thumbnails[0].frames.findIndex(
frame => this.seekTime >= frame.startTime && this.seekTime <= frame.endTime, (frame) => this.seekTime >= frame.startTime && this.seekTime <= frame.endTime,
); );
const hasThumb = thumbNum >= 0; const hasThumb = thumbNum >= 0;
let qualityIndex = 0; let qualityIndex = 0;
@@ -454,7 +454,7 @@ class PreviewThumbnails {
// Remove all preview images that aren't the designated current image // Remove all preview images that aren't the designated current image
removeOldImages(currentImage) { removeOldImages(currentImage) {
// Get a list of all images, convert it from a DOM list to an array // Get a list of all images, convert it from a DOM list to an array
Array.from(this.currentImageContainer.children).forEach(image => { Array.from(this.currentImageContainer.children).forEach((image) => {
if (image.tagName.toLowerCase() !== 'img') { if (image.tagName.toLowerCase() !== 'img') {
return; return;
} }
@@ -481,7 +481,7 @@ class PreviewThumbnails {
// Preload images before and after the current one. Only if the user is still hovering/seeking the same frame // Preload images before and after the current one. Only if the user is still hovering/seeking the same frame
// This will only preload the lowest quality // This will only preload the lowest quality
preloadNearby(thumbNum, forward = true) { preloadNearby(thumbNum, forward = true) {
return new Promise(resolve => { return new Promise((resolve) => {
setTimeout(() => { setTimeout(() => {
const oldThumbFilename = this.thumbnails[0].frames[thumbNum].text; const oldThumbFilename = this.thumbnails[0].frames[thumbNum].text;
@@ -496,7 +496,7 @@ class PreviewThumbnails {
let foundOne = false; let foundOne = false;
thumbnailsClone.forEach(frame => { thumbnailsClone.forEach((frame) => {
const newThumbFilename = frame.text; const newThumbFilename = frame.text;
if (newThumbFilename !== oldThumbFilename) { if (newThumbFilename !== oldThumbFilename) {
+16 -16
View File
@@ -58,7 +58,7 @@ const vimeo = {
.then(() => { .then(() => {
vimeo.ready.call(player); vimeo.ready.call(player);
}) })
.catch(error => { .catch((error) => {
player.debug.warn('Vimeo SDK (player.js) failed to load', error); player.debug.warn('Vimeo SDK (player.js) failed to load', error);
}); });
} else { } else {
@@ -123,7 +123,7 @@ const vimeo = {
} }
// Get poster image // Get poster image
fetch(format(player.config.urls.vimeo.api, id), 'json').then(response => { fetch(format(player.config.urls.vimeo.api, id), 'json').then((response) => {
if (is.empty(response)) { if (is.empty(response)) {
return; return;
} }
@@ -269,11 +269,11 @@ const vimeo = {
let currentSrc; let currentSrc;
player.embed player.embed
.getVideoUrl() .getVideoUrl()
.then(value => { .then((value) => {
currentSrc = value; currentSrc = value;
controls.setDownloadUrl.call(player); controls.setDownloadUrl.call(player);
}) })
.catch(error => { .catch((error) => {
this.debug.warn(error); this.debug.warn(error);
}); });
@@ -291,49 +291,49 @@ const vimeo = {
}); });
// Set aspect ratio based on video size // Set aspect ratio based on video size
Promise.all([player.embed.getVideoWidth(), player.embed.getVideoHeight()]).then(dimensions => { Promise.all([player.embed.getVideoWidth(), player.embed.getVideoHeight()]).then((dimensions) => {
const [width, height] = dimensions; const [width, height] = dimensions;
player.embed.ratio = [width, height]; player.embed.ratio = [width, height];
setAspectRatio.call(this); setAspectRatio.call(this);
}); });
// Set autopause // Set autopause
player.embed.setAutopause(player.config.autopause).then(state => { player.embed.setAutopause(player.config.autopause).then((state) => {
player.config.autopause = state; player.config.autopause = state;
}); });
// Get title // Get title
player.embed.getVideoTitle().then(title => { player.embed.getVideoTitle().then((title) => {
player.config.title = title; player.config.title = title;
ui.setTitle.call(this); ui.setTitle.call(this);
}); });
// Get current time // Get current time
player.embed.getCurrentTime().then(value => { player.embed.getCurrentTime().then((value) => {
currentTime = value; currentTime = value;
triggerEvent.call(player, player.media, 'timeupdate'); triggerEvent.call(player, player.media, 'timeupdate');
}); });
// Get duration // Get duration
player.embed.getDuration().then(value => { player.embed.getDuration().then((value) => {
player.media.duration = value; player.media.duration = value;
triggerEvent.call(player, player.media, 'durationchange'); triggerEvent.call(player, player.media, 'durationchange');
}); });
// Get captions // Get captions
player.embed.getTextTracks().then(tracks => { player.embed.getTextTracks().then((tracks) => {
player.media.textTracks = tracks; player.media.textTracks = tracks;
captions.setup.call(player); captions.setup.call(player);
}); });
player.embed.on('cuechange', ({ cues = [] }) => { player.embed.on('cuechange', ({ cues = [] }) => {
const strippedCues = cues.map(cue => stripHTML(cue.text)); const strippedCues = cues.map((cue) => stripHTML(cue.text));
captions.updateCues.call(player, strippedCues); captions.updateCues.call(player, strippedCues);
}); });
player.embed.on('loaded', () => { player.embed.on('loaded', () => {
// Assure state and events are updated on autoplay // Assure state and events are updated on autoplay
player.embed.getPaused().then(paused => { player.embed.getPaused().then((paused) => {
assurePlaybackState.call(player, !paused); assurePlaybackState.call(player, !paused);
if (!paused) { if (!paused) {
triggerEvent.call(player, player.media, 'playing'); triggerEvent.call(player, player.media, 'playing');
@@ -366,13 +366,13 @@ const vimeo = {
assurePlaybackState.call(player, false); assurePlaybackState.call(player, false);
}); });
player.embed.on('timeupdate', data => { player.embed.on('timeupdate', (data) => {
player.media.seeking = false; player.media.seeking = false;
currentTime = data.seconds; currentTime = data.seconds;
triggerEvent.call(player, player.media, 'timeupdate'); triggerEvent.call(player, player.media, 'timeupdate');
}); });
player.embed.on('progress', data => { player.embed.on('progress', (data) => {
player.media.buffered = data.percent; player.media.buffered = data.percent;
triggerEvent.call(player, player.media, 'progress'); triggerEvent.call(player, player.media, 'progress');
@@ -383,7 +383,7 @@ const vimeo = {
// Get duration as if we do it before load, it gives an incorrect value // Get duration as if we do it before load, it gives an incorrect value
// https://github.com/sampotts/plyr/issues/891 // https://github.com/sampotts/plyr/issues/891
player.embed.getDuration().then(value => { player.embed.getDuration().then((value) => {
if (value !== player.media.duration) { if (value !== player.media.duration) {
player.media.duration = value; player.media.duration = value;
triggerEvent.call(player, player.media, 'durationchange'); triggerEvent.call(player, player.media, 'durationchange');
@@ -401,7 +401,7 @@ const vimeo = {
triggerEvent.call(player, player.media, 'ended'); triggerEvent.call(player, player.media, 'ended');
}); });
player.embed.on('error', detail => { player.embed.on('error', (detail) => {
player.media.error = detail; player.media.error = detail;
triggerEvent.call(player, player.media, 'error'); triggerEvent.call(player, player.media, 'error');
}); });
+6 -6
View File
@@ -70,7 +70,7 @@ const youtube = {
}; };
// Load the SDK // Load the SDK
loadScript(this.config.urls.youtube.sdk).catch(error => { loadScript(this.config.urls.youtube.sdk).catch((error) => {
this.debug.warn('YouTube API failed to load', error); this.debug.warn('YouTube API failed to load', error);
}); });
} }
@@ -81,7 +81,7 @@ const youtube = {
const url = format(this.config.urls.youtube.api, videoId); const url = format(this.config.urls.youtube.api, videoId);
fetch(url) fetch(url)
.then(data => { .then((data) => {
if (is.object(data)) { if (is.object(data)) {
const { title, height, width } = data; const { title, height, width } = data;
@@ -128,14 +128,14 @@ const youtube = {
player.media = replaceElement(container, player.media); player.media = replaceElement(container, player.media);
// Id to poster wrapper // Id to poster wrapper
const posterSrc = s => `https://i.ytimg.com/vi/${videoId}/${s}default.jpg`; const posterSrc = (s) => `https://i.ytimg.com/vi/${videoId}/${s}default.jpg`;
// Check thumbnail images in order of quality, but reject fallback thumbnails (120px wide) // Check thumbnail images in order of quality, but reject fallback thumbnails (120px wide)
loadImage(posterSrc('maxres'), 121) // Higest quality and unpadded loadImage(posterSrc('maxres'), 121) // Higest quality and unpadded
.catch(() => loadImage(posterSrc('sd'), 121)) // 480p padded 4:3 .catch(() => loadImage(posterSrc('sd'), 121)) // 480p padded 4:3
.catch(() => loadImage(posterSrc('hq'))) // 360p padded 4:3. Always exists .catch(() => loadImage(posterSrc('hq'))) // 360p padded 4:3. Always exists
.then(image => ui.setPoster.call(player, image.src)) .then((image) => ui.setPoster.call(player, image.src))
.then(src => { .then((src) => {
// If the image is padded, use background-size "cover" instead (like youtube does too with their posters) // If the image is padded, use background-size "cover" instead (like youtube does too with their posters)
if (!src.includes('maxres')) { if (!src.includes('maxres')) {
player.elements.poster.style.backgroundSize = 'cover'; player.elements.poster.style.backgroundSize = 'cover';
@@ -299,7 +299,7 @@ const youtube = {
// Get available speeds // Get available speeds
const speeds = instance.getAvailablePlaybackRates(); const speeds = instance.getAvailablePlaybackRates();
// Filter based on config // Filter based on config
player.options.speed = speeds.filter(s => player.config.speed.options.includes(s)); player.options.speed = speeds.filter((s) => player.config.speed.options.includes(s));
// Set the tabindex to avoid focus entering iframe // Set the tabindex to avoid focus entering iframe
if (player.supported.ui) { if (player.supported.ui) {
+2 -2
View File
@@ -282,7 +282,7 @@ class Plyr {
// Listen for events if debugging // Listen for events if debugging
if (this.config.debug) { if (this.config.debug) {
on.call(this, this.elements.container, this.config.events.join(' '), event => { on.call(this, this.elements.container, this.config.events.join(' '), (event) => {
this.debug.log(`event: ${event.type}`); this.debug.log(`event: ${event.type}`);
}); });
} }
@@ -1257,7 +1257,7 @@ class Plyr {
return null; return null;
} }
return targets.map(t => new Plyr(t, options)); return targets.map((t) => new Plyr(t, options));
} }
} }
+1 -1
View File
@@ -20,7 +20,7 @@ const source = {
src: attributes, src: attributes,
}); });
} else if (is.array(attributes)) { } else if (is.array(attributes)) {
attributes.forEach(attribute => { attributes.forEach((attribute) => {
insertElement(type, this.media, attribute); insertElement(type, this.media, attribute);
}); });
} }
+5 -5
View File
@@ -135,7 +135,7 @@ const ui = {
} }
// If there's a play button, set label // If there's a play button, set label
Array.from(this.elements.buttons.play || []).forEach(button => { Array.from(this.elements.buttons.play || []).forEach((button) => {
button.setAttribute('aria-label', label); button.setAttribute('aria-label', label);
}); });
@@ -178,7 +178,7 @@ const ui = {
.call(this) .call(this)
// Load image // Load image
.then(() => loadImage(poster)) .then(() => loadImage(poster))
.catch(err => { .catch((err) => {
// Hide poster on error unless it's been set by another call // Hide poster on error unless it's been set by another call
if (poster === this.poster) { if (poster === this.poster) {
ui.togglePoster.call(this, false); ui.togglePoster.call(this, false);
@@ -214,7 +214,7 @@ const ui = {
toggleClass(this.elements.container, this.config.classNames.stopped, this.stopped); toggleClass(this.elements.container, this.config.classNames.stopped, this.stopped);
// Set state // Set state
Array.from(this.elements.buttons.play || []).forEach(target => { Array.from(this.elements.buttons.play || []).forEach((target) => {
Object.assign(target, { pressed: this.playing }); Object.assign(target, { pressed: this.playing });
target.setAttribute('aria-label', i18n.get(this.playing ? 'pause' : 'play', this.config)); target.setAttribute('aria-label', i18n.get(this.playing ? 'pause' : 'play', this.config));
}); });
@@ -270,8 +270,8 @@ const ui = {
// Loop through values (as they are the keys when the object is spread 🤔) // Loop through values (as they are the keys when the object is spread 🤔)
Object.values({ ...this.media.style }) Object.values({ ...this.media.style })
// We're only fussed about Plyr specific properties // We're only fussed about Plyr specific properties
.filter(key => !is.empty(key) && is.string(key) && key.startsWith('--plyr')) .filter((key) => !is.empty(key) && is.string(key) && key.startsWith('--plyr'))
.forEach(key => { .forEach((key) => {
// Set on the container // Set on the container
this.elements.container.style.setProperty(key, this.media.style.getPropertyValue(key)); this.elements.container.style.setProperty(key, this.media.style.getPropertyValue(key));
+1 -1
View File
@@ -14,7 +14,7 @@ export const transitionEndEvent = (() => {
transition: 'transitionend', transition: 'transitionend',
}; };
const type = Object.keys(events).find(event => element.style[event] !== undefined); const type = Object.keys(events).find((event) => element.style[event] !== undefined);
return is.string(type) ? events[type] : false; return is.string(type) ? events[type] : false;
})(); })();
+2 -2
View File
@@ -138,7 +138,7 @@ export function getAttributesFromSelector(sel, existingAttributes) {
const attributes = {}; const attributes = {};
const existing = extend({}, existingAttributes); const existing = extend({}, existingAttributes);
sel.split(',').forEach(s => { sel.split(',').forEach((s) => {
// Remove whitespace // Remove whitespace
const selector = s.trim(); const selector = s.trim();
const className = selector.replace('.', ''); const className = selector.replace('.', '');
@@ -198,7 +198,7 @@ export function toggleHidden(element, hidden) {
// Mirror Element.classList.toggle, with IE compatibility for "force" argument // Mirror Element.classList.toggle, with IE compatibility for "force" argument
export function toggleClass(element, className, force) { export function toggleClass(element, className, force) {
if (is.nodeList(element)) { if (is.nodeList(element)) {
return Array.from(element).map(e => toggleClass(e, className, force)); return Array.from(element).map((e) => toggleClass(e, className, force));
} }
if (is.element(element)) { if (is.element(element)) {
+3 -3
View File
@@ -50,7 +50,7 @@ export function toggleListener(element, event, callback, toggle = false, passive
} }
// If a single node is passed, bind the event listener // If a single node is passed, bind the event listener
events.forEach(type => { events.forEach((type) => {
if (this && this.eventListeners && toggle) { if (this && this.eventListeners && toggle) {
// Cache event listener // Cache event listener
this.eventListeners.push({ element, type, callback, options }); this.eventListeners.push({ element, type, callback, options });
@@ -100,7 +100,7 @@ export function triggerEvent(element, type = '', bubbles = false, detail = {}) {
// Unbind all cached event listeners // Unbind all cached event listeners
export function unbindListeners() { export function unbindListeners() {
if (this && this.eventListeners) { if (this && this.eventListeners) {
this.eventListeners.forEach(item => { this.eventListeners.forEach((item) => {
const { element, type, callback, options } = item; const { element, type, callback, options } = item;
element.removeEventListener(type, callback, options); element.removeEventListener(type, callback, options);
}); });
@@ -111,7 +111,7 @@ export function unbindListeners() {
// Run method when / if player is ready // Run method when / if player is ready
export function ready() { export function ready() {
return new Promise(resolve => return new Promise((resolve) =>
this.ready ? setTimeout(resolve, 0) : on.call(this, this.elements.container, 'ready', resolve), this.ready ? setTimeout(resolve, 0) : on.call(this, this.elements.container, 'ready', resolve),
).then(() => {}); ).then(() => {});
} }
+19 -19
View File
@@ -2,31 +2,31 @@
// Type checking utils // Type checking utils
// ========================================================================== // ==========================================================================
const getConstructor = input => (input !== null && typeof input !== 'undefined' ? input.constructor : null); const getConstructor = (input) => (input !== null && typeof input !== 'undefined' ? input.constructor : null);
const instanceOf = (input, constructor) => Boolean(input && constructor && input instanceof constructor); const instanceOf = (input, constructor) => Boolean(input && constructor && input instanceof constructor);
const isNullOrUndefined = input => input === null || typeof input === 'undefined'; const isNullOrUndefined = (input) => input === null || typeof input === 'undefined';
const isObject = input => getConstructor(input) === Object; const isObject = (input) => getConstructor(input) === Object;
const isNumber = input => getConstructor(input) === Number && !Number.isNaN(input); const isNumber = (input) => getConstructor(input) === Number && !Number.isNaN(input);
const isString = input => getConstructor(input) === String; const isString = (input) => getConstructor(input) === String;
const isBoolean = input => getConstructor(input) === Boolean; const isBoolean = (input) => getConstructor(input) === Boolean;
const isFunction = input => getConstructor(input) === Function; const isFunction = (input) => getConstructor(input) === Function;
const isArray = input => Array.isArray(input); const isArray = (input) => Array.isArray(input);
const isWeakMap = input => instanceOf(input, WeakMap); const isWeakMap = (input) => instanceOf(input, WeakMap);
const isNodeList = input => instanceOf(input, NodeList); const isNodeList = (input) => instanceOf(input, NodeList);
const isElement = input => instanceOf(input, Element); const isElement = (input) => instanceOf(input, Element);
const isTextNode = input => getConstructor(input) === Text; const isTextNode = (input) => getConstructor(input) === Text;
const isEvent = input => instanceOf(input, Event); const isEvent = (input) => instanceOf(input, Event);
const isKeyboardEvent = input => instanceOf(input, KeyboardEvent); const isKeyboardEvent = (input) => instanceOf(input, KeyboardEvent);
const isCue = input => instanceOf(input, window.TextTrackCue) || instanceOf(input, window.VTTCue); const isCue = (input) => instanceOf(input, window.TextTrackCue) || instanceOf(input, window.VTTCue);
const isTrack = input => instanceOf(input, TextTrack) || (!isNullOrUndefined(input) && isString(input.kind)); const isTrack = (input) => instanceOf(input, TextTrack) || (!isNullOrUndefined(input) && isString(input.kind));
const isPromise = input => instanceOf(input, Promise) && isFunction(input.then); const isPromise = (input) => instanceOf(input, Promise) && isFunction(input.then);
const isEmpty = input => const isEmpty = (input) =>
isNullOrUndefined(input) || isNullOrUndefined(input) ||
((isString(input) || isArray(input) || isNodeList(input)) && !input.length) || ((isString(input) || isArray(input) || isNodeList(input)) && !input.length) ||
(isObject(input) && !Object.keys(input).length); (isObject(input) && !Object.keys(input).length);
const isUrl = input => { const isUrl = (input) => {
// Accept a URL object // Accept a URL object
if (instanceOf(input, window.URL)) { if (instanceOf(input, window.URL)) {
return true; return true;
+1 -1
View File
@@ -54,7 +54,7 @@ export default function loadSprite(url, id) {
// Get the sprite // Get the sprite
fetch(url) fetch(url)
.then(result => { .then((result) => {
if (is.empty(result)) { if (is.empty(result)) {
return; return;
} }
+1 -1
View File
@@ -26,7 +26,7 @@ export function extend(target = {}, ...sources) {
return target; return target;
} }
Object.keys(source).forEach(key => { Object.keys(source).forEach((key) => {
if (is.object(source[key])) { if (is.object(source[key])) {
if (!Object.keys(target).includes(key)) { if (!Object.keys(target).includes(key)) {
Object.assign(target, { [key]: {} }); Object.assign(target, { [key]: {} });
+1 -1
View File
@@ -33,7 +33,7 @@ export const replaceAll = (input = '', find = '', replace = '') =>
// Convert to title case // Convert to title case
export const toTitleCase = (input = '') => export const toTitleCase = (input = '') =>
input.toString().replace(/\w\S*/g, text => text.charAt(0).toUpperCase() + text.substr(1).toLowerCase()); input.toString().replace(/\w\S*/g, (text) => text.charAt(0).toUpperCase() + text.substr(1).toLowerCase());
// Convert string to pascalCase // Convert string to pascalCase
export function toPascalCase(input = '') { export function toPascalCase(input = '') {
+2 -2
View File
@@ -27,7 +27,7 @@ export function reduceAspectRatio(ratio) {
} }
export function getAspectRatio(input) { export function getAspectRatio(input) {
const parse = ratio => (validateRatio(ratio) ? ratio.split(':').map(Number) : null); const parse = (ratio) => (validateRatio(ratio) ? ratio.split(':').map(Number) : null);
// Try provided ratio // Try provided ratio
let ratio = parse(input); let ratio = parse(input);
@@ -68,7 +68,7 @@ export function setAspectRatio(input) {
const height = (100 / this.media.offsetWidth) * parseInt(window.getComputedStyle(this.media).paddingBottom, 10); const height = (100 / this.media.offsetWidth) * parseInt(window.getComputedStyle(this.media).paddingBottom, 10);
const offset = (height - padding) / (height / 50); const offset = (height - padding) / (height / 50);
if(this.fullscreen.active) { if (this.fullscreen.active) {
wrapper.style.paddingBottom = null; wrapper.style.paddingBottom = null;
} else { } else {
this.media.style.transform = `translateY(-${offset}%)`; this.media.style.transform = `translateY(-${offset}%)`;
+4 -4
View File
@@ -5,9 +5,9 @@
import is from './is'; import is from './is';
// Time helpers // Time helpers
export const getHours = value => Math.trunc((value / 60 / 60) % 60, 10); export const getHours = (value) => Math.trunc((value / 60 / 60) % 60, 10);
export const getMinutes = value => Math.trunc((value / 60) % 60, 10); export const getMinutes = (value) => Math.trunc((value / 60) % 60, 10);
export const getSeconds = value => Math.trunc(value % 60, 10); export const getSeconds = (value) => Math.trunc(value % 60, 10);
// Format time to UI friendly string // Format time to UI friendly string
export function formatTime(time = 0, displayHours = false, inverted = false) { export function formatTime(time = 0, displayHours = false, inverted = false) {
@@ -17,7 +17,7 @@ export function formatTime(time = 0, displayHours = false, inverted = false) {
} }
// Format time component to add leading zero // Format time component to add leading zero
const format = value => `0${value}`.slice(-2); const format = (value) => `0${value}`.slice(-2);
// Breakdown to hours, mins, secs // Breakdown to hours, mins, secs
let hours = getHours(time); let hours = getHours(time);
const mins = getMinutes(time); const mins = getMinutes(time);
+1744 -776
View File
File diff suppressed because it is too large Load Diff