Fullscreen API changes, color settings tweaks
This commit is contained in:
parent
d21b58e1c9
commit
73a39769d4
2
demo/dist/demo.css
vendored
2
demo/dist/demo.css
vendored
File diff suppressed because one or more lines are too long
@ -6,11 +6,11 @@
|
|||||||
.button,
|
.button,
|
||||||
.button__count {
|
.button__count {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background: #fff;
|
background: $color-button-background;
|
||||||
border: 0;
|
border: 0;
|
||||||
border-radius: $border-radius-base;
|
border-radius: $border-radius-base;
|
||||||
box-shadow: 0 1px 1px rgba(#000, 0.1);
|
box-shadow: 0 1px 1px rgba(#000, 0.1);
|
||||||
color: $gray;
|
color: $color-button-text;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
padding: ($spacing-base * 0.75);
|
padding: ($spacing-base * 0.75);
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -71,7 +71,7 @@
|
|||||||
&::before {
|
&::before {
|
||||||
border: $arrow-size solid transparent;
|
border: $arrow-size solid transparent;
|
||||||
border-left-width: 0;
|
border-left-width: 0;
|
||||||
border-right-color: #fff;
|
border-right-color: $color-button-background;
|
||||||
content: '';
|
content: '';
|
||||||
height: 0;
|
height: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -28,6 +28,7 @@ body {
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
padding-bottom: 1px; // Collapsing margins
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,5 +24,9 @@ $color-vimeo: #19b7ed;
|
|||||||
$color-link: #fff;
|
$color-link: #fff;
|
||||||
$color-background: $color-brand-primary;
|
$color-background: $color-brand-primary;
|
||||||
|
|
||||||
|
// Buttons
|
||||||
|
$color-button-background: #fff;
|
||||||
|
$color-button-text: $gray;
|
||||||
|
|
||||||
// Focus
|
// Focus
|
||||||
$tab-focus-default-color: #fff;
|
$tab-focus-default-color: #fff;
|
||||||
|
2
dist/plyr.css
vendored
2
dist/plyr.css
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.js
vendored
2
dist/plyr.js
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.js.map
vendored
2
dist/plyr.js.map
vendored
File diff suppressed because one or more lines are too long
@ -44,7 +44,7 @@
|
|||||||
"stylelint-order": "^0.8.0",
|
"stylelint-order": "^0.8.0",
|
||||||
"stylelint-scss": "^2.3.0",
|
"stylelint-scss": "^2.3.0",
|
||||||
"stylelint-selector-bem-pattern": "^2.0.0",
|
"stylelint-selector-bem-pattern": "^2.0.0",
|
||||||
"uglify-es": "^3.3.9"
|
"uglify-es": "^3.3.10"
|
||||||
},
|
},
|
||||||
"keywords": ["HTML5 Video", "HTML5 Audio", "Media Player", "DASH", "Shaka", "WordPress", "HLS"],
|
"keywords": ["HTML5 Video", "HTML5 Audio", "Media Player", "DASH", "Shaka", "WordPress", "HLS"],
|
||||||
"repository": {
|
"repository": {
|
||||||
|
100
readme.md
100
readme.md
@ -304,69 +304,77 @@ element.addEventListener('ready', event => {
|
|||||||
|
|
||||||
### Methods
|
### Methods
|
||||||
|
|
||||||
Methods are not chainable. An example use of a method:
|
Example method use:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
player.play();
|
player.play(); // Start playback
|
||||||
|
player.fullscreen.enter(); // Enter fullscreen
|
||||||
```
|
```
|
||||||
|
|
||||||
| Method | Parameters | Description |
|
| Method | Parameters | Description |
|
||||||
| ------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------- |
|
| ------------------------ | ---------------- | ---------------------------------------------------------------------------------------------------------- |
|
||||||
| `play()`¹ | - | Start playback. |
|
| `play()`¹ | - | Start playback. |
|
||||||
| `pause()` | - | Pause playback. |
|
| `pause()` | - | Pause playback. |
|
||||||
| `togglePlay(toggle)` | Boolean | Toggle playback, if no parameters are passed, it will toggle based on current status. |
|
| `togglePlay(toggle)` | Boolean | Toggle playback, if no parameters are passed, it will toggle based on current status. |
|
||||||
| `stop()` | - | Stop playback and reset to start. |
|
| `stop()` | - | Stop playback and reset to start. |
|
||||||
| `restart()` | - | Restart playback. |
|
| `restart()` | - | Restart playback. |
|
||||||
| `rewind(seekTime)` | Number | Rewind playback by the specified seek time. If no parameter is passed, the default seek time will be used. |
|
| `rewind(seekTime)` | Number | Rewind playback by the specified seek time. If no parameter is passed, the default seek time will be used. |
|
||||||
| `forward(seekTime)` | Number | Fast forward by the specified seek time. If no parameter is passed, the default seek time will be used. |
|
| `forward(seekTime)` | Number | Fast forward by the specified seek time. If no parameter is passed, the default seek time will be used. |
|
||||||
| `increaseVolume(step)` | Number | Increase volume by the specified step. If no parameter is passed, the default step will be used. |
|
| `increaseVolume(step)` | Number | Increase volume by the specified step. If no parameter is passed, the default step will be used. |
|
||||||
| `decreaseVolume(step)` | Number | Increase volume by the specified step. If no parameter is passed, the default step will be used. |
|
| `decreaseVolume(step)` | Number | Increase volume by the specified step. If no parameter is passed, the default step will be used. |
|
||||||
| `toggleCaptions(toggle)` | Boolean | Toggle captions display. If no parameter is passed, it will toggle based on current status. |
|
| `toggleCaptions(toggle)` | Boolean | Toggle captions display. If no parameter is passed, it will toggle based on current status. |
|
||||||
| `toggleFullscreen(event)` | Event | Toggle fullscreen. Fullscreen can only be initiated by a user event. Exit is possible without user input. |
|
| `fullscreen.enter()` | - | Enter fullscreen. If fullscreen is not supported, a fallback "full window/viewport" is used instead. |
|
||||||
| `airplay()` | - | Trigger the airplay dialog on supported devices. |
|
| `fullscreen.exit()` | - | Exit fullscreen. |
|
||||||
| `toggleControls(toggle)` | Boolean | Toggle the controls based on the specified boolean. |
|
| `fullscreen.toggle()` | - | Toggle fullscreen. |
|
||||||
| `on(event, function)` | String, Function | Add an event listener for the specified event. |
|
| `airplay()` | - | Trigger the airplay dialog on supported devices. |
|
||||||
| `off(event, function)` | String, Function | Remove an event listener for the specified event. |
|
| `toggleControls(toggle)` | Boolean | Toggle the controls based on the specified boolean. |
|
||||||
| `supports(type)` | String | Check support for a mime type. |
|
| `on(event, function)` | String, Function | Add an event listener for the specified event. |
|
||||||
| `destroy()` | - | Destroy the instance and garbage collect any elements. |
|
| `off(event, function)` | String, Function | Remove an event listener for the specified event. |
|
||||||
|
| `supports(type)` | String | Check support for a mime type. |
|
||||||
|
| `destroy()` | - | Destroy the instance and garbage collect any elements. |
|
||||||
|
|
||||||
1. For HTML5 players, `play()` will return a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) in _some_ browsers - WebKit and Mozilla [according to MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play) at time of writing.
|
1. For HTML5 players, `play()` will return a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) in _some_ browsers - WebKit and Mozilla [according to MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play) at time of writing.
|
||||||
|
|
||||||
### Getters and Setters
|
### Getters and Setters
|
||||||
|
|
||||||
An example setter:
|
Example setters:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
player.volume = 0.5;
|
player.volume = 0.5; // Sets volume at 50%
|
||||||
|
player.currentTime = 10; // Seeks to 10 seconds
|
||||||
```
|
```
|
||||||
|
|
||||||
An example getter:
|
Example getters:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
player.volume; // returns 0.5;
|
player.volume; // 0.5;
|
||||||
|
player.currentTime; // 10
|
||||||
|
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. |
|
||||||
| `paused` | ✓ | - | Returns a boolean indicating if the current player is paused. |
|
| `paused` | ✓ | - | Returns a boolean indicating if the current player is paused. |
|
||||||
| `playing` | ✓ | - | Returns a boolean indicating if the current player is playing. |
|
| `playing` | ✓ | - | Returns a boolean indicating if the current player is playing. |
|
||||||
| `ended` | ✓ | - | Returns a boolean indicating if the current player has finished playback. |
|
| `ended` | ✓ | - | Returns a boolean indicating if the current player has finished playback. |
|
||||||
| `currentTime` | ✓ | ✓ | Gets or sets the currentTime for the player. The setter accepts a float in seconds. |
|
| `currentTime` | ✓ | ✓ | Gets or sets the currentTime for the player. The setter accepts a float in seconds. |
|
||||||
| `seeking` | ✓ | - | Returns a boolean indicating if the current player is seeking. |
|
| `seeking` | ✓ | - | Returns a boolean indicating if the current player is seeking. |
|
||||||
| `duration` | ✓ | - | Returns the duration for the current media. |
|
| `duration` | ✓ | - | Returns the duration for the current media. |
|
||||||
| `volume` | ✓ | ✓ | Gets or sets the volume for the player. The setter accepts a float between 0 and 1. |
|
| `volume` | ✓ | ✓ | Gets or sets the volume for the player. The setter accepts a float between 0 and 1. |
|
||||||
| `muted` | ✓ | ✓ | Gets or sets the muted state of the player. The setter accepts a boolean. |
|
| `muted` | ✓ | ✓ | Gets or sets the muted state of the player. The setter accepts a boolean. |
|
||||||
| `hasAudio` | ✓ | - | Returns a boolean indicating if the current media has an audio track. |
|
| `hasAudio` | ✓ | - | Returns a boolean indicating if the current media has an audio track. |
|
||||||
| `speed` | ✓ | ✓ | Gets or sets the speed for the player. The setter accepts a value in the options specified in your config. Generally the minimum should be 0.5. |
|
| `speed` | ✓ | ✓ | Gets or sets the speed for the player. The setter accepts a value in the options specified in your config. Generally the minimum should be 0.5. |
|
||||||
| `quality`¹ | ✓ | ✓ | Gets or sets the quality for the player. The setter accepts a value from the options specified in your config. |
|
| `quality`¹ | ✓ | ✓ | Gets or sets the quality for the player. The setter accepts a value from the options specified in your config. |
|
||||||
| `loop` | ✓ | ✓ | Gets or sets the current loop state of the player. The setter accepts a boolean. |
|
| `loop` | ✓ | ✓ | Gets or sets the current loop state of the player. The setter accepts a boolean. |
|
||||||
| `source` | ✓ | ✓ | Gets or sets the current source for the player. The setter accepts an object. See [source setter](#source-setter) below for examples. |
|
| `source` | ✓ | ✓ | Gets or sets the current source for the player. The setter accepts an object. See [source setter](#source-setter) below for examples. |
|
||||||
| `poster`² | ✓ | ✓ | Gets or sets the current poster image for the player. The setter accepts a string; the URL for the updated poster image. |
|
| `poster`² | ✓ | ✓ | Gets or sets the current poster image for the player. The setter accepts a string; the URL for the updated poster image. |
|
||||||
| `autoplay` | ✓ | ✓ | Gets or sets the autoplay state of the player. The setter accepts a boolean. |
|
| `autoplay` | ✓ | ✓ | Gets or sets the autoplay state of the player. The setter accepts a boolean. |
|
||||||
| `language` | ✓ | ✓ | Gets or sets the preferred captions language for the player. The setter accepts an ISO two-letter language code. Support for the languages is dependent on the captions you include. |
|
| `language` | ✓ | ✓ | Gets or sets the preferred captions language for the player. The setter accepts an ISO two-letter language code. Support for the languages is dependent on the captions you include. |
|
||||||
| `pip` | ✓ | ✓ | Gets or sets the picture-in-picture state of the player. The setter accepts a boolean. This currently only supported on Safari 10+ on MacOS Sierra+ and iOS 10+. |
|
| `fullscreen.active` | ✓ | - | Returns a boolean indicating if the current player is in fullscreen mode. |
|
||||||
|
| `fullscreen.enabled` | ✓ | - | Returns a boolean indicating if the current player has fullscreen enabled. |
|
||||||
|
| `pip` | ✓ | ✓ | Gets or sets the picture-in-picture state of the player. The setter accepts a boolean. This currently only supported on Safari 10+ on MacOS Sierra+ and iOS 10+. |
|
||||||
|
|
||||||
1. YouTube only. HTML5 will follow.
|
1. YouTube only. HTML5 will follow.
|
||||||
2. HTML5 only
|
2. HTML5 only
|
||||||
|
@ -120,6 +120,7 @@ const defaults = {
|
|||||||
fullscreen: {
|
fullscreen: {
|
||||||
enabled: true, // Allow fullscreen?
|
enabled: true, // Allow fullscreen?
|
||||||
fallback: true, // Fallback for vintage browsers
|
fallback: true, // Fallback for vintage browsers
|
||||||
|
iosNative: false, // Use the native fullscreen in iOS (disables custom controls)
|
||||||
},
|
},
|
||||||
|
|
||||||
// Local storage
|
// Local storage
|
||||||
|
@ -1,127 +1,201 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Plyr fullscreen API
|
// Fullscreen wrapper
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
import utils from './utils';
|
import utils from './utils';
|
||||||
|
|
||||||
// Determine the prefix
|
const browser = utils.getBrowser();
|
||||||
const prefix = (() => {
|
|
||||||
let value = false;
|
|
||||||
|
|
||||||
if (utils.is.function(document.cancelFullScreen)) {
|
function onChange() {
|
||||||
value = '';
|
if (!this.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update toggle button
|
||||||
|
const button = this.player.elements.buttons.fullscreen;
|
||||||
|
if (utils.is.element(button)) {
|
||||||
|
utils.toggleState(button, this.active);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger an event
|
||||||
|
utils.dispatchEvent(this.target, this.active ? 'enterfullscreen' : 'exitfullscreen', true);
|
||||||
|
|
||||||
|
// Trap focus in container
|
||||||
|
if (!browser.isIos) {
|
||||||
|
utils.trapFocus.call(this.player, this.target, this.active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleFallback(toggle = false) {
|
||||||
|
// Store or restore scroll position
|
||||||
|
if (toggle) {
|
||||||
|
this.scrollPosition = {
|
||||||
|
x: window.scrollX || 0,
|
||||||
|
y: window.scrollY || 0,
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
|
window.scrollTo(this.scrollPosition.x, this.scrollPosition.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle scroll
|
||||||
|
document.body.style.overflow = toggle ? 'hidden' : '';
|
||||||
|
|
||||||
|
// Toggle class hook
|
||||||
|
utils.toggleClass(this.target, this.player.config.classNames.fullscreen.fallback, toggle);
|
||||||
|
|
||||||
|
// Toggle button and fire events
|
||||||
|
onChange.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Fullscreen {
|
||||||
|
constructor(player) {
|
||||||
|
// Keep reference to parent
|
||||||
|
this.player = player;
|
||||||
|
|
||||||
|
// Get prefix
|
||||||
|
this.prefix = Fullscreen.prefix;
|
||||||
|
|
||||||
|
// Scroll position
|
||||||
|
this.scrollPosition = { x: 0, y: 0 };
|
||||||
|
|
||||||
|
// Register event listeners
|
||||||
|
// Handle event (incase user presses escape etc)
|
||||||
|
utils.on(document, this.prefix === 'ms' ? 'MSFullscreenChange' : `${this.prefix}fullscreenchange`, () => {
|
||||||
|
// TODO: Filter for target??
|
||||||
|
onChange.call(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fullscreen toggle on double click
|
||||||
|
utils.on(this.player.elements.container, 'dblclick', () => {
|
||||||
|
this.toggle();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update the UI
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine if native supported
|
||||||
|
static get native() {
|
||||||
|
return !!(document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the prefix for handlers
|
||||||
|
static get prefix() {
|
||||||
|
// No prefix
|
||||||
|
if (utils.is.function(document.cancelFullScreen)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for fullscreen support by vendor prefix
|
// Check for fullscreen support by vendor prefix
|
||||||
[
|
let value = '';
|
||||||
|
const prefixes = [
|
||||||
'webkit',
|
'webkit',
|
||||||
'o',
|
|
||||||
'moz',
|
'moz',
|
||||||
'ms',
|
'ms',
|
||||||
'khtml',
|
];
|
||||||
].some(pre => {
|
|
||||||
|
prefixes.some(pre => {
|
||||||
if (utils.is.function(document[`${pre}CancelFullScreen`])) {
|
if (utils.is.function(document[`${pre}CancelFullScreen`])) {
|
||||||
value = pre;
|
value = pre;
|
||||||
return true;
|
return true;
|
||||||
} else if (utils.is.function(document.msExitFullscreen) && document.msFullscreenEnabled) {
|
} else if (utils.is.function(document.msExitFullscreen)) {
|
||||||
// Special case for MS (when isn't it?)
|
|
||||||
value = 'ms';
|
value = 'ms';
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
// Determine if fullscreen is enabled
|
||||||
})();
|
get enabled() {
|
||||||
|
const fallback = this.player.config.fullscreen.fallback && !utils.inFrame();
|
||||||
|
|
||||||
// Fullscreen API
|
return (Fullscreen.native || fallback) && this.player.config.fullscreen.enabled && this.player.supported.ui && this.player.isVideo;
|
||||||
const fullscreen = {
|
}
|
||||||
// Get the prefix
|
|
||||||
prefix,
|
|
||||||
|
|
||||||
// Check if we can use it
|
// Get active state
|
||||||
enabled: document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled,
|
get active() {
|
||||||
|
if (!this.enabled) {
|
||||||
// Yet again Microsoft awesomeness,
|
|
||||||
// Sometimes the prefix is 'ms', sometimes 'MS' to keep you on your toes
|
|
||||||
eventType: prefix === 'ms' ? 'MSFullscreenChange' : `${prefix}fullscreenchange`,
|
|
||||||
|
|
||||||
// Is an element fullscreen
|
|
||||||
isFullScreen(element) {
|
|
||||||
if (!fullscreen.enabled) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const target = utils.is.nullOrUndefined(element) ? document.body : element;
|
// Fallback using classname
|
||||||
|
if (!Fullscreen.native) {
|
||||||
switch (prefix) {
|
return utils.hasClass(this.target, this.player.config.classNames.fullscreen.fallback);
|
||||||
case '':
|
|
||||||
return document.fullscreenElement === target;
|
|
||||||
|
|
||||||
case 'moz':
|
|
||||||
return document.mozFullScreenElement === target;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return document[`${prefix}FullscreenElement`] === target;
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
const element = !this.prefix ? document.fullscreenElement : document[`${this.prefix}FullscreenElement`];
|
||||||
|
|
||||||
|
return element === this.target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get target element
|
||||||
|
get target() {
|
||||||
|
return browser.isIos && this.player.config.fullscreen.iosNative ? this.player.media : this.player.elements.container;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update UI
|
||||||
|
update() {
|
||||||
|
if (this.enabled) {
|
||||||
|
this.player.debug.log(`${Fullscreen.native ? 'Native' : 'Fallback'} fullscreen enabled`);
|
||||||
|
} else {
|
||||||
|
this.player.debug.log('Fullscreen not supported and fallback disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add styling hook to show button
|
||||||
|
utils.toggleClass(this.player.elements.container, this.player.config.classNames.fullscreen.enabled, this.enabled);
|
||||||
|
}
|
||||||
|
|
||||||
// Make an element fullscreen
|
// Make an element fullscreen
|
||||||
requestFullScreen(element) {
|
enter() {
|
||||||
if (!fullscreen.enabled) {
|
if (!this.enabled) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const target = utils.is.nullOrUndefined(element) ? document.body : element;
|
|
||||||
|
|
||||||
return !prefix.length ? target.requestFullScreen() : target[prefix + (prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen')]();
|
|
||||||
},
|
|
||||||
|
|
||||||
// Bail from fullscreen
|
|
||||||
cancelFullScreen() {
|
|
||||||
if (!fullscreen.enabled) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return !prefix.length ? document.cancelFullScreen() : document[prefix + (prefix === 'ms' ? 'ExitFullscreen' : 'CancelFullScreen')]();
|
|
||||||
},
|
|
||||||
|
|
||||||
// Get the current element
|
|
||||||
element() {
|
|
||||||
if (!fullscreen.enabled) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return !prefix.length ? document.fullscreenElement : document[`${prefix}FullscreenElement`];
|
|
||||||
},
|
|
||||||
|
|
||||||
// Setup fullscreen
|
|
||||||
setup() {
|
|
||||||
if (!this.supported.ui || this.isAudio || !this.config.fullscreen.enabled) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for native support
|
// iOS native fullscreen doesn't need the request step
|
||||||
const nativeSupport = fullscreen.enabled;
|
if (browser.isIos && this.player.config.fullscreen.iosNative) {
|
||||||
|
if (this.player.playing) {
|
||||||
|
this.target.webkitEnterFullscreen();
|
||||||
|
}
|
||||||
|
} else if (!Fullscreen.native) {
|
||||||
|
toggleFallback.call(this, true);
|
||||||
|
} else if (!this.prefix) {
|
||||||
|
this.target.requestFullScreen();
|
||||||
|
} else if (!utils.is.empty(this.prefix)) {
|
||||||
|
this.target[`${this.prefix}${this.prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen'}`]();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (nativeSupport || (this.config.fullscreen.fallback && !utils.inFrame())) {
|
// Bail from fullscreen
|
||||||
this.debug.log(`${nativeSupport ? 'Native' : 'Fallback'} fullscreen enabled`);
|
exit() {
|
||||||
|
if (!this.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Add styling hook to show button
|
// iOS native fullscreen
|
||||||
utils.toggleClass(this.elements.container, this.config.classNames.fullscreen.enabled, true);
|
if (browser.isIos && this.player.config.fullscreen.iosNative) {
|
||||||
|
this.target.webkitExitFullscreen();
|
||||||
|
this.player.play();
|
||||||
|
} else if (!Fullscreen.native) {
|
||||||
|
toggleFallback.call(this, false);
|
||||||
|
} else if (!this.prefix) {
|
||||||
|
document.cancelFullScreen();
|
||||||
|
} else if (!utils.is.empty(this.prefix)) {
|
||||||
|
document[`${this.prefix}${this.prefix === 'ms' ? 'ExitFullscreen' : 'CancelFullScreen'}`]();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle state
|
||||||
|
toggle() {
|
||||||
|
if (!this.active) {
|
||||||
|
this.enter();
|
||||||
} else {
|
} else {
|
||||||
this.debug.log('Fullscreen not supported and fallback disabled');
|
this.exit();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Toggle state
|
export default Fullscreen;
|
||||||
if (this.elements.buttons && this.elements.buttons.fullscreen) {
|
|
||||||
utils.toggleState(this.elements.buttons.fullscreen, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trap focus in container
|
|
||||||
utils.trapFocus.call(this);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default fullscreen;
|
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
import support from './support';
|
import support from './support';
|
||||||
import utils from './utils';
|
import utils from './utils';
|
||||||
import controls from './controls';
|
import controls from './controls';
|
||||||
import fullscreen from './fullscreen';
|
|
||||||
import ui from './ui';
|
import ui from './ui';
|
||||||
|
|
||||||
// Sniff out the browser
|
// Sniff out the browser
|
||||||
@ -138,7 +137,7 @@ const listeners = {
|
|||||||
|
|
||||||
case 70:
|
case 70:
|
||||||
// F key
|
// F key
|
||||||
this.toggleFullscreen();
|
this.fullscreen.toggle();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 67:
|
case 67:
|
||||||
@ -171,8 +170,8 @@ const listeners = {
|
|||||||
|
|
||||||
// Escape is handle natively when in full screen
|
// Escape is handle natively when in full screen
|
||||||
// So we only need to worry about non native
|
// So we only need to worry about non native
|
||||||
if (!fullscreen.enabled && this.fullscreen.active && code === 27) {
|
if (!this.fullscreen.enabled && this.fullscreen.active && code === 27) {
|
||||||
this.toggleFullscreen();
|
this.fullscreen.toggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store last code for next cycle
|
// Store last code for next cycle
|
||||||
@ -215,18 +214,6 @@ const listeners = {
|
|||||||
this.toggleControls(event);
|
this.toggleControls(event);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle user exiting fullscreen by escaping etc
|
|
||||||
if (fullscreen.enabled) {
|
|
||||||
utils.on(document, fullscreen.eventType, event => {
|
|
||||||
this.toggleFullscreen(event);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Fullscreen toggle on double click
|
|
||||||
utils.on(this.elements.container, 'dblclick', event => {
|
|
||||||
this.toggleFullscreen(event);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Listen for media events
|
// Listen for media events
|
||||||
@ -266,7 +253,7 @@ const listeners = {
|
|||||||
utils.on(this.media, 'playing play pause ended', event => ui.checkPlaying.call(this, event));
|
utils.on(this.media, 'playing play pause ended', event => ui.checkPlaying.call(this, event));
|
||||||
|
|
||||||
// Loading
|
// Loading
|
||||||
utils.on(this.media, 'stalled waiting canplay seeked playing', event => ui.checkLoading.call(this, event));
|
utils.on(this.media, 'waiting canplay seeked playing', event => ui.checkLoading.call(this, event));
|
||||||
|
|
||||||
// Check if media failed to load
|
// Check if media failed to load
|
||||||
// utils.on(this.media, 'play', event => ui.checkFailed.call(this, event));
|
// utils.on(this.media, 'play', event => ui.checkFailed.call(this, event));
|
||||||
@ -307,7 +294,7 @@ const listeners = {
|
|||||||
event => {
|
event => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
},
|
},
|
||||||
false
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,63 +381,63 @@ const listeners = {
|
|||||||
utils.on(this.elements.buttons.play, 'click', event =>
|
utils.on(this.elements.buttons.play, 'click', event =>
|
||||||
proxy(event, 'play', () => {
|
proxy(event, 'play', () => {
|
||||||
this.togglePlay();
|
this.togglePlay();
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Pause
|
// Pause
|
||||||
utils.on(this.elements.buttons.restart, 'click', event =>
|
utils.on(this.elements.buttons.restart, 'click', event =>
|
||||||
proxy(event, 'restart', () => {
|
proxy(event, 'restart', () => {
|
||||||
this.restart();
|
this.restart();
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Rewind
|
// Rewind
|
||||||
utils.on(this.elements.buttons.rewind, 'click', event =>
|
utils.on(this.elements.buttons.rewind, 'click', event =>
|
||||||
proxy(event, 'rewind', () => {
|
proxy(event, 'rewind', () => {
|
||||||
this.rewind();
|
this.rewind();
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Rewind
|
// Rewind
|
||||||
utils.on(this.elements.buttons.forward, 'click', event =>
|
utils.on(this.elements.buttons.forward, 'click', event =>
|
||||||
proxy(event, 'forward', () => {
|
proxy(event, 'forward', () => {
|
||||||
this.forward();
|
this.forward();
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Mute toggle
|
// Mute toggle
|
||||||
utils.on(this.elements.buttons.mute, 'click', event =>
|
utils.on(this.elements.buttons.mute, 'click', event =>
|
||||||
proxy(event, 'mute', () => {
|
proxy(event, 'mute', () => {
|
||||||
this.muted = !this.muted;
|
this.muted = !this.muted;
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Captions toggle
|
// Captions toggle
|
||||||
utils.on(this.elements.buttons.captions, 'click', event =>
|
utils.on(this.elements.buttons.captions, 'click', event =>
|
||||||
proxy(event, 'captions', () => {
|
proxy(event, 'captions', () => {
|
||||||
this.toggleCaptions();
|
this.toggleCaptions();
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Fullscreen toggle
|
// Fullscreen toggle
|
||||||
utils.on(this.elements.buttons.fullscreen, 'click', event =>
|
utils.on(this.elements.buttons.fullscreen, 'click', event =>
|
||||||
proxy(event, 'fullscreen', () => {
|
proxy(event, 'fullscreen', () => {
|
||||||
this.toggleFullscreen();
|
this.fullscreen.toggle();
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Picture-in-Picture
|
// Picture-in-Picture
|
||||||
utils.on(this.elements.buttons.pip, 'click', event =>
|
utils.on(this.elements.buttons.pip, 'click', event =>
|
||||||
proxy(event, 'pip', () => {
|
proxy(event, 'pip', () => {
|
||||||
this.pip = 'toggle';
|
this.pip = 'toggle';
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Airplay
|
// Airplay
|
||||||
utils.on(this.elements.buttons.airplay, 'click', event =>
|
utils.on(this.elements.buttons.airplay, 'click', event =>
|
||||||
proxy(event, 'airplay', () => {
|
proxy(event, 'airplay', () => {
|
||||||
this.airplay();
|
this.airplay();
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Settings menu
|
// Settings menu
|
||||||
@ -489,7 +476,7 @@ const listeners = {
|
|||||||
utils.on(this.elements.inputs.seek, inputEvent, event =>
|
utils.on(this.elements.inputs.seek, inputEvent, event =>
|
||||||
proxy(event, 'seek', () => {
|
proxy(event, 'seek', () => {
|
||||||
this.currentTime = event.target.value / event.target.max * this.duration;
|
this.currentTime = event.target.value / event.target.max * this.duration;
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Current time invert
|
// Current time invert
|
||||||
@ -510,7 +497,7 @@ const listeners = {
|
|||||||
utils.on(this.elements.inputs.volume, inputEvent, event =>
|
utils.on(this.elements.inputs.volume, inputEvent, event =>
|
||||||
proxy(event, 'volume', () => {
|
proxy(event, 'volume', () => {
|
||||||
this.volume = event.target.value;
|
this.volume = event.target.value;
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Polyfill for lower fill in <input type="range"> for webkit
|
// Polyfill for lower fill in <input type="range"> for webkit
|
||||||
@ -583,7 +570,7 @@ const listeners = {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
false
|
false,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Plyr
|
// Plyr
|
||||||
// plyr.js v3.0.0-beta.12
|
// plyr.js v3.0.0-beta.12
|
||||||
// https://github.com/sampotts/plyr
|
// https://github.com/sampotts/plyr
|
||||||
@ -11,12 +11,12 @@ import support from './support';
|
|||||||
import utils from './utils';
|
import utils from './utils';
|
||||||
|
|
||||||
import Console from './console';
|
import Console from './console';
|
||||||
|
import Fullscreen from './fullscreen';
|
||||||
import Storage from './storage';
|
import Storage from './storage';
|
||||||
import Ads from './plugins/ads';
|
import Ads from './plugins/ads';
|
||||||
|
|
||||||
import captions from './captions';
|
import captions from './captions';
|
||||||
import controls from './controls';
|
import controls from './controls';
|
||||||
import fullscreen from './fullscreen';
|
|
||||||
import listeners from './listeners';
|
import listeners from './listeners';
|
||||||
import media from './media';
|
import media from './media';
|
||||||
import source from './source';
|
import source from './source';
|
||||||
@ -26,12 +26,6 @@ import ui from './ui';
|
|||||||
// TODO: Use a WeakMap for private globals
|
// TODO: Use a WeakMap for private globals
|
||||||
// const globals = new WeakMap();
|
// const globals = new WeakMap();
|
||||||
|
|
||||||
// Globals
|
|
||||||
let scrollPosition = {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Plyr instance
|
// Plyr instance
|
||||||
class Plyr {
|
class Plyr {
|
||||||
constructor(target, options) {
|
constructor(target, options) {
|
||||||
@ -232,9 +226,6 @@ class Plyr {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup local storage for user settings
|
|
||||||
this.storage = new Storage(this);
|
|
||||||
|
|
||||||
// Check for support again but with type
|
// Check for support again but with type
|
||||||
this.supported = support.check(this.type, this.provider, this.config.inline);
|
this.supported = support.check(this.type, this.provider, this.config.inline);
|
||||||
|
|
||||||
@ -244,6 +235,9 @@ class Plyr {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup local storage for user settings
|
||||||
|
this.storage = new Storage(this);
|
||||||
|
|
||||||
// Store reference
|
// Store reference
|
||||||
this.media.plyr = this;
|
this.media.plyr = this;
|
||||||
|
|
||||||
@ -278,6 +272,9 @@ class Plyr {
|
|||||||
ui.build.call(this);
|
ui.build.call(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup fullscreen
|
||||||
|
this.fullscreen = new Fullscreen(this);
|
||||||
|
|
||||||
// Setup ads if provided
|
// Setup ads if provided
|
||||||
this.ads = new Ads(this);
|
this.ads = new Ads(this);
|
||||||
}
|
}
|
||||||
@ -850,62 +847,6 @@ class Plyr {
|
|||||||
return this.captions.language;
|
return this.captions.language;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggle fullscreen playback
|
|
||||||
* Requires user input event
|
|
||||||
* @param {event} event
|
|
||||||
*/
|
|
||||||
toggleFullscreen(event) {
|
|
||||||
// Video only
|
|
||||||
if (this.isAudio) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for native support
|
|
||||||
if (fullscreen.enabled) {
|
|
||||||
if (utils.is.event(event) && event.type === fullscreen.eventType) {
|
|
||||||
// If it's a fullscreen change event, update the state
|
|
||||||
this.fullscreen.active = fullscreen.isFullScreen(this.elements.container);
|
|
||||||
} else {
|
|
||||||
// Else it's a user request to enter or exit
|
|
||||||
if (!this.fullscreen.active) {
|
|
||||||
fullscreen.requestFullScreen(this.elements.container);
|
|
||||||
} else {
|
|
||||||
fullscreen.cancelFullScreen();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Otherwise, it's a simple toggle
|
|
||||||
this.fullscreen.active = !this.fullscreen.active;
|
|
||||||
|
|
||||||
// Add class hook
|
|
||||||
utils.toggleClass(this.elements.container, this.config.classNames.fullscreen.fallback, this.fullscreen.active);
|
|
||||||
|
|
||||||
// Make sure we don't lose scroll position
|
|
||||||
if (this.fullscreen.active) {
|
|
||||||
scrollPosition = {
|
|
||||||
x: window.pageXOffset || 0,
|
|
||||||
y: window.pageYOffset || 0,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
window.scrollTo(scrollPosition.x, scrollPosition.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind/unbind escape key
|
|
||||||
document.body.style.overflow = this.fullscreen.active ? 'hidden' : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set button state
|
|
||||||
if (utils.is.element(this.elements.buttons.fullscreen)) {
|
|
||||||
utils.toggleState(this.elements.buttons.fullscreen, this.fullscreen.active);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trigger an event
|
|
||||||
utils.dispatchEvent.call(this, this.media, this.fullscreen.active ? 'enterfullscreen' : 'exitfullscreen');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle picture-in-picture playback on WebKit/MacOS
|
* Toggle picture-in-picture playback on WebKit/MacOS
|
||||||
* TODO: update player with state, support, enabled
|
* TODO: update player with state, support, enabled
|
||||||
|
@ -136,6 +136,9 @@ const source = {
|
|||||||
// Setup interface
|
// Setup interface
|
||||||
ui.build.call(this);
|
ui.build.call(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the fullscreen support
|
||||||
|
this.fullscreen.update();
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
import utils from './utils';
|
import utils from './utils';
|
||||||
import captions from './captions';
|
import captions from './captions';
|
||||||
import controls from './controls';
|
import controls from './controls';
|
||||||
import fullscreen from './fullscreen';
|
|
||||||
import listeners from './listeners';
|
import listeners from './listeners';
|
||||||
|
|
||||||
const ui = {
|
const ui = {
|
||||||
@ -63,9 +62,6 @@ const ui = {
|
|||||||
// Remove native controls
|
// Remove native controls
|
||||||
ui.toggleNativeControls.call(this);
|
ui.toggleNativeControls.call(this);
|
||||||
|
|
||||||
// Setup fullscreen
|
|
||||||
fullscreen.setup.call(this);
|
|
||||||
|
|
||||||
// Captions
|
// Captions
|
||||||
captions.setup.call(this);
|
captions.setup.call(this);
|
||||||
|
|
||||||
|
@ -525,41 +525,46 @@ const utils = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Trap focus inside container
|
// Trap focus inside container
|
||||||
trapFocus() {
|
trapFocus(element = null, toggle = false) {
|
||||||
|
if (!utils.is.element(element)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const focusable = utils.getElements.call(this, 'button:not(:disabled), input:not(:disabled), [tabindex]');
|
const focusable = utils.getElements.call(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];
|
||||||
|
|
||||||
utils.on(
|
const trap = event => {
|
||||||
this.elements.container,
|
// Bail if not tab key or not fullscreen
|
||||||
'keydown',
|
if (event.key !== 'Tab' || event.keyCode !== 9) {
|
||||||
event => {
|
return;
|
||||||
// Bail if not tab key or not fullscreen
|
}
|
||||||
if (event.key !== 'Tab' || event.keyCode !== 9 || !this.fullscreen.active) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the current focused element
|
// Get the current focused element
|
||||||
const focused = utils.getFocusElement();
|
const focused = utils.getFocusElement();
|
||||||
|
|
||||||
if (focused === last && !event.shiftKey) {
|
if (focused === last && !event.shiftKey) {
|
||||||
// Move focus to first element that can be tabbed if Shift isn't used
|
// Move focus to first element that can be tabbed if Shift isn't used
|
||||||
first.focus();
|
first.focus();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
} else if (focused === first && event.shiftKey) {
|
} else if (focused === first && event.shiftKey) {
|
||||||
// Move focus to last element that can be tabbed if Shift is used
|
// Move focus to last element that can be tabbed if Shift is used
|
||||||
last.focus();
|
last.focus();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
false,
|
|
||||||
);
|
if (toggle) {
|
||||||
|
utils.on(this.elements.container, 'keydown', trap, false);
|
||||||
|
} else {
|
||||||
|
utils.off(this.elements.container, 'keydown', trap, false);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Toggle event listener
|
// Toggle event listener
|
||||||
toggleListener(elements, event, callback, toggle, passive, capture) {
|
toggleListener(elements, event, callback, toggle, passive, capture) {
|
||||||
// Bail if no elements
|
// Bail if no elemetns, event, or callback
|
||||||
if (utils.is.nullOrUndefined(elements)) {
|
if (utils.is.empty(elements) || utils.is.empty(event) || !utils.is.function(callback)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
// --------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
|
|
||||||
.plyr__badge {
|
.plyr__badge {
|
||||||
background: $plyr-menu-color;
|
background: $plyr-badge-bg;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
color: $plyr-menu-bg;
|
color: $plyr-badge-color;
|
||||||
font-size: $plyr-font-size-badge;
|
font-size: $plyr-font-size-badge;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
padding: 3px 4px;
|
padding: 3px 4px;
|
||||||
|
@ -59,6 +59,14 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: $plyr-control-padding;
|
padding: $plyr-control-padding;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-top: 2px;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
@import 'settings/cosmetics';
|
@import 'settings/cosmetics';
|
||||||
@import 'settings/type';
|
@import 'settings/type';
|
||||||
|
|
||||||
|
@import 'settings/badges';
|
||||||
@import 'settings/captions';
|
@import 'settings/captions';
|
||||||
@import 'settings/controls';
|
@import 'settings/controls';
|
||||||
@import 'settings/helpers';
|
@import 'settings/helpers';
|
||||||
|
6
src/sass/settings/badges.scss
Normal file
6
src/sass/settings/badges.scss
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Badges
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
$plyr-badge-bg: $plyr-color-fiord !default;
|
||||||
|
$plyr-badge-color: #fff !default;
|
Loading…
x
Reference in New Issue
Block a user