aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/js/plyr.js219
-rw-r--r--src/less/plyr.less5
2 files changed, 117 insertions, 107 deletions
diff --git a/src/js/plyr.js b/src/js/plyr.js
index e6bdd055..317e3b1b 100644
--- a/src/js/plyr.js
+++ b/src/js/plyr.js
@@ -9,7 +9,7 @@
;(function(root, factory) {
'use strict';
- /*global define,module*/
+ /* global define,module */
if (typeof module === 'object' && typeof module.exports === 'object') {
// Node, CommonJS-like
@@ -25,8 +25,7 @@
'use strict';
// Globals
- var fullscreen,
- scroll = { x: 0, y: 0 },
+ var scroll = { x: 0, y: 0 },
// Default config
defaults = {
@@ -118,6 +117,10 @@
enabled: 'plyr--fullscreen-enabled',
active: 'plyr--fullscreen-active'
},
+ pip: {
+ enabled: 'plyr--pip-enabled',
+ active: 'plyr--pip-active'
+ },
tabFocus: 'tab-focus'
},
captions: {
@@ -191,7 +194,7 @@
// Credits: http://paypal.github.io/accessible-html5-video-player/
// Unfortunately, due to mixed support, UA sniffing is required
- function _browserSniff() {
+ function _getBrowser() {
var ua = navigator.userAgent,
name = navigator.appName,
fullVersion = '' + parseFloat(navigator.appVersion),
@@ -270,32 +273,6 @@
};
}
- // Check for mime type support against a player instance
- // Credits: http://diveintohtml5.info/everything.html
- // Related: http://www.leanbackplyr.com/test/h5mt.html
- function _supportMime(plyr, mimeType) {
- var media = plyr.media;
-
- if (plyr.type === 'video') {
- // Check type
- switch (mimeType) {
- case 'video/webm': return !!(media.canPlayType && media.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/no/, ''));
- case 'video/mp4': return !!(media.canPlayType && media.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/, ''));
- case 'video/ogg': return !!(media.canPlayType && media.canPlayType('video/ogg; codecs="theora"').replace(/no/, ''));
- }
- } else if (plyr.type === 'audio') {
- // Check type
- switch (mimeType) {
- case 'audio/mpeg': return !!(media.canPlayType && media.canPlayType('audio/mpeg;').replace(/no/, ''));
- case 'audio/ogg': return !!(media.canPlayType && media.canPlayType('audio/ogg; codecs="vorbis"').replace(/no/, ''));
- case 'audio/wav': return !!(media.canPlayType && media.canPlayType('audio/wav; codecs="1"').replace(/no/, ''));
- }
- }
-
- // If we got this far, we're stuffed
- return false;
- }
-
// Inject a script
function _injectScript(source) {
if (document.querySelectorAll('script[src="' + source + '"]').length) {
@@ -587,45 +564,38 @@
};
// Fullscreen API
- function _fullscreen() {
- var fullscreen = {
- supportsFullScreen: false,
- isFullScreen: function() { return false; },
- requestFullScreen: function() {},
- cancelFullScreen: function() {},
- fullScreenEventName: '',
- element: null,
- prefix: ''
- },
- browserPrefixes = 'webkit o moz ms khtml'.split(' ');
-
- // Check for native support
- if (!_is.undefined(document.cancelFullScreen)) {
- fullscreen.supportsFullScreen = true;
- } else {
- // Check for fullscreen support by vendor prefix
- for (var i = 0, il = browserPrefixes.length; i < il; i++ ) {
- fullscreen.prefix = browserPrefixes[i];
-
- if (!_is.undefined(document[fullscreen.prefix + 'CancelFullScreen'])) {
- fullscreen.supportsFullScreen = true;
- break;
- } else if (!_is.undefined(document.msExitFullscreen) && document.msFullscreenEnabled) {
- // Special case for MS (when isn't it?)
- fullscreen.prefix = 'ms';
- fullscreen.supportsFullScreen = true;
- break;
- }
+ var _fullscreen;
+ (function() {
+ // Determine the prefix
+ var prefix = (function() {
+ if (!_is.undefined(document.cancelFullScreen)) {
+ return '';
+ } else {
+ // Check for fullscreen support by vendor prefix
+ ['webkit', 'o', 'moz', 'ms', 'khtml'].forEach(function(prefix) {
+ if (!_is.undefined(document[prefix + 'CancelFullScreen'])) {
+ return prefix;
+ } else if (!_is.undefined(document.msExitFullscreen) && document.msFullscreenEnabled) {
+ // Special case for MS (when isn't it?)
+ return 'ms';
+ }
+ });
}
- }
- // Update methods to do something useful
- if (fullscreen.supportsFullScreen) {
+ // If we got this far, there's no support
+ return false;
+ })();
+
+ _fullscreen = {
// Yet again Microsoft awesomeness,
// Sometimes the prefix is 'ms', sometimes 'MS' to keep you on your toes
- fullscreen.fullScreenEventName = (fullscreen.prefix === 'ms' ? 'MSFullscreenChange' : fullscreen.prefix + 'fullscreenchange');
+ eventType: (prefix === 'ms' ? 'MSFullscreenChange' : prefix + 'fullscreenchange'),
- fullscreen.isFullScreen = function(element) {
+ // Is an element fullscreen
+ isFullScreen: function(element) {
+ if (!_support.fullscreen) {
+ return false;
+ }
if (_is.undefined(element)) {
element = document.body;
}
@@ -635,29 +605,40 @@
case 'moz':
return document.mozFullScreenElement === element;
default:
- return document[this.prefix + 'FullscreenElement'] === element;
+ return document[prefix + 'FullscreenElement'] === element;
+ }
+ },
+ requestFullScreen: function(element) {
+ if (!_support.fullscreen) {
+ return false;
}
- };
- fullscreen.requestFullScreen = function(element) {
if (_is.undefined(element)) {
element = document.body;
}
- return (this.prefix === '') ? element.requestFullScreen() : element[this.prefix + (this.prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen')]();
- };
- fullscreen.cancelFullScreen = function() {
- return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + (this.prefix === 'ms' ? 'ExitFullscreen' : 'CancelFullScreen')]();
- };
- fullscreen.element = function() {
- return (this.prefix === '') ? document.fullscreenElement : document[this.prefix + 'FullscreenElement'];
- };
- }
-
- return fullscreen;
- }
+ return (prefix === '') ? element.requestFullScreen() : element[prefix + (prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen')]();
+ },
+ cancelFullScreen: function() {
+ if (!_support.fullscreen) {
+ return false;
+ }
+ return (prefix === '') ? document.cancelFullScreen() : document[prefix + (prefix === 'ms' ? 'ExitFullscreen' : 'CancelFullScreen')]();
+ },
+ element: function() {
+ if (!_support.fullscreen) {
+ return null;
+ }
+ return (prefix === '') ? document.fullscreenElement : document[prefix + 'FullscreenElement'];
+ }
+ };
+ })();
- // Local storage
- var _storage = {
- supported: (function() {
+ // Check for support
+ var _support = {
+ // Fullscreen support and set prefix
+ fullscreen: _fullscreen.prefix !== false,
+ // Local storage mode
+ // We can't assume if local storage is present that we can use it
+ storage: (function() {
if (!('localStorage' in window)) {
return false;
}
@@ -682,7 +663,37 @@
}
return false;
- })()
+ })(),
+ // Picture-in-picture support
+ // Safari only currently
+ pip: function(plyr) {
+ return _is.function(plyr.media.webkitSetPresentationMode);
+ },
+ // Check for mime type support against a player instance
+ // Credits: http://diveintohtml5.info/everything.html
+ // Related: http://www.leanbackplyr.com/test/h5mt.html
+ mime: function(plyr, type) {
+ var media = plyr.media;
+
+ if (plyr.type === 'video') {
+ // Check type
+ switch (type) {
+ case 'video/webm': return !!(media.canPlayType && media.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/no/, ''));
+ case 'video/mp4': return !!(media.canPlayType && media.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/, ''));
+ case 'video/ogg': return !!(media.canPlayType && media.canPlayType('video/ogg; codecs="theora"').replace(/no/, ''));
+ }
+ } else if (plyr.type === 'audio') {
+ // Check type
+ switch (type) {
+ case 'audio/mpeg': return !!(media.canPlayType && media.canPlayType('audio/mpeg;').replace(/no/, ''));
+ case 'audio/ogg': return !!(media.canPlayType && media.canPlayType('audio/ogg; codecs="vorbis"').replace(/no/, ''));
+ case 'audio/wav': return !!(media.canPlayType && media.canPlayType('audio/wav; codecs="1"').replace(/no/, ''));
+ }
+ }
+
+ // If we got this far, we're stuffed
+ return false;
+ }
};
// Player instance
@@ -867,8 +878,6 @@
// Settings button
if (_inArray(config.controls, 'settings')) {
-
-
html.push(
'<div class="plyr__menu">',
'<button type="button" id="plyr-settings-toggle-{id}" data-plyr="settings" aria-haspopup="true" aria-controls="plyr-settings-{id}" aria-expanded="false">',
@@ -888,7 +897,7 @@
'</button>',
'</li>',
'<li>',
- '<button type="button" data-plyr="slide-speed">',
+ '<button type="button" data-plyr="slide-quality">',
config.i18n.quality + ' <span class="plyr__menu__value">Auto</span>',
'</button>',
'</li>',
@@ -923,7 +932,7 @@
if ((plyr.type !== 'audio' || config.fullscreen.allowAudio) && config.fullscreen.enabled) {
// Check for native support
- var nativeSupport = fullscreen.supportsFullScreen;
+ var nativeSupport = _support.fullscreen;
if (nativeSupport || (config.fullscreen.fallback && !_inFrame())) {
_log((nativeSupport ? 'Native' : 'Fallback') + ' fullscreen enabled');
@@ -1435,7 +1444,7 @@
plyr.storage = {};
// Bail if we don't have localStorage support or it's disabled
- if (!_storage.supported || !config.storage.enabled) {
+ if (!_support.storage || !config.storage.enabled) {
return;
}
@@ -1463,7 +1472,7 @@
// Save a value back to local storage
function _updateStorage(value) {
// Bail if we don't have localStorage support or it's disabled
- if (!_storage.supported || !config.storage.enabled) {
+ if (!_support.storage || !config.storage.enabled) {
return;
}
@@ -1492,6 +1501,9 @@
_toggleClass(plyr.container, config.classes.type.replace('{0}', 'video'), true);
}
+ // Check for picture-in-picture support
+ _toggleClass(plyr.container, config.classes.pip.enabled, _support.pip(plyr));
+
// If there's no autoplay attribute, assume the video is stopped and add state class
_toggleClass(plyr.container, config.classes.stopped, config.autoplay);
@@ -2126,27 +2138,27 @@
// Toggle fullscreen
function _toggleFullscreen(event) {
// Check for native support
- var nativeSupport = fullscreen.supportsFullScreen;
+ var nativeSupport = _support.fullscreen;
if (nativeSupport) {
// If it's a fullscreen change event, update the UI
- if (event && event.type === fullscreen.fullScreenEventName) {
- plyr.isFullscreen = fullscreen.isFullScreen(plyr.container);
+ if (event && event.type === _fullscreen.eventType) {
+ plyr.isFullscreen = _fullscreen.isFullScreen(plyr.container);
} else {
// Else it's a user request to enter or exit
- if (!fullscreen.isFullScreen(plyr.container)) {
+ if (!_fullscreen.isFullScreen(plyr.container)) {
// Save scroll position
_saveScrollPosition();
// Request full screen
- fullscreen.requestFullScreen(plyr.container);
+ _fullscreen.requestFullScreen(plyr.container);
} else {
// Bail from fullscreen
- fullscreen.cancelFullScreen();
+ _fullscreen.cancelFullScreen();
}
// Check if we're actually full screen (it could fail)
- plyr.isFullscreen = fullscreen.isFullScreen(plyr.container);
+ plyr.isFullscreen = _fullscreen.isFullScreen(plyr.container);
return;
}
@@ -3009,7 +3021,7 @@
// Escape is handle natively when in full screen
// So we only need to worry about non native
- if (!fullscreen.supportsFullScreen && plyr.isFullscreen && code === 27) {
+ if (!_support.fullscreen && plyr.isFullscreen && code === 27) {
_toggleFullscreen();
}
@@ -3073,8 +3085,8 @@
_proxyListener(plyr.buttons.fullscreen, 'click', config.listeners.fullscreen, _toggleFullscreen);
// Handle user exiting fullscreen by escaping etc
- if (fullscreen.supportsFullScreen) {
- _on(document, fullscreen.fullScreenEventName, _toggleFullscreen);
+ if (_support.fullscreen) {
+ _on(document, _fullscreen.eventType, _toggleFullscreen);
}
// Captions
@@ -3330,11 +3342,8 @@
return null;
}
- // Setup the fullscreen api
- fullscreen = _fullscreen();
-
// Sniff out the browser
- plyr.browser = _browserSniff();
+ plyr.browser = _getBrowser();
// Bail if nothing to setup
if (!_is.htmlElement(plyr.media)) {
@@ -3493,7 +3502,7 @@
toggleFullscreen: _toggleFullscreen,
toggleControls: _toggleControls,
isFullscreen: function() { return plyr.isFullscreen || false; },
- support: function(mimeType) { return _supportMime(plyr, mimeType); },
+ support: function(mimeType) { return _support.mime(plyr, mimeType); },
destroy: _destroy
};
@@ -3564,7 +3573,7 @@
// Check for support
function supported(type) {
- var browser = _browserSniff(),
+ var browser = _getBrowser(),
isOldIE = (browser.isIE && browser.version <= 9),
isIos = browser.isIos,
isIphone = /iPhone|iPod/i.test(navigator.userAgent),
diff --git a/src/less/plyr.less b/src/less/plyr.less
index 78b967a5..ae9fae0e 100644
--- a/src/less/plyr.less
+++ b/src/less/plyr.less
@@ -30,6 +30,7 @@
max-width: 100%;
min-width: 200px;
font-family: @plyr-font-family;
+ font-weight: 500;
direction: ltr;
& when (@plyr-border-box = true) {
@@ -239,7 +240,6 @@
color: @plyr-captions-color;
font-size: @plyr-font-size-captions-base;
text-align: center;
- font-weight: 400;
span {
border-radius: 2px;
@@ -521,7 +521,7 @@
.plyr__menu__value {
margin-left: auto;
padding-left: 25px;
- font-weight: 400;
+ font-weight: 500;
color: fade(@plyr-menu-color, 80%);
}
@@ -555,6 +555,7 @@
color: @plyr-tooltip-color;
font-size: @plyr-font-size-small;
+ font-weight: 500;
line-height: 1.3;
transform: translate(-50%, 10px) scale(.8);