aboutsummaryrefslogtreecommitdiffstats
path: root/src/js/controls.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/js/controls.js')
-rw-r--r--src/js/controls.js139
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'));