diff options
Diffstat (limited to 'src/js/controls.js')
-rw-r--r-- | src/js/controls.js | 139 |
1 files changed, 91 insertions, 48 deletions
diff --git a/src/js/controls.js b/src/js/controls.js index 661ceb32..785f100d 100644 --- a/src/js/controls.js +++ b/src/js/controls.js @@ -122,17 +122,13 @@ const controls = { }, // Create hidden text label - createLabel(type, attr = {}) { - // Skip i18n for abbreviations and brand names - const universals = { - pip: 'PIP', - airplay: 'AirPlay', - }; - const text = universals[type] || i18n.get(type, this.config); + createLabel(key, attr = {}) { + const text = i18n.get(key, this.config); const attributes = Object.assign({}, attr, { class: [attr.class, this.config.classNames.hidden].filter(Boolean).join(' '), }); + return createElement('span', attributes, text); }, @@ -161,21 +157,32 @@ const controls = { // Create a <button> createButton(buttonType, attr) { - const button = createElement('button'); const attributes = Object.assign({}, attr); let type = toCamelCase(buttonType); - let toggle = false; - let label; - let icon; - let labelPressed; - let iconPressed; + const props = { + element: 'button', + toggle: false, + label: null, + icon: null, + labelPressed: null, + iconPressed: null, + }; - if (!('type' in attributes)) { + ['element', 'icon', 'label'].forEach(key => { + if (Object.keys(attributes).includes(key)) { + props[key] = attributes[key]; + delete attributes[key]; + } + }); + + // Default to 'button' type to prevent form submission + if (props.element === 'button' && !Object.keys(attributes).includes('type')) { attributes.type = 'button'; } - if ('class' in attributes) { + // Set class name + if (Object.keys(attributes).includes('class')) { if (!attributes.class.includes(this.config.classNames.control)) { attributes.class += ` ${this.config.classNames.control}`; } @@ -186,82 +193,87 @@ const controls = { // Large play button switch (buttonType) { case 'play': - toggle = true; - label = 'play'; - labelPressed = 'pause'; - icon = 'play'; - iconPressed = 'pause'; + props.toggle = true; + props.label = 'play'; + props.labelPressed = 'pause'; + props.icon = 'play'; + props.iconPressed = 'pause'; break; case 'mute': - toggle = true; - label = 'mute'; - labelPressed = 'unmute'; - icon = 'volume'; - iconPressed = 'muted'; + props.toggle = true; + props.label = 'mute'; + props.labelPressed = 'unmute'; + props.icon = 'volume'; + props.iconPressed = 'muted'; break; case 'captions': - toggle = true; - label = 'enableCaptions'; - labelPressed = 'disableCaptions'; - icon = 'captions-off'; - iconPressed = 'captions-on'; + props.toggle = true; + props.label = 'enableCaptions'; + props.labelPressed = 'disableCaptions'; + props.icon = 'captions-off'; + props.iconPressed = 'captions-on'; break; case 'fullscreen': - toggle = true; - label = 'enterFullscreen'; - labelPressed = 'exitFullscreen'; - icon = 'enter-fullscreen'; - iconPressed = 'exit-fullscreen'; + props.toggle = true; + props.label = 'enterFullscreen'; + props.labelPressed = 'exitFullscreen'; + props.icon = 'enter-fullscreen'; + props.iconPressed = 'exit-fullscreen'; break; case 'play-large': attributes.class += ` ${this.config.classNames.control}--overlaid`; type = 'play'; - label = 'play'; - icon = 'play'; + props.label = 'play'; + props.icon = 'play'; break; default: - label = type; - icon = buttonType; + if (is.empty(props.label)) { + props.label = type; + } + if (is.empty(props.icon)) { + props.icon = buttonType; + } } + const button = createElement(props.element); + // Setup toggle icon and labels - if (toggle) { + if (props.toggle) { // Icon button.appendChild( - controls.createIcon.call(this, iconPressed, { + controls.createIcon.call(this, props.iconPressed, { class: 'icon--pressed', }), ); button.appendChild( - controls.createIcon.call(this, icon, { + controls.createIcon.call(this, props.icon, { class: 'icon--not-pressed', }), ); // Label/Tooltip button.appendChild( - controls.createLabel.call(this, labelPressed, { + controls.createLabel.call(this, props.labelPressed, { class: 'label--pressed', }), ); button.appendChild( - controls.createLabel.call(this, label, { + controls.createLabel.call(this, props.label, { class: 'label--not-pressed', }), ); } else { - button.appendChild(controls.createIcon.call(this, icon)); - button.appendChild(controls.createLabel.call(this, label)); + button.appendChild(controls.createIcon.call(this, props.icon)); + button.appendChild(controls.createLabel.call(this, props.label)); } - // Merge attributes + // Merge and set attributes extend(attributes, getAttributesFromSelector(this.config.selectors.buttons[type], attributes)); - setAttributes(button, attributes); // We have multiple play buttons @@ -1214,6 +1226,15 @@ const controls = { controls.focusFirstMenuItem.call(this, target, tabFocus); }, + // Set the download link + setDownloadLink() { + // Set download link + const { download } = this.elements.buttons; + if (is.element(download)) { + download.setAttribute('href', this.source); + } + }, + // Build the default HTML // TODO: Set order based on order in the config.controls array? create(data) { @@ -1490,6 +1511,28 @@ const controls = { container.appendChild(controls.createButton.call(this, 'airplay')); } + // Download button + if (this.config.controls.includes('download')) { + const attributes = { + element: 'a', + href: this.source, + target: '_blank', + }; + + if (this.isHTML5) { + extend(attributes, { + download: '', + }); + } else if (this.isEmbed) { + extend(attributes, { + icon: `logo-${this.provider}`, + label: this.provider, + }); + } + + container.appendChild(controls.createButton.call(this, 'download', attributes)); + } + // Toggle fullscreen button if (this.config.controls.includes('fullscreen')) { container.appendChild(controls.createButton.call(this, 'fullscreen')); |