diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/js/captions.js | 9 | ||||
-rw-r--r-- | src/js/controls.js | 19 | ||||
-rw-r--r-- | src/js/defaults.js | 3 | ||||
-rw-r--r-- | src/js/fullscreen.js | 241 | ||||
-rw-r--r-- | src/js/listeners.js | 49 | ||||
-rw-r--r-- | src/js/media.js | 2 | ||||
-rw-r--r-- | src/js/plyr.js | 83 | ||||
-rw-r--r-- | src/js/source.js | 3 | ||||
-rw-r--r-- | src/js/ui.js | 10 | ||||
-rw-r--r-- | src/js/utils.js | 68 | ||||
-rw-r--r-- | src/sass/components/badges.scss | 4 | ||||
-rw-r--r-- | src/sass/components/menus.scss | 8 | ||||
-rw-r--r-- | src/sass/plyr.scss | 1 | ||||
-rw-r--r-- | src/sass/settings/badges.scss | 6 |
14 files changed, 267 insertions, 239 deletions
diff --git a/src/js/captions.js b/src/js/captions.js index 847ef7ff..6ab8c69e 100644 --- a/src/js/captions.js +++ b/src/js/captions.js @@ -39,7 +39,7 @@ const captions = { // Only Vimeo and HTML5 video supported at this point if (!this.isVideo || this.isYouTube || (this.isHTML5 && !support.textTracks)) { // Clear menu and hide - if (this.config.controls.includes('settings') && this.config.settings.includes('captions')) { + if (utils.is.array(this.config.controls) && this.config.controls.includes('settings') && this.config.settings.includes('captions')) { controls.setCaptionsMenu.call(this); } @@ -68,7 +68,7 @@ const captions = { captions.show.call(this); // Set available languages in list - if (this.config.controls.includes('settings') && this.config.settings.includes('captions')) { + if (utils.is.array(this.config.controls) && this.config.controls.includes('settings') && this.config.settings.includes('captions')) { controls.setCaptionsMenu.call(this); } }, @@ -78,7 +78,7 @@ const captions = { // Setup HTML5 track rendering if (this.isHTML5 && this.isVideo) { captions.getTracks.call(this).forEach(track => { - // Remove previous bindings + // Show track utils.on(track, 'cuechange', event => captions.setCue.call(this, event)); // Turn off native caption rendering to avoid double captions @@ -124,7 +124,8 @@ const captions = { setCue(input) { // Get the track from the event if needed const track = utils.is.event(input) ? input.target : input; - const active = track.activeCues[0]; + const { activeCues } = track; + const active = activeCues.length && activeCues[0]; const currentTrack = captions.getCurrentTrack.call(this); // Only display current track diff --git a/src/js/controls.js b/src/js/controls.js index ea30acec..5e16b952 100644 --- a/src/js/controls.js +++ b/src/js/controls.js @@ -215,7 +215,16 @@ const controls = { utils.setAttributes(button, attributes); - this.elements.buttons[type] = button; + // We have multiple play buttons + if (type === 'play') { + if (!utils.is.array(this.elements.buttons[type])) { + this.elements.buttons[type] = []; + } + + this.elements.buttons[type].push(button); + } else { + this.elements.buttons[type] = button; + } return button; }, @@ -893,7 +902,6 @@ const controls = { // Play/Pause button if (this.config.controls.includes('play')) { container.appendChild(controls.createButton.call(this, 'play')); - // container.appendChild(controls.createButton.call(this, 'pause')); } // Fast forward button @@ -1147,9 +1155,10 @@ const controls = { // Null by default let container = null; + this.elements.controls = null; - // HTML passed as the option - if (utils.is.string(this.config.controls)) { + // HTML or Element passed as the option + if (utils.is.string(this.config.controls) || utils.is.element(this.config.controls)) { container = this.config.controls; } else if (utils.is.function(this.config.controls)) { // A custom function to build controls @@ -1193,7 +1202,7 @@ const controls = { } // Find the elements if need be - if (utils.is.element(this.elements.controls)) { + if (!utils.is.element(this.elements.controls)) { utils.findElements.call(this); } diff --git a/src/js/defaults.js b/src/js/defaults.js index 8e50631e..ee87b8f6 100644 --- a/src/js/defaults.js +++ b/src/js/defaults.js @@ -56,7 +56,7 @@ const defaults = { // Sprite (for icons) loadSprite: true, iconPrefix: 'plyr', - iconUrl: 'https://cdn.plyr.io/3.0.0-beta.12/plyr.svg', + iconUrl: 'https://cdn.plyr.io/3.0.0-beta.13/plyr.svg', // Blank video (used to prevent errors on source change) blankVideo: 'https://cdn.plyr.io/static/blank.mp4', @@ -120,6 +120,7 @@ const defaults = { fullscreen: { enabled: true, // Allow fullscreen? fallback: true, // Fallback for vintage browsers + iosNative: false, // Use the native fullscreen in iOS (disables custom controls) }, // Local storage diff --git a/src/js/fullscreen.js b/src/js/fullscreen.js index 366ea729..6d90bd6e 100644 --- a/src/js/fullscreen.js +++ b/src/js/fullscreen.js @@ -1,127 +1,204 @@ // ========================================================================== -// Plyr fullscreen API +// Fullscreen wrapper // ========================================================================== import utils from './utils'; -// Determine the prefix -const prefix = (() => { - let value = false; +const browser = utils.getBrowser(); - if (utils.is.function(document.cancelFullScreen)) { - value = ''; +function onChange() { + 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 { + 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(); + }); + + // Prevent double click on controls bubbling up + utils.on(this.player.elements.controls, 'dblclick', event => event.stopPropagation()); + + // 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 - [ + let value = ''; + const prefixes = [ 'webkit', - 'o', 'moz', 'ms', - 'khtml', - ].some(pre => { + ]; + + prefixes.some(pre => { if (utils.is.function(document[`${pre}CancelFullScreen`])) { value = pre; return true; - } else if (utils.is.function(document.msExitFullscreen) && document.msFullscreenEnabled) { - // Special case for MS (when isn't it?) + } else if (utils.is.function(document.msExitFullscreen)) { value = 'ms'; return true; } return false; }); - } - return value; -})(); - -// Fullscreen API -const fullscreen = { - // Get the prefix - prefix, + return value; + } - // Check if we can use it - enabled: document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled, + // Determine if fullscreen is enabled + get enabled() { + const fallback = this.player.config.fullscreen.fallback && !utils.inFrame(); - // Yet again Microsoft awesomeness, - // Sometimes the prefix is 'ms', sometimes 'MS' to keep you on your toes - eventType: prefix === 'ms' ? 'MSFullscreenChange' : `${prefix}fullscreenchange`, + return (Fullscreen.native || fallback) && this.player.config.fullscreen.enabled && this.player.supported.ui && this.player.isVideo; + } - // Is an element fullscreen - isFullScreen(element) { - if (!fullscreen.enabled) { + // Get active state + get active() { + if (!this.enabled) { return false; } - const target = utils.is.nullOrUndefined(element) ? document.body : element; - - switch (prefix) { - case '': - return document.fullscreenElement === target; - - case 'moz': - return document.mozFullScreenElement === target; - - default: - return document[`${prefix}FullscreenElement`] === target; + // Fallback using classname + if (!Fullscreen.native) { + return utils.hasClass(this.target, this.player.config.classNames.fullscreen.fallback); } - }, - // Make an element fullscreen - requestFullScreen(element) { - if (!fullscreen.enabled) { - return false; - } + const element = !this.prefix ? document.fullscreenElement : document[`${this.prefix}FullscreenElement`]; - const target = utils.is.nullOrUndefined(element) ? document.body : element; + return element === this.target; + } - return !prefix.length ? target.requestFullScreen() : target[prefix + (prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen')](); - }, + // Get target element + get target() { + return browser.isIos && this.player.config.fullscreen.iosNative ? this.player.media : this.player.elements.container; + } - // Bail from fullscreen - cancelFullScreen() { - if (!fullscreen.enabled) { - return false; + // 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'); } - return !prefix.length ? document.cancelFullScreen() : document[prefix + (prefix === 'ms' ? 'ExitFullscreen' : 'CancelFullScreen')](); - }, + // Add styling hook to show button + utils.toggleClass(this.player.elements.container, this.player.config.classNames.fullscreen.enabled, this.enabled); + } - // Get the current element - element() { - if (!fullscreen.enabled) { - return null; + // Make an element fullscreen + enter() { + if (!this.enabled) { + return; } - return !prefix.length ? document.fullscreenElement : document[`${prefix}FullscreenElement`]; - }, + // iOS native fullscreen doesn't need the request step + 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'}`](); + } + } - // Setup fullscreen - setup() { - if (!this.supported.ui || this.isAudio || !this.config.fullscreen.enabled) { + // Bail from fullscreen + exit() { + if (!this.enabled) { return; } - // Check for native support - const nativeSupport = fullscreen.enabled; - - if (nativeSupport || (this.config.fullscreen.fallback && !utils.inFrame())) { - this.debug.log(`${nativeSupport ? 'Native' : 'Fallback'} fullscreen enabled`); - - // Add styling hook to show button - utils.toggleClass(this.elements.container, this.config.classNames.fullscreen.enabled, true); - } else { - this.debug.log('Fullscreen not supported and fallback disabled'); + // iOS native fullscreen + 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 - if (this.elements.buttons && this.elements.buttons.fullscreen) { - utils.toggleState(this.elements.buttons.fullscreen, false); + // Toggle state + toggle() { + if (!this.active) { + this.enter(); + } else { + this.exit(); } + } +} - // Trap focus in container - utils.trapFocus.call(this); - }, -}; - -export default fullscreen; +export default Fullscreen; diff --git a/src/js/listeners.js b/src/js/listeners.js index b3ccc1c6..214f6e7d 100644 --- a/src/js/listeners.js +++ b/src/js/listeners.js @@ -5,7 +5,6 @@ import support from './support'; import utils from './utils'; import controls from './controls'; -import fullscreen from './fullscreen'; import ui from './ui'; // Sniff out the browser @@ -138,7 +137,7 @@ const listeners = { case 70: // F key - this.toggleFullscreen(); + this.fullscreen.toggle(); break; case 67: @@ -171,8 +170,8 @@ const listeners = { // Escape is handle natively when in full screen // So we only need to worry about non native - if (!fullscreen.enabled && this.fullscreen.active && code === 27) { - this.toggleFullscreen(); + if (!this.fullscreen.enabled && this.fullscreen.active && code === 27) { + this.fullscreen.toggle(); } // Store last code for next cycle @@ -215,18 +214,6 @@ const listeners = { 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 @@ -266,7 +253,7 @@ const listeners = { utils.on(this.media, 'playing play pause ended', event => ui.checkPlaying.call(this, event)); // 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 // utils.on(this.media, 'play', event => ui.checkFailed.call(this, event)); @@ -307,7 +294,7 @@ const listeners = { event => { event.preventDefault(); }, - false + false, ); } @@ -394,63 +381,63 @@ const listeners = { utils.on(this.elements.buttons.play, 'click', event => proxy(event, 'play', () => { this.togglePlay(); - }) + }), ); // Pause utils.on(this.elements.buttons.restart, 'click', event => proxy(event, 'restart', () => { this.restart(); - }) + }), ); // Rewind utils.on(this.elements.buttons.rewind, 'click', event => proxy(event, 'rewind', () => { this.rewind(); - }) + }), ); // Rewind utils.on(this.elements.buttons.forward, 'click', event => proxy(event, 'forward', () => { this.forward(); - }) + }), ); // Mute toggle utils.on(this.elements.buttons.mute, 'click', event => proxy(event, 'mute', () => { this.muted = !this.muted; - }) + }), ); // Captions toggle utils.on(this.elements.buttons.captions, 'click', event => proxy(event, 'captions', () => { this.toggleCaptions(); - }) + }), ); // Fullscreen toggle utils.on(this.elements.buttons.fullscreen, 'click', event => proxy(event, 'fullscreen', () => { - this.toggleFullscreen(); - }) + this.fullscreen.toggle(); + }), ); // Picture-in-Picture utils.on(this.elements.buttons.pip, 'click', event => proxy(event, 'pip', () => { this.pip = 'toggle'; - }) + }), ); // Airplay utils.on(this.elements.buttons.airplay, 'click', event => proxy(event, 'airplay', () => { this.airplay(); - }) + }), ); // Settings menu @@ -489,7 +476,7 @@ const listeners = { utils.on(this.elements.inputs.seek, inputEvent, event => proxy(event, 'seek', () => { this.currentTime = event.target.value / event.target.max * this.duration; - }) + }), ); // Current time invert @@ -510,7 +497,7 @@ const listeners = { utils.on(this.elements.inputs.volume, inputEvent, event => proxy(event, 'volume', () => { this.volume = event.target.value; - }) + }), ); // Polyfill for lower fill in <input type="range"> for webkit @@ -583,7 +570,7 @@ const listeners = { event.preventDefault(); } }), - false + false, ); }, }; diff --git a/src/js/media.js b/src/js/media.js index 3fbd9774..494c5376 100644 --- a/src/js/media.js +++ b/src/js/media.js @@ -86,7 +86,7 @@ const media = { } // Remove child sources - Array.from(this.media.querySelectorAll('source')).forEach(utils.removeElement); + utils.removeElement(this.media.querySelectorAll('source')); // Set blank video src attribute // This is to prevent a MEDIA_ERR_SRC_NOT_SUPPORTED error diff --git a/src/js/plyr.js b/src/js/plyr.js index 1d3e0918..aebf311f 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1,6 +1,6 @@ // ========================================================================== // Plyr -// plyr.js v3.0.0-beta.12 +// plyr.js v3.0.0-beta.13 // https://github.com/sampotts/plyr // License: The MIT License (MIT) // ========================================================================== @@ -11,12 +11,12 @@ import support from './support'; import utils from './utils'; import Console from './console'; +import Fullscreen from './fullscreen'; import Storage from './storage'; import Ads from './plugins/ads'; import captions from './captions'; import controls from './controls'; -import fullscreen from './fullscreen'; import listeners from './listeners'; import media from './media'; import source from './source'; @@ -26,12 +26,6 @@ import ui from './ui'; // TODO: Use a WeakMap for private globals // const globals = new WeakMap(); -// Globals -let scrollPosition = { - x: 0, - y: 0, -}; - // Plyr instance class Plyr { constructor(target, options) { @@ -232,9 +226,6 @@ class Plyr { return; } - // Setup local storage for user settings - this.storage = new Storage(this); - // Check for support again but with type this.supported = support.check(this.type, this.provider, this.config.inline); @@ -244,6 +235,9 @@ class Plyr { return; } + // Setup local storage for user settings + this.storage = new Storage(this); + // Store reference this.media.plyr = this; @@ -278,6 +272,9 @@ class Plyr { ui.build.call(this); } + // Setup fullscreen + this.fullscreen = new Fullscreen(this); + // Setup ads if provided this.ads = new Ads(this); } @@ -851,62 +848,6 @@ class Plyr { } /** - * 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 * TODO: update player with state, support, enabled * TODO: detect outside changes @@ -1101,12 +1042,8 @@ class Plyr { // If it's a soft destroy, make minimal changes if (soft) { if (Object.keys(this.elements).length) { - // Remove buttons - if (this.elements.buttons && this.elements.buttons.play) { - Array.from(this.elements.buttons.play).forEach(button => utils.removeElement(button)); - } - - // Remove others + // Remove elements + utils.removeElement(this.elements.buttons.play); utils.removeElement(this.elements.captions); utils.removeElement(this.elements.controls); utils.removeElement(this.elements.wrapper); diff --git a/src/js/source.js b/src/js/source.js index 9a6b219c..d252ba6b 100644 --- a/src/js/source.js +++ b/src/js/source.js @@ -136,6 +136,9 @@ const source = { // Setup interface ui.build.call(this); } + + // Update the fullscreen support + this.fullscreen.update(); }, true, ); diff --git a/src/js/ui.js b/src/js/ui.js index 14724fc6..5a52543d 100644 --- a/src/js/ui.js +++ b/src/js/ui.js @@ -5,7 +5,6 @@ import utils from './utils'; import captions from './captions'; import controls from './controls'; -import fullscreen from './fullscreen'; import listeners from './listeners'; const ui = { @@ -33,12 +32,6 @@ const ui = { if (!this.supported.ui) { this.debug.warn(`Basic support only for ${this.provider} ${this.type}`); - // Remove controls - utils.removeElement.call(this, 'controls'); - - // Remove large play - utils.removeElement.call(this, 'buttons.play'); - // Restore native controls ui.toggleNativeControls.call(this, true); @@ -63,9 +56,6 @@ const ui = { // Remove native controls ui.toggleNativeControls.call(this); - // Setup fullscreen - fullscreen.setup.call(this); - // Captions captions.setup.call(this); diff --git a/src/js/utils.js b/src/js/utils.js index 3e9f06ff..c53293f4 100644 --- a/src/js/utils.js +++ b/src/js/utils.js @@ -306,12 +306,15 @@ const utils = { // Remove an element removeElement(element) { if (!utils.is.element(element) || !utils.is.element(element.parentNode)) { - return null; + return; } - element.parentNode.removeChild(element); + if (utils.is.nodeList(element) || utils.is.array(element)) { + Array.from(element).forEach(utils.removeElement); + return; + } - return element; + element.parentNode.removeChild(element); }, // Remove all child elements @@ -525,46 +528,51 @@ const utils = { }, // 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 first = focusable[0]; const last = focusable[focusable.length - 1]; - utils.on( - this.elements.container, - 'keydown', - event => { - // Bail if not tab key or not fullscreen - if (event.key !== 'Tab' || event.keyCode !== 9 || !this.fullscreen.active) { - return; - } + const trap = event => { + // Bail if not tab key or not fullscreen + if (event.key !== 'Tab' || event.keyCode !== 9) { + return; + } - // Get the current focused element - const focused = utils.getFocusElement(); - - if (focused === last && !event.shiftKey) { - // Move focus to first element that can be tabbed if Shift isn't used - first.focus(); - event.preventDefault(); - } else if (focused === first && event.shiftKey) { - // Move focus to last element that can be tabbed if Shift is used - last.focus(); - event.preventDefault(); - } - }, - false, - ); + // Get the current focused element + const focused = utils.getFocusElement(); + + if (focused === last && !event.shiftKey) { + // Move focus to first element that can be tabbed if Shift isn't used + first.focus(); + event.preventDefault(); + } else if (focused === first && event.shiftKey) { + // Move focus to last element that can be tabbed if Shift is used + last.focus(); + event.preventDefault(); + } + }; + + if (toggle) { + utils.on(this.elements.container, 'keydown', trap, false); + } else { + utils.off(this.elements.container, 'keydown', trap, false); + } }, // Toggle event listener toggleListener(elements, event, callback, toggle, passive, capture) { - // Bail if no elements - if (utils.is.nullOrUndefined(elements)) { + // Bail if no elemetns, event, or callback + if (utils.is.empty(elements) || utils.is.empty(event) || !utils.is.function(callback)) { return; } // If a nodelist is passed, call itself on each node - if (utils.is.nodeList(elements)) { + if (utils.is.nodeList(elements) || utils.is.array(elements)) { // Create listener for each node Array.from(elements).forEach(element => { if (element instanceof Node) { diff --git a/src/sass/components/badges.scss b/src/sass/components/badges.scss index 7d28ffaf..3a9a28b5 100644 --- a/src/sass/components/badges.scss +++ b/src/sass/components/badges.scss @@ -3,9 +3,9 @@ // -------------------------------------------------------------- .plyr__badge { - background: $plyr-menu-color; + background: $plyr-badge-bg; border-radius: 2px; - color: $plyr-menu-bg; + color: $plyr-badge-color; font-size: $plyr-font-size-badge; line-height: 1; padding: 3px 4px; diff --git a/src/sass/components/menus.scss b/src/sass/components/menus.scss index 35fc580d..4ad67ec1 100644 --- a/src/sass/components/menus.scss +++ b/src/sass/components/menus.scss @@ -59,6 +59,14 @@ margin: 0; overflow: hidden; padding: $plyr-control-padding; + + li { + margin-top: 2px; + + &:first-child { + margin-top: 0; + } + } } // Options diff --git a/src/sass/plyr.scss b/src/sass/plyr.scss index e8615989..14856957 100644 --- a/src/sass/plyr.scss +++ b/src/sass/plyr.scss @@ -10,6 +10,7 @@ @import 'settings/cosmetics'; @import 'settings/type'; +@import 'settings/badges'; @import 'settings/captions'; @import 'settings/controls'; @import 'settings/helpers'; diff --git a/src/sass/settings/badges.scss b/src/sass/settings/badges.scss new file mode 100644 index 00000000..4f98c9a8 --- /dev/null +++ b/src/sass/settings/badges.scss @@ -0,0 +1,6 @@ +// ========================================================================== +// Badges +// ========================================================================== + +$plyr-badge-bg: $plyr-color-fiord !default; +$plyr-badge-color: #fff !default; |