Menu toggle
This commit is contained in:
parent
e1a19faf26
commit
857dfe838c
11
.github/issue_template.md
vendored
11
.github/issue_template.md
vendored
@ -2,9 +2,6 @@
|
|||||||
Please use this issue template as it makes replicating and fixing the issue easier!
|
Please use this issue template as it makes replicating and fixing the issue easier!
|
||||||
--->
|
--->
|
||||||
|
|
||||||
- [ ] Issue does not already exist
|
|
||||||
- [ ] Issue observed on https://plyr.io
|
|
||||||
|
|
||||||
### Expected behaviour
|
### Expected behaviour
|
||||||
|
|
||||||
### Actual behaviour
|
### Actual behaviour
|
||||||
@ -16,13 +13,5 @@ Please use this issue template as it makes replicating and fixing the issue easi
|
|||||||
- Operating System:
|
- Operating System:
|
||||||
- Version:
|
- Version:
|
||||||
|
|
||||||
Players affected:
|
|
||||||
- [ ] HTML5 Video
|
|
||||||
- [ ] HTML5 Audio
|
|
||||||
- [ ] YouTube
|
|
||||||
- [ ] Vimeo
|
|
||||||
|
|
||||||
### Steps to reproduce
|
### Steps to reproduce
|
||||||
-
|
-
|
||||||
|
|
||||||
### Relevant links
|
|
||||||
|
2
demo/dist/demo.js
vendored
2
demo/dist/demo.js
vendored
File diff suppressed because one or more lines are too long
@ -37,6 +37,7 @@
|
|||||||
'airplay'
|
'airplay'
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
window.loadSprite('dist/demo.svg', 'demo-sprite');
|
window.loadSprite('dist/demo.svg', 'demo-sprite');
|
||||||
|
|
||||||
// Setup type toggle
|
// Setup type toggle
|
||||||
|
4
dist/plyr.js
vendored
4
dist/plyr.js
vendored
File diff suppressed because one or more lines are too long
15
notes.md
15
notes.md
@ -3,15 +3,16 @@
|
|||||||
#### To build
|
#### To build
|
||||||
[x] Get list of subtitles/captions available (HTML5, Vimeo)
|
[x] Get list of subtitles/captions available (HTML5, Vimeo)
|
||||||
[x] Add preferred quality option into config
|
[x] Add preferred quality option into config
|
||||||
[ ] Update quality options on YouTube play (can't get up front?!)
|
[ ] Update quality options on YouTube play
|
||||||
[ ] Update speed options on YouTube load
|
[ ] Update speed options on YouTube load
|
||||||
[ ] Finish and test PiP (need MacOS Sierra)
|
[ ] Hide unsupported menu items
|
||||||
[ ] Finish and test AirPlay (need MacOS Sierra)
|
[ ] Test PiP (need MacOS Sierra)
|
||||||
[ ] Controls hide/show events
|
[ ] Test AirPlay (need MacOS Sierra)
|
||||||
[ ] Test custom controls still works
|
[ ] Add controlshidden controlsshown events
|
||||||
|
[ ] Test custom controls (with settings support for now)
|
||||||
[ ] Tidy up small UI for iOS inline
|
[ ] Tidy up small UI for iOS inline
|
||||||
[ ] Finish new loop setup and UI
|
[ ] Finish new loop setup and display in seek bar
|
||||||
[ ] Toggle settings menu
|
[ ] Update docs for removal of setup
|
||||||
|
|
||||||
#### Later
|
#### Later
|
||||||
[ ] Get quality options for HTML5 somehow (multi source?)
|
[ ] Get quality options for HTML5 somehow (multi source?)
|
||||||
|
164
src/js/plyr.js
164
src/js/plyr.js
@ -977,7 +977,27 @@
|
|||||||
|
|
||||||
xhr.send();
|
xhr.send();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
// Get the transition end event
|
||||||
|
transitionEnd: (function() {
|
||||||
|
var element = document.createElement('span');
|
||||||
|
|
||||||
|
var events = {
|
||||||
|
WebkitTransition: 'webkitTransitionEnd',
|
||||||
|
MozTransition: 'transitionend',
|
||||||
|
OTransition: 'oTransitionEnd otransitionend',
|
||||||
|
transition: 'transitionend'
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var type in events) {
|
||||||
|
if (element.style[type] !== undefined) {
|
||||||
|
return events[type];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
})()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fullscreen API
|
// Fullscreen API
|
||||||
@ -1160,7 +1180,11 @@
|
|||||||
|
|
||||||
// Touch
|
// Touch
|
||||||
// Remember a device can be moust + touch enabled
|
// Remember a device can be moust + touch enabled
|
||||||
touch: 'ontouchstart' in document.documentElement
|
touch: 'ontouchstart' in document.documentElement,
|
||||||
|
|
||||||
|
// Detect transitions and if user has iOS & MacOS "Reduced motion" setting off
|
||||||
|
// https://webkit.org/blog/7551/responsive-design-for-motion/
|
||||||
|
transitions: utils.transitionEnd !== false && (!('matchMedia' in window) || !window.matchMedia('(prefers-reduced-motion)').matches)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Player instance
|
// Player instance
|
||||||
@ -1615,9 +1639,9 @@
|
|||||||
|
|
||||||
// Settings button / menu
|
// Settings button / menu
|
||||||
if (utils.inArray(config.controls, 'settings')) {
|
if (utils.inArray(config.controls, 'settings')) {
|
||||||
var menu = utils.createElement('span', utils.extend(utils.getAttributesFromSelector(config.selectors.buttons.settings), {
|
var menu = utils.createElement('div', {
|
||||||
class: 'plyr__menu'
|
class: 'plyr__menu'
|
||||||
}));
|
});
|
||||||
|
|
||||||
menu.appendChild(createButton('settings', {
|
menu.appendChild(createButton('settings', {
|
||||||
id: 'plyr-settings-toggle-' + data.id,
|
id: 'plyr-settings-toggle-' + data.id,
|
||||||
@ -1716,6 +1740,8 @@
|
|||||||
|
|
||||||
controls.appendChild(menu);
|
controls.appendChild(menu);
|
||||||
|
|
||||||
|
player.elements.settings.form = form;
|
||||||
|
|
||||||
player.elements.settings.menu = menu;
|
player.elements.settings.menu = menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3292,42 +3318,75 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle Menu
|
// Show/hide menu
|
||||||
function toggleMenu(event) {
|
function toggleMenu(event) {
|
||||||
var menu = player.elements.settings.menu.parentNode;
|
var form = player.elements.settings.form;
|
||||||
var toggle = event.target;
|
var button = player.elements.buttons.settings;
|
||||||
var target = document.getElementById(toggle.getAttribute('aria-controls'));
|
|
||||||
var show = (toggle.getAttribute('aria-expanded') === 'false');
|
|
||||||
|
|
||||||
// Nothing to show, bail
|
// If the click was inside the form, do nothing
|
||||||
if (!utils.is.htmlElement(target)) {
|
if (form.contains(event.target)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent the toggleMenu being fired twice
|
||||||
|
if (event.target === player.elements.buttons.settings) {
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do we need to show it?
|
||||||
|
var show = form.getAttribute('aria-hidden') === 'true';
|
||||||
|
|
||||||
|
// Set form and button attributes
|
||||||
|
form.setAttribute('aria-hidden', !show);
|
||||||
|
button.setAttribute('aria-expanded', show);
|
||||||
|
|
||||||
|
if (show) {
|
||||||
|
form.removeAttribute('tabindex');
|
||||||
|
} else {
|
||||||
|
form.setAttribute('tabindex', -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle Menu
|
||||||
|
function showTab(event) {
|
||||||
|
var menu = player.elements.settings.menu;
|
||||||
|
var tab = event.target;
|
||||||
|
var show = tab.getAttribute('aria-expanded') === 'false';
|
||||||
|
var pane = document.getElementById(tab.getAttribute('aria-controls'));
|
||||||
|
|
||||||
|
// Nothing to show, bail
|
||||||
|
if (!utils.is.htmlElement(pane)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Are we targetting a tab? If not, bail
|
||||||
|
var isTab = pane.getAttribute('role') === 'tabpanel';
|
||||||
|
if (!isTab) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are we targetting a tab?
|
|
||||||
var isTab = target.getAttribute('role') === 'tabpanel';
|
|
||||||
var targetWidth;
|
var targetWidth;
|
||||||
var targetHeight;
|
var targetHeight;
|
||||||
var container;
|
var container;
|
||||||
|
|
||||||
// Hide all other tabs
|
// Hide all other tabs
|
||||||
if (isTab) {
|
// Get other tabs
|
||||||
// Get other tabs
|
var current = menu.querySelector('[role="tabpanel"][aria-hidden="false"]');
|
||||||
var current = menu.querySelector('[role="tabpanel"][aria-hidden="false"]');
|
container = current.parentNode;
|
||||||
container = current.parentNode;
|
|
||||||
|
|
||||||
[].forEach.call(menu.querySelectorAll('[aria-controls="' + current.getAttribute('id') + '"]'), function(toggle) {
|
// Set other toggles to be expanded false
|
||||||
toggle.setAttribute('aria-expanded', false);
|
[].forEach.call(menu.querySelectorAll('[aria-controls="' + current.getAttribute('id') + '"]'), function(toggle) {
|
||||||
});
|
toggle.setAttribute('aria-expanded', false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// If we can do fancy animations, we'll animate the height/width
|
||||||
|
if (support.transitions) {
|
||||||
|
// Set the current width as a base
|
||||||
container.style.width = current.scrollWidth + 'px';
|
container.style.width = current.scrollWidth + 'px';
|
||||||
container.style.height = current.scrollHeight + 'px';
|
container.style.height = current.scrollHeight + 'px';
|
||||||
|
|
||||||
current.setAttribute('aria-hidden', true);
|
// Get the natural element size of the target pane
|
||||||
current.setAttribute('tabindex', -1);
|
var clone = pane.cloneNode(true);
|
||||||
|
|
||||||
// Get the natural element size
|
|
||||||
var clone = target.cloneNode(true);
|
|
||||||
clone.style.position = "absolute";
|
clone.style.position = "absolute";
|
||||||
clone.style.opacity = 0;
|
clone.style.opacity = 0;
|
||||||
clone.setAttribute('aria-hidden', false);
|
clone.setAttribute('aria-hidden', false);
|
||||||
@ -3335,21 +3394,39 @@
|
|||||||
targetWidth = clone.scrollWidth;
|
targetWidth = clone.scrollWidth;
|
||||||
targetHeight = clone.scrollHeight;
|
targetHeight = clone.scrollHeight;
|
||||||
utils.removeElement(clone);
|
utils.removeElement(clone);
|
||||||
}
|
|
||||||
|
|
||||||
target.setAttribute('aria-hidden', !show);
|
// Restore auto height/width
|
||||||
toggle.setAttribute('aria-expanded', show);
|
var restore = function(event) {
|
||||||
target.removeAttribute('tabindex');
|
// We're only bothered about height and width on the container
|
||||||
|
if (event.target !== container ||
|
||||||
|
!utils.inArray(['width', 'height'], event.propertyName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isTab) {
|
// Revert back to auto
|
||||||
container.style.width = targetWidth + 'px';
|
|
||||||
container.style.height = targetHeight + 'px';
|
|
||||||
|
|
||||||
window.setTimeout(function() {
|
|
||||||
container.style.width = '';
|
container.style.width = '';
|
||||||
container.style.height = '';
|
container.style.height = '';
|
||||||
}, 300);
|
|
||||||
|
// Only listen once
|
||||||
|
utils.off(container, utils.transitionEnd, restore)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen for the transtion finishing and restore auto height/width
|
||||||
|
utils.on(container, utils.transitionEnd, restore);
|
||||||
|
|
||||||
|
// Set dimensions to target
|
||||||
|
container.style.width = targetWidth + 'px';
|
||||||
|
container.style.height = targetHeight + 'px';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set attributes on current tab
|
||||||
|
current.setAttribute('aria-hidden', true);
|
||||||
|
current.setAttribute('tabindex', -1);
|
||||||
|
|
||||||
|
// Set attributes on target
|
||||||
|
pane.setAttribute('aria-hidden', !show);
|
||||||
|
tab.setAttribute('aria-expanded', show);
|
||||||
|
pane.removeAttribute('tabindex');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mute
|
// Mute
|
||||||
@ -4275,23 +4352,16 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Settings menu
|
// Settings menu
|
||||||
utils.on(player.elements.settings.menu, 'click', toggleMenu);
|
utils.on(player.elements.buttons.settings, 'click', toggleMenu);
|
||||||
|
|
||||||
// Click anywhere closes menu
|
// Click anywhere closes menu
|
||||||
utils.on(document.body, 'click', function(event) {
|
utils.on(document.body, 'click', toggleMenu);
|
||||||
var menu = player.elements.settings.menu;
|
|
||||||
var form = menu.querySelector('form');
|
|
||||||
|
|
||||||
if (form.getAttribute('aria-hidden') === 'true' || menu.contains(event.target)) {
|
// Show tab in menu
|
||||||
return;
|
utils.on(player.elements.settings.form, 'click', showTab);
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: This should call some sort of menuToggle function?
|
|
||||||
form.setAttribute('aria-hidden', true);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Settings menu items - use event delegation as items are added/removed
|
// Settings menu items - use event delegation as items are added/removed
|
||||||
utils.on(player.elements.settings.menu, 'click', function(event) {
|
utils.on(player.elements.settings.form, 'click', function(event) {
|
||||||
// Settings - Language
|
// Settings - Language
|
||||||
if (utils.matches(event.target, config.selectors.inputs.language)) {
|
if (utils.matches(event.target, config.selectors.inputs.language)) {
|
||||||
handlerProxy.call(this, event, config.listeners.language, setLanguage);
|
handlerProxy.call(this, event, config.listeners.language, setLanguage);
|
||||||
|
@ -336,7 +336,9 @@
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background .3s ease, color .3s ease, opacity .3s ease;
|
transition: background .3s ease,
|
||||||
|
color .3s ease,
|
||||||
|
opacity .3s ease;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
@ -515,7 +517,8 @@
|
|||||||
|
|
||||||
> div {
|
> div {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: height .35s cubic-bezier(.4,0,.2,1), width .35s cubic-bezier(.4,0,.2,1);
|
transition: height .35s cubic-bezier(.4, 0, .2, 1),
|
||||||
|
width .35s cubic-bezier(.4, 0, .2, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arrow
|
// Arrow
|
||||||
|
Loading…
x
Reference in New Issue
Block a user