diff options
author | Sam Potts <me@sampotts.me> | 2017-05-22 08:55:45 +1000 |
---|---|---|
committer | Sam Potts <me@sampotts.me> | 2017-05-22 08:55:45 +1000 |
commit | 86c900418322353239a40fe2e061a3f2fbc786dc (patch) | |
tree | 6cd4a4e17f5f5df7e12d7d9e38ca7afa71fa174d /src/js/plyr.js | |
parent | 857dfe838c8b977abbb9ca9189f840852f42ec52 (diff) | |
download | plyr-86c900418322353239a40fe2e061a3f2fbc786dc.tar.lz plyr-86c900418322353239a40fe2e061a3f2fbc786dc.tar.xz plyr-86c900418322353239a40fe2e061a3f2fbc786dc.zip |
More work on the menu
Diffstat (limited to 'src/js/plyr.js')
-rw-r--r-- | src/js/plyr.js | 173 |
1 files changed, 106 insertions, 67 deletions
diff --git a/src/js/plyr.js b/src/js/plyr.js index 0ada1779..df910664 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -68,8 +68,8 @@ // Speed up/down speed: { - selected: 1.0, - options: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2.0] + selected: 1, + options: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 2] }, // Keyboard shortcut settings @@ -204,6 +204,12 @@ 'airplay', 'fullscreen' ], + settings: [ + 'captions', + 'quality', + 'speed', + 'loop' + ], // Localisation i18n: { @@ -1442,13 +1448,9 @@ })); } - // Add the icon button.appendChild(createIcon(iconDefault)); - - // Add the label button.appendChild(createLabel(labelKey)); - // Set element attributes utils.setAttributes(button, attributes); player.elements.buttons[type] = button; @@ -1668,13 +1670,16 @@ role: 'tabpanel' }); + // Create the tab list var tabs = utils.createElement('ul', { role: 'tablist' }); - ['captions', 'quality', 'speed', 'loop'].forEach(function(type) { + // Build the tabs + config.settings.forEach(function(type) { var tab = utils.createElement('li', { - role: 'tab' + role: 'tab', + hidden: '' }); var button = utils.createElement('button', utils.extend(utils.getAttributesFromSelector(config.selectors.buttons.settings), { @@ -1694,25 +1699,24 @@ value.innerHTML = data[type]; button.appendChild(value); - tab.appendChild(button); - tabs.appendChild(tab); player.elements.settings.tabs[type] = tab; }); home.appendChild(tabs); - inner.appendChild(home); - ['captions', 'quality', 'speed', 'loop'].forEach(function(type) { + // Build the panes + config.settings.forEach(function(type) { var pane = utils.createElement('div', { id: 'plyr-settings-' + data.id + '-' + type, 'aria-hidden': true, 'aria-labelled-by': 'plyr-settings-' + data.id + '-' + type + '-tab', role: 'tabpanel', - tabindex: -1 + tabindex: -1, + hidden: '' }); var back = utils.createElement('button', { @@ -1728,20 +1732,16 @@ var options = utils.createElement('ul'); pane.appendChild(options); - inner.appendChild(pane); player.elements.settings.panes[type] = pane; }); form.appendChild(inner); - menu.appendChild(form); - controls.appendChild(menu); player.elements.settings.form = form; - player.elements.settings.menu = menu; } @@ -1774,6 +1774,10 @@ function setQualityMenu(options, current) { var list = player.elements.settings.panes.quality.querySelector('ul'); + // Show the pane and tab + player.elements.settings.tabs.quality.removeAttribute('hidden'); + player.elements.settings.panes.quality.removeAttribute('hidden'); + // Empty the menu utils.emptyElement(list); @@ -1833,19 +1837,17 @@ var item = utils.createElement('li'); var label = utils.createElement('label', { - class: config.classes.control, - for: 'plyr-quality-' + quality + class: config.classes.control }); var radio = utils.createElement('input', utils.extend(utils.getAttributesFromSelector(config.selectors.inputs.quality), { type: 'radio', - id: 'plyr-quality-' + quality, name: 'plyr-quality', value: quality, })); if (quality === config.quality.selected) { - radio.setAttribute('checked', ''); + radio.checked = true; } label.appendChild(radio); @@ -1857,7 +1859,6 @@ } item.appendChild(label); - list.appendChild(item); }); } @@ -1868,6 +1869,10 @@ var options = ['start', 'end', 'all', 'reset']; var list = player.elements.settings.panes.loop.querySelector('ul'); + // Show the pane and tab + player.elements.settings.tabs.loop.removeAttribute('hidden'); + player.elements.settings.panes.loop.removeAttribute('hidden'); + // Empty the menu utils.emptyElement(list); @@ -1881,12 +1886,11 @@ }), config.i18n[option]); if (utils.inArray(['start', 'end'], option)) { - var badge = createBadge('0:00'); + var badge = createBadge('00:00'); button.appendChild(badge); } item.appendChild(button); - list.appendChild(item); }); } @@ -1895,6 +1899,10 @@ function setCaptionsMenu() { var list = player.elements.settings.panes.captions.querySelector('ul'); + // Show the pane and tab + player.elements.settings.tabs.captions.removeAttribute('hidden'); + player.elements.settings.panes.captions.removeAttribute('hidden'); + // Empty the menu utils.emptyElement(list); @@ -1923,19 +1931,17 @@ var item = utils.createElement('li'); var label = utils.createElement('label', { - class: config.classes.control, - for: 'plyr-language-' + track.language + class: config.classes.control }); var radio = utils.createElement('input', utils.extend(utils.getAttributesFromSelector(config.selectors.inputs.language), { type: 'radio', - id: 'plyr-language-' + track.language, name: 'plyr-language', value: track.language, })); - if (track.language === config.captions.language.toLowerCase()) { - radio.setAttribute('checked', ''); + if (track.language.toLowerCase() === config.captions.language.toLowerCase()) { + radio.checked = true; } label.appendChild(radio); @@ -1946,7 +1952,6 @@ } item.appendChild(label); - list.appendChild(item); }); } @@ -1955,6 +1960,10 @@ function setSpeedMenu(options) { var list = player.elements.settings.panes.speed.querySelector('ul'); + // Show the pane and tab + player.elements.settings.tabs.speed.removeAttribute('hidden'); + player.elements.settings.panes.speed.removeAttribute('hidden'); + // Empty the menu utils.emptyElement(list); @@ -1967,26 +1976,22 @@ var item = utils.createElement('li'); var label = utils.createElement('label', { - class: config.classes.control, - for: 'plyr-speed-' + speed.toString().replace('.', '-') + class: config.classes.control }); var radio = utils.createElement('input', utils.extend(utils.getAttributesFromSelector(config.selectors.inputs.speed), { type: 'radio', - id: 'plyr-speed-' + speed.toString().replace('.', '-'), name: 'plyr-speed', value: speed, })); if (speed === config.speed.selected) { - radio.setAttribute('checked', ''); + radio.checked = true; } label.appendChild(radio); - label.insertAdjacentHTML('beforeend', '×' + speed); - + label.insertAdjacentHTML('beforeend', getSpeedLabel(speed)); item.appendChild(label); - list.appendChild(item); }); } @@ -2259,7 +2264,7 @@ controls = createControls({ id: player.id, seektime: config.seekTime, - speed: getSpeed(), + speed: getSpeedLabel(), // TODO: Get current quality quality: 'HD', captions: getLanguage(), @@ -3136,8 +3141,16 @@ } // Get the current speed value - function getSpeed() { - return config.speed.selected.toFixed(1).toString().replace('.0', '') + '×' + function getSpeedLabel(speed) { + if (!utils.is.number(speed)) { + speed = config.speed.selected; + } + + if (speed === 1) { + return 'Normal'; + } + + return speed + '×'; } // Rewind @@ -3322,19 +3335,24 @@ function toggleMenu(event) { var form = player.elements.settings.form; var button = player.elements.buttons.settings; + var show = utils.is.boolean(event) ? event : form.getAttribute('aria-hidden') === 'true'; - // If the click was inside the form, do nothing - if (form.contains(event.target)) { - return; - } + if (utils.is.event(event)) { + var isMenuItem = form.contains(event.target); + var isButton = event.target === player.elements.buttons.settings; - // Prevent the toggleMenu being fired twice - if (event.target === player.elements.buttons.settings) { - event.stopPropagation(); - } + // If the click was inside the form or if the click + // wasn't the button or menu item and we're trying to + // show the menu (a doc click shouldn't show the menu) + if (isMenuItem || (!isMenuItem && !isButton && show)) { + return; + } - // Do we need to show it? - var show = form.getAttribute('aria-hidden') === 'true'; + // Prevent the toggle being caught by the doc listener + if (isButton) { + event.stopPropagation(); + } + } // Set form and button attributes form.setAttribute('aria-hidden', !show); @@ -3347,6 +3365,38 @@ } } + // Get the natural size of a tab + function getTabSize(tab) { + var width; + var height; + + var clone = tab.cloneNode(true); + clone.style.position = "absolute"; + clone.style.opacity = 0; + clone.setAttribute('aria-hidden', false); + + // Prevent input's being unchecked due to the name being identical + [].forEach.call(clone.querySelectorAll('input[name]'), function(input) { + var name = input.getAttribute('name'); + input.setAttribute('name', name + '-clone'); + }); + + // Append to parent so we get the "real" size + tab.parentNode.appendChild(clone); + + // Get the sizes before we remove + width = clone.scrollWidth; + height = clone.scrollHeight; + + // Remove from the DOM + utils.removeElement(clone); + + return { + width: width, + height: height + }; + } + // Toggle Menu function showTab(event) { var menu = player.elements.settings.menu; @@ -3365,14 +3415,10 @@ return; } - var targetWidth; - var targetHeight; - var container; - // Hide all other tabs // Get other tabs var current = menu.querySelector('[role="tabpanel"][aria-hidden="false"]'); - container = current.parentNode; + var container = current.parentNode; // Set other toggles to be expanded false [].forEach.call(menu.querySelectorAll('[aria-controls="' + current.getAttribute('id') + '"]'), function(toggle) { @@ -3385,15 +3431,8 @@ container.style.width = current.scrollWidth + 'px'; container.style.height = current.scrollHeight + 'px'; - // Get the natural element size of the target pane - var clone = pane.cloneNode(true); - clone.style.position = "absolute"; - clone.style.opacity = 0; - clone.setAttribute('aria-hidden', false); - container.appendChild(clone); - targetWidth = clone.scrollWidth; - targetHeight = clone.scrollHeight; - utils.removeElement(clone); + // Get potential sizes + var size = getTabSize(pane); // Restore auto height/width var restore = function(event) { @@ -3415,8 +3454,8 @@ utils.on(container, utils.transitionEnd, restore); // Set dimensions to target - container.style.width = targetWidth + 'px'; - container.style.height = targetHeight + 'px'; + container.style.width = size.width + 'px'; + container.style.height = size.height + 'px'; } // Set attributes on current tab @@ -4355,7 +4394,7 @@ utils.on(player.elements.buttons.settings, 'click', toggleMenu); // Click anywhere closes menu - utils.on(document.body, 'click', toggleMenu); + utils.on(document.documentElement, 'click', toggleMenu); // Show tab in menu utils.on(player.elements.settings.form, 'click', showTab); |