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

View File

@ -1,30 +1,18 @@
{ {
"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 },
}, "globals": {
"globals": { "Plyr": false,
"Plyr": false, "jQuery": false
"jQuery": false },
}, "rules": {
"rules": { "import/no-cycle": "warn"
"import/no-cycle": "warn", },
"padding-line-between-statements": [ "parserOptions": {
"error", "sourceType": "module"
{ }
"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": {
"sourceType": "module"
}
} }

2
demo/dist/demo.css vendored

File diff suppressed because one or more lines are too long

2081
demo/dist/demo.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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"
} }
} }

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==

2
dist/plyr.css vendored

File diff suppressed because one or more lines are too long

39
dist/plyr.js vendored
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);
this.media.style.transform = "translateY(-".concat(offset, "%)");
if (this.fullscreen.active) {
wrapper.style.paddingBottom = null;
} else {
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

4
dist/plyr.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
dist/plyr.min.mjs vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

39
dist/plyr.mjs vendored
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);
this.media.style.transform = "translateY(-".concat(offset, "%)");
if (this.fullscreen.active) {
wrapper.style.paddingBottom = null;
} else {
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

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);
this.media.style.transform = "translateY(-".concat(offset, "%)");
if (this.fullscreen.active) {
wrapper.style.paddingBottom = null;
} else {
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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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);
this.media.style.transform = "translateY(-".concat(offset, "%)");
if (this.fullscreen.active) {
wrapper.style.paddingBottom = null;
} else {
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

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"
} }
} }

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) {

52
src/js/controls.js vendored
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);
}); });

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(',');
} }
} }

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) {

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);

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);
} }

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) {

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');
}); });

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) {

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));
} }
} }

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);
}); });
} }

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));

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;
})(); })();

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)) {

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(() => {});
} }

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;

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;
} }

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]: {} });

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 = '') {

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}%)`;

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);

2520
yarn.lock

File diff suppressed because it is too large Load Diff