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,7 +1,6 @@
{
"parser": "babel-eslint",
"extends": ["airbnb-base", "prettier"],
"plugins": ["simple-import-sort", "import"],
"extends": "@sampotts/eslint-config/es6",
"env": {
"browser": true,
"es6": true
@ -11,18 +10,7 @@
"jQuery": false
},
"rules": {
"import/no-cycle": "warn",
"padding-line-between-statements": [
"error",
{
"blankLine": "never",
"prev": ["singleline-const", "singleline-let", "singleline-var"],
"next": ["singleline-const", "singleline-let", "singleline-var"]
}
],
"sort-imports": "off",
"import/order": "off",
"simple-import-sort/sort": "error"
"import/no-cycle": "warn"
},
"parserOptions": {
"sourceType": "module"

2
demo/dist/demo.css vendored

File diff suppressed because one or more lines are too long

2065
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",
"author": "Sam Potts <sam@potts.es>",
"dependencies": {
"@sentry/browser": "^5.15.5",
"@sentry/browser": "^5.22.3",
"core-js": "^3.6.5",
"custom-event-polyfill": "^1.0.7",
"shr-buttons": "2.0.3",
"url-polyfill": "^1.1.8"
"url-polyfill": "^1.1.10"
}
}

View File

@ -2,56 +2,56 @@
# yarn lockfile v1
"@sentry/browser@^5.15.5":
version "5.15.5"
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.15.5.tgz#d9a51f1388581067b50d30ed9b1aed2cbb333a36"
integrity sha512-rqDvjk/EvogfdbZ4TiEpxM/lwpPKmq23z9YKEO4q81+1SwJNua53H60dOk9HpRU8nOJ1g84TMKT2Ov8H7sqDWA==
"@sentry/browser@^5.22.3":
version "5.22.3"
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.22.3.tgz#7a64bd1cf01bf393741a3e4bf35f82aa927f5b4e"
integrity sha512-2TzE/CoBa5ZkvxJizDdi1Iz1ldmXSJpFQ1mL07PIXBjCt0Wxf+WOuFSj5IP4L40XHfJE5gU8wEvSH0VDR8nXtA==
dependencies:
"@sentry/core" "5.15.5"
"@sentry/types" "5.15.5"
"@sentry/utils" "5.15.5"
"@sentry/core" "5.22.3"
"@sentry/types" "5.22.3"
"@sentry/utils" "5.22.3"
tslib "^1.9.3"
"@sentry/core@5.15.5":
version "5.15.5"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.15.5.tgz#40ea79bff5272d3fbbeeb4a98cdc59e1adbd2c92"
integrity sha512-enxBLv5eibBMqcWyr+vApqeix8uqkfn0iGsD3piKvoMXCgKsrfMwlb/qo9Ox0lKr71qIlZVt+9/A2vZohdgnlg==
"@sentry/core@5.22.3":
version "5.22.3"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.22.3.tgz#030f435f2b518f282ba8bd954dac90cd70888bd7"
integrity sha512-eGL5uUarw3o4i9QUb9JoFHnhriPpWCaqeaIBB06HUpdcvhrjoowcKZj1+WPec5lFg5XusE35vez7z/FPzmJUDw==
dependencies:
"@sentry/hub" "5.15.5"
"@sentry/minimal" "5.15.5"
"@sentry/types" "5.15.5"
"@sentry/utils" "5.15.5"
"@sentry/hub" "5.22.3"
"@sentry/minimal" "5.22.3"
"@sentry/types" "5.22.3"
"@sentry/utils" "5.22.3"
tslib "^1.9.3"
"@sentry/hub@5.15.5":
version "5.15.5"
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.15.5.tgz#f5abbcdbe656a70e2ff02c02a5a4cffa0f125935"
integrity sha512-zX9o49PcNIVMA4BZHe//GkbQ4Jx+nVofqU/Il32/IbwKhcpPlhGX3c1sOVQo4uag3cqd/JuQsk+DML9TKkN0Lw==
"@sentry/hub@5.22.3":
version "5.22.3"
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.22.3.tgz#08309a70d2ea8d5e313d05840c1711f34f2fffe5"
integrity sha512-INo47m6N5HFEs/7GMP9cqxOIt7rmRxdERunA3H2L37owjcr77MwHVeeJ9yawRS6FMtbWXplgWTyTIWIYOuqVbw==
dependencies:
"@sentry/types" "5.15.5"
"@sentry/utils" "5.15.5"
"@sentry/types" "5.22.3"
"@sentry/utils" "5.22.3"
tslib "^1.9.3"
"@sentry/minimal@5.15.5":
version "5.15.5"
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.15.5.tgz#a0e4e071f01d9c4d808094ae7203f6c4cca9348a"
integrity sha512-zQkkJ1l9AjmU/Us5IrOTzu7bic4sTPKCatptXvLSTfyKW7N6K9MPIIFeSpZf9o1yM2sRYdK7GV08wS2eCT3JYw==
"@sentry/minimal@5.22.3":
version "5.22.3"
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.22.3.tgz#706e4029ae5494123d3875c658ba8911aa5cc440"
integrity sha512-HoINpYnVYCpNjn2XIPIlqH5o4BAITpTljXjtAftOx6Hzj+Opjg8tR8PWliyKDvkXPpc4kXK9D6TpEDw8MO0wZA==
dependencies:
"@sentry/hub" "5.15.5"
"@sentry/types" "5.15.5"
"@sentry/hub" "5.22.3"
"@sentry/types" "5.22.3"
tslib "^1.9.3"
"@sentry/types@5.15.5":
version "5.15.5"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.15.5.tgz#16c97e464cf09bbd1d2e8ce90d130e781709076e"
integrity sha512-F9A5W7ucgQLJUG4LXw1ZIy4iLevrYZzbeZ7GJ09aMlmXH9PqGThm1t5LSZlVpZvUfQ2rYA8NU6BdKJSt7B5LPw==
"@sentry/types@5.22.3":
version "5.22.3"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.22.3.tgz#d1d547b30ee8bd7771fa893af74c4f3d71f0fd18"
integrity sha512-cv+VWK0YFgCVDvD1/HrrBWOWYG3MLuCUJRBTkV/Opdy7nkdNjhCAJQrEyMM9zX0sac8FKWKOHT0sykNh8KgmYw==
"@sentry/utils@5.15.5":
version "5.15.5"
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.15.5.tgz#dec1d4c79037c4da08b386f5d34409234dcbfb15"
integrity sha512-Nl9gl/MGnzSkuKeo3QaefoD/OJrFLB8HmwQ7HUbTXb6E7yyEzNKAQMHXGkwNAjbdYyYbd42iABP6Y5F/h39NtA==
"@sentry/utils@5.22.3":
version "5.22.3"
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.22.3.tgz#e3bda3e789239eb16d436f768daa12829f33d18f"
integrity sha512-AHNryXMBvIkIE+GQxTlmhBXD0Ksh+5w1SwM5qi6AttH+1qjWLvV6WB4+4pvVvEoS8t5F+WaVUZPQLmCCWp6zKw==
dependencies:
"@sentry/types" "5.15.5"
"@sentry/types" "5.22.3"
tslib "^1.9.3"
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"
integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==
url-polyfill@^1.1.8:
version "1.1.8"
resolved "https://registry.yarnpkg.com/url-polyfill/-/url-polyfill-1.1.8.tgz#21eb58ad61192f52b77dcac8ab5293ae7bc67060"
integrity sha512-Ey61F4FEqhcu1vHSOMmjl0Vd/RPRLEjMj402qszD/dhMBrVfoUsnIj8KSZo2yj+eIlxJGKFdnm6ES+7UzMgZ3Q==
url-polyfill@^1.1.10:
version "1.1.10"
resolved "https://registry.yarnpkg.com/url-polyfill/-/url-polyfill-1.1.10.tgz#fd5bbcf66c9491fa682b0cb6d6a855e1643a9281"
integrity sha512-vSaPpaRgBrf41+Uky1myiSh6gpcbw8FpwHYnEy0abxndojOBnIs+yh/49gKYFLtUMP9qoNWjn6j9aUVy23Ie2A==

2
dist/plyr.css vendored

File diff suppressed because one or more lines are too long

37
dist/plyr.js vendored
View File

@ -1,7 +1,7 @@
typeof navigator === "object" && (function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = 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';
function _classCallCheck(instance, Constructor) {
@ -163,7 +163,7 @@ typeof navigator === "object" && (function (global, factory) {
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
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);
}
@ -1084,7 +1084,7 @@ typeof navigator === "object" && (function (global, factory) {
var event = new CustomEvent(type, {
bubbles: bubbles,
detail: _objectSpread2({}, detail, {
detail: _objectSpread2(_objectSpread2({}, detail), {}, {
plyr: this
})
}); // Dispatch the event
@ -1197,7 +1197,12 @@ typeof navigator === "object" && (function (global, factory) {
if (this.isVimeo && !this.config.vimeo.premium && this.supported.ui) {
var height = 100 / this.media.offsetWidth * parseInt(window.getComputedStyle(this.media).paddingBottom, 10);
var offset = (height - padding) / (height / 50);
if (this.fullscreen.active) {
wrapper.style.paddingBottom = null;
} else {
this.media.style.transform = "translateY(-".concat(offset, "%)");
}
} else if (this.isHTML5) {
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 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(' ')
});
@ -2786,7 +2791,7 @@ typeof navigator === "object" && (function (global, factory) {
showMenuPanel = controls.showMenuPanel;
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'));
} // Create the container
@ -2798,7 +2803,7 @@ typeof navigator === "object" && (function (global, factory) {
class: 'plyr__controls__item'
}; // 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
if (control === 'restart') {
container.appendChild(createButton.call(_this10, 'restart', defaultAttributes));
@ -3117,8 +3122,6 @@ typeof navigator === "object" && (function (global, factory) {
if (update) {
if (is$1.string(this.config.controls)) {
container = replace(container);
} else if (is$1.element(container)) {
container.innerHTML = replace(container.innerHTML);
}
} // Controls container
@ -4103,10 +4106,12 @@ typeof navigator === "object" && (function (global, factory) {
if (is$1.element(button)) {
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",
@ -4572,7 +4577,7 @@ typeof navigator === "object" && (function (global, factory) {
// 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
.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) {
// Set on the container
_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) {
setTimeout(function () {
this.once('canplay', function () {
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
@ -8491,7 +8496,7 @@ typeof navigator === "object" && (function (global, factory) {
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);
} // Trigger event on change
@ -8584,7 +8589,9 @@ typeof navigator === "object" && (function (global, factory) {
}
} else {
// 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

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

37
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)) {
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);
var n = Object.prototype.toString.call(o).slice(8, -1);
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);
}
@ -1078,7 +1078,7 @@ function triggerEvent(element) {
var event = new CustomEvent(type, {
bubbles: bubbles,
detail: _objectSpread2({}, detail, {
detail: _objectSpread2(_objectSpread2({}, detail), {}, {
plyr: this
})
}); // Dispatch the event
@ -1191,7 +1191,12 @@ function setAspectRatio(input) {
if (this.isVimeo && !this.config.vimeo.premium && this.supported.ui) {
var height = 100 / this.media.offsetWidth * parseInt(window.getComputedStyle(this.media).paddingBottom, 10);
var offset = (height - padding) / (height / 50);
if (this.fullscreen.active) {
wrapper.style.paddingBottom = null;
} else {
this.media.style.transform = "translateY(-".concat(offset, "%)");
}
} else if (this.isHTML5) {
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 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(' ')
});
@ -2780,7 +2785,7 @@ var controls = {
showMenuPanel = controls.showMenuPanel;
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'));
} // Create the container
@ -2792,7 +2797,7 @@ var controls = {
class: 'plyr__controls__item'
}; // 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
if (control === 'restart') {
container.appendChild(createButton.call(_this10, 'restart', defaultAttributes));
@ -3111,8 +3116,6 @@ var controls = {
if (update) {
if (is$1.string(this.config.controls)) {
container = replace(container);
} else if (is$1.element(container)) {
container.innerHTML = replace(container.innerHTML);
}
} // Controls container
@ -4097,10 +4100,12 @@ var Fullscreen = /*#__PURE__*/function () {
if (is$1.element(button)) {
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",
@ -4566,7 +4571,7 @@ var ui = {
// 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
.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) {
// Set on the container
_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) {
setTimeout(function () {
this.once('canplay', function () {
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
@ -8485,7 +8490,7 @@ var Plyr = /*#__PURE__*/function () {
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);
} // Trigger event on change
@ -8578,7 +8583,9 @@ var Plyr = /*#__PURE__*/function () {
}
} else {
// 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

View File

@ -1,7 +1,7 @@
typeof navigator === "object" && (function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = 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';
// 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);
var n = Object.prototype.toString.call(o).slice(8, -1);
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);
}
@ -4408,7 +4408,7 @@ typeof navigator === "object" && (function (global, factory) {
var checkIfURLSearchParamsSupported = function checkIfURLSearchParamsSupported() {
try {
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) {
return false;
}
@ -4532,7 +4532,11 @@ typeof navigator === "object" && (function (global, factory) {
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');
}
@ -7320,7 +7324,7 @@ typeof navigator === "object" && (function (global, factory) {
var event = new CustomEvent(type, {
bubbles: bubbles,
detail: _objectSpread2({}, detail, {
detail: _objectSpread2(_objectSpread2({}, detail), {}, {
plyr: this
})
}); // Dispatch the event
@ -7433,7 +7437,12 @@ typeof navigator === "object" && (function (global, factory) {
if (this.isVimeo && !this.config.vimeo.premium && this.supported.ui) {
var height = 100 / this.media.offsetWidth * parseInt(window.getComputedStyle(this.media).paddingBottom, 10);
var offset = (height - padding) / (height / 50);
if (this.fullscreen.active) {
wrapper.style.paddingBottom = null;
} else {
this.media.style.transform = "translateY(-".concat(offset, "%)");
}
} else if (this.isHTML5) {
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 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(' ')
});
@ -9107,7 +9116,7 @@ typeof navigator === "object" && (function (global, factory) {
showMenuPanel = controls.showMenuPanel;
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'));
} // Create the container
@ -9119,7 +9128,7 @@ typeof navigator === "object" && (function (global, factory) {
class: 'plyr__controls__item'
}; // 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
if (control === 'restart') {
container.appendChild(createButton.call(_this10, 'restart', defaultAttributes));
@ -9438,8 +9447,6 @@ typeof navigator === "object" && (function (global, factory) {
if (update) {
if (is$1.string(this.config.controls)) {
container = replace(container);
} else if (is$1.element(container)) {
container.innerHTML = replace(container.innerHTML);
}
} // Controls container
@ -10424,10 +10431,12 @@ typeof navigator === "object" && (function (global, factory) {
if (is$1.element(button)) {
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",
@ -10906,7 +10915,7 @@ typeof navigator === "object" && (function (global, factory) {
// 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
.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) {
// Set on the container
_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) {
setTimeout(function () {
this.once('canplay', function () {
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
@ -14926,7 +14935,7 @@ typeof navigator === "object" && (function (global, factory) {
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);
} // Trigger event on change
@ -15019,7 +15028,9 @@ typeof navigator === "object" && (function (global, factory) {
}
} else {
// 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

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:
// https://github.com/d4tocchini/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);
var n = Object.prototype.toString.call(o).slice(8, -1);
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);
}
@ -4402,7 +4402,7 @@ function _nonIterableRest() {
var checkIfURLSearchParamsSupported = function checkIfURLSearchParamsSupported() {
try {
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) {
return false;
}
@ -4526,7 +4526,11 @@ function _nonIterableRest() {
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');
}
@ -7314,7 +7318,7 @@ function triggerEvent(element) {
var event = new CustomEvent(type, {
bubbles: bubbles,
detail: _objectSpread2({}, detail, {
detail: _objectSpread2(_objectSpread2({}, detail), {}, {
plyr: this
})
}); // Dispatch the event
@ -7427,7 +7431,12 @@ function setAspectRatio(input) {
if (this.isVimeo && !this.config.vimeo.premium && this.supported.ui) {
var height = 100 / this.media.offsetWidth * parseInt(window.getComputedStyle(this.media).paddingBottom, 10);
var offset = (height - padding) / (height / 50);
if (this.fullscreen.active) {
wrapper.style.paddingBottom = null;
} else {
this.media.style.transform = "translateY(-".concat(offset, "%)");
}
} else if (this.isHTML5) {
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 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(' ')
});
@ -9101,7 +9110,7 @@ var controls = {
showMenuPanel = controls.showMenuPanel;
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'));
} // Create the container
@ -9113,7 +9122,7 @@ var controls = {
class: 'plyr__controls__item'
}; // 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
if (control === 'restart') {
container.appendChild(createButton.call(_this10, 'restart', defaultAttributes));
@ -9432,8 +9441,6 @@ var controls = {
if (update) {
if (is$1.string(this.config.controls)) {
container = replace(container);
} else if (is$1.element(container)) {
container.innerHTML = replace(container.innerHTML);
}
} // Controls container
@ -10418,10 +10425,12 @@ var Fullscreen = /*#__PURE__*/function () {
if (is$1.element(button)) {
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",
@ -10900,7 +10909,7 @@ var ui = {
// 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
.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) {
// Set on the container
_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) {
setTimeout(function () {
this.once('canplay', function () {
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
@ -14920,7 +14929,7 @@ var Plyr = /*#__PURE__*/function () {
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);
} // Trigger event on change
@ -15013,7 +15022,9 @@ var Plyr = /*#__PURE__*/function () {
}
} else {
// 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

View File

@ -35,27 +35,25 @@
"lint:fix": "eslint --fix src/js",
"remark": "remark -f --use 'validate-links=repository:\"sampotts/plyr\"' '{,!(node_modules),.?**/}*.md'",
"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": {
"@sampotts/eslint-config": "1.0.0",
"ansi-colors": "^4.1.1",
"autoprefixer": "^9.7.6",
"aws-sdk": "^2.668.0",
"@babel/core": "^7.9.6",
"@babel/preset-env": "^7.9.6",
"autoprefixer": "^9.8.6",
"aws-sdk": "^2.742.0",
"@babel/core": "^7.11.4",
"@babel/preset-env": "^7.11.0",
"babel-eslint": "^10.1.0",
"browser-sync": "^2.26.7",
"browser-sync": "^2.26.12",
"del": "^5.1.0",
"eslint": "^6.8.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",
"eslint": "^7.7.0",
"fancy-log": "^1.3.3",
"fastly-purge": "^1.0.1",
"git-branch": "^2.0.1",
"gulp": "^4.0.2",
"gulp-awspublish": "^4.1.1",
"gulp-awspublish": "^4.1.2",
"gulp-better-rollup": "^4.0.1",
"gulp-filter": "^6.0.0",
"gulp-header": "^2.0.9",
@ -71,31 +69,30 @@
"gulp-size": "^3.0.0",
"gulp-sourcemaps": "^2.6.5",
"gulp-svgstore": "^7.0.1",
"gulp-terser": "^1.2.0",
"gulp-terser": "^1.4.0",
"postcss-clean": "^1.1.0",
"postcss-custom-properties": "^9.1.1",
"prettier-eslint": "^9.0.1",
"prettier-stylelint": "^0.4.2",
"remark-cli": "^8.0.0",
"remark-validate-links": "^10.0.0",
"rollup": "^2.7.6",
"remark-cli": "^8.0.1",
"remark-validate-links": "^10.0.2",
"rollup": "^2.26.8",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0",
"stylelint": "^13.3.3",
"stylelint-config-prettier": "^8.0.1",
"stylelint": "^13.6.1",
"stylelint-config-prettier": "^8.0.2",
"stylelint-config-recommended": "^3.0.0",
"stylelint-config-sass-guidelines": "^7.0.0",
"stylelint-order": "^4.0.0",
"stylelint-scss": "^3.17.1",
"stylelint-order": "^4.1.0",
"stylelint-scss": "^3.18.0",
"stylelint-selector-bem-pattern": "^2.1.0",
"through2": "^3.0.1"
"through2": "^4.0.2"
},
"dependencies": {
"core-js": "^3.6.5",
"custom-event-polyfill": "^1.0.7",
"loadjs": "^4.2.0",
"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) {
const elements = this.media.querySelectorAll('track');
Array.from(elements).forEach(track => {
Array.from(elements).forEach((track) => {
const src = track.getAttribute('src');
const url = parseUrl(src);
@ -66,7 +66,7 @@ const captions = {
['http:', 'https:'].includes(url.protocol)
) {
fetch(src, 'blob')
.then(blob => {
.then((blob) => {
track.setAttribute('src', window.URL.createObjectURL(blob));
})
.catch(() => {
@ -84,7 +84,7 @@ const captions = {
// * toggled: The real captions state
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();
// Use first browser language when language is 'auto'
@ -119,13 +119,13 @@ const captions = {
const tracks = captions.getTracks.call(this, true);
// Get the wanted language
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)
if (this.isHTML5 && this.isVideo) {
tracks
.filter(track => !meta.get(track))
.forEach(track => {
.filter((track) => !meta.get(track))
.forEach((track) => {
this.debug.log('Track added', track);
// 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)
// Filter out removed tracks and tracks that aren't captions/subtitles (for example metadata)
return tracks
.filter(track => !this.isHTML5 || update || this.captions.meta.has(track))
.filter(track => ['captions', 'subtitles'].includes(track.kind));
.filter((track) => !this.isHTML5 || update || this.captions.meta.has(track))
.filter((track) => ['captions', 'subtitles'].includes(track.kind));
},
// Match tracks based on languages and get the first
findTrack(languages, force = false) {
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));
let track;
languages.every(language => {
track = sorted.find(t => t.language === language);
languages.every((language) => {
track = sorted.find((t) => t.language === language);
return !track; // Break iteration if there is a match
});
@ -383,12 +383,12 @@ const captions = {
const track = captions.getCurrentTrack.call(this);
cues = Array.from((track || {}).activeCues || [])
.map(cue => cue.getCueAsHTML())
.map((cue) => cue.getCueAsHTML())
.map(getHTML);
}
// 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;
if (changed) {

52
src/js/controls.js vendored
View File

@ -179,7 +179,7 @@ const controls = {
iconPressed: null,
};
['element', 'icon', 'label'].forEach(key => {
['element', 'icon', 'label'].forEach((key) => {
if (Object.keys(attributes).includes(key)) {
props[key] = attributes[key];
delete attributes[key];
@ -193,7 +193,7 @@ const controls = {
// Set class name
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, {
class: `${attributes.class} ${this.config.classNames.control}`,
});
@ -401,7 +401,7 @@ const controls = {
this,
menuItem,
'keydown keyup',
event => {
(event) => {
// We only care about space and ⬆️ ⬇️️ ➡️
if (![32, 38, 39, 40].includes(event.which)) {
return;
@ -448,7 +448,7 @@ const controls = {
// 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
on.call(this, menuItem, 'keyup', event => {
on.call(this, menuItem, 'keyup', (event) => {
if (event.which !== 13) {
return;
}
@ -493,8 +493,8 @@ const controls = {
// Ensure exclusivity
if (check) {
Array.from(menuItem.parentNode.children)
.filter(node => matches(node, '[role="menuitemradio"]'))
.forEach(node => node.setAttribute('aria-checked', 'false'));
.filter((node) => matches(node, '[role="menuitemradio"]'))
.forEach((node) => node.setAttribute('aria-checked', 'false'));
}
menuItem.setAttribute('aria-checked', check ? 'true' : 'false');
@ -504,7 +504,7 @@ const controls = {
this.listeners.bind(
menuItem,
'click keyup',
event => {
(event) => {
if (is.keyboardEvent(event) && event.which !== 32) {
return;
}
@ -698,7 +698,7 @@ const controls = {
}
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
if (this.touch) {
@ -894,7 +894,7 @@ const controls = {
// Set options if passed and filter based on uniqueness and config
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
@ -913,7 +913,7 @@ const controls = {
}
// Get the badge HTML for HD, 4K etc
const getBadge = quality => {
const getBadge = (quality) => {
const label = i18n.get(`qualityBadge.${quality}`, this.config);
if (!label.length) {
@ -929,7 +929,7 @@ const controls = {
const sorting = this.config.quality.options;
return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1;
})
.forEach(quality => {
.forEach((quality) => {
controls.createMenuItem.call(this, {
value: quality,
list,
@ -1052,7 +1052,7 @@ const controls = {
const list = this.elements.settings.panels.speed.querySelector('[role="menu"]');
// 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
const toggle = !is.empty(this.options.speed) && this.options.speed.length > 1;
@ -1070,7 +1070,7 @@ const controls = {
}
// Create items
this.options.speed.forEach(speed => {
this.options.speed.forEach((speed) => {
controls.createMenuItem.call(this, {
value: speed,
list,
@ -1085,7 +1085,7 @@ const controls = {
// Check if we need to hide/show the settings menu
checkMenu() {
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);
},
@ -1099,7 +1099,7 @@ const controls = {
let target = pane;
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"]');
@ -1191,7 +1191,7 @@ const controls = {
// Hide all other panels
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 (support.transitions && !support.reducedMotion) {
@ -1203,7 +1203,7 @@ const controls = {
const size = controls.getMenuSize.call(this, target);
// Restore auto height/width
const restore = event => {
const restore = (event) => {
// We're only bothered about height and width on the container
if (event.target !== container || !['width', 'height'].includes(event.propertyName)) {
return;
@ -1275,7 +1275,7 @@ const controls = {
const defaultAttributes = { class: 'plyr__controls__item' };
// 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
if (control === 'restart') {
container.appendChild(createButton.call(this, 'restart', defaultAttributes));
@ -1437,7 +1437,7 @@ const controls = {
this.elements.settings.panels.home = home;
// Build the menu items
this.config.settings.forEach(type => {
this.config.settings.forEach((type) => {
// TODO: bundle this with the createMenuItem helper and bindings
const menuItem = createElement(
'button',
@ -1510,7 +1510,7 @@ const controls = {
this,
pane,
'keydown',
event => {
(event) => {
// We only care about <-
if (event.which !== 37) {
return;
@ -1661,7 +1661,7 @@ const controls = {
}
// Replace props with their value
const replace = input => {
const replace = (input) => {
let result = input;
Object.entries(props).forEach(([key, value]) => {
@ -1702,7 +1702,7 @@ const controls = {
// Add pressed property to buttons
if (!is.empty(this.elements.buttons)) {
const addProperty = button => {
const addProperty = (button) => {
const className = this.config.classNames.controlPressed;
Object.defineProperty(button, 'pressed', {
enumerable: true,
@ -1718,11 +1718,9 @@ const controls = {
// Toggle classname when pressed property is set
Object.values(this.elements.buttons)
.filter(Boolean)
.forEach(button => {
.forEach((button) => {
if (is.array(button) || is.nodeList(button)) {
Array.from(button)
.filter(Boolean)
.forEach(addProperty);
Array.from(button).filter(Boolean).forEach(addProperty);
} else {
addProperty(button);
}
@ -1740,7 +1738,7 @@ const controls = {
const selector = `${selectors.controls.wrapper} ${selectors.labels} .${classNames.hidden}`;
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.tooltip, true);
});

View File

@ -5,7 +5,7 @@
// ==========================================================================
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 is from './utils/is';
import { silencePromise } from './utils/promise';
@ -43,7 +43,7 @@ class Fullscreen {
);
// 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
if (is.element(this.player.elements.controls) && this.player.elements.controls.contains(event.target)) {
return;
@ -53,7 +53,7 @@ class 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
this.update();
@ -85,7 +85,7 @@ class Fullscreen {
let value = '';
const prefixes = ['webkit', 'moz', 'ms'];
prefixes.some(pre => {
prefixes.some((pre) => {
if (is.function(document[`${pre}ExitFullscreen`]) || is.function(document[`${pre}CancelFullScreen`])) {
value = pre;
return true;
@ -191,7 +191,7 @@ class Fullscreen {
} else if (this.cleanupViewport) {
viewport.content = viewport.content
.split(',')
.filter(part => part.trim() !== property)
.filter((part) => part.trim() !== property)
.join(',');
}
}

View File

@ -18,7 +18,7 @@ const html5 = {
const sources = Array.from(this.media.querySelectorAll('source'));
// Filter out unsupported sources (if type is specified)
return sources.filter(source => {
return sources.filter((source) => {
const type = source.getAttribute('type');
if (is.empty(type)) {
@ -39,7 +39,7 @@ const html5 = {
// Get sizes from <source> elements
return html5.getSources
.call(this)
.map(source => Number(source.getAttribute('size')))
.map((source) => Number(source.getAttribute('size')))
.filter(Boolean);
},
@ -63,7 +63,7 @@ const html5 = {
get() {
// Get sources
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 source && Number(source.getAttribute('size'));
@ -80,7 +80,7 @@ const html5 = {
// Get sources
const sources = html5.getSources.call(player);
// 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
if (!source) {

View File

@ -277,7 +277,7 @@ class Listeners {
player,
elements.container,
'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen',
event => {
(event) => {
const { controls: controlsElement } = elements;
// Remove button states for fullscreen
@ -319,7 +319,7 @@ class Listeners {
};
// Resize on fullscreen change
const setPlayerSize = measure => {
const setPlayerSize = (measure) => {
// If we don't need to measure the viewport
if (!measure) {
return setAspectRatio.call(player);
@ -336,7 +336,7 @@ class Listeners {
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;
// Ignore events not from target
@ -373,10 +373,10 @@ class Listeners {
const { elements } = player;
// 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
on.call(player, player.media, 'durationchange loadeddata loadedmetadata', event =>
on.call(player, player.media, 'durationchange loadeddata loadedmetadata', (event) =>
controls.durationUpdate.call(player, event),
);
@ -393,20 +393,20 @@ class Listeners {
});
// 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),
);
// 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
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),
);
// 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
if (player.supported.ui && player.config.clickToPlay && !player.isAudio) {
@ -419,7 +419,7 @@ class Listeners {
}
// 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];
// Ignore if click if not container or in video wrapper
@ -459,7 +459,7 @@ class Listeners {
player,
elements.wrapper,
'contextmenu',
event => {
(event) => {
event.preventDefault();
},
false,
@ -485,7 +485,7 @@ class Listeners {
});
// Quality change
on.call(player, player.media, 'qualitychange', event => {
on.call(player, player.media, 'qualitychange', (event) => {
// Update UI
controls.updateSetting.call(player, 'quality', null, event.detail.quality);
});
@ -499,7 +499,7 @@ class Listeners {
// Bubble up key events for Edge
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;
// Get error details from media
@ -539,7 +539,7 @@ class Listeners {
player,
element,
type,
event => this.proxy(event, defaultHandler, customHandlerKey),
(event) => this.proxy(event, defaultHandler, customHandlerKey),
passive && !hasCustomHandler,
);
}
@ -553,7 +553,7 @@ class Listeners {
// Play/pause toggle
if (elements.buttons.play) {
Array.from(elements.buttons.play).forEach(button => {
Array.from(elements.buttons.play).forEach((button) => {
this.bind(
button,
'click',
@ -624,7 +624,7 @@ class Listeners {
this.bind(
elements.buttons.settings,
'click',
event => {
(event) => {
// Prevent the document click listener closing the menu
event.stopPropagation();
event.preventDefault();
@ -641,7 +641,7 @@ class Listeners {
this.bind(
elements.buttons.settings,
'keyup',
event => {
(event) => {
const code = event.which;
// We only care about space and return
@ -669,21 +669,21 @@ class Listeners {
);
// Escape closes menu
this.bind(elements.settings.menu, 'keydown', event => {
this.bind(elements.settings.menu, 'keydown', (event) => {
if (event.which === 27) {
controls.toggleMenu.call(player, event);
}
});
// 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 percent = (100 / rect.width) * (event.pageX - rect.left);
event.currentTarget.setAttribute('seek-value', percent);
});
// 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 code = event.keyCode ? event.keyCode : event.which;
const attribute = 'play-on-seeked';
@ -715,14 +715,14 @@ class Listeners {
// it takes over further interactions on the page. This is a hack
if (browser.isIos) {
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
this.bind(
elements.inputs.seek,
inputEvent,
event => {
(event) => {
const seek = event.currentTarget;
// If it exists, use seek-value instead of "value" for consistency with tooltip time (#954)
let seekTo = seek.getAttribute('seek-value');
@ -739,13 +739,13 @@ class Listeners {
);
// Seek tooltip
this.bind(elements.progress, 'mouseenter mouseleave mousemove', event =>
this.bind(elements.progress, 'mouseenter mouseleave mousemove', (event) =>
controls.updateSeekTooltip.call(player, event),
);
// Preview thumbnails plugin
// 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;
if (previewThumbnails && previewThumbnails.loaded) {
@ -763,7 +763,7 @@ class Listeners {
});
// Show scrubbing preview
this.bind(elements.progress, 'mousedown touchstart', event => {
this.bind(elements.progress, 'mousedown touchstart', (event) => {
const { previewThumbnails } = player;
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;
if (previewThumbnails && previewThumbnails.loaded) {
@ -781,8 +781,8 @@ class Listeners {
// Polyfill for lower fill in <input type="range"> for webkit
if (browser.isWebkit) {
Array.from(getElements.call(player, 'input[type="range"]')).forEach(element => {
this.bind(element, 'input', event => controls.updateRangeFill.call(player, event.target));
Array.from(getElements.call(player, 'input[type="range"]')).forEach((element) => {
this.bind(element, 'input', (event) => controls.updateRangeFill.call(player, event.target));
});
}
@ -805,30 +805,30 @@ class Listeners {
this.bind(
elements.inputs.volume,
inputEvent,
event => {
(event) => {
player.volume = event.target.value;
},
'volume',
);
// 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';
});
// Also update controls.hover state for any non-player children of fullscreen element (as above)
if (elements.fullscreen) {
Array.from(elements.fullscreen.children)
.filter(c => !c.contains(elements.container))
.forEach(child => {
this.bind(child, 'mouseenter mouseleave', event => {
.filter((c) => !c.contains(elements.container))
.forEach((child) => {
this.bind(child, 'mouseenter mouseleave', (event) => {
elements.controls.hover = !player.touch && event.type === 'mouseenter';
});
});
}
// 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);
});
@ -861,12 +861,12 @@ class Listeners {
this.bind(
elements.inputs.volume,
'wheel',
event => {
(event) => {
// Detect "natural" scroll - suppored on OS X Safari only
// Other browsers on OS X will be inverted until support improves
const inverted = event.webkitDirectionInvertedFromDevice;
// 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)
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 { buildUrlParams } from '../utils/urls';
const destroy = instance => {
const destroy = (instance) => {
// Destroy our adsManager
if (instance.manager) {
instance.manager.destroy();
@ -179,10 +179,10 @@ class Ads {
// Listen and respond to ads loaded and error events
this.loader.addEventListener(
google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
event => this.onAdsManagerLoaded(event),
(event) => this.onAdsManagerLoaded(event),
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
this.requestAds();
@ -264,11 +264,11 @@ class Ads {
// Add listeners to the required 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
Object.keys(google.ima.AdEvent.Type).forEach(type => {
this.manager.addEventListener(google.ima.AdEvent.Type[type], e => this.onAdEvent(e));
Object.keys(google.ima.AdEvent.Type).forEach((type) => {
this.manager.addEventListener(google.ima.AdEvent.Type[type], (e) => this.onAdEvent(e));
});
// Resolve our adsManager
@ -278,7 +278,7 @@ class Ads {
addCuePoints() {
// Add advertisement cue's within the time line if available
if (!is.empty(this.cuePoints)) {
this.cuePoints.forEach(cuePoint => {
this.cuePoints.forEach((cuePoint) => {
if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < this.player.duration) {
const seekElement = this.player.elements.progress;
@ -310,7 +310,7 @@ class Ads {
const adData = event.getAdData();
// Proxy event
const dispatchEvent = type => {
const dispatchEvent = (type) => {
triggerEvent.call(this.player, this.player.media, `ads${type.replace(/_/g, '').toLowerCase()}`);
};
@ -565,7 +565,7 @@ class Ads {
}
// Re-set our adsManager promises
this.managerPromise = new Promise(resolve => {
this.managerPromise = new Promise((resolve) => {
this.on('loaded', resolve);
this.player.debug.log(this.manager);
});
@ -586,7 +586,7 @@ class Ads {
const handlers = this.events[event];
if (is.array(handlers)) {
handlers.forEach(handler => {
handlers.forEach((handler) => {
if (is.function(handler)) {
handler.apply(this, args);
}

View File

@ -5,15 +5,15 @@ import is from '../utils/is';
import { formatTime } from '../utils/time';
// 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 frames = vttDataString.split(/\r\n\r\n|\n\n|\r\r/);
frames.forEach(frame => {
frames.forEach((frame) => {
const result = {};
const lines = frame.split(/\r\n|\n|\r/);
lines.forEach(line => {
lines.forEach((line) => {
if (!is.number(result.startTime)) {
// The line with start and end times on it is the first line of interest
const matchTimes = line.match(
@ -130,7 +130,7 @@ class PreviewThumbnails {
// Download VTT files and parse them
getThumbnails() {
return new Promise(resolve => {
return new Promise((resolve) => {
const { src } = this.player.config.previewThumbnails;
if (is.empty(src)) {
@ -149,7 +149,7 @@ class PreviewThumbnails {
// Via callback()
if (is.function(src)) {
src(thumbnails => {
src((thumbnails) => {
this.thumbnails = thumbnails;
sortAndResolve();
});
@ -159,7 +159,7 @@ class PreviewThumbnails {
// If string, convert into single-element list
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
const promises = urls.map(u => this.getThumbnail(u));
const promises = urls.map((u) => this.getThumbnail(u));
// Resolve
Promise.all(promises).then(sortAndResolve);
}
@ -168,8 +168,8 @@ class PreviewThumbnails {
// Process individual VTT file
getThumbnail(url) {
return new Promise(resolve => {
fetch(url).then(response => {
return new Promise((resolve) => {
fetch(url).then((response) => {
const thumbnail = {
frames: parseVtt(response),
height: null,
@ -360,7 +360,7 @@ class PreviewThumbnails {
// Find the desired thumbnail index
// TODO: Handle a video longer than the thumbs where thumbNum is null
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;
let qualityIndex = 0;
@ -454,7 +454,7 @@ class PreviewThumbnails {
// Remove all preview images that aren't the designated current image
removeOldImages(currentImage) {
// 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') {
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
// This will only preload the lowest quality
preloadNearby(thumbNum, forward = true) {
return new Promise(resolve => {
return new Promise((resolve) => {
setTimeout(() => {
const oldThumbFilename = this.thumbnails[0].frames[thumbNum].text;
@ -496,7 +496,7 @@ class PreviewThumbnails {
let foundOne = false;
thumbnailsClone.forEach(frame => {
thumbnailsClone.forEach((frame) => {
const newThumbFilename = frame.text;
if (newThumbFilename !== oldThumbFilename) {

View File

@ -58,7 +58,7 @@ const vimeo = {
.then(() => {
vimeo.ready.call(player);
})
.catch(error => {
.catch((error) => {
player.debug.warn('Vimeo SDK (player.js) failed to load', error);
});
} else {
@ -123,7 +123,7 @@ const vimeo = {
}
// 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)) {
return;
}
@ -269,11 +269,11 @@ const vimeo = {
let currentSrc;
player.embed
.getVideoUrl()
.then(value => {
.then((value) => {
currentSrc = value;
controls.setDownloadUrl.call(player);
})
.catch(error => {
.catch((error) => {
this.debug.warn(error);
});
@ -291,49 +291,49 @@ const vimeo = {
});
// 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;
player.embed.ratio = [width, height];
setAspectRatio.call(this);
});
// Set autopause
player.embed.setAutopause(player.config.autopause).then(state => {
player.embed.setAutopause(player.config.autopause).then((state) => {
player.config.autopause = state;
});
// Get title
player.embed.getVideoTitle().then(title => {
player.embed.getVideoTitle().then((title) => {
player.config.title = title;
ui.setTitle.call(this);
});
// Get current time
player.embed.getCurrentTime().then(value => {
player.embed.getCurrentTime().then((value) => {
currentTime = value;
triggerEvent.call(player, player.media, 'timeupdate');
});
// Get duration
player.embed.getDuration().then(value => {
player.embed.getDuration().then((value) => {
player.media.duration = value;
triggerEvent.call(player, player.media, 'durationchange');
});
// Get captions
player.embed.getTextTracks().then(tracks => {
player.embed.getTextTracks().then((tracks) => {
player.media.textTracks = tracks;
captions.setup.call(player);
});
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);
});
player.embed.on('loaded', () => {
// Assure state and events are updated on autoplay
player.embed.getPaused().then(paused => {
player.embed.getPaused().then((paused) => {
assurePlaybackState.call(player, !paused);
if (!paused) {
triggerEvent.call(player, player.media, 'playing');
@ -366,13 +366,13 @@ const vimeo = {
assurePlaybackState.call(player, false);
});
player.embed.on('timeupdate', data => {
player.embed.on('timeupdate', (data) => {
player.media.seeking = false;
currentTime = data.seconds;
triggerEvent.call(player, player.media, 'timeupdate');
});
player.embed.on('progress', data => {
player.embed.on('progress', (data) => {
player.media.buffered = data.percent;
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
// https://github.com/sampotts/plyr/issues/891
player.embed.getDuration().then(value => {
player.embed.getDuration().then((value) => {
if (value !== player.media.duration) {
player.media.duration = value;
triggerEvent.call(player, player.media, 'durationchange');
@ -401,7 +401,7 @@ const vimeo = {
triggerEvent.call(player, player.media, 'ended');
});
player.embed.on('error', detail => {
player.embed.on('error', (detail) => {
player.media.error = detail;
triggerEvent.call(player, player.media, 'error');
});

View File

@ -70,7 +70,7 @@ const youtube = {
};
// 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);
});
}
@ -81,7 +81,7 @@ const youtube = {
const url = format(this.config.urls.youtube.api, videoId);
fetch(url)
.then(data => {
.then((data) => {
if (is.object(data)) {
const { title, height, width } = data;
@ -128,14 +128,14 @@ const youtube = {
player.media = replaceElement(container, player.media);
// 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)
loadImage(posterSrc('maxres'), 121) // Higest quality and unpadded
.catch(() => loadImage(posterSrc('sd'), 121)) // 480p padded 4:3
.catch(() => loadImage(posterSrc('hq'))) // 360p padded 4:3. Always exists
.then(image => ui.setPoster.call(player, image.src))
.then(src => {
.then((image) => ui.setPoster.call(player, image.src))
.then((src) => {
// If the image is padded, use background-size "cover" instead (like youtube does too with their posters)
if (!src.includes('maxres')) {
player.elements.poster.style.backgroundSize = 'cover';
@ -299,7 +299,7 @@ const youtube = {
// Get available speeds
const speeds = instance.getAvailablePlaybackRates();
// 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
if (player.supported.ui) {

View File

@ -282,7 +282,7 @@ class Plyr {
// Listen for events if debugging
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}`);
});
}
@ -1257,7 +1257,7 @@ class Plyr {
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,
});
} else if (is.array(attributes)) {
attributes.forEach(attribute => {
attributes.forEach((attribute) => {
insertElement(type, this.media, attribute);
});
}

View File

@ -135,7 +135,7 @@ const ui = {
}
// 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);
});
@ -178,7 +178,7 @@ const ui = {
.call(this)
// Load image
.then(() => loadImage(poster))
.catch(err => {
.catch((err) => {
// Hide poster on error unless it's been set by another call
if (poster === this.poster) {
ui.togglePoster.call(this, false);
@ -214,7 +214,7 @@ const ui = {
toggleClass(this.elements.container, this.config.classNames.stopped, this.stopped);
// Set state
Array.from(this.elements.buttons.play || []).forEach(target => {
Array.from(this.elements.buttons.play || []).forEach((target) => {
Object.assign(target, { pressed: this.playing });
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 🤔)
Object.values({ ...this.media.style })
// We're only fussed about Plyr specific properties
.filter(key => !is.empty(key) && is.string(key) && key.startsWith('--plyr'))
.forEach(key => {
.filter((key) => !is.empty(key) && is.string(key) && key.startsWith('--plyr'))
.forEach((key) => {
// Set on the container
this.elements.container.style.setProperty(key, this.media.style.getPropertyValue(key));

View File

@ -14,7 +14,7 @@ export const transitionEndEvent = (() => {
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;
})();

View File

@ -138,7 +138,7 @@ export function getAttributesFromSelector(sel, existingAttributes) {
const attributes = {};
const existing = extend({}, existingAttributes);
sel.split(',').forEach(s => {
sel.split(',').forEach((s) => {
// Remove whitespace
const selector = s.trim();
const className = selector.replace('.', '');
@ -198,7 +198,7 @@ export function toggleHidden(element, hidden) {
// Mirror Element.classList.toggle, with IE compatibility for "force" argument
export function toggleClass(element, className, force) {
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)) {

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
events.forEach(type => {
events.forEach((type) => {
if (this && this.eventListeners && toggle) {
// Cache event listener
this.eventListeners.push({ element, type, callback, options });
@ -100,7 +100,7 @@ export function triggerEvent(element, type = '', bubbles = false, detail = {}) {
// Unbind all cached event listeners
export function unbindListeners() {
if (this && this.eventListeners) {
this.eventListeners.forEach(item => {
this.eventListeners.forEach((item) => {
const { element, type, callback, options } = item;
element.removeEventListener(type, callback, options);
});
@ -111,7 +111,7 @@ export function unbindListeners() {
// Run method when / if player is 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),
).then(() => {});
}

View File

@ -2,31 +2,31 @@
// 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 isNullOrUndefined = input => input === null || typeof input === 'undefined';
const isObject = input => getConstructor(input) === Object;
const isNumber = input => getConstructor(input) === Number && !Number.isNaN(input);
const isString = input => getConstructor(input) === String;
const isBoolean = input => getConstructor(input) === Boolean;
const isFunction = input => getConstructor(input) === Function;
const isArray = input => Array.isArray(input);
const isWeakMap = input => instanceOf(input, WeakMap);
const isNodeList = input => instanceOf(input, NodeList);
const isElement = input => instanceOf(input, Element);
const isTextNode = input => getConstructor(input) === Text;
const isEvent = input => instanceOf(input, Event);
const isKeyboardEvent = input => instanceOf(input, KeyboardEvent);
const isCue = input => instanceOf(input, window.TextTrackCue) || instanceOf(input, window.VTTCue);
const isTrack = input => instanceOf(input, TextTrack) || (!isNullOrUndefined(input) && isString(input.kind));
const isPromise = input => instanceOf(input, Promise) && isFunction(input.then);
const isNullOrUndefined = (input) => input === null || typeof input === 'undefined';
const isObject = (input) => getConstructor(input) === Object;
const isNumber = (input) => getConstructor(input) === Number && !Number.isNaN(input);
const isString = (input) => getConstructor(input) === String;
const isBoolean = (input) => getConstructor(input) === Boolean;
const isFunction = (input) => getConstructor(input) === Function;
const isArray = (input) => Array.isArray(input);
const isWeakMap = (input) => instanceOf(input, WeakMap);
const isNodeList = (input) => instanceOf(input, NodeList);
const isElement = (input) => instanceOf(input, Element);
const isTextNode = (input) => getConstructor(input) === Text;
const isEvent = (input) => instanceOf(input, Event);
const isKeyboardEvent = (input) => instanceOf(input, KeyboardEvent);
const isCue = (input) => instanceOf(input, window.TextTrackCue) || instanceOf(input, window.VTTCue);
const isTrack = (input) => instanceOf(input, TextTrack) || (!isNullOrUndefined(input) && isString(input.kind));
const isPromise = (input) => instanceOf(input, Promise) && isFunction(input.then);
const isEmpty = input =>
const isEmpty = (input) =>
isNullOrUndefined(input) ||
((isString(input) || isArray(input) || isNodeList(input)) && !input.length) ||
(isObject(input) && !Object.keys(input).length);
const isUrl = input => {
const isUrl = (input) => {
// Accept a URL object
if (instanceOf(input, window.URL)) {
return true;

View File

@ -54,7 +54,7 @@ export default function loadSprite(url, id) {
// Get the sprite
fetch(url)
.then(result => {
.then((result) => {
if (is.empty(result)) {
return;
}

View File

@ -26,7 +26,7 @@ export function extend(target = {}, ...sources) {
return target;
}
Object.keys(source).forEach(key => {
Object.keys(source).forEach((key) => {
if (is.object(source[key])) {
if (!Object.keys(target).includes(key)) {
Object.assign(target, { [key]: {} });

View File

@ -33,7 +33,7 @@ export const replaceAll = (input = '', find = '', replace = '') =>
// Convert to title case
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
export function toPascalCase(input = '') {

View File

@ -27,7 +27,7 @@ export function reduceAspectRatio(ratio) {
}
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
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 offset = (height - padding) / (height / 50);
if(this.fullscreen.active) {
if (this.fullscreen.active) {
wrapper.style.paddingBottom = null;
} else {
this.media.style.transform = `translateY(-${offset}%)`;

View File

@ -5,9 +5,9 @@
import is from './is';
// Time helpers
export const getHours = value => Math.trunc((value / 60 / 60) % 60, 10);
export const getMinutes = value => Math.trunc((value / 60) % 60, 10);
export const getSeconds = value => Math.trunc(value % 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 getSeconds = (value) => Math.trunc(value % 60, 10);
// Format time to UI friendly string
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
const format = value => `0${value}`.slice(-2);
const format = (value) => `0${value}`.slice(-2);
// Breakdown to hours, mins, secs
let hours = getHours(time);
const mins = getMinutes(time);

2520
yarn.lock

File diff suppressed because it is too large Load Diff