Compare commits
43 Commits
v3.4.0-beta.1
...
v3.4.4
| Author | SHA1 | Date | |
|---|---|---|---|
| de47071256 | |||
| 87072cb690 | |||
| d9565e9250 | |||
| f80b568e67 | |||
| 7fed689f9a | |||
| 3f48df8f10 | |||
| cc55092ca6 | |||
| 3331d9d01d | |||
| 62d80e6b76 | |||
| 7dc4d9cd22 | |||
| 8fb8ae1260 | |||
| 90304369f4 | |||
| 922456c46c | |||
| eaeccd66ae | |||
| 7a43649c13 | |||
| 525bbf313e | |||
| cfaebe9bf2 | |||
| b57b7b2153 | |||
| 48bf368316 | |||
| 8f94ce86a0 | |||
| 10a9cf08f1 | |||
| 286d0d1794 | |||
| 95f6fa2731 | |||
| 1aeef81288 | |||
| 211ad6c8f5 | |||
| 468b20d227 | |||
| f6bc42c2bc | |||
| 2c01b8ba76 | |||
| 4e1df8677f | |||
| 6953a12e2a | |||
| 1d0db89194 | |||
| 297f297d18 | |||
| 059205c378 | |||
| f94e53ffb1 | |||
| a4f1fdec5d | |||
| 75374eb154 | |||
| 3ad118c026 | |||
| 0bc6b1f1b3 | |||
| 4ea458e1a3 | |||
| aacb172017 | |||
| dbf768b1bd | |||
| a8f8486cf4 | |||
| a343e58e53 |
+24
-1
@@ -1,8 +1,31 @@
|
|||||||
# v3.4.0-beta.1
|
# v3.4.4
|
||||||
|
|
||||||
|
- Fixed issue with double binding for `click` and `touchstart` for `clickToPlay` option
|
||||||
|
- Improved "faux" fullscreen on iPhone X/XS phones with notch
|
||||||
|
- Babel 7 upgrade (which reduced the polyfilled build by ~10kb!)
|
||||||
|
|
||||||
|
# v3.4.3
|
||||||
|
|
||||||
|
- Fixed issue with nodeList for custom playback controls
|
||||||
|
|
||||||
|
# v3.4.2
|
||||||
|
|
||||||
|
- Fix play/pause button state
|
||||||
|
|
||||||
|
# v3.4.1
|
||||||
|
|
||||||
|
- Bug fix for custom controls (fixes #1161)
|
||||||
|
|
||||||
|
# v3.4.0
|
||||||
|
|
||||||
- Accessibility improvements (see #905)
|
- Accessibility improvements (see #905)
|
||||||
- Improvements to the way the controls work on iOS
|
- Improvements to the way the controls work on iOS
|
||||||
- Demo code clean up
|
- Demo code clean up
|
||||||
|
- YouTube quality selection removed due to their poor support for it. As a result, the `qualityrequested` event has been removed
|
||||||
|
- Controls spacing improvements
|
||||||
|
- Fix for pressed property missing with custom controls (Fixes #1062)
|
||||||
|
- Fix #1153: Captions language fallback (thanks @friday)
|
||||||
|
- Fix for setting pressed property of undefined (Fixes #1102)
|
||||||
|
|
||||||
# v3.3.23
|
# v3.3.23
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+48
-61
@@ -1833,7 +1833,6 @@ typeof navigator === "object" && (function () {
|
|||||||
};
|
};
|
||||||
this._fetchDefaults = {
|
this._fetchDefaults = {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
keepalive: true,
|
|
||||||
// Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default
|
// Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default
|
||||||
// https://caniuse.com/#feat=referrer-policy
|
// https://caniuse.com/#feat=referrer-policy
|
||||||
// It doesn't. And it throw exception instead of ignoring this parameter...
|
// It doesn't. And it throw exception instead of ignoring this parameter...
|
||||||
@@ -1874,7 +1873,7 @@ typeof navigator === "object" && (function () {
|
|||||||
// webpack (using a build step causes webpack #1617). Grunt verifies that
|
// webpack (using a build step causes webpack #1617). Grunt verifies that
|
||||||
// this value matches package.json during build.
|
// this value matches package.json during build.
|
||||||
// See: https://github.com/getsentry/raven-js/issues/465
|
// See: https://github.com/getsentry/raven-js/issues/465
|
||||||
VERSION: '3.26.4',
|
VERSION: '3.27.0',
|
||||||
|
|
||||||
debug: false,
|
debug: false,
|
||||||
|
|
||||||
@@ -2612,7 +2611,7 @@ typeof navigator === "object" && (function () {
|
|||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
options = Object.assign(
|
options = objectMerge$1(
|
||||||
{
|
{
|
||||||
eventId: this.lastEventId(),
|
eventId: this.lastEventId(),
|
||||||
dsn: this._dsn,
|
dsn: this._dsn,
|
||||||
@@ -4094,12 +4093,10 @@ typeof navigator === "object" && (function () {
|
|||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
var host = window.location.host;
|
var host = window.location.host;
|
||||||
|
|
||||||
var env = {
|
var env = {
|
||||||
prod: host === 'plyr.io',
|
prod: host === 'plyr.io',
|
||||||
dev: host === 'dev.plyr.io'
|
dev: host === 'dev.plyr.io'
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
singleton.context(function () {
|
singleton.context(function () {
|
||||||
var selector = '#player';
|
var selector = '#player';
|
||||||
@@ -4111,39 +4108,37 @@ typeof navigator === "object" && (function () {
|
|||||||
classname: 'button__count'
|
classname: 'button__count'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
} // Setup tab focus
|
||||||
|
|
||||||
// Setup tab focus
|
|
||||||
var tabClassName = 'tab-focus';
|
|
||||||
|
|
||||||
// Remove class on blur
|
var tabClassName = 'tab-focus'; // Remove class on blur
|
||||||
|
|
||||||
document.addEventListener('focusout', function (event) {
|
document.addEventListener('focusout', function (event) {
|
||||||
if (container.contains(event.target)) {
|
if (!event.target.classList || container.contains(event.target)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
event.target.classList.remove(tabClassName);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add classname to tabbed elements
|
event.target.classList.remove(tabClassName);
|
||||||
|
}); // Add classname to tabbed elements
|
||||||
|
|
||||||
document.addEventListener('keydown', function (event) {
|
document.addEventListener('keydown', function (event) {
|
||||||
if (event.keyCode !== 9) {
|
if (event.keyCode !== 9) {
|
||||||
return;
|
return;
|
||||||
}
|
} // Delay the adding of classname until the focus has changed
|
||||||
|
|
||||||
// Delay the adding of classname until the focus has changed
|
|
||||||
// This event fires before the focusin event
|
// This event fires before the focusin event
|
||||||
|
|
||||||
|
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
var focused = document.activeElement;
|
var focused = document.activeElement;
|
||||||
|
|
||||||
if (!focused || container.contains(focused)) {
|
if (!focused || !focused.classList || container.contains(focused)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
focused.classList.add(tabClassName);
|
focused.classList.add(tabClassName);
|
||||||
}, 10);
|
}, 10);
|
||||||
});
|
}); // Setup the player
|
||||||
|
|
||||||
// Setup the player
|
|
||||||
var player = new Plyr(selector, {
|
var player = new Plyr(selector, {
|
||||||
debug: true,
|
debug: true,
|
||||||
title: 'View From A Blue Moon',
|
title: 'View From A Blue Moon',
|
||||||
@@ -4164,12 +4159,10 @@ typeof navigator === "object" && (function () {
|
|||||||
enabled: env.prod || env.dev,
|
enabled: env.prod || env.dev,
|
||||||
publisherId: '918848828995742'
|
publisherId: '918848828995742'
|
||||||
}
|
}
|
||||||
});
|
}); // Expose for tinkering in the console
|
||||||
|
|
||||||
// Expose for tinkering in the console
|
window.player = player; // Setup type toggle
|
||||||
window.player = player;
|
|
||||||
|
|
||||||
// Setup type toggle
|
|
||||||
var buttons = document.querySelectorAll('[data-source]');
|
var buttons = document.querySelectorAll('[data-source]');
|
||||||
var types = {
|
var types = {
|
||||||
video: 'video',
|
video: 'video',
|
||||||
@@ -4178,16 +4171,15 @@ typeof navigator === "object" && (function () {
|
|||||||
vimeo: 'vimeo'
|
vimeo: 'vimeo'
|
||||||
};
|
};
|
||||||
var currentType = window.location.hash.replace('#', '');
|
var currentType = window.location.hash.replace('#', '');
|
||||||
var historySupport = window.history && window.history.pushState;
|
var historySupport = window.history && window.history.pushState; // Toggle class on an element
|
||||||
|
|
||||||
// Toggle class on an element
|
|
||||||
function toggleClass(element, className, state) {
|
function toggleClass(element, className, state) {
|
||||||
if (element) {
|
if (element) {
|
||||||
element.classList[state ? 'add' : 'remove'](className);
|
element.classList[state ? 'add' : 'remove'](className);
|
||||||
}
|
}
|
||||||
}
|
} // Set a new source
|
||||||
|
|
||||||
|
|
||||||
// Set a new source
|
|
||||||
function newSource(type, init) {
|
function newSource(type, init) {
|
||||||
// Bail if new type isn't known, it's the current type, or current type is empty (video is default) and new type is video
|
// Bail if new type isn't known, it's the current type, or current type is empty (video is default) and new type is video
|
||||||
if (!(type in types) || !init && type === currentType || !currentType.length && type === types.video) {
|
if (!(type in types) || !init && type === currentType || !currentType.length && type === types.video) {
|
||||||
@@ -4230,7 +4222,6 @@ typeof navigator === "object" && (function () {
|
|||||||
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt'
|
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt'
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case types.audio:
|
case types.audio:
|
||||||
@@ -4245,7 +4236,6 @@ typeof navigator === "object" && (function () {
|
|||||||
type: 'audio/ogg'
|
type: 'audio/ogg'
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case types.youtube:
|
case types.youtube:
|
||||||
@@ -4256,7 +4246,6 @@ typeof navigator === "object" && (function () {
|
|||||||
provider: 'youtube'
|
provider: 'youtube'
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case types.vimeo:
|
case types.vimeo:
|
||||||
@@ -4267,90 +4256,86 @@ typeof navigator === "object" && (function () {
|
|||||||
provider: 'vimeo'
|
provider: 'vimeo'
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
} // Set the current type for next time
|
||||||
|
|
||||||
// Set the current type for next time
|
|
||||||
currentType = type;
|
|
||||||
|
|
||||||
// Remove active classes
|
currentType = type; // Remove active classes
|
||||||
|
|
||||||
Array.from(buttons).forEach(function (button) {
|
Array.from(buttons).forEach(function (button) {
|
||||||
return toggleClass(button.parentElement, 'active', false);
|
return toggleClass(button.parentElement, 'active', false);
|
||||||
});
|
}); // Set active on parent
|
||||||
|
|
||||||
// Set active on parent
|
toggleClass(document.querySelector("[data-source=\"".concat(type, "\"]")), 'active', true); // Show cite
|
||||||
toggleClass(document.querySelector('[data-source="' + type + '"]'), 'active', true);
|
|
||||||
|
|
||||||
// Show cite
|
|
||||||
Array.from(document.querySelectorAll('.plyr__cite')).forEach(function (cite) {
|
Array.from(document.querySelectorAll('.plyr__cite')).forEach(function (cite) {
|
||||||
cite.setAttribute('hidden', '');
|
cite.setAttribute('hidden', '');
|
||||||
});
|
});
|
||||||
document.querySelector('.plyr__cite--' + type).removeAttribute('hidden');
|
document.querySelector(".plyr__cite--".concat(type)).removeAttribute('hidden');
|
||||||
}
|
} // Bind to each button
|
||||||
|
|
||||||
|
|
||||||
// Bind to each button
|
|
||||||
Array.from(buttons).forEach(function (button) {
|
Array.from(buttons).forEach(function (button) {
|
||||||
button.addEventListener('click', function () {
|
button.addEventListener('click', function () {
|
||||||
var type = button.getAttribute('data-source');
|
var type = button.getAttribute('data-source');
|
||||||
|
|
||||||
newSource(type);
|
newSource(type);
|
||||||
|
|
||||||
if (historySupport) {
|
if (historySupport) {
|
||||||
window.history.pushState({ type: type }, '', '#' + type);
|
window.history.pushState({
|
||||||
|
type: type
|
||||||
|
}, '', "#".concat(type));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}); // List for backwards/forwards
|
||||||
|
|
||||||
// List for backwards/forwards
|
|
||||||
window.addEventListener('popstate', function (event) {
|
window.addEventListener('popstate', function (event) {
|
||||||
if (event.state && 'type' in event.state) {
|
if (event.state && 'type' in event.state) {
|
||||||
newSource(event.state.type);
|
newSource(event.state.type);
|
||||||
}
|
}
|
||||||
});
|
}); // On load
|
||||||
|
|
||||||
// On load
|
|
||||||
if (historySupport) {
|
if (historySupport) {
|
||||||
var video = !currentType.length;
|
var video = !currentType.length; // If there's no current type set, assume video
|
||||||
|
|
||||||
// If there's no current type set, assume video
|
|
||||||
if (video) {
|
if (video) {
|
||||||
currentType = types.video;
|
currentType = types.video;
|
||||||
}
|
} // Replace current history state
|
||||||
|
|
||||||
|
|
||||||
// Replace current history state
|
|
||||||
if (currentType in types) {
|
if (currentType in types) {
|
||||||
window.history.replaceState({
|
window.history.replaceState({
|
||||||
type: currentType
|
type: currentType
|
||||||
}, '', video ? '' : '#' + currentType);
|
}, '', video ? '' : "#".concat(currentType));
|
||||||
}
|
} // If it's not video, load the source
|
||||||
|
|
||||||
|
|
||||||
// If it's not video, load the source
|
|
||||||
if (currentType !== types.video) {
|
if (currentType !== types.video) {
|
||||||
newSource(currentType, true);
|
newSource(currentType, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}); // Raven / Sentry
|
||||||
|
|
||||||
// Raven / Sentry
|
|
||||||
// For demo site (https://plyr.io) only
|
// For demo site (https://plyr.io) only
|
||||||
|
|
||||||
if (env.prod) {
|
if (env.prod) {
|
||||||
singleton.config('https://d4ad9866ad834437a4754e23937071e4@sentry.io/305555').install();
|
singleton.config('https://d4ad9866ad834437a4754e23937071e4@sentry.io/305555').install();
|
||||||
}
|
} // Google analytics
|
||||||
|
|
||||||
// Google analytics
|
|
||||||
// For demo site (https://plyr.io) only
|
// For demo site (https://plyr.io) only
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
|
||||||
|
|
||||||
if (env.prod) {
|
if (env.prod) {
|
||||||
(function (i, s, o, g, r, a, m) {
|
(function (i, s, o, g, r, a, m) {
|
||||||
i.GoogleAnalyticsObject = r;
|
i.GoogleAnalyticsObject = r;
|
||||||
|
|
||||||
i[r] = i[r] || function () {
|
i[r] = i[r] || function () {
|
||||||
(i[r].q = i[r].q || []).push(arguments);
|
(i[r].q = i[r].q || []).push(arguments);
|
||||||
};
|
};
|
||||||
|
|
||||||
i[r].l = 1 * new Date();
|
i[r].l = 1 * new Date();
|
||||||
a = s.createElement(o);
|
a = s.createElement(o);
|
||||||
m = s.getElementsByTagName(o)[0];
|
m = s.getElementsByTagName(o)[0];
|
||||||
@@ -4358,10 +4343,12 @@ typeof navigator === "object" && (function () {
|
|||||||
a.src = g;
|
a.src = g;
|
||||||
m.parentNode.insertBefore(a, m);
|
m.parentNode.insertBefore(a, m);
|
||||||
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
|
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
|
||||||
|
|
||||||
window.ga('create', 'UA-40881672-11', 'auto');
|
window.ga('create', 'UA-40881672-11', 'auto');
|
||||||
window.ga('send', 'pageview');
|
window.ga('send', 'pageview');
|
||||||
}
|
}
|
||||||
/* eslint-enable */
|
/* eslint-enable */
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+3
-2
@@ -31,9 +31,10 @@ import Raven from 'raven-js';
|
|||||||
|
|
||||||
// Remove class on blur
|
// Remove class on blur
|
||||||
document.addEventListener('focusout', event => {
|
document.addEventListener('focusout', event => {
|
||||||
if (container.contains(event.target)) {
|
if (!event.target.classList || container.contains(event.target)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.target.classList.remove(tabClassName);
|
event.target.classList.remove(tabClassName);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -48,7 +49,7 @@ import Raven from 'raven-js';
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const focused = document.activeElement;
|
const focused = document.activeElement;
|
||||||
|
|
||||||
if (!focused || container.contains(focused)) {
|
if (!focused || !focused.classList || container.contains(focused)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1668
-2505
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+3138
-6676
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg"><symbol id="plyr-airplay" viewBox="0 0 18 18"><path d="M16 1H2a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h3v-2H3V3h12v8h-2v2h3a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1z"/><path d="M4 17h10l-5-6z"/></symbol><symbol id="plyr-captions-off" viewBox="0 0 18 18"><path d="M1 1c-.6 0-1 .4-1 1v11c0 .6.4 1 1 1h4.6l2.7 2.7c.2.2.4.3.7.3.3 0 .5-.1.7-.3l2.7-2.7H17c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1H1zm4.52 10.15c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41C8.47 4.96 7.46 3.76 5.5 3.76c-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69zm7.57 0c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41c-.28-1.15-1.29-2.35-3.25-2.35-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69z" fill-rule="evenodd" fill-opacity=".5"/></symbol><symbol id="plyr-captions-on" viewBox="0 0 18 18"><path d="M1 1c-.6 0-1 .4-1 1v11c0 .6.4 1 1 1h4.6l2.7 2.7c.2.2.4.3.7.3.3 0 .5-.1.7-.3l2.7-2.7H17c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1H1zm4.52 10.15c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41C8.47 4.96 7.46 3.76 5.5 3.76c-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69zm7.57 0c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41c-.28-1.15-1.29-2.35-3.25-2.35-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69z" fill-rule="evenodd"/></symbol><symbol id="plyr-enter-fullscreen" viewBox="0 0 18 18"><path d="M10 3h3.6l-4 4L11 8.4l4-4V8h2V1h-7zM7 9.6l-4 4V10H1v7h7v-2H4.4l4-4z"/></symbol><symbol id="plyr-exit-fullscreen" viewBox="0 0 18 18"><path d="M1 12h3.6l-4 4L2 17.4l4-4V17h2v-7H1zM16 .6l-4 4V1h-2v7h7V6h-3.6l4-4z"/></symbol><symbol id="plyr-fast-forward" viewBox="0 0 18 18"><path d="M7.875 7.171L0 1v16l7.875-6.171V17L18 9 7.875 1z"/></symbol><symbol id="plyr-muted" viewBox="0 0 18 18"><path d="M12.4 12.5l2.1-2.1 2.1 2.1 1.4-1.4L15.9 9 18 6.9l-1.4-1.4-2.1 2.1-2.1-2.1L11 6.9 13.1 9 11 11.1zM3.786 6.008H.714C.286 6.008 0 6.31 0 6.76v4.512c0 .452.286.752.714.752h3.072l4.071 3.858c.5.3 1.143 0 1.143-.602V2.752c0-.601-.643-.977-1.143-.601L3.786 6.008z"/></symbol><symbol id="plyr-pause" viewBox="0 0 18 18"><path d="M6 1H3c-.6 0-1 .4-1 1v14c0 .6.4 1 1 1h3c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1zM12 1c-.6 0-1 .4-1 1v14c0 .6.4 1 1 1h3c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1h-3z"/></symbol><symbol id="plyr-pip" viewBox="0 0 18 18"><path d="M13.293 3.293L7.022 9.564l1.414 1.414 6.271-6.271L17 7V1h-6z"/><path d="M13 15H3V5h5V3H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-6h-2v5z"/></symbol><symbol id="plyr-play" viewBox="0 0 18 18"><path d="M15.562 8.1L3.87.225C3.052-.337 2 .225 2 1.125v15.75c0 .9 1.052 1.462 1.87.9L15.563 9.9c.584-.45.584-1.35 0-1.8z"/></symbol><symbol id="plyr-restart" viewBox="0 0 18 18"><path d="M9.7 1.2l.7 6.4 2.1-2.1c1.9 1.9 1.9 5.1 0 7-.9 1-2.2 1.5-3.5 1.5-1.3 0-2.6-.5-3.5-1.5-1.9-1.9-1.9-5.1 0-7 .6-.6 1.4-1.1 2.3-1.3l-.6-1.9C6 2.6 4.9 3.2 4 4.1 1.3 6.8 1.3 11.2 4 14c1.3 1.3 3.1 2 4.9 2 1.9 0 3.6-.7 4.9-2 2.7-2.7 2.7-7.1 0-9.9L16 1.9l-6.3-.7z"/></symbol><symbol id="plyr-rewind" viewBox="0 0 18 18"><path d="M10.125 1L0 9l10.125 8v-6.171L18 17V1l-7.875 6.171z"/></symbol><symbol id="plyr-settings" viewBox="0 0 18 18"><path d="M16.135 7.784a2 2 0 0 1-1.23-2.969c.322-.536.225-.998-.094-1.316l-.31-.31c-.318-.318-.78-.415-1.316-.094a2 2 0 0 1-2.969-1.23C10.065 1.258 9.669 1 9.219 1h-.438c-.45 0-.845.258-.997.865a2 2 0 0 1-2.969 1.23c-.536-.322-.999-.225-1.317.093l-.31.31c-.318.318-.415.781-.093 1.317a2 2 0 0 1-1.23 2.969C1.26 7.935 1 8.33 1 8.781v.438c0 .45.258.845.865.997a2 2 0 0 1 1.23 2.969c-.322.536-.225.998.094 1.316l.31.31c.319.319.782.415 1.316.094a2 2 0 0 1 2.969 1.23c.151.607.547.865.997.865h.438c.45 0 .845-.258.997-.865a2 2 0 0 1 2.969-1.23c.535.321.997.225 1.316-.094l.31-.31c.318-.318.415-.781.094-1.316a2 2 0 0 1 1.23-2.969c.607-.151.865-.547.865-.997v-.438c0-.451-.26-.846-.865-.997zM9 12a3 3 0 1 1 0-6 3 3 0 0 1 0 6z"/></symbol><symbol id="plyr-volume" viewBox="0 0 18 18"><path d="M15.6 3.3c-.4-.4-1-.4-1.4 0-.4.4-.4 1 0 1.4C15.4 5.9 16 7.4 16 9c0 1.6-.6 3.1-1.8 4.3-.4.4-.4 1 0 1.4.2.2.5.3.7.3.3 0 .5-.1.7-.3C17.1 13.2 18 11.2 18 9s-.9-4.2-2.4-5.7z"/><path d="M11.282 5.282a.909.909 0 0 0 0 1.316c.735.735.995 1.458.995 2.402 0 .936-.425 1.917-.995 2.487a.909.909 0 0 0 0 1.316c.145.145.636.262 1.018.156a.725.725 0 0 0 .298-.156C13.773 11.733 14.13 10.16 14.13 9c0-.17-.002-.34-.011-.51-.053-.992-.319-2.005-1.522-3.208a.909.909 0 0 0-1.316 0zM3.786 6.008H.714C.286 6.008 0 6.31 0 6.76v4.512c0 .452.286.752.714.752h3.072l4.071 3.858c.5.3 1.143 0 1.143-.602V2.752c0-.601-.643-.977-1.143-.601L3.786 6.008z"/></symbol></svg>
|
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg"><symbol id="plyr-airplay"><path d="M16 1H2a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h3v-2H3V3h12v8h-2v2h3a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1z"/><path d="M4 17h10l-5-6z"/></symbol><symbol id="plyr-captions-off"><path d="M1 1c-.6 0-1 .4-1 1v11c0 .6.4 1 1 1h4.6l2.7 2.7c.2.2.4.3.7.3.3 0 .5-.1.7-.3l2.7-2.7H17c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1H1zm4.52 10.15c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41C8.47 4.96 7.46 3.76 5.5 3.76c-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69zm7.57 0c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41c-.28-1.15-1.29-2.35-3.25-2.35-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69z" fill-rule="evenodd" fill-opacity=".5"/></symbol><symbol id="plyr-captions-on"><path d="M1 1c-.6 0-1 .4-1 1v11c0 .6.4 1 1 1h4.6l2.7 2.7c.2.2.4.3.7.3.3 0 .5-.1.7-.3l2.7-2.7H17c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1H1zm4.52 10.15c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41C8.47 4.96 7.46 3.76 5.5 3.76c-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69zm7.57 0c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41c-.28-1.15-1.29-2.35-3.25-2.35-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69z" fill-rule="evenodd"/></symbol><symbol id="plyr-enter-fullscreen"><path d="M10 3h3.6l-4 4L11 8.4l4-4V8h2V1h-7zM7 9.6l-4 4V10H1v7h7v-2H4.4l4-4z"/></symbol><symbol id="plyr-exit-fullscreen"><path d="M1 12h3.6l-4 4L2 17.4l4-4V17h2v-7H1zM16 .6l-4 4V1h-2v7h7V6h-3.6l4-4z"/></symbol><symbol id="plyr-fast-forward"><path d="M7.875 7.171L0 1v16l7.875-6.171V17L18 9 7.875 1z"/></symbol><symbol id="plyr-muted"><path d="M12.4 12.5l2.1-2.1 2.1 2.1 1.4-1.4L15.9 9 18 6.9l-1.4-1.4-2.1 2.1-2.1-2.1L11 6.9 13.1 9 11 11.1zM3.786 6.008H.714C.286 6.008 0 6.31 0 6.76v4.512c0 .452.286.752.714.752h3.072l4.071 3.858c.5.3 1.143 0 1.143-.602V2.752c0-.601-.643-.977-1.143-.601L3.786 6.008z"/></symbol><symbol id="plyr-pause"><path d="M6 1H3c-.6 0-1 .4-1 1v14c0 .6.4 1 1 1h3c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1zM12 1c-.6 0-1 .4-1 1v14c0 .6.4 1 1 1h3c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1h-3z"/></symbol><symbol id="plyr-pip"><path d="M13.293 3.293L7.022 9.564l1.414 1.414 6.271-6.271L17 7V1h-6z"/><path d="M13 15H3V5h5V3H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-6h-2v5z"/></symbol><symbol id="plyr-play"><path d="M15.562 8.1L3.87.225C3.052-.337 2 .225 2 1.125v15.75c0 .9 1.052 1.462 1.87.9L15.563 9.9c.584-.45.584-1.35 0-1.8z"/></symbol><symbol id="plyr-restart"><path d="M9.7 1.2l.7 6.4 2.1-2.1c1.9 1.9 1.9 5.1 0 7-.9 1-2.2 1.5-3.5 1.5-1.3 0-2.6-.5-3.5-1.5-1.9-1.9-1.9-5.1 0-7 .6-.6 1.4-1.1 2.3-1.3l-.6-1.9C6 2.6 4.9 3.2 4 4.1 1.3 6.8 1.3 11.2 4 14c1.3 1.3 3.1 2 4.9 2 1.9 0 3.6-.7 4.9-2 2.7-2.7 2.7-7.1 0-9.9L16 1.9l-6.3-.7z"/></symbol><symbol id="plyr-rewind"><path d="M10.125 1L0 9l10.125 8v-6.171L18 17V1l-7.875 6.171z"/></symbol><symbol id="plyr-settings"><path d="M16.135 7.784a2 2 0 0 1-1.23-2.969c.322-.536.225-.998-.094-1.316l-.31-.31c-.318-.318-.78-.415-1.316-.094a2 2 0 0 1-2.969-1.23C10.065 1.258 9.669 1 9.219 1h-.438c-.45 0-.845.258-.997.865a2 2 0 0 1-2.969 1.23c-.536-.322-.999-.225-1.317.093l-.31.31c-.318.318-.415.781-.093 1.317a2 2 0 0 1-1.23 2.969C1.26 7.935 1 8.33 1 8.781v.438c0 .45.258.845.865.997a2 2 0 0 1 1.23 2.969c-.322.536-.225.998.094 1.316l.31.31c.319.319.782.415 1.316.094a2 2 0 0 1 2.969 1.23c.151.607.547.865.997.865h.438c.45 0 .845-.258.997-.865a2 2 0 0 1 2.969-1.23c.535.321.997.225 1.316-.094l.31-.31c.318-.318.415-.781.094-1.316a2 2 0 0 1 1.23-2.969c.607-.151.865-.547.865-.997v-.438c0-.451-.26-.846-.865-.997zM9 12a3 3 0 1 1 0-6 3 3 0 0 1 0 6z"/></symbol><symbol id="plyr-volume"><path d="M15.6 3.3c-.4-.4-1-.4-1.4 0-.4.4-.4 1 0 1.4C15.4 5.9 16 7.4 16 9c0 1.6-.6 3.1-1.8 4.3-.4.4-.4 1 0 1.4.2.2.5.3.7.3.3 0 .5-.1.7-.3C17.1 13.2 18 11.2 18 9s-.9-4.2-2.4-5.7z"/><path d="M11.282 5.282a.909.909 0 0 0 0 1.316c.735.735.995 1.458.995 2.402 0 .936-.425 1.917-.995 2.487a.909.909 0 0 0 0 1.316c.145.145.636.262 1.018.156a.725.725 0 0 0 .298-.156C13.773 11.733 14.13 10.16 14.13 9c0-.17-.002-.34-.011-.51-.053-.992-.319-2.005-1.522-3.208a.909.909 0 0 0-1.316 0zM3.786 6.008H.714C.286 6.008 0 6.31 0 6.76v4.512c0 .452.286.752.714.752h3.072l4.071 3.858c.5.3 1.143 0 1.143-.602V2.752c0-.601-.643-.977-1.143-.601L3.786 6.008z"/></symbol></svg>
|
||||||
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.6 KiB |
+22
-47
@@ -44,7 +44,7 @@ const paths = {
|
|||||||
// Source paths
|
// Source paths
|
||||||
src: {
|
src: {
|
||||||
sass: path.join(root, 'src/sass/**/*.scss'),
|
sass: path.join(root, 'src/sass/**/*.scss'),
|
||||||
js: path.join(root, 'src/js/**/*'),
|
js: path.join(root, 'src/js/**/*.js'),
|
||||||
sprite: path.join(root, 'src/sprite/*.svg'),
|
sprite: path.join(root, 'src/sprite/*.svg'),
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ const paths = {
|
|||||||
// Source paths
|
// Source paths
|
||||||
src: {
|
src: {
|
||||||
sass: path.join(root, 'demo/src/sass/**/*.scss'),
|
sass: path.join(root, 'demo/src/sass/**/*.scss'),
|
||||||
js: path.join(root, 'demo/src/js/**/*'),
|
js: path.join(root, 'demo/src/js/**/*.js'),
|
||||||
},
|
},
|
||||||
|
|
||||||
// Output paths
|
// Output paths
|
||||||
@@ -88,29 +88,26 @@ const sizeOptions = { showFiles: true, gzip: true };
|
|||||||
const browsers = ['> 1%'];
|
const browsers = ['> 1%'];
|
||||||
|
|
||||||
// Babel config
|
// Babel config
|
||||||
const babelrc = {
|
const babelrc = (polyfill = false) => ({
|
||||||
presets: [
|
presets: [
|
||||||
[
|
[
|
||||||
'env',
|
'@babel/preset-env',
|
||||||
{
|
{
|
||||||
targets: {
|
targets: {
|
||||||
browsers,
|
browsers,
|
||||||
},
|
},
|
||||||
useBuiltIns: true,
|
useBuiltIns: polyfill ? 'usage' : false,
|
||||||
modules: false,
|
modules: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
plugins: ['external-helpers'],
|
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
exclude: 'node_modules/**',
|
exclude: 'node_modules/**',
|
||||||
};
|
});
|
||||||
|
|
||||||
// Clean out /dist
|
// Clean out /dist
|
||||||
gulp.task('clean', () => {
|
gulp.task('clean', () => {
|
||||||
const dirs = [paths.plyr.output, paths.demo.output].map(dir =>
|
const dirs = [paths.plyr.output, paths.demo.output].map(dir => path.join(dir, '**/*'));
|
||||||
path.join(dir, '**/*'),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Don't delete the mp4
|
// Don't delete the mp4
|
||||||
dirs.push(`!${path.join(paths.plyr.output, '**/*.mp4')}`);
|
dirs.push(`!${path.join(paths.plyr.output, '**/*.mp4')}`);
|
||||||
@@ -124,6 +121,7 @@ const build = {
|
|||||||
const name = `js:${key}`;
|
const name = `js:${key}`;
|
||||||
tasks.js.push(name);
|
tasks.js.push(name);
|
||||||
const { output } = paths[bundle];
|
const { output } = paths[bundle];
|
||||||
|
const polyfill = name.includes('polyfilled');
|
||||||
|
|
||||||
return gulp.task(name, () =>
|
return gulp.task(name, () =>
|
||||||
gulp
|
gulp
|
||||||
@@ -133,11 +131,7 @@ const build = {
|
|||||||
.pipe(
|
.pipe(
|
||||||
rollup(
|
rollup(
|
||||||
{
|
{
|
||||||
plugins: [
|
plugins: [resolve(), commonjs(), babel(babelrc(polyfill))],
|
||||||
resolve(),
|
|
||||||
commonjs(),
|
|
||||||
babel(babelrc),
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
options,
|
options,
|
||||||
),
|
),
|
||||||
@@ -244,10 +238,7 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If deployment is setup
|
// If deployment is setup
|
||||||
if (
|
if (Object.keys(credentials).includes('aws') && Object.keys(credentials).includes('fastly')) {
|
||||||
Object.keys(credentials).includes('aws') &&
|
|
||||||
Object.keys(credentials).includes('fastly')
|
|
||||||
) {
|
|
||||||
const { version } = pkg;
|
const { version } = pkg;
|
||||||
const { aws, fastly } = credentials;
|
const { aws, fastly } = credentials;
|
||||||
|
|
||||||
@@ -269,8 +260,7 @@ if (
|
|||||||
demo: {
|
demo: {
|
||||||
uploadPath: branch.current === branch.develop ? 'beta/' : null,
|
uploadPath: branch.current === branch.develop ? 'beta/' : null,
|
||||||
headers: {
|
headers: {
|
||||||
'Cache-Control':
|
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
|
||||||
'no-cache, no-store, must-revalidate, max-age=0',
|
|
||||||
Vary: 'Accept-Encoding',
|
Vary: 'Accept-Encoding',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -279,8 +269,7 @@ if (
|
|||||||
headers: {
|
headers: {
|
||||||
// http://stackoverflow.com/questions/2272835/amazon-s3-object-redirect
|
// http://stackoverflow.com/questions/2272835/amazon-s3-object-redirect
|
||||||
'x-amz-website-redirect-location': `/${ver}/${filename}`,
|
'x-amz-website-redirect-location': `/${ver}/${filename}`,
|
||||||
'Cache-Control':
|
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
|
||||||
'no-cache, no-store, must-revalidate, max-age=0',
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -303,11 +292,7 @@ if (
|
|||||||
const allowed = [branch.master, branch.develop];
|
const allowed = [branch.master, branch.develop];
|
||||||
|
|
||||||
if (!allowed.includes(branch.current)) {
|
if (!allowed.includes(branch.current)) {
|
||||||
console.error(
|
console.error(`Must be on ${allowed.join(', ')} to publish! (current: ${branch.current})`);
|
||||||
`Must be on ${allowed.join(', ')} to publish! (current: ${
|
|
||||||
branch.current
|
|
||||||
})`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -349,8 +334,7 @@ if (
|
|||||||
.pipe(
|
.pipe(
|
||||||
replace(
|
replace(
|
||||||
/sourceMappingURL=([\w-?.]+)/,
|
/sourceMappingURL=([\w-?.]+)/,
|
||||||
(match, p1) =>
|
(match, p1) => `sourceMappingURL=${p1.replace(minSuffix, '')}`,
|
||||||
`sourceMappingURL=${p1.replace(minSuffix, '')}`,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.pipe(
|
.pipe(
|
||||||
@@ -368,13 +352,16 @@ if (
|
|||||||
gulp.task('purge', () => {
|
gulp.task('purge', () => {
|
||||||
const list = [];
|
const list = [];
|
||||||
|
|
||||||
return gulp.src(paths.upload).pipe(
|
return gulp
|
||||||
|
.src(paths.upload)
|
||||||
|
.pipe(
|
||||||
through.obj((file, enc, cb) => {
|
through.obj((file, enc, cb) => {
|
||||||
const filename = file.path.split('/').pop();
|
const filename = file.path.split('/').pop();
|
||||||
list.push(`${versionPath}/${filename}`);
|
list.push(`${versionPath}/${filename}`);
|
||||||
cb(null);
|
cb(null);
|
||||||
}),
|
}),
|
||||||
).on('end', () => {
|
)
|
||||||
|
.on('end', () => {
|
||||||
const purge = new FastlyPurge(fastly.token);
|
const purge = new FastlyPurge(fastly.token);
|
||||||
|
|
||||||
list.forEach(url => {
|
list.forEach(url => {
|
||||||
@@ -400,8 +387,7 @@ if (
|
|||||||
console.log(`Uploading '${version}' demo to ${aws.demo.domain}...`);
|
console.log(`Uploading '${version}' demo to ${aws.demo.domain}...`);
|
||||||
|
|
||||||
// Replace versioned files in readme.md
|
// Replace versioned files in readme.md
|
||||||
gulp
|
gulp.src([`${root}/readme.md`])
|
||||||
.src([`${root}/readme.md`])
|
|
||||||
.pipe(replace(cdnpath, `${aws.cdn.domain}/${version}/`))
|
.pipe(replace(cdnpath, `${aws.cdn.domain}/${version}/`))
|
||||||
.pipe(gulp.dest(root));
|
.pipe(gulp.dest(root));
|
||||||
|
|
||||||
@@ -415,8 +401,7 @@ if (
|
|||||||
pages.push(error);
|
pages.push(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
gulp
|
gulp.src(pages)
|
||||||
.src(pages)
|
|
||||||
.pipe(replace(localPath, versionPath))
|
.pipe(replace(localPath, versionPath))
|
||||||
.pipe(s3(aws.demo, options.demo));
|
.pipe(s3(aws.demo, options.demo));
|
||||||
|
|
||||||
@@ -468,16 +453,6 @@ if (
|
|||||||
|
|
||||||
// Do everything
|
// Do everything
|
||||||
gulp.task('deploy', () =>
|
gulp.task('deploy', () =>
|
||||||
run(
|
run('version', tasks.clean, tasks.js, tasks.sass, tasks.sprite, 'cdn', 'purge', 'demo', 'open'),
|
||||||
'version',
|
|
||||||
tasks.clean,
|
|
||||||
tasks.js,
|
|
||||||
tasks.sass,
|
|
||||||
tasks.sprite,
|
|
||||||
'cdn',
|
|
||||||
'purge',
|
|
||||||
'demo',
|
|
||||||
'open',
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-30
@@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "plyr",
|
"name": "plyr",
|
||||||
"version": "3.4.0-beta.1",
|
"version": "3.4.4",
|
||||||
"description":
|
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
|
||||||
"A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
|
|
||||||
"homepage": "https://plyr.io",
|
"homepage": "https://plyr.io",
|
||||||
"author": "Sam Potts <sam@potts.es>",
|
"author": "Sam Potts <sam@potts.es>",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@@ -32,64 +31,62 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "gulp build",
|
"build": "gulp build",
|
||||||
"lint": "eslint src/js && npm run-script remark",
|
"lint": "eslint src/js && npm run-script remark",
|
||||||
"remark":
|
"remark": "remark -f --use 'validate-links=repository:\"sampotts/plyr\"' '{,!(node_modules),.?**/}*.md'",
|
||||||
"remark -f --use 'validate-links=repository:\"sampotts/plyr\"' '{,!(node_modules),.?**/}*.md'",
|
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-core": "^6.26.3",
|
"babel-core": "^6.26.3",
|
||||||
"babel-eslint": "^8.2.6",
|
"babel-eslint": "^9.0.0",
|
||||||
"babel-plugin-external-helpers": "^6.22.0",
|
"@babel/preset-env": "^7.1.0",
|
||||||
"babel-preset-env": "^1.7.0",
|
|
||||||
"del": "^3.0.0",
|
"del": "^3.0.0",
|
||||||
"eslint": "^5.2.0",
|
"eslint": "^5.6.0",
|
||||||
"eslint-config-airbnb-base": "^13.0.0",
|
"eslint-config-airbnb-base": "^13.1.0",
|
||||||
"eslint-config-prettier": "^2.9.0",
|
"eslint-config-prettier": "^3.1.0",
|
||||||
"eslint-plugin-import": "^2.13.0",
|
"eslint-plugin-import": "^2.14.0",
|
||||||
"fastly-purge": "^1.0.1",
|
"fastly-purge": "^1.0.1",
|
||||||
"git-branch": "^2.0.1",
|
"git-branch": "^2.0.1",
|
||||||
"gulp": "^3.9.1",
|
"gulp": "^3.9.1",
|
||||||
"gulp-autoprefixer": "^5.0.0",
|
"gulp-autoprefixer": "^6.0.0",
|
||||||
"gulp-better-rollup": "^3.3.0",
|
"gulp-better-rollup": "^3.3.0",
|
||||||
"gulp-clean-css": "^3.9.4",
|
"gulp-clean-css": "^3.10.0",
|
||||||
"gulp-concat": "^2.6.1",
|
"gulp-concat": "^2.6.1",
|
||||||
"gulp-filter": "^5.1.0",
|
"gulp-filter": "^5.1.0",
|
||||||
"gulp-header": "^2.0.5",
|
"gulp-header": "^2.0.5",
|
||||||
"gulp-open": "^3.0.1",
|
"gulp-open": "^3.0.1",
|
||||||
"gulp-postcss": "^7.0.1",
|
"gulp-postcss": "^8.0.0",
|
||||||
"gulp-rename": "^1.4.0",
|
"gulp-rename": "^1.4.0",
|
||||||
"gulp-replace": "^1.0.0",
|
"gulp-replace": "^1.0.0",
|
||||||
"gulp-s3": "^0.11.0",
|
"gulp-s3": "^0.11.0",
|
||||||
"gulp-sass": "^4.0.1",
|
"gulp-sass": "^4.0.1",
|
||||||
"gulp-size": "^3.0.0",
|
"gulp-size": "^3.0.0",
|
||||||
"gulp-sourcemaps": "^2.6.4",
|
"gulp-sourcemaps": "^2.6.4",
|
||||||
"gulp-svgmin": "^1.2.4",
|
"gulp-svgmin": "^2.1.0",
|
||||||
"gulp-svgstore": "^6.1.1",
|
"gulp-svgstore": "^7.0.0",
|
||||||
"gulp-uglify-es": "^1.0.4",
|
"gulp-uglify-es": "^1.0.4",
|
||||||
"gulp-util": "^3.0.8",
|
"gulp-util": "^3.0.8",
|
||||||
"postcss-custom-properties": "^7.0.0",
|
"postcss-custom-properties": "^8.0.5",
|
||||||
"prettier-eslint": "^8.8.2",
|
"prettier-eslint": "^8.8.2",
|
||||||
"prettier-stylelint": "^0.4.2",
|
"prettier-stylelint": "^0.4.2",
|
||||||
"remark-cli": "^5.0.0",
|
"remark-cli": "^5.0.0",
|
||||||
"remark-validate-links": "^7.0.0",
|
"remark-validate-links": "^7.1.0",
|
||||||
"rollup-plugin-babel": "^3.0.7",
|
"rollup-plugin-babel": "^4.0.3",
|
||||||
"rollup-plugin-commonjs": "^9.1.4",
|
"rollup-plugin-commonjs": "^9.1.8",
|
||||||
"rollup-plugin-node-resolve": "^3.3.0",
|
"rollup-plugin-node-resolve": "^3.4.0",
|
||||||
"run-sequence": "^2.2.1",
|
"run-sequence": "^2.2.1",
|
||||||
"stylelint": "^9.4.0",
|
"stylelint": "^9.5.0",
|
||||||
"stylelint-config-prettier": "^3.3.0",
|
"stylelint-config-prettier": "^4.0.0",
|
||||||
"stylelint-config-recommended": "^2.1.0",
|
"stylelint-config-recommended": "^2.1.0",
|
||||||
"stylelint-config-sass-guidelines": "^5.0.0",
|
"stylelint-config-sass-guidelines": "^5.2.0",
|
||||||
"stylelint-order": "^0.8.1",
|
"stylelint-order": "^1.0.0",
|
||||||
"stylelint-scss": "^3.2.0",
|
"stylelint-scss": "^3.3.1",
|
||||||
"stylelint-selector-bem-pattern": "^2.0.0",
|
"stylelint-selector-bem-pattern": "^2.0.0",
|
||||||
"through2": "^2.0.3"
|
"through2": "^2.0.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"babel-polyfill": "^6.26.0",
|
"core-js": "^2.5.7",
|
||||||
"custom-event-polyfill": "^1.0.6",
|
"custom-event-polyfill": "^1.0.6",
|
||||||
"loadjs": "^3.5.4",
|
"loadjs": "^3.5.4",
|
||||||
"raven-js": "^3.26.4",
|
"raven-js": "^3.27.0",
|
||||||
"url-polyfill": "^1.0.13"
|
"url-polyfill": "^1.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,26 +8,26 @@ A simple, lightweight, accessible and customizable HTML5, YouTube and Vimeo medi
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* **Accessible** - full support for VTT captions and screen readers
|
- **Accessible** - full support for VTT captions and screen readers
|
||||||
* **[Customisable](#html)** - make the player look how you want with the markup you want
|
- **[Customisable](#html)** - make the player look how you want with the markup you want
|
||||||
* **Good HTML** - uses the _right_ elements. `<input type="range">` for volume and `<progress>` for progress and well, `<button>`s for buttons. There's no
|
- **Good HTML** - uses the _right_ elements. `<input type="range">` for volume and `<progress>` for progress and well, `<button>`s for buttons. There's no
|
||||||
`<span>` or `<a href="#">` button hacks
|
`<span>` or `<a href="#">` button hacks
|
||||||
* **Responsive** - works with any screen size
|
- **Responsive** - works with any screen size
|
||||||
* **HTML Video & Audio** - support for both formats
|
- **HTML Video & Audio** - support for both formats
|
||||||
* **[Embedded Video](#embeds)** - support for YouTube and Vimeo video playback
|
- **[Embedded Video](#embeds)** - support for YouTube and Vimeo video playback
|
||||||
* **[Monetization](#ads)** - make money from your videos
|
- **[Monetization](#ads)** - make money from your videos
|
||||||
* **[Streaming](#try-plyr-online)** - support for hls.js, Shaka and dash.js streaming playback
|
- **[Streaming](#try-plyr-online)** - support for hls.js, Shaka and dash.js streaming playback
|
||||||
* **[API](#api)** - toggle playback, volume, seeking, and more through a standardized API
|
- **[API](#api)** - toggle playback, volume, seeking, and more through a standardized API
|
||||||
* **[Events](#events)** - no messing around with Vimeo and YouTube APIs, all events are standardized across formats
|
- **[Events](#events)** - no messing around with Vimeo and YouTube APIs, all events are standardized across formats
|
||||||
* **[Fullscreen](#fullscreen)** - supports native fullscreen with fallback to "full window" modes
|
- **[Fullscreen](#fullscreen)** - supports native fullscreen with fallback to "full window" modes
|
||||||
* **[Shortcuts](#shortcuts)** - supports keyboard shortcuts
|
- **[Shortcuts](#shortcuts)** - supports keyboard shortcuts
|
||||||
* **Picture-in-Picture** - supports Safari's picture-in-picture mode
|
- **Picture-in-Picture** - supports Safari's picture-in-picture mode
|
||||||
* **Playsinline** - supports the `playsinline` attribute
|
- **Playsinline** - supports the `playsinline` attribute
|
||||||
* **Speed controls** - adjust speed on the fly
|
- **Speed controls** - adjust speed on the fly
|
||||||
* **Multiple captions** - support for multiple caption tracks
|
- **Multiple captions** - support for multiple caption tracks
|
||||||
* **i18n support** - support for internationalization of controls
|
- **i18n support** - support for internationalization of controls
|
||||||
* **No dependencies** - written in "vanilla" ES6 JavaScript, no jQuery required
|
- **No dependencies** - written in "vanilla" ES6 JavaScript, no jQuery required
|
||||||
* **SASS** - to include in your build processes
|
- **SASS** - to include in your build processes
|
||||||
|
|
||||||
Oh and yes, it works with Bootstrap.
|
Oh and yes, it works with Bootstrap.
|
||||||
|
|
||||||
@@ -132,13 +132,13 @@ See [initialising](#initialising) for more information on advanced setups.
|
|||||||
You can use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript. There's 2 versions; one with and one without [polyfills](#polyfills). My recommendation would be to manage polyfills seperately as part of your application but to make life easier you can use the polyfilled build.
|
You can use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript. There's 2 versions; one with and one without [polyfills](#polyfills). My recommendation would be to manage polyfills seperately as part of your application but to make life easier you can use the polyfilled build.
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script src="https://cdn.plyr.io/3.4.0-beta.1/plyr.js"></script>
|
<script src="https://cdn.plyr.io/3.4.4/plyr.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
...or...
|
...or...
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script src="https://cdn.plyr.io/3.4.0-beta.1/plyr.polyfilled.js"></script>
|
<script src="https://cdn.plyr.io/3.4.4/plyr.polyfilled.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
### CSS
|
### CSS
|
||||||
@@ -152,21 +152,21 @@ Include the `plyr.css` stylsheet into your `<head>`
|
|||||||
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the default CSS, you can use the following:
|
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the default CSS, you can use the following:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<link rel="stylesheet" href="https://cdn.plyr.io/3.4.0-beta.1/plyr.css">
|
<link rel="stylesheet" href="https://cdn.plyr.io/3.4.4/plyr.css">
|
||||||
```
|
```
|
||||||
|
|
||||||
### SVG Sprite
|
### SVG Sprite
|
||||||
|
|
||||||
The SVG sprite is loaded automatically from our CDN (provided by [Fastly](https://www.fastly.com/)). To change this, see the [options](#options) below. For
|
The SVG sprite is loaded automatically from our CDN (provided by [Fastly](https://www.fastly.com/)). To change this, see the [options](#options) below. For
|
||||||
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.4.0-beta.1/plyr.svg`.
|
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.4.4/plyr.svg`.
|
||||||
|
|
||||||
## Ads
|
## Ads
|
||||||
|
|
||||||
Plyr has partnered up with [vi.ai](https://vi.ai/publisher-video-monetization/?aid=plyrio) to offer monetization options for your videos. Getting setup is easy:
|
Plyr has partnered up with [vi.ai](https://vi.ai/publisher-video-monetization/?aid=plyrio) to offer monetization options for your videos. Getting setup is easy:
|
||||||
|
|
||||||
* [Sign up for a vi.ai account](https://vi.ai/publisher-video-monetization/?aid=plyrio)
|
- [Sign up for a vi.ai account](https://vi.ai/publisher-video-monetization/?aid=plyrio)
|
||||||
* Grab your publisher ID from the code snippet
|
- Grab your publisher ID from the code snippet
|
||||||
* Enable ads in the [config options](#options) and enter your publisher ID
|
- Enable ads in the [config options](#options) and enter your publisher ID
|
||||||
|
|
||||||
Any questions regarding the ads can be sent straight to vi.ai and any issues with rendering raised through GitHub issues.
|
Any questions regarding the ads can be sent straight to vi.ai and any issues with rendering raised through GitHub issues.
|
||||||
|
|
||||||
@@ -213,10 +213,10 @@ WebVTT captions are supported. To add a caption track, check the HTML example ab
|
|||||||
|
|
||||||
You can specify a range of arguments for the constructor to use:
|
You can specify a range of arguments for the constructor to use:
|
||||||
|
|
||||||
* A CSS string selector that's compatible with [`querySelector`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)
|
- A CSS string selector that's compatible with [`querySelector`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)
|
||||||
* A [`HTMLElement`](https://developer.mozilla.org/en/docs/Web/API/HTMLElement)
|
- A [`HTMLElement`](https://developer.mozilla.org/en/docs/Web/API/HTMLElement)
|
||||||
* A [`NodeList`](https://developer.mozilla.org/en-US/docs/Web/API/NodeList)
|
- A [`NodeList`](https://developer.mozilla.org/en-US/docs/Web/API/NodeList)
|
||||||
* A [jQuery](https://jquery.com) object
|
- A [jQuery](https://jquery.com) object
|
||||||
|
|
||||||
_Note_: If a `NodeList`, `Array`, or jQuery object are passed, the first element will be used for setup. To setup multiple players, see [setting up multiple players](#setting-up-multiple-players) below.
|
_Note_: If a `NodeList`, `Array`, or jQuery object are passed, the first element will be used for setup. To setup multiple players, see [setting up multiple players](#setting-up-multiple-players) below.
|
||||||
|
|
||||||
@@ -290,7 +290,7 @@ Note the single quotes encapsulating the JSON and double quotes on the object ke
|
|||||||
| `loadSprite` | Boolean | `true` | Load the SVG sprite specified as the `iconUrl` option (if a URL). If `false`, it is assumed you are handling sprite loading yourself. |
|
| `loadSprite` | Boolean | `true` | Load the SVG sprite specified as the `iconUrl` option (if a URL). If `false`, it is assumed you are handling sprite loading yourself. |
|
||||||
| `iconUrl` | String | `null` | Specify a URL or path to the SVG sprite. See the [SVG section](#svg) for more info. |
|
| `iconUrl` | String | `null` | Specify a URL or path to the SVG sprite. See the [SVG section](#svg) for more info. |
|
||||||
| `iconPrefix` | String | `plyr` | Specify the id prefix for the icons used in the default controls (e.g. "plyr-play" would be "plyr"). This is to prevent clashes if you're using your own SVG sprite but with the default controls. Most people can ignore this option. |
|
| `iconPrefix` | String | `plyr` | Specify the id prefix for the icons used in the default controls (e.g. "plyr-play" would be "plyr"). This is to prevent clashes if you're using your own SVG sprite but with the default controls. Most people can ignore this option. |
|
||||||
| `blankUrl` | String | `https://cdn.plyr.io/static/blank.mp4` | Specify a URL or path to a blank video file used to properly cancel network requests. |
|
| `blankVideo` | String | `https://cdn.plyr.io/static/blank.mp4` | Specify a URL or path to a blank video file used to properly cancel network requests. |
|
||||||
| `autoplay` | Boolean | `false` | Autoplay the media on load. This is generally advised against on UX grounds. It is also disabled by default in some browsers. If the `autoplay` attribute is present on a `<video>` or `<audio>` element, this will be automatically set to true. |
|
| `autoplay` | Boolean | `false` | Autoplay the media on load. This is generally advised against on UX grounds. It is also disabled by default in some browsers. If the `autoplay` attribute is present on a `<video>` or `<audio>` element, this will be automatically set to true. |
|
||||||
| `autopause`¹ | Boolean | `true` | Only allow one player playing at once. |
|
| `autopause`¹ | Boolean | `true` | Only allow one player playing at once. |
|
||||||
| `seekTime` | Number | `10` | The time, in seconds, to seek when a user hits fast forward or rewind. |
|
| `seekTime` | Number | `10` | The time, in seconds, to seek when a user hits fast forward or rewind. |
|
||||||
@@ -392,7 +392,7 @@ player.fullscreen.active; // false;
|
|||||||
```
|
```
|
||||||
|
|
||||||
| Property | Getter | Setter | Description |
|
| Property | Getter | Setter | Description |
|
||||||
| -------------------- | ------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
| -------------------- | ------ | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `isHTML5` | ✓ | - | Returns a boolean indicating if the current player is HTML5. |
|
| `isHTML5` | ✓ | - | Returns a boolean indicating if the current player is HTML5. |
|
||||||
| `isEmbed` | ✓ | - | Returns a boolean indicating if the current player is an embedded player. |
|
| `isEmbed` | ✓ | - | Returns a boolean indicating if the current player is an embedded player. |
|
||||||
| `playing` | ✓ | - | Returns a boolean indicating if the current player is playing. |
|
| `playing` | ✓ | - | Returns a boolean indicating if the current player is playing. |
|
||||||
@@ -565,6 +565,7 @@ player.on('ready', event => {
|
|||||||
| `loadstart` | Sent when loading of the media begins. |
|
| `loadstart` | Sent when loading of the media begins. |
|
||||||
| `loadeddata` | The first frame of the media has finished loading. |
|
| `loadeddata` | The first frame of the media has finished loading. |
|
||||||
| `loadedmetadata` | The media's metadata has finished loading; all attributes now contain as much useful information as they're going to. |
|
| `loadedmetadata` | The media's metadata has finished loading; all attributes now contain as much useful information as they're going to. |
|
||||||
|
| `qualitychange` | The quality of playback has changed. |
|
||||||
| `canplay` | Sent when enough data is available that the media can be played, at least for a couple of frames. This corresponds to the `HAVE_ENOUGH_DATA` `readyState`. |
|
| `canplay` | Sent when enough data is available that the media can be played, at least for a couple of frames. This corresponds to the `HAVE_ENOUGH_DATA` `readyState`. |
|
||||||
| `canplaythrough` | Sent when the ready state changes to `CAN_PLAY_THROUGH`, indicating that the entire media can be played without interruption, assuming the download rate remains at least at the current level. _Note:_ Manually setting the `currentTime` will eventually fire a `canplaythrough` event in firefox. Other browsers might not fire this event. |
|
| `canplaythrough` | Sent when the ready state changes to `CAN_PLAY_THROUGH`, indicating that the entire media can be played without interruption, assuming the download rate remains at least at the current level. _Note:_ Manually setting the `currentTime` will eventually fire a `canplaythrough` event in firefox. Other browsers might not fire this event. |
|
||||||
| `stalled` | Sent when the user agent is trying to fetch media data, but data is unexpectedly not forthcoming. |
|
| `stalled` | Sent when the user agent is trying to fetch media data, but data is unexpectedly not forthcoming. |
|
||||||
@@ -576,10 +577,8 @@ player.on('ready', event => {
|
|||||||
#### YouTube only
|
#### YouTube only
|
||||||
|
|
||||||
| Event Type | Description |
|
| Event Type | Description |
|
||||||
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `statechange` | The state of the player has changed. The code can be accessed via `event.detail.code`. Possible values are `-1`: Unstarted, `0`: Ended, `1`: Playing, `2`: Paused, `3`: Buffering, `5`: Video cued. See the [YouTube Docs](https://developers.google.com/youtube/iframe_api_reference#onStateChange) for more information. |
|
| `statechange` | The state of the player has changed. The code can be accessed via `event.detail.code`. Possible values are `-1`: Unstarted, `0`: Ended, `1`: Playing, `2`: Paused, `3`: Buffering, `5`: Video cued. See the [YouTube Docs](https://developers.google.com/youtube/iframe_api_reference#onStateChange) for more information. |
|
||||||
| `qualitychange` | The quality of playback has changed. |
|
|
||||||
| `qualityrequested` | A change to playback quality has been requested. _Note:_ A change to quality can only be _requested_ via the API. There is no guarantee the quality will change to the level requested. You should listen to the `qualitychange` event for true changes. |
|
|
||||||
|
|
||||||
_Note:_ These events also bubble up the DOM. The event target will be the container element.
|
_Note:_ These events also bubble up the DOM. The event target will be the container element.
|
||||||
|
|
||||||
@@ -591,8 +590,8 @@ YouTube and Vimeo are currently supported and function much like a HTML5 video.
|
|||||||
to access the API's directly. You can do so via the `embed` property of your player object - e.g. `player.embed`. You can then use the relevant methods from the
|
to access the API's directly. You can do so via the `embed` property of your player object - e.g. `player.embed`. You can then use the relevant methods from the
|
||||||
third party APIs. More info on the respective API's here:
|
third party APIs. More info on the respective API's here:
|
||||||
|
|
||||||
* [YouTube iframe API Reference](https://developers.google.com/youtube/iframe_api_reference)
|
- [YouTube iframe API Reference](https://developers.google.com/youtube/iframe_api_reference)
|
||||||
* [Vimeo player.js Reference](https://github.com/vimeo/player.js)
|
- [Vimeo player.js Reference](https://github.com/vimeo/player.js)
|
||||||
|
|
||||||
_Note_: Not all API methods may work 100%. Your mileage may vary. It's better to use the Plyr API where possible.
|
_Note_: Not all API methods may work 100%. Your mileage may vary. It's better to use the Plyr API where possible.
|
||||||
|
|
||||||
@@ -652,9 +651,9 @@ const supported = Plyr.supported('video', 'html5', true);
|
|||||||
|
|
||||||
The arguments are:
|
The arguments are:
|
||||||
|
|
||||||
* Media type (`audio` or `video`)
|
- Media type (`audio` or `video`)
|
||||||
* Provider (`html5`, `youtube` or `vimeo`)
|
- Provider (`html5`, `youtube` or `vimeo`)
|
||||||
* Whether the player has the `playsinline` attribute (only applicable to iOS 10+)
|
- Whether the player has the `playsinline` attribute (only applicable to iOS 10+)
|
||||||
|
|
||||||
### Disable support programatically
|
### Disable support programatically
|
||||||
|
|
||||||
@@ -687,33 +686,33 @@ Plyr is developed by [@sam_potts](https://twitter.com/sam_potts) / [sampotts.me]
|
|||||||
|
|
||||||
Plyr costs money to run, not only my time. I donate my time for free as I enjoy building Plyr but unfortunately have to pay for domains, hosting, and more. Any help with costs is appreciated...
|
Plyr costs money to run, not only my time. I donate my time for free as I enjoy building Plyr but unfortunately have to pay for domains, hosting, and more. Any help with costs is appreciated...
|
||||||
|
|
||||||
* [Donate via Patron](https://www.patreon.com/plyr)
|
- [Donate via Patreon](https://www.patreon.com/plyr)
|
||||||
* [Donate via PayPal](https://www.paypal.me/pottsy/20usd)
|
- [Donate via PayPal](https://www.paypal.me/pottsy/20usd)
|
||||||
|
|
||||||
## Mentions
|
## Mentions
|
||||||
|
|
||||||
* [ProductHunt](https://www.producthunt.com/tech/plyr)
|
- [ProductHunt](https://www.producthunt.com/tech/plyr)
|
||||||
* [The Changelog](http://thechangelog.com/plyr-simple-html5-media-player-custom-controls-webvtt-captions/)
|
- [The Changelog](http://thechangelog.com/plyr-simple-html5-media-player-custom-controls-webvtt-captions/)
|
||||||
* [HTML5 Weekly #177](http://html5weekly.com/issues/177)
|
- [HTML5 Weekly #177](http://html5weekly.com/issues/177)
|
||||||
* [Responsive Design #149](http://us4.campaign-archive2.com/?u=559bc631fe5294fc66f5f7f89&id=451a61490f)
|
- [Responsive Design #149](http://us4.campaign-archive2.com/?u=559bc631fe5294fc66f5f7f89&id=451a61490f)
|
||||||
* [Web Design Weekly #174](https://web-design-weekly.com/2015/02/24/web-design-weekly-174/)
|
- [Web Design Weekly #174](https://web-design-weekly.com/2015/02/24/web-design-weekly-174/)
|
||||||
* [Hacker News](https://news.ycombinator.com/item?id=9136774)
|
- [Hacker News](https://news.ycombinator.com/item?id=9136774)
|
||||||
* [Web Platform Daily](http://webplatformdaily.org/releases/2015-03-04)
|
- [Web Platform Daily](http://webplatformdaily.org/releases/2015-03-04)
|
||||||
* [LayerVault Designer News](https://news.layervault.com/stories/45394-plyr--a-simple-html5-media-player)
|
- [LayerVault Designer News](https://news.layervault.com/stories/45394-plyr--a-simple-html5-media-player)
|
||||||
* [The Treehouse Show #131](https://teamtreehouse.com/library/episode-131-origami-react-responsive-hero-images)
|
- [The Treehouse Show #131](https://teamtreehouse.com/library/episode-131-origami-react-responsive-hero-images)
|
||||||
* [noupe.com](http://www.noupe.com/design/html5-plyr-is-a-responsive-and-accessible-video-player-94389.html)
|
- [noupe.com](http://www.noupe.com/design/html5-plyr-is-a-responsive-and-accessible-video-player-94389.html)
|
||||||
|
|
||||||
## Used by
|
## Used by
|
||||||
|
|
||||||
* [Selz.com](https://selz.com)
|
- [Selz.com](https://selz.com)
|
||||||
* [Peugeot.fr](http://www.peugeot.fr/marque-et-technologie/technologies/peugeot-i-cockpit.html)
|
- [Peugeot.fr](http://www.peugeot.fr/marque-et-technologie/technologies/peugeot-i-cockpit.html)
|
||||||
* [Peugeot.de](http://www.peugeot.de/modelle/modellberater/208-3-turer/fotos-videos.html)
|
- [Peugeot.de](http://www.peugeot.de/modelle/modellberater/208-3-turer/fotos-videos.html)
|
||||||
* [TomTom.com](http://prioritydriving.tomtom.com/)
|
- [TomTom.com](http://prioritydriving.tomtom.com/)
|
||||||
* [DIGBMX](http://digbmx.com/)
|
- [DIGBMX](http://digbmx.com/)
|
||||||
* [Grime Archive](https://grimearchive.com/)
|
- [Grime Archive](https://grimearchive.com/)
|
||||||
* [koel - A personal music streaming server that works.](http://koel.phanan.net/)
|
- [koel - A personal music streaming server that works.](http://koel.phanan.net/)
|
||||||
* [Oscar Radio](http://oscar-radio.xyz/)
|
- [Oscar Radio](http://oscar-radio.xyz/)
|
||||||
* [Sparkk TV](https://www.sparkktv.com/)
|
- [Sparkk TV](https://www.sparkktv.com/)
|
||||||
|
|
||||||
Let me know on [Twitter](https://twitter.com/sam_potts) I can add you to the above list. It'd be awesome to see how you're using Plyr :-)
|
Let me know on [Twitter](https://twitter.com/sam_potts) I can add you to the above list. It'd be awesome to see how you're using Plyr :-)
|
||||||
|
|
||||||
@@ -721,8 +720,8 @@ Let me know on [Twitter](https://twitter.com/sam_potts) I can add you to the abo
|
|||||||
|
|
||||||
Credit to the PayPal HTML5 Video player from which Plyr's caption functionality was originally ported from:
|
Credit to the PayPal HTML5 Video player from which Plyr's caption functionality was originally ported from:
|
||||||
|
|
||||||
* [PayPal's Accessible HTML5 Video Player](https://github.com/paypal/accessible-html5-video-player)
|
- [PayPal's Accessible HTML5 Video Player](https://github.com/paypal/accessible-html5-video-player)
|
||||||
* [An awesome guide for Plyr in Japanese!](http://syncer.jp/how-to-use-plyr-io) by [@arayutw](https://twitter.com/arayutw)
|
- [An awesome guide for Plyr in Japanese!](http://syncer.jp/how-to-use-plyr-io) by [@arayutw](https://twitter.com/arayutw)
|
||||||
|
|
||||||
## Thanks
|
## Thanks
|
||||||
|
|
||||||
|
|||||||
+3
-6
@@ -4,7 +4,6 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
import controls from './controls';
|
import controls from './controls';
|
||||||
import i18n from './i18n';
|
|
||||||
import support from './support';
|
import support from './support';
|
||||||
import { dedupe } from './utils/arrays';
|
import { dedupe } from './utils/arrays';
|
||||||
import browser from './utils/browser';
|
import browser from './utils/browser';
|
||||||
@@ -18,6 +17,7 @@ import {
|
|||||||
} from './utils/elements';
|
} from './utils/elements';
|
||||||
import { on, triggerEvent } from './utils/events';
|
import { on, triggerEvent } from './utils/events';
|
||||||
import fetch from './utils/fetch';
|
import fetch from './utils/fetch';
|
||||||
|
import i18n from './utils/i18n';
|
||||||
import is from './utils/is';
|
import is from './utils/is';
|
||||||
import { getHTML } from './utils/strings';
|
import { getHTML } from './utils/strings';
|
||||||
import { parseUrl } from './utils/urls';
|
import { parseUrl } from './utils/urls';
|
||||||
@@ -83,11 +83,8 @@ const captions = {
|
|||||||
// * active: The state preferred by user settings or config
|
// * active: The state preferred by user settings or config
|
||||||
// * toggled: The real captions state
|
// * toggled: The real captions state
|
||||||
|
|
||||||
const languages = dedupe(
|
const browserLanguages = navigator.languages || [navigator.language || navigator.userLanguage || 'en'];
|
||||||
Array.from(navigator.languages || navigator.language || navigator.userLanguage).map(
|
const languages = dedupe(browserLanguages.map(language => language.split('-')[0]));
|
||||||
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();
|
||||||
|
|
||||||
|
|||||||
@@ -68,19 +68,7 @@ const defaults = {
|
|||||||
// Quality default
|
// Quality default
|
||||||
quality: {
|
quality: {
|
||||||
default: 576,
|
default: 576,
|
||||||
options: [
|
options: [4320, 2880, 2160, 1440, 1080, 720, 576, 480, 360, 240],
|
||||||
4320,
|
|
||||||
2880,
|
|
||||||
2160,
|
|
||||||
1440,
|
|
||||||
1080,
|
|
||||||
720,
|
|
||||||
576,
|
|
||||||
480,
|
|
||||||
360,
|
|
||||||
240,
|
|
||||||
'default', // YouTube's "auto"
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Set loops
|
// Set loops
|
||||||
@@ -268,8 +256,9 @@ const defaults = {
|
|||||||
|
|
||||||
// YouTube
|
// YouTube
|
||||||
'statechange',
|
'statechange',
|
||||||
|
|
||||||
|
// Quality
|
||||||
'qualitychange',
|
'qualitychange',
|
||||||
'qualityrequested',
|
|
||||||
|
|
||||||
// Ads
|
// Ads
|
||||||
'adsloaded',
|
'adsloaded',
|
||||||
|
|||||||
Vendored
+73
-39
@@ -5,13 +5,13 @@
|
|||||||
|
|
||||||
import captions from './captions';
|
import captions from './captions';
|
||||||
import html5 from './html5';
|
import html5 from './html5';
|
||||||
import i18n from './i18n';
|
|
||||||
import support from './support';
|
import support from './support';
|
||||||
import { repaint, transitionEndEvent } from './utils/animation';
|
import { repaint, transitionEndEvent } from './utils/animation';
|
||||||
import { dedupe } from './utils/arrays';
|
import { dedupe } from './utils/arrays';
|
||||||
import browser from './utils/browser';
|
import browser from './utils/browser';
|
||||||
import { createElement, emptyElement, getAttributesFromSelector, getElement, getElements, hasClass, matches, removeElement, setAttributes, setFocus, toggleClass, toggleHidden } from './utils/elements';
|
import { createElement, emptyElement, getAttributesFromSelector, getElement, getElements, hasClass, matches, removeElement, setAttributes, setFocus, toggleClass, toggleHidden } from './utils/elements';
|
||||||
import { off, on } from './utils/events';
|
import { off, on } from './utils/events';
|
||||||
|
import i18n from './utils/i18n';
|
||||||
import is from './utils/is';
|
import is from './utils/is';
|
||||||
import loadSprite from './utils/loadSprite';
|
import loadSprite from './utils/loadSprite';
|
||||||
import { extend } from './utils/objects';
|
import { extend } from './utils/objects';
|
||||||
@@ -275,18 +275,6 @@ const controls = {
|
|||||||
this.elements.buttons[type] = button;
|
this.elements.buttons[type] = button;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle classname when pressed property is set
|
|
||||||
const className = this.config.classNames.controlPressed;
|
|
||||||
Object.defineProperty(button, 'pressed', {
|
|
||||||
enumerable: true,
|
|
||||||
get() {
|
|
||||||
return hasClass(button, className);
|
|
||||||
},
|
|
||||||
set(pressed = false) {
|
|
||||||
toggleClass(button, className, pressed);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return button;
|
return button;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -381,7 +369,7 @@ const controls = {
|
|||||||
// We have to bind to keyup otherwise Firefox triggers a click when a keydown event handler shifts focus
|
// We have to bind to keyup otherwise Firefox triggers a click when a keydown event handler shifts focus
|
||||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1220143
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=1220143
|
||||||
bindMenuItemShortcuts(menuItem, type) {
|
bindMenuItemShortcuts(menuItem, type) {
|
||||||
// Handle space or -> to open menu
|
// Navigate through menus via arrow keys and space
|
||||||
on(
|
on(
|
||||||
menuItem,
|
menuItem,
|
||||||
'keydown keyup',
|
'keydown keyup',
|
||||||
@@ -429,6 +417,16 @@ const controls = {
|
|||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 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(menuItem, 'keyup', event => {
|
||||||
|
if (event.which !== 13) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
controls.focusFirstMenuItem.call(this, null, true);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Create a settings menu item
|
// Create a settings menu item
|
||||||
@@ -645,7 +643,7 @@ const controls = {
|
|||||||
} else if (matches(range, this.config.selectors.inputs.volume)) {
|
} else if (matches(range, this.config.selectors.inputs.volume)) {
|
||||||
const percent = range.value * 100;
|
const percent = range.value * 100;
|
||||||
range.setAttribute('aria-valuenow', percent);
|
range.setAttribute('aria-valuenow', percent);
|
||||||
range.setAttribute('aria-valuetext', `${percent}%`);
|
range.setAttribute('aria-valuetext', `${percent.toFixed(1)}%`);
|
||||||
} else {
|
} else {
|
||||||
range.setAttribute('aria-valuenow', range.value);
|
range.setAttribute('aria-valuenow', range.value);
|
||||||
}
|
}
|
||||||
@@ -1074,6 +1072,23 @@ const controls = {
|
|||||||
toggleHidden(this.elements.settings.menu, !visible);
|
toggleHidden(this.elements.settings.menu, !visible);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Focus the first menu item in a given (or visible) menu
|
||||||
|
focusFirstMenuItem(pane, tabFocus = false) {
|
||||||
|
if (this.elements.settings.popup.hidden) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let target = pane;
|
||||||
|
|
||||||
|
if (!is.element(target)) {
|
||||||
|
target = Object.values(this.elements.settings.panels).find(pane => !pane.hidden);
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstItem = target.querySelector('[role^="menuitem"]');
|
||||||
|
|
||||||
|
setFocus.call(this, firstItem, tabFocus);
|
||||||
|
},
|
||||||
|
|
||||||
// Show/hide menu
|
// Show/hide menu
|
||||||
toggleMenu(input) {
|
toggleMenu(input) {
|
||||||
const { popup } = this.elements.settings;
|
const { popup } = this.elements.settings;
|
||||||
@@ -1085,7 +1100,7 @@ const controls = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// True toggle by default
|
// True toggle by default
|
||||||
const hidden = popup.hasAttribute('hidden');
|
const { hidden } = popup;
|
||||||
let show = hidden;
|
let show = hidden;
|
||||||
|
|
||||||
if (is.boolean(input)) {
|
if (is.boolean(input)) {
|
||||||
@@ -1094,19 +1109,13 @@ const controls = {
|
|||||||
show = false;
|
show = false;
|
||||||
} else if (is.event(input)) {
|
} else if (is.event(input)) {
|
||||||
const isMenuItem = popup.contains(input.target);
|
const isMenuItem = popup.contains(input.target);
|
||||||
const isButton = input.target === button;
|
|
||||||
|
|
||||||
// If the click was inside the menu or if the click
|
// If the click was inside the menu or if the click
|
||||||
// wasn't the button or menu item and we're trying to
|
// wasn't the button or menu item and we're trying to
|
||||||
// show the menu (a doc click shouldn't show the menu)
|
// show the menu (a doc click shouldn't show the menu)
|
||||||
if (isMenuItem || (!isMenuItem && !isButton && show)) {
|
if (isMenuItem || (!isMenuItem && input.target !== button && show)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent the toggle being caught by the doc listener
|
|
||||||
if (isButton) {
|
|
||||||
input.stopPropagation();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set button attributes
|
// Set button attributes
|
||||||
@@ -1120,12 +1129,9 @@ const controls = {
|
|||||||
|
|
||||||
// Focus the first item if key interaction
|
// Focus the first item if key interaction
|
||||||
if (show && is.keyboardEvent(input)) {
|
if (show && is.keyboardEvent(input)) {
|
||||||
const pane = Object.values(this.elements.settings.panels).find(pane => !pane.hidden);
|
controls.focusFirstMenuItem.call(this, null, true);
|
||||||
const firstItem = pane.querySelector('[role^="menuitem"]');
|
} else if (!show && !hidden) {
|
||||||
setFocus.call(this, firstItem, true);
|
|
||||||
}
|
|
||||||
// If closing, re-focus the button
|
// If closing, re-focus the button
|
||||||
else if (!show && !hidden) {
|
|
||||||
setFocus.call(this, button, is.keyboardEvent(input));
|
setFocus.call(this, button, is.keyboardEvent(input));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1205,8 +1211,7 @@ const controls = {
|
|||||||
toggleHidden(target, false);
|
toggleHidden(target, false);
|
||||||
|
|
||||||
// Focus the first item
|
// Focus the first item
|
||||||
const firstItem = target.querySelector('[role^="menuitem"]');
|
controls.focusFirstMenuItem.call(this, target, tabFocus);
|
||||||
setFocus.call(this, firstItem, tabFocus);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Build the default HTML
|
// Build the default HTML
|
||||||
@@ -1279,17 +1284,19 @@ const controls = {
|
|||||||
container.appendChild(controls.createTime.call(this, 'duration'));
|
container.appendChild(controls.createTime.call(this, 'duration'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle mute button
|
// Volume controls
|
||||||
if (this.config.controls.includes('mute')) {
|
if (this.config.controls.includes('mute') || this.config.controls.includes('volume')) {
|
||||||
container.appendChild(controls.createButton.call(this, 'mute'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Volume range control
|
|
||||||
if (this.config.controls.includes('volume')) {
|
|
||||||
const volume = createElement('div', {
|
const volume = createElement('div', {
|
||||||
class: 'plyr__volume',
|
class: 'plyr__volume',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Toggle mute button
|
||||||
|
if (this.config.controls.includes('mute')) {
|
||||||
|
volume.appendChild(controls.createButton.call(this, 'mute'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Volume range control
|
||||||
|
if (this.config.controls.includes('volume')) {
|
||||||
// Set the attributes
|
// Set the attributes
|
||||||
const attributes = {
|
const attributes = {
|
||||||
max: 1,
|
max: 1,
|
||||||
@@ -1309,6 +1316,7 @@ const controls = {
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.elements.volume = volume;
|
this.elements.volume = volume;
|
||||||
|
}
|
||||||
|
|
||||||
container.appendChild(volume);
|
container.appendChild(volume);
|
||||||
}
|
}
|
||||||
@@ -1327,7 +1335,6 @@ const controls = {
|
|||||||
|
|
||||||
control.appendChild(
|
control.appendChild(
|
||||||
controls.createButton.call(this, 'settings', {
|
controls.createButton.call(this, 'settings', {
|
||||||
id: `plyr-settings-toggle-${data.id}`,
|
|
||||||
'aria-haspopup': true,
|
'aria-haspopup': true,
|
||||||
'aria-controls': `plyr-settings-${data.id}`,
|
'aria-controls': `plyr-settings-${data.id}`,
|
||||||
'aria-expanded': false,
|
'aria-expanded': false,
|
||||||
@@ -1338,7 +1345,6 @@ const controls = {
|
|||||||
class: 'plyr__menu__container',
|
class: 'plyr__menu__container',
|
||||||
id: `plyr-settings-${data.id}`,
|
id: `plyr-settings-${data.id}`,
|
||||||
hidden: '',
|
hidden: '',
|
||||||
'aria-labelled-by': `plyr-settings-toggle-${data.id}`,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const inner = createElement('div');
|
const inner = createElement('div');
|
||||||
@@ -1496,6 +1502,7 @@ const controls = {
|
|||||||
|
|
||||||
this.elements.controls = container;
|
this.elements.controls = container;
|
||||||
|
|
||||||
|
// Set available quality levels
|
||||||
if (this.isHTML5) {
|
if (this.isHTML5) {
|
||||||
controls.setQualityMenu.call(this, html5.getQualityOptions.call(this));
|
controls.setQualityMenu.call(this, html5.getQualityOptions.call(this));
|
||||||
}
|
}
|
||||||
@@ -1601,6 +1608,33 @@ const controls = {
|
|||||||
controls.findElements.call(this);
|
controls.findElements.call(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add pressed property to buttons
|
||||||
|
if (!is.empty(this.elements.buttons)) {
|
||||||
|
const addProperty = button => {
|
||||||
|
const className = this.config.classNames.controlPressed;
|
||||||
|
Object.defineProperty(button, 'pressed', {
|
||||||
|
enumerable: true,
|
||||||
|
get() {
|
||||||
|
return hasClass(button, className);
|
||||||
|
},
|
||||||
|
set(pressed = false) {
|
||||||
|
toggleClass(button, className, pressed);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Toggle classname when pressed property is set
|
||||||
|
Object.values(this.elements.buttons)
|
||||||
|
.filter(Boolean)
|
||||||
|
.forEach(button => {
|
||||||
|
if (is.array(button) || is.nodeList(button)) {
|
||||||
|
Array.from(button).filter(Boolean).forEach(addProperty);
|
||||||
|
} else {
|
||||||
|
addProperty(button);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Edge sometimes doesn't finish the paint so force a redraw
|
// Edge sometimes doesn't finish the paint so force a redraw
|
||||||
if (window.navigator.userAgent.includes('Edge')) {
|
if (window.navigator.userAgent.includes('Edge')) {
|
||||||
repaint(target);
|
repaint(target);
|
||||||
|
|||||||
+33
-2
@@ -1,8 +1,10 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Fullscreen wrapper
|
// Fullscreen wrapper
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API#prefixing
|
// https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API#prefixing
|
||||||
|
// https://webkit.org/blog/7929/designing-websites-for-iphone-x/
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
|
import { repaint } from './utils/animation';
|
||||||
import browser from './utils/browser';
|
import browser from './utils/browser';
|
||||||
import { hasClass, toggleClass, trapFocus } from './utils/elements';
|
import { hasClass, toggleClass, trapFocus } from './utils/elements';
|
||||||
import { on, triggerEvent } from './utils/events';
|
import { on, triggerEvent } from './utils/events';
|
||||||
@@ -45,6 +47,37 @@ function toggleFallback(toggle = false) {
|
|||||||
// Toggle class hook
|
// Toggle class hook
|
||||||
toggleClass(this.target, this.player.config.classNames.fullscreen.fallback, toggle);
|
toggleClass(this.target, this.player.config.classNames.fullscreen.fallback, toggle);
|
||||||
|
|
||||||
|
// Force full viewport on iPhone X+
|
||||||
|
if (browser.isIos) {
|
||||||
|
let viewport = document.head.querySelector('meta[name="viewport"]');
|
||||||
|
const property = 'viewport-fit=cover';
|
||||||
|
|
||||||
|
// Inject the viewport meta if required
|
||||||
|
if (!viewport) {
|
||||||
|
viewport = document.createElement('meta');
|
||||||
|
viewport.setAttribute('name', 'viewport');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the property already exists
|
||||||
|
const hasProperty = is.string(viewport.content) && viewport.content.includes(property);
|
||||||
|
|
||||||
|
if (toggle) {
|
||||||
|
this.cleanupViewport = !hasProperty;
|
||||||
|
|
||||||
|
if (!hasProperty) {
|
||||||
|
viewport.content += `,${property}`;
|
||||||
|
}
|
||||||
|
} else if (this.cleanupViewport) {
|
||||||
|
viewport.content = viewport.content
|
||||||
|
.split(',')
|
||||||
|
.filter(part => part.trim() !== property)
|
||||||
|
.join(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force a repaint as sometimes Safari doesn't want to fill the screen
|
||||||
|
setTimeout(() => repaint(this.target), 100);
|
||||||
|
}
|
||||||
|
|
||||||
// Toggle button and fire events
|
// Toggle button and fire events
|
||||||
onChange.call(this);
|
onChange.call(this);
|
||||||
}
|
}
|
||||||
@@ -177,9 +210,7 @@ class Fullscreen {
|
|||||||
|
|
||||||
// iOS native fullscreen doesn't need the request step
|
// iOS native fullscreen doesn't need the request step
|
||||||
if (browser.isIos && this.player.config.fullscreen.iosNative) {
|
if (browser.isIos && this.player.config.fullscreen.iosNative) {
|
||||||
if (this.player.playing) {
|
|
||||||
this.target.webkitEnterFullscreen();
|
this.target.webkitEnterFullscreen();
|
||||||
}
|
|
||||||
} else if (!Fullscreen.native) {
|
} else if (!Fullscreen.native) {
|
||||||
toggleFallback.call(this, true);
|
toggleFallback.call(this, true);
|
||||||
} else if (!this.prefix) {
|
} else if (!this.prefix) {
|
||||||
|
|||||||
@@ -82,6 +82,9 @@ const html5 = {
|
|||||||
triggerEvent.call(player, player.media, 'qualitychange', false, {
|
triggerEvent.call(player, player.media, 'qualitychange', false, {
|
||||||
quality: input,
|
quality: input,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Save to storage
|
||||||
|
player.storage.set({ quality: input });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
+21
-23
@@ -6,7 +6,7 @@ import controls from './controls';
|
|||||||
import ui from './ui';
|
import ui from './ui';
|
||||||
import { repaint } from './utils/animation';
|
import { repaint } from './utils/animation';
|
||||||
import browser from './utils/browser';
|
import browser from './utils/browser';
|
||||||
import { getElement, getElements, hasClass, matches, toggleClass, toggleHidden } from './utils/elements';
|
import { getElement, getElements, matches, toggleClass, toggleHidden } from './utils/elements';
|
||||||
import { on, once, toggleListener, triggerEvent } from './utils/events';
|
import { on, once, toggleListener, triggerEvent } from './utils/events';
|
||||||
import is from './utils/is';
|
import is from './utils/is';
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ class Listeners {
|
|||||||
// Seek by the number keys
|
// Seek by the number keys
|
||||||
const seekByKey = () => {
|
const seekByKey = () => {
|
||||||
// Divide the max duration into 10th's and times by the number value
|
// Divide the max duration into 10th's and times by the number value
|
||||||
player.currentTime = player.duration / 10 * (code - 48);
|
player.currentTime = (player.duration / 10) * (code - 48);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle the key on keydown
|
// Handle the key on keydown
|
||||||
@@ -277,7 +277,7 @@ class Listeners {
|
|||||||
const { controls } = elements;
|
const { controls } = elements;
|
||||||
|
|
||||||
// Remove button states for fullscreen
|
// Remove button states for fullscreen
|
||||||
if (event.type === 'enterfullscreen') {
|
if (controls && event.type === 'enterfullscreen') {
|
||||||
controls.pressed = false;
|
controls.pressed = false;
|
||||||
controls.hover = false;
|
controls.hover = false;
|
||||||
}
|
}
|
||||||
@@ -372,7 +372,7 @@ class Listeners {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// On click play, pause ore restart
|
// On click play, pause ore restart
|
||||||
on.call(player, elements.container, 'click touchstart', 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
|
||||||
@@ -380,13 +380,8 @@ class Listeners {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// First touch on touch devices will just show controls (if we're hiding controls)
|
// Touch devices will just show controls (if hidden)
|
||||||
// If controls are shown then it'll toggle like a pointer device
|
if (player.touch && player.config.hideControls) {
|
||||||
if (
|
|
||||||
player.config.hideControls &&
|
|
||||||
player.touch &&
|
|
||||||
hasClass(elements.container, player.config.classNames.hideControls)
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,12 +425,6 @@ class Listeners {
|
|||||||
player.storage.set({ speed: player.speed });
|
player.storage.set({ speed: player.speed });
|
||||||
});
|
});
|
||||||
|
|
||||||
// Quality request
|
|
||||||
on.call(player, player.media, 'qualityrequested', event => {
|
|
||||||
// Save to storage
|
|
||||||
player.storage.set({ quality: event.detail.quality });
|
|
||||||
});
|
|
||||||
|
|
||||||
// Quality change
|
// Quality change
|
||||||
on.call(player, player.media, 'qualitychange', event => {
|
on.call(player, player.media, 'qualitychange', event => {
|
||||||
// Update UI
|
// Update UI
|
||||||
@@ -553,6 +542,9 @@ class Listeners {
|
|||||||
|
|
||||||
// Settings menu - click toggle
|
// Settings menu - click toggle
|
||||||
this.bind(elements.buttons.settings, 'click', event => {
|
this.bind(elements.buttons.settings, 'click', event => {
|
||||||
|
// Prevent the document click listener closing the menu
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
controls.toggleMenu.call(player, event);
|
controls.toggleMenu.call(player, event);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -563,8 +555,16 @@ class Listeners {
|
|||||||
elements.buttons.settings,
|
elements.buttons.settings,
|
||||||
'keyup',
|
'keyup',
|
||||||
event => {
|
event => {
|
||||||
|
const code = event.which;
|
||||||
|
|
||||||
// We only care about space and return
|
// We only care about space and return
|
||||||
if (event.which !== 32 && event.which !== 13) {
|
if (![13, 32].includes(code)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Because return triggers a click anyway, all we need to do is set focus
|
||||||
|
if (code === 13) {
|
||||||
|
controls.focusFirstMenuItem.call(player, null, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -572,15 +572,13 @@ class Listeners {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
// Prevent playing video (Firefox)
|
// Prevent playing video (Firefox)
|
||||||
if (event.which === 32) {
|
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
|
||||||
|
|
||||||
// Toggle menu
|
// Toggle menu
|
||||||
controls.toggleMenu.call(player, event);
|
controls.toggleMenu.call(player, event);
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
false,
|
false, // Can't be passive as we're preventing default
|
||||||
);
|
);
|
||||||
|
|
||||||
// Escape closes menu
|
// Escape closes menu
|
||||||
@@ -593,7 +591,7 @@ class Listeners {
|
|||||||
// 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);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -647,7 +645,7 @@ class Listeners {
|
|||||||
|
|
||||||
seek.removeAttribute('seek-value');
|
seek.removeAttribute('seek-value');
|
||||||
|
|
||||||
player.currentTime = seekTo / seek.max * player.duration;
|
player.currentTime = (seekTo / seek.max) * player.duration;
|
||||||
},
|
},
|
||||||
'seek',
|
'seek',
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
/* global google */
|
/* global google */
|
||||||
|
|
||||||
import i18n from '../i18n';
|
|
||||||
import { createElement } from '../utils/elements';
|
import { createElement } from '../utils/elements';
|
||||||
import { triggerEvent } from '../utils/events';
|
import { triggerEvent } from '../utils/events';
|
||||||
|
import i18n from '../utils/i18n';
|
||||||
import is from '../utils/is';
|
import is from '../utils/is';
|
||||||
import loadScript from '../utils/loadScript';
|
import loadScript from '../utils/loadScript';
|
||||||
import { formatTime } from '../utils/time';
|
import { formatTime } from '../utils/time';
|
||||||
|
|||||||
@@ -2,9 +2,7 @@
|
|||||||
// YouTube plugin
|
// YouTube plugin
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
import controls from '../controls';
|
|
||||||
import ui from '../ui';
|
import ui from '../ui';
|
||||||
import { dedupe } from '../utils/arrays';
|
|
||||||
import { createElement, replaceElement, toggleClass } from '../utils/elements';
|
import { createElement, replaceElement, toggleClass } from '../utils/elements';
|
||||||
import { triggerEvent } from '../utils/events';
|
import { triggerEvent } from '../utils/events';
|
||||||
import fetch from '../utils/fetch';
|
import fetch from '../utils/fetch';
|
||||||
@@ -23,37 +21,6 @@ function parseId(url) {
|
|||||||
return url.match(regex) ? RegExp.$2 : url;
|
return url.match(regex) ? RegExp.$2 : url;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Standardise YouTube quality unit
|
|
||||||
function mapQualityUnit(input) {
|
|
||||||
const qualities = {
|
|
||||||
hd2160: 2160,
|
|
||||||
hd1440: 1440,
|
|
||||||
hd1080: 1080,
|
|
||||||
hd720: 720,
|
|
||||||
large: 480,
|
|
||||||
medium: 360,
|
|
||||||
small: 240,
|
|
||||||
tiny: 144,
|
|
||||||
};
|
|
||||||
|
|
||||||
const entry = Object.entries(qualities).find(entry => entry.includes(input));
|
|
||||||
|
|
||||||
if (entry) {
|
|
||||||
// Get the match corresponding to the input
|
|
||||||
return entry.find(value => value !== input);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'default';
|
|
||||||
}
|
|
||||||
|
|
||||||
function mapQualityUnits(levels) {
|
|
||||||
if (is.empty(levels)) {
|
|
||||||
return levels;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dedupe(levels.map(level => mapQualityUnit(level)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set playback state and trigger change (only on actual change)
|
// Set playback state and trigger change (only on actual change)
|
||||||
function assurePlaybackState(play) {
|
function assurePlaybackState(play) {
|
||||||
if (play && !this.embed.hasPlayed) {
|
if (play && !this.embed.hasPlayed) {
|
||||||
@@ -225,11 +192,6 @@ const youtube = {
|
|||||||
triggerEvent.call(player, player.media, 'error');
|
triggerEvent.call(player, player.media, 'error');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onPlaybackQualityChange() {
|
|
||||||
triggerEvent.call(player, player.media, 'qualitychange', false, {
|
|
||||||
quality: player.media.quality,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onPlaybackRateChange(event) {
|
onPlaybackRateChange(event) {
|
||||||
// Get the instance
|
// Get the instance
|
||||||
const instance = event.target;
|
const instance = event.target;
|
||||||
@@ -299,16 +261,6 @@ const youtube = {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Quality
|
|
||||||
Object.defineProperty(player.media, 'quality', {
|
|
||||||
get() {
|
|
||||||
return mapQualityUnit(instance.getPlaybackQuality());
|
|
||||||
},
|
|
||||||
set(input) {
|
|
||||||
instance.setPlaybackQuality(mapQualityUnit(input));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Volume
|
// Volume
|
||||||
let { volume } = player.config;
|
let { volume } = player.config;
|
||||||
Object.defineProperty(player.media, 'volume', {
|
Object.defineProperty(player.media, 'volume', {
|
||||||
@@ -457,12 +409,6 @@ const youtube = {
|
|||||||
player.media.duration = instance.getDuration();
|
player.media.duration = instance.getDuration();
|
||||||
triggerEvent.call(player, player.media, 'durationchange');
|
triggerEvent.call(player, player.media, 'durationchange');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get quality
|
|
||||||
controls.setQualityMenu.call(
|
|
||||||
player,
|
|
||||||
mapQualityUnits(instance.getAvailableQualityLevels()),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
+1
-6
@@ -1,6 +1,6 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Plyr
|
// Plyr
|
||||||
// plyr.js v3.4.0-beta.1
|
// plyr.js v3.4.4
|
||||||
// https://github.com/sampotts/plyr
|
// https://github.com/sampotts/plyr
|
||||||
// License: The MIT License (MIT)
|
// License: The MIT License (MIT)
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
@@ -698,11 +698,6 @@ class Plyr {
|
|||||||
quality = value;
|
quality = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger request event
|
|
||||||
triggerEvent.call(this, this.media, 'qualityrequested', false, {
|
|
||||||
quality,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update config
|
// Update config
|
||||||
config.selected = quality;
|
config.selected = quality;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Plyr Polyfilled Build
|
// Plyr Polyfilled Build
|
||||||
// plyr.js v3.4.0-beta.1
|
// plyr.js v3.4.4
|
||||||
// https://github.com/sampotts/plyr
|
// https://github.com/sampotts/plyr
|
||||||
// License: The MIT License (MIT)
|
// License: The MIT License (MIT)
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
import 'babel-polyfill';
|
|
||||||
import 'custom-event-polyfill';
|
import 'custom-event-polyfill';
|
||||||
import 'url-polyfill';
|
import 'url-polyfill';
|
||||||
import Plyr from './plyr';
|
import Plyr from './plyr';
|
||||||
|
|||||||
+1
-1
@@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
import captions from './captions';
|
import captions from './captions';
|
||||||
import controls from './controls';
|
import controls from './controls';
|
||||||
import i18n from './i18n';
|
|
||||||
import support from './support';
|
import support from './support';
|
||||||
import browser from './utils/browser';
|
import browser from './utils/browser';
|
||||||
import { getElement, toggleClass } from './utils/elements';
|
import { getElement, toggleClass } from './utils/elements';
|
||||||
import { ready, triggerEvent } from './utils/events';
|
import { ready, triggerEvent } from './utils/events';
|
||||||
|
import i18n from './utils/i18n';
|
||||||
import is from './utils/is';
|
import is from './utils/is';
|
||||||
import loadImage from './utils/loadImage';
|
import loadImage from './utils/loadImage';
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,7 @@ export const transitionEndEvent = (() => {
|
|||||||
transition: 'transitionend',
|
transition: 'transitionend',
|
||||||
};
|
};
|
||||||
|
|
||||||
const type = Object.keys(events).find(
|
const type = Object.keys(events).find(event => element.style[event] !== undefined);
|
||||||
event => element.style[event] !== undefined,
|
|
||||||
);
|
|
||||||
|
|
||||||
return is.string(type) ? events[type] : false;
|
return is.string(type) ? events[type] : false;
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -116,11 +116,7 @@ export function emptyElement(element) {
|
|||||||
|
|
||||||
// Replace element
|
// Replace element
|
||||||
export function replaceElement(newChild, oldChild) {
|
export function replaceElement(newChild, oldChild) {
|
||||||
if (
|
if (!is.element(oldChild) || !is.element(oldChild.parentNode) || !is.element(newChild)) {
|
||||||
!is.element(oldChild) ||
|
|
||||||
!is.element(oldChild.parentNode) ||
|
|
||||||
!is.element(newChild)
|
|
||||||
) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +191,7 @@ export function toggleHidden(element, hidden) {
|
|||||||
let hide = hidden;
|
let hide = hidden;
|
||||||
|
|
||||||
if (!is.boolean(hide)) {
|
if (!is.boolean(hide)) {
|
||||||
hide = !element.hasAttribute('hidden');
|
hide = !element.hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hide) {
|
if (hide) {
|
||||||
@@ -263,10 +259,7 @@ export function trapFocus(element = null, toggle = false) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const focusable = getElements.call(
|
const focusable = getElements.call(this, 'button:not(:disabled), input:not(:disabled), [tabindex]');
|
||||||
this,
|
|
||||||
'button:not(:disabled), input:not(:disabled), [tabindex]',
|
|
||||||
);
|
|
||||||
const first = focusable[0];
|
const first = focusable[0];
|
||||||
const last = focusable[focusable.length - 1];
|
const last = focusable[focusable.length - 1];
|
||||||
|
|
||||||
@@ -290,14 +283,7 @@ export function trapFocus(element = null, toggle = false) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
toggleListener.call(
|
toggleListener.call(this, this.elements.container, 'keydown', trap, toggle, false);
|
||||||
this,
|
|
||||||
this.elements.container,
|
|
||||||
'keydown',
|
|
||||||
trap,
|
|
||||||
toggle,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set focus and tab focus class
|
// Set focus and tab focus class
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
// Plyr internationalization
|
// Plyr internationalization
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
import is from './utils/is';
|
import is from './is';
|
||||||
import { getDeep } from './utils/objects';
|
import { getDeep } from './objects';
|
||||||
import { replaceAll } from './utils/strings';
|
import { replaceAll } from './strings';
|
||||||
|
|
||||||
const i18n = {
|
const i18n = {
|
||||||
get(key = '', config = {}) {
|
get(key = '', config = {}) {
|
||||||
@@ -24,7 +24,7 @@ export function getPercentage(current, max) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (current / max * 100).toFixed(2);
|
return ((current / max) * 100).toFixed(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace all occurances of a string in a string
|
// Replace all occurances of a string in a string
|
||||||
|
|||||||
@@ -81,11 +81,10 @@
|
|||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
|
||||||
|
// Offset icon to make the play button look right
|
||||||
svg {
|
svg {
|
||||||
height: $plyr-control-icon-size-large;
|
left: 2px;
|
||||||
left: 2px; // Offset to make the play button look right
|
|
||||||
position: relative;
|
position: relative;
|
||||||
width: $plyr-control-icon-size-large;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
|
|||||||
@@ -18,20 +18,24 @@
|
|||||||
> .plyr__control,
|
> .plyr__control,
|
||||||
.plyr__progress,
|
.plyr__progress,
|
||||||
.plyr__time,
|
.plyr__time,
|
||||||
.plyr__menu {
|
.plyr__menu,
|
||||||
margin-left: ($plyr-control-spacing / 2);
|
|
||||||
|
|
||||||
&:first-child,
|
|
||||||
&:first-child + [data-plyr='pause'] {
|
|
||||||
margin-left: 0;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.plyr__volume {
|
.plyr__volume {
|
||||||
margin-left: ($plyr-control-spacing / 2);
|
margin-left: ($plyr-control-spacing / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.plyr__menu + .plyr__control,
|
||||||
|
> .plyr__control + .plyr__menu,
|
||||||
|
> .plyr__control + .plyr__control,
|
||||||
|
.plyr__progress + .plyr__control {
|
||||||
|
margin-left: floor($plyr-control-spacing / 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
> .plyr__control:first-child,
|
||||||
|
> .plyr__control:first-child + [data-plyr='pause'] {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
// Hide empty controls
|
// Hide empty controls
|
||||||
&:empty {
|
&:empty {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -39,17 +43,12 @@
|
|||||||
|
|
||||||
@media (min-width: $plyr-bp-sm) {
|
@media (min-width: $plyr-bp-sm) {
|
||||||
> .plyr__control,
|
> .plyr__control,
|
||||||
|
.plyr__menu,
|
||||||
.plyr__progress,
|
.plyr__progress,
|
||||||
.plyr__time,
|
.plyr__time,
|
||||||
.plyr__menu {
|
.plyr__volume {
|
||||||
margin-left: $plyr-control-spacing;
|
margin-left: $plyr-control-spacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .plyr__control + .plyr__control,
|
|
||||||
.plyr__menu + .plyr__control,
|
|
||||||
> .plyr__control + .plyr__menu {
|
|
||||||
margin-left: ($plyr-control-spacing / 2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,12 +71,15 @@
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
color: $plyr-video-control-color;
|
color: $plyr-video-control-color;
|
||||||
left: 0;
|
left: 0;
|
||||||
padding: ($plyr-control-spacing * 3.5) $plyr-control-spacing
|
padding: ($plyr-control-spacing * 2) ($plyr-control-spacing / 2) ($plyr-control-spacing / 2);
|
||||||
$plyr-control-spacing;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
transition: opacity 0.4s ease-in-out, transform 0.4s ease-in-out;
|
transition: opacity 0.4s ease-in-out, transform 0.4s ease-in-out;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
|
|
||||||
|
@media (min-width: $plyr-bp-sm) {
|
||||||
|
padding: ($plyr-control-spacing * 3.5) $plyr-control-spacing $plyr-control-spacing;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide video controls
|
// Hide video controls
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
color: $plyr-tooltip-color;
|
color: $plyr-tooltip-color;
|
||||||
font-size: $plyr-font-size-small;
|
font-size: $plyr-font-size-small;
|
||||||
font-weight: $plyr-font-weight-regular;
|
font-weight: $plyr-font-weight-regular;
|
||||||
|
left: 50%;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
margin-bottom: ($plyr-tooltip-padding * 2);
|
margin-bottom: ($plyr-tooltip-padding * 2);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@@ -64,6 +65,7 @@
|
|||||||
|
|
||||||
// Last tooltip
|
// Last tooltip
|
||||||
.plyr__controls > .plyr__control:last-child .plyr__tooltip {
|
.plyr__controls > .plyr__control:last-child .plyr__tooltip {
|
||||||
|
left: auto;
|
||||||
right: 0;
|
right: 0;
|
||||||
transform: translate(0, 10px) scale(0.8);
|
transform: translate(0, 10px) scale(0.8);
|
||||||
transform-origin: 100% 100%;
|
transform-origin: 100% 100%;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// --------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
|
|
||||||
.plyr--video {
|
.plyr--video {
|
||||||
|
background: #000;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
// Menu open
|
// Menu open
|
||||||
|
|||||||
@@ -3,20 +3,23 @@
|
|||||||
// --------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
|
|
||||||
.plyr__volume {
|
.plyr__volume {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
input[type='range'] {
|
input[type='range'] {
|
||||||
|
margin-left: ($plyr-control-spacing / 2);
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: $plyr-bp-sm) {
|
@media (min-width: $plyr-bp-sm) {
|
||||||
max-width: 50px;
|
max-width: 90px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: $plyr-bp-md) {
|
@media (min-width: $plyr-bp-md) {
|
||||||
max-width: 80px;
|
max-width: 110px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
$plyr-control-icon-size: 18px !default;
|
$plyr-control-icon-size: 18px !default;
|
||||||
$plyr-control-icon-size-large: 20px !default;
|
|
||||||
$plyr-control-spacing: 10px !default;
|
$plyr-control-spacing: 10px !default;
|
||||||
$plyr-control-padding: ($plyr-control-spacing * 0.7) !default;
|
$plyr-control-padding: ($plyr-control-spacing * 0.7) !default;
|
||||||
$plyr-control-radius: 3px !default;
|
$plyr-control-radius: 3px !default;
|
||||||
|
|||||||
Reference in New Issue
Block a user