Work on menus
This commit is contained in:
parent
bb546fe43f
commit
1f1d74ba50
2
.gitignore
vendored
2
.gitignore
vendored
@ -6,6 +6,6 @@ aws.json
|
|||||||
index-*.html
|
index-*.html
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
*.webm
|
*.webm
|
||||||
/package-lock.json
|
package-lock.json
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
|
2
demo/dist/demo.css
vendored
2
demo/dist/demo.css
vendored
File diff suppressed because one or more lines are too long
2
demo/dist/error.css
vendored
2
demo/dist/error.css
vendored
File diff suppressed because one or more lines are too long
@ -166,7 +166,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
<p>If you think Plyr's good,
|
<p>If you think Plyr's good,
|
||||||
<a href="https://twitter.com/intent/tweet?text=A+simple+HTML5+media+player+with+custom+controls+and+WebVTT+captions.&url=http%3A%2F%2Fplyr.io&via=Sam_Potts"
|
<a href="https://twitter.com/intent/tweet?text=A+simple+HTML5+media+player+with+custom+controls+and+WebVTT+captions.&url=http%3A%2F%2Fplyr.io&via=Sam_Potts"
|
||||||
target="_blank" data-shr-network="twitter">tweet it</a>
|
target="_blank" data-shr-network="twitter">tweet it</a> 👍
|
||||||
</p>
|
</p>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
// Typography
|
// Typography
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
$font-sans-serif: 'Gordita', 'Avenir', 'Helvetica Neue', sans-serif;
|
$font-sans-serif: 'Gordita', 'Avenir', 'Helvetica Neue', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
|
||||||
|
'Segoe UI Symbol';
|
||||||
|
|
||||||
$font-size-base: 15;
|
$font-size-base: 15;
|
||||||
$font-size-small: 13;
|
$font-size-small: 13;
|
||||||
|
2
dist/plyr.css
vendored
2
dist/plyr.css
vendored
File diff suppressed because one or more lines are too long
609
dist/plyr.js
vendored
609
dist/plyr.js
vendored
@ -11,60 +11,92 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
var getConstructor = function getConstructor(input) {
|
var getConstructor = function getConstructor(input) {
|
||||||
return input !== null && typeof input !== 'undefined' ? input.constructor : null;
|
return input !== null && typeof input !== 'undefined' ? input.constructor : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
var instanceOf = function instanceOf(input, constructor) {
|
var instanceOf = function instanceOf(input, constructor) {
|
||||||
return Boolean(input && constructor && input instanceof constructor);
|
return Boolean(input && constructor && input instanceof constructor);
|
||||||
};
|
};
|
||||||
|
var isNullOrUndefined = function isNullOrUndefined(input) {
|
||||||
|
return input === null || typeof input === 'undefined';
|
||||||
|
};
|
||||||
|
var isObject = function isObject(input) {
|
||||||
|
return getConstructor(input) === Object;
|
||||||
|
};
|
||||||
|
var isNumber = function isNumber(input) {
|
||||||
|
return getConstructor(input) === Number && !Number.isNaN(input);
|
||||||
|
};
|
||||||
|
var isString = function isString(input) {
|
||||||
|
return getConstructor(input) === String;
|
||||||
|
};
|
||||||
|
var isBoolean = function isBoolean(input) {
|
||||||
|
return getConstructor(input) === Boolean;
|
||||||
|
};
|
||||||
|
var isFunction = function isFunction(input) {
|
||||||
|
return getConstructor(input) === Function;
|
||||||
|
};
|
||||||
|
var isArray = function isArray(input) {
|
||||||
|
return Array.isArray(input);
|
||||||
|
};
|
||||||
|
var isWeakMap = function isWeakMap(input) {
|
||||||
|
return instanceOf(input, WeakMap);
|
||||||
|
};
|
||||||
|
var isNodeList = function isNodeList(input) {
|
||||||
|
return instanceOf(input, NodeList);
|
||||||
|
};
|
||||||
|
var isElement = function isElement(input) {
|
||||||
|
return instanceOf(input, Element);
|
||||||
|
};
|
||||||
|
var isTextNode = function isTextNode(input) {
|
||||||
|
return getConstructor(input) === Text;
|
||||||
|
};
|
||||||
|
var isEvent = function isEvent(input) {
|
||||||
|
return instanceOf(input, Event);
|
||||||
|
};
|
||||||
|
var isCue = function isCue(input) {
|
||||||
|
return instanceOf(input, window.TextTrackCue) || instanceOf(input, window.VTTCue);
|
||||||
|
};
|
||||||
|
var isTrack = function isTrack(input) {
|
||||||
|
return instanceOf(input, TextTrack) || !isNullOrUndefined(input) && isString(input.kind);
|
||||||
|
};
|
||||||
|
|
||||||
|
var isEmpty = function isEmpty(input) {
|
||||||
|
return isNullOrUndefined(input) || (isString(input) || isArray(input) || isNodeList(input)) && !input.length || isObject(input) && !Object.keys(input).length;
|
||||||
|
};
|
||||||
|
|
||||||
|
var isUrl = function isUrl(input) {
|
||||||
|
// Accept a URL object
|
||||||
|
if (instanceOf(input, window.URL)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the protocol if required
|
||||||
|
var string = input;
|
||||||
|
if (!input.startsWith('http://') || !input.startsWith('https://')) {
|
||||||
|
string = 'http://' + input;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return !isEmpty(new URL(string).hostname);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var is = {
|
var is = {
|
||||||
object: function object(input) {
|
nullOrUndefined: isNullOrUndefined,
|
||||||
return getConstructor(input) === Object;
|
object: isObject,
|
||||||
},
|
number: isNumber,
|
||||||
number: function number(input) {
|
string: isString,
|
||||||
return getConstructor(input) === Number && !Number.isNaN(input);
|
boolean: isBoolean,
|
||||||
},
|
function: isFunction,
|
||||||
string: function string(input) {
|
array: isArray,
|
||||||
return getConstructor(input) === String;
|
weakMap: isWeakMap,
|
||||||
},
|
nodeList: isNodeList,
|
||||||
boolean: function boolean(input) {
|
element: isElement,
|
||||||
return getConstructor(input) === Boolean;
|
textNode: isTextNode,
|
||||||
},
|
event: isEvent,
|
||||||
function: function _function(input) {
|
cue: isCue,
|
||||||
return getConstructor(input) === Function;
|
track: isTrack,
|
||||||
},
|
url: isUrl,
|
||||||
array: function array(input) {
|
empty: isEmpty
|
||||||
return !is.nullOrUndefined(input) && Array.isArray(input);
|
|
||||||
},
|
|
||||||
weakMap: function weakMap(input) {
|
|
||||||
return instanceOf(input, WeakMap);
|
|
||||||
},
|
|
||||||
nodeList: function nodeList(input) {
|
|
||||||
return instanceOf(input, NodeList);
|
|
||||||
},
|
|
||||||
element: function element(input) {
|
|
||||||
return instanceOf(input, Element);
|
|
||||||
},
|
|
||||||
textNode: function textNode(input) {
|
|
||||||
return getConstructor(input) === Text;
|
|
||||||
},
|
|
||||||
event: function event(input) {
|
|
||||||
return instanceOf(input, Event);
|
|
||||||
},
|
|
||||||
cue: function cue(input) {
|
|
||||||
return instanceOf(input, window.TextTrackCue) || instanceOf(input, window.VTTCue);
|
|
||||||
},
|
|
||||||
track: function track(input) {
|
|
||||||
return instanceOf(input, TextTrack) || !is.nullOrUndefined(input) && is.string(input.kind);
|
|
||||||
},
|
|
||||||
url: function url(input) {
|
|
||||||
return !is.nullOrUndefined(input) && /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-/]))?/.test(input);
|
|
||||||
},
|
|
||||||
nullOrUndefined: function nullOrUndefined(input) {
|
|
||||||
return input === null || typeof input === 'undefined';
|
|
||||||
},
|
|
||||||
empty: function empty(input) {
|
|
||||||
return is.nullOrUndefined(input) || (is.string(input) || is.array(input) || is.nodeList(input)) && !input.length || is.object(input) && !Object.keys(input).length;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
@ -1637,6 +1669,8 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Create a settings menu item
|
// Create a settings menu item
|
||||||
createMenuItem: function createMenuItem(_ref) {
|
createMenuItem: function createMenuItem(_ref) {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
var value = _ref.value,
|
var value = _ref.value,
|
||||||
list = _ref.list,
|
list = _ref.list,
|
||||||
type = _ref.type,
|
type = _ref.type,
|
||||||
@ -1652,17 +1686,21 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
type: 'button',
|
type: 'button',
|
||||||
role: 'menuitemradio',
|
role: 'menuitemradio',
|
||||||
class: (this.config.classNames.control + ' ' + (attributes.class ? attributes.class : '')).trim(),
|
class: (this.config.classNames.control + ' ' + (attributes.class ? attributes.class : '')).trim(),
|
||||||
value: value,
|
'aria-checked': checked,
|
||||||
'aria-checked': checked
|
value: value
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
var flex = createElement('span');
|
||||||
|
|
||||||
// We have to set as HTML incase of special characters
|
// We have to set as HTML incase of special characters
|
||||||
item.innerHTML = title;
|
flex.innerHTML = title;
|
||||||
|
|
||||||
if (is.element(badge)) {
|
if (is.element(badge)) {
|
||||||
item.appendChild(badge);
|
flex.appendChild(badge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item.appendChild(flex);
|
||||||
|
|
||||||
Object.defineProperty(item, 'checked', {
|
Object.defineProperty(item, 'checked', {
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
get: function get$$1() {
|
get: function get$$1() {
|
||||||
@ -1682,6 +1720,29 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.listeners.bind(item, 'click', function () {
|
||||||
|
item.checked = true;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'language':
|
||||||
|
_this.currentTrack = Number(value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'quality':
|
||||||
|
_this.quality = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'speed':
|
||||||
|
_this.speed = parseFloat(value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
controls.showMenuPanel.call(_this, 'home');
|
||||||
|
}, type);
|
||||||
|
|
||||||
list.appendChild(item);
|
list.appendChild(item);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1755,7 +1816,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Update <progress> elements
|
// Update <progress> elements
|
||||||
updateProgress: function updateProgress(event) {
|
updateProgress: function updateProgress(event) {
|
||||||
var _this = this;
|
var _this2 = this;
|
||||||
|
|
||||||
if (!this.supported.ui || !is.event(event)) {
|
if (!this.supported.ui || !is.event(event)) {
|
||||||
return;
|
return;
|
||||||
@ -1765,7 +1826,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
var setProgress = function setProgress(target, input) {
|
var setProgress = function setProgress(target, input) {
|
||||||
var value = is.number(input) ? input : 0;
|
var value = is.number(input) ? input : 0;
|
||||||
var progress = is.element(target) ? target : _this.elements.display.buffer;
|
var progress = is.element(target) ? target : _this2.elements.display.buffer;
|
||||||
|
|
||||||
// Update value and label
|
// Update value and label
|
||||||
if (is.element(progress)) {
|
if (is.element(progress)) {
|
||||||
@ -1845,7 +1906,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Update hover tooltip for seeking
|
// Update hover tooltip for seeking
|
||||||
updateSeekTooltip: function updateSeekTooltip(event) {
|
updateSeekTooltip: function updateSeekTooltip(event) {
|
||||||
var _this2 = this;
|
var _this3 = this;
|
||||||
|
|
||||||
// Bail if setting not true
|
// Bail if setting not true
|
||||||
if (!this.config.tooltips.seek || !is.element(this.elements.inputs.seek) || !is.element(this.elements.display.seekTooltip) || this.duration === 0) {
|
if (!this.config.tooltips.seek || !is.element(this.elements.inputs.seek) || !is.element(this.elements.display.seekTooltip) || this.duration === 0) {
|
||||||
@ -1858,7 +1919,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
var visible = this.config.classNames.tooltip + '--visible';
|
var visible = this.config.classNames.tooltip + '--visible';
|
||||||
|
|
||||||
var toggle = function toggle(_toggle) {
|
var toggle = function toggle(_toggle) {
|
||||||
toggleClass(_this2.elements.display.seekTooltip, visible, _toggle);
|
toggleClass(_this3.elements.display.seekTooltip, visible, _toggle);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hide on touch
|
// Hide on touch
|
||||||
@ -1951,99 +2012,6 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
// Set the quality menu
|
|
||||||
setQualityMenu: function setQualityMenu(options) {
|
|
||||||
var _this3 = this;
|
|
||||||
|
|
||||||
// Menu required
|
|
||||||
if (!is.element(this.elements.settings.panels.quality)) {
|
|
||||||
console.warn('Not an element');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var type = 'quality';
|
|
||||||
var list = this.elements.settings.panels.quality.querySelector('[role="menu"]');
|
|
||||||
|
|
||||||
// Set options if passed and filter based on uniqueness and config
|
|
||||||
if (is.array(options)) {
|
|
||||||
this.options.quality = dedupe(options).filter(function (quality) {
|
|
||||||
return _this3.config.quality.options.includes(quality);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggle the pane and tab
|
|
||||||
console.warn(this.options.quality);
|
|
||||||
var toggle = !is.empty(this.options.quality) && this.options.quality.length > 1;
|
|
||||||
controls.toggleMenuButton.call(this, type, toggle);
|
|
||||||
|
|
||||||
// Check if we need to toggle the parent
|
|
||||||
controls.checkMenu.call(this);
|
|
||||||
|
|
||||||
// If we're hiding, nothing more to do
|
|
||||||
if (!toggle) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Empty the menu
|
|
||||||
emptyElement(list);
|
|
||||||
|
|
||||||
// Get the badge HTML for HD, 4K etc
|
|
||||||
var getBadge = function getBadge(quality) {
|
|
||||||
var label = i18n.get('qualityBadge.' + quality, _this3.config);
|
|
||||||
|
|
||||||
if (!label.length) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return controls.createBadge.call(_this3, label);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Sort options by the config and then render options
|
|
||||||
this.options.quality.sort(function (a, b) {
|
|
||||||
var sorting = _this3.config.quality.options;
|
|
||||||
return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1;
|
|
||||||
}).forEach(function (quality) {
|
|
||||||
controls.createMenuItem.call(_this3, {
|
|
||||||
value: quality,
|
|
||||||
list: list,
|
|
||||||
type: type,
|
|
||||||
title: controls.getLabel.call(_this3, 'quality', quality),
|
|
||||||
badge: getBadge(quality)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
controls.updateSetting.call(this, type, list);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// Translate a value into a nice label
|
|
||||||
getLabel: function getLabel(setting, value) {
|
|
||||||
switch (setting) {
|
|
||||||
case 'speed':
|
|
||||||
return value === 1 ? i18n.get('normal', this.config) : value + '×';
|
|
||||||
|
|
||||||
case 'quality':
|
|
||||||
if (is.number(value)) {
|
|
||||||
var label = i18n.get('qualityLabel.' + value, this.config);
|
|
||||||
|
|
||||||
if (!label.length) {
|
|
||||||
return value + 'p';
|
|
||||||
}
|
|
||||||
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
return toTitleCase(value);
|
|
||||||
|
|
||||||
case 'captions':
|
|
||||||
return captions.getLabel.call(this);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// Update the selected setting
|
// Update the selected setting
|
||||||
updateSetting: function updateSetting(setting, container, input) {
|
updateSetting: function updateSetting(setting, container, input) {
|
||||||
var pane = this.elements.settings.panels[setting];
|
var pane = this.elements.settings.panels[setting];
|
||||||
@ -2096,6 +2064,97 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// Translate a value into a nice label
|
||||||
|
getLabel: function getLabel(setting, value) {
|
||||||
|
switch (setting) {
|
||||||
|
case 'speed':
|
||||||
|
return value === 1 ? i18n.get('normal', this.config) : value + '×';
|
||||||
|
|
||||||
|
case 'quality':
|
||||||
|
if (is.number(value)) {
|
||||||
|
var label = i18n.get('qualityLabel.' + value, this.config);
|
||||||
|
|
||||||
|
if (!label.length) {
|
||||||
|
return value + 'p';
|
||||||
|
}
|
||||||
|
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
return toTitleCase(value);
|
||||||
|
|
||||||
|
case 'captions':
|
||||||
|
return captions.getLabel.call(this);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// Set the quality menu
|
||||||
|
setQualityMenu: function setQualityMenu(options) {
|
||||||
|
var _this4 = this;
|
||||||
|
|
||||||
|
// Menu required
|
||||||
|
if (!is.element(this.elements.settings.panels.quality)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var type = 'quality';
|
||||||
|
var list = this.elements.settings.panels.quality.querySelector('[role="menu"]');
|
||||||
|
|
||||||
|
// Set options if passed and filter based on uniqueness and config
|
||||||
|
if (is.array(options)) {
|
||||||
|
this.options.quality = dedupe(options).filter(function (quality) {
|
||||||
|
return _this4.config.quality.options.includes(quality);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle the pane and tab
|
||||||
|
var toggle = !is.empty(this.options.quality) && this.options.quality.length > 1;
|
||||||
|
controls.toggleMenuButton.call(this, type, toggle);
|
||||||
|
|
||||||
|
// Empty the menu
|
||||||
|
emptyElement(list);
|
||||||
|
|
||||||
|
// Check if we need to toggle the parent
|
||||||
|
controls.checkMenu.call(this);
|
||||||
|
|
||||||
|
// If we're hiding, nothing more to do
|
||||||
|
if (!toggle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the badge HTML for HD, 4K etc
|
||||||
|
var getBadge = function getBadge(quality) {
|
||||||
|
var label = i18n.get('qualityBadge.' + quality, _this4.config);
|
||||||
|
|
||||||
|
if (!label.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return controls.createBadge.call(_this4, label);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sort options by the config and then render options
|
||||||
|
this.options.quality.sort(function (a, b) {
|
||||||
|
var sorting = _this4.config.quality.options;
|
||||||
|
return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1;
|
||||||
|
}).forEach(function (quality) {
|
||||||
|
controls.createMenuItem.call(_this4, {
|
||||||
|
value: quality,
|
||||||
|
list: list,
|
||||||
|
type: type,
|
||||||
|
title: controls.getLabel.call(_this4, 'quality', quality),
|
||||||
|
badge: getBadge(quality)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
controls.updateSetting.call(this, type, list);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
// Set the looping options
|
// Set the looping options
|
||||||
/* setLoopMenu() {
|
/* setLoopMenu() {
|
||||||
// Menu required
|
// Menu required
|
||||||
@ -2137,15 +2196,21 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Set a list of available captions languages
|
// Set a list of available captions languages
|
||||||
setCaptionsMenu: function setCaptionsMenu() {
|
setCaptionsMenu: function setCaptionsMenu() {
|
||||||
var _this4 = this;
|
var _this5 = this;
|
||||||
|
|
||||||
|
// Menu required
|
||||||
|
if (!is.element(this.elements.settings.panels.captions)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Captions or language? Currently it's mixed
|
// TODO: Captions or language? Currently it's mixed
|
||||||
var type = 'captions';
|
var type = 'captions';
|
||||||
var list = this.elements.settings.panels.captions.querySelector('[role="menu"]');
|
var list = this.elements.settings.panels.captions.querySelector('[role="menu"]');
|
||||||
var tracks = captions.getTracks.call(this);
|
var tracks = captions.getTracks.call(this);
|
||||||
|
var toggle = Boolean(tracks.length);
|
||||||
|
|
||||||
// Toggle the pane and tab
|
// Toggle the pane and tab
|
||||||
controls.toggleMenuButton.call(this, type, tracks.length);
|
controls.toggleMenuButton.call(this, type, toggle);
|
||||||
|
|
||||||
// Empty the menu
|
// Empty the menu
|
||||||
emptyElement(list);
|
emptyElement(list);
|
||||||
@ -2154,7 +2219,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
controls.checkMenu.call(this);
|
controls.checkMenu.call(this);
|
||||||
|
|
||||||
// If there's no captions, bail
|
// If there's no captions, bail
|
||||||
if (!tracks.length) {
|
if (!toggle) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2162,9 +2227,9 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
var options = tracks.map(function (track, value) {
|
var options = tracks.map(function (track, value) {
|
||||||
return {
|
return {
|
||||||
value: value,
|
value: value,
|
||||||
checked: _this4.captions.toggled && _this4.currentTrack === value,
|
checked: _this5.captions.toggled && _this5.currentTrack === value,
|
||||||
title: captions.getLabel.call(_this4, track),
|
title: captions.getLabel.call(_this5, track),
|
||||||
badge: track.language && controls.createBadge.call(_this4, track.language.toUpperCase()),
|
badge: track.language && controls.createBadge.call(_this5, track.language.toUpperCase()),
|
||||||
list: list,
|
list: list,
|
||||||
type: 'language'
|
type: 'language'
|
||||||
};
|
};
|
||||||
@ -2188,12 +2253,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Set a list of available captions languages
|
// Set a list of available captions languages
|
||||||
setSpeedMenu: function setSpeedMenu(options) {
|
setSpeedMenu: function setSpeedMenu(options) {
|
||||||
var _this5 = this;
|
var _this6 = this;
|
||||||
|
|
||||||
// Do nothing if not selected
|
|
||||||
if (!this.config.controls.includes('settings') || !this.config.settings.includes('speed')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Menu required
|
// Menu required
|
||||||
if (!is.element(this.elements.settings.panels.speed)) {
|
if (!is.element(this.elements.settings.panels.speed)) {
|
||||||
@ -2201,6 +2261,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var type = 'speed';
|
var type = 'speed';
|
||||||
|
var list = this.elements.settings.panels.speed.querySelector('[role="menu"]');
|
||||||
|
|
||||||
// Set the speed options
|
// Set the speed options
|
||||||
if (is.array(options)) {
|
if (is.array(options)) {
|
||||||
@ -2211,13 +2272,16 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Set options if passed and filter based on config
|
// Set options if passed and filter based on config
|
||||||
this.options.speed = this.options.speed.filter(function (speed) {
|
this.options.speed = this.options.speed.filter(function (speed) {
|
||||||
return _this5.config.speed.options.includes(speed);
|
return _this6.config.speed.options.includes(speed);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Toggle the pane and tab
|
// Toggle the pane and tab
|
||||||
var toggle = !is.empty(this.options.speed) && this.options.speed.length > 1;
|
var toggle = !is.empty(this.options.speed) && this.options.speed.length > 1;
|
||||||
controls.toggleMenuButton.call(this, type, toggle);
|
controls.toggleMenuButton.call(this, type, toggle);
|
||||||
|
|
||||||
|
// Empty the menu
|
||||||
|
emptyElement(list);
|
||||||
|
|
||||||
// Check if we need to toggle the parent
|
// Check if we need to toggle the parent
|
||||||
controls.checkMenu.call(this);
|
controls.checkMenu.call(this);
|
||||||
|
|
||||||
@ -2226,19 +2290,13 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the list to populate
|
|
||||||
var list = this.elements.settings.panels.speed.querySelector('[role="menu"]');
|
|
||||||
|
|
||||||
// Empty the menu
|
|
||||||
emptyElement(list);
|
|
||||||
|
|
||||||
// Create items
|
// Create items
|
||||||
this.options.speed.forEach(function (speed) {
|
this.options.speed.forEach(function (speed) {
|
||||||
controls.createMenuItem.call(_this5, {
|
controls.createMenuItem.call(_this6, {
|
||||||
value: speed,
|
value: speed,
|
||||||
list: list,
|
list: list,
|
||||||
type: type,
|
type: type,
|
||||||
title: controls.getLabel.call(_this5, 'speed', speed)
|
title: controls.getLabel.call(_this6, 'speed', speed)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2332,7 +2390,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Show a panel in the menu
|
// Show a panel in the menu
|
||||||
showMenuPanel: function showMenuPanel() {
|
showMenuPanel: function showMenuPanel() {
|
||||||
var _this6 = this;
|
var _this7 = this;
|
||||||
|
|
||||||
var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
||||||
|
|
||||||
@ -2370,7 +2428,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
container.style.height = '';
|
container.style.height = '';
|
||||||
|
|
||||||
// Only listen once
|
// Only listen once
|
||||||
off.call(_this6, container, transitionEndEvent, restore);
|
off.call(_this7, container, transitionEndEvent, restore);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Listen for the transition finishing and restore auto height/width
|
// Listen for the transition finishing and restore auto height/width
|
||||||
@ -2383,7 +2441,6 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Set attributes on current tab
|
// Set attributes on current tab
|
||||||
toggleHidden(current, true);
|
toggleHidden(current, true);
|
||||||
// current.setAttribute('tabindex', -1);
|
|
||||||
|
|
||||||
// Set attributes on target
|
// Set attributes on target
|
||||||
toggleHidden(target, false);
|
toggleHidden(target, false);
|
||||||
@ -2399,7 +2456,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
// Build the default HTML
|
// Build the default HTML
|
||||||
// TODO: Set order based on order in the config.controls array?
|
// TODO: Set order based on order in the config.controls array?
|
||||||
create: function create(data) {
|
create: function create(data) {
|
||||||
var _this7 = this;
|
var _this8 = this;
|
||||||
|
|
||||||
// Do nothing if we want no controls
|
// Do nothing if we want no controls
|
||||||
if (is.empty(this.config.controls)) {
|
if (is.empty(this.config.controls)) {
|
||||||
@ -2534,17 +2591,18 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Build the menu items
|
// Build the menu items
|
||||||
this.config.settings.forEach(function (type) {
|
this.config.settings.forEach(function (type) {
|
||||||
var menuItem = createElement('button', extend(getAttributesFromSelector(_this7.config.selectors.buttons.settings), {
|
var menuItem = createElement('button', extend(getAttributesFromSelector(_this8.config.selectors.buttons.settings), {
|
||||||
type: 'button',
|
type: 'button',
|
||||||
class: _this7.config.classNames.control + ' ' + _this7.config.classNames.control + '--forward',
|
class: _this8.config.classNames.control + ' ' + _this8.config.classNames.control + '--forward',
|
||||||
role: 'menuitem',
|
role: 'menuitem',
|
||||||
'aria-haspopup': true
|
'aria-haspopup': true,
|
||||||
|
hidden: ''
|
||||||
}));
|
}));
|
||||||
|
|
||||||
var flex = createElement('span', null, i18n.get(type, _this7.config));
|
var flex = createElement('span', null, i18n.get(type, _this8.config));
|
||||||
|
|
||||||
var value = createElement('span', {
|
var value = createElement('span', {
|
||||||
class: _this7.config.classNames.menu.value
|
class: _this8.config.classNames.menu.value
|
||||||
});
|
});
|
||||||
|
|
||||||
// Speed contains HTML entities
|
// Speed contains HTML entities
|
||||||
@ -2563,10 +2621,10 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
// Back button
|
// Back button
|
||||||
var back = createElement('button', {
|
var back = createElement('button', {
|
||||||
type: 'button',
|
type: 'button',
|
||||||
class: _this7.config.classNames.control + ' ' + _this7.config.classNames.control + '--back'
|
class: _this8.config.classNames.control + ' ' + _this8.config.classNames.control + '--back'
|
||||||
}, i18n.get(type, _this7.config));
|
}, i18n.get(type, _this8.config));
|
||||||
back.addEventListener('click', function () {
|
back.addEventListener('click', function () {
|
||||||
controls.showMenuPanel.call(_this7, 'home');
|
controls.showMenuPanel.call(_this8, 'home');
|
||||||
});
|
});
|
||||||
pane.appendChild(back);
|
pane.appendChild(back);
|
||||||
|
|
||||||
@ -2578,11 +2636,11 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
inner.appendChild(pane);
|
inner.appendChild(pane);
|
||||||
|
|
||||||
menuItem.addEventListener('click', function () {
|
menuItem.addEventListener('click', function () {
|
||||||
controls.showMenuPanel.call(_this7, type);
|
controls.showMenuPanel.call(_this8, type);
|
||||||
});
|
});
|
||||||
|
|
||||||
_this7.elements.settings.buttons[type] = menuItem;
|
_this8.elements.settings.buttons[type] = menuItem;
|
||||||
_this7.elements.settings.panels[type] = pane;
|
_this8.elements.settings.panels[type] = pane;
|
||||||
});
|
});
|
||||||
|
|
||||||
home.appendChild(menu);
|
home.appendChild(menu);
|
||||||
@ -2630,7 +2688,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Insert controls
|
// Insert controls
|
||||||
inject: function inject() {
|
inject: function inject() {
|
||||||
var _this8 = this;
|
var _this9 = this;
|
||||||
|
|
||||||
// Sprite
|
// Sprite
|
||||||
if (this.config.loadSprite) {
|
if (this.config.loadSprite) {
|
||||||
@ -2742,8 +2800,8 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
var labels = getElements.call(this, selector);
|
var labels = getElements.call(this, selector);
|
||||||
|
|
||||||
Array.from(labels).forEach(function (label) {
|
Array.from(labels).forEach(function (label) {
|
||||||
toggleClass(label, _this8.config.classNames.hidden, false);
|
toggleClass(label, _this9.config.classNames.hidden, false);
|
||||||
toggleClass(label, _this8.config.classNames.tooltip, true);
|
toggleClass(label, _this9.config.classNames.tooltip, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4374,7 +4432,8 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Clear timer
|
// Clear timer
|
||||||
clearTimeout(_this2.player.timers.controls);
|
clearTimeout(_this2.player.timers.controls);
|
||||||
// Timer to prevent flicker when seeking
|
|
||||||
|
// Set new timer to prevent flicker when seeking
|
||||||
_this2.player.timers.controls = setTimeout(function () {
|
_this2.player.timers.controls = setTimeout(function () {
|
||||||
return ui.toggleControls.call(_this2.player, false);
|
return ui.toggleControls.call(_this2.player, false);
|
||||||
}, delay);
|
}, delay);
|
||||||
@ -4531,124 +4590,104 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen for control events
|
// Run default and custom handlers
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: 'controls',
|
key: 'proxy',
|
||||||
value: function controls$$1() {
|
value: function proxy(event, defaultHandler, customHandlerKey) {
|
||||||
var _this4 = this;
|
var customHandler = this.player.config.listeners[customHandlerKey];
|
||||||
|
|
||||||
// IE doesn't support input event, so we fallback to change
|
|
||||||
var inputEvent = browser.isIE ? 'change' : 'input';
|
|
||||||
|
|
||||||
// Run default and custom handlers
|
|
||||||
var proxy = function proxy(event, defaultHandler, customHandlerKey) {
|
|
||||||
var customHandler = _this4.player.config.listeners[customHandlerKey];
|
|
||||||
var hasCustomHandler = is.function(customHandler);
|
var hasCustomHandler = is.function(customHandler);
|
||||||
var returned = true;
|
var returned = true;
|
||||||
|
|
||||||
// Execute custom handler
|
// Execute custom handler
|
||||||
if (hasCustomHandler) {
|
if (hasCustomHandler) {
|
||||||
returned = customHandler.call(_this4.player, event);
|
returned = customHandler.call(this.player, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only call default handler if not prevented in custom handler
|
// Only call default handler if not prevented in custom handler
|
||||||
if (returned && is.function(defaultHandler)) {
|
if (returned && is.function(defaultHandler)) {
|
||||||
defaultHandler.call(_this4.player, event);
|
defaultHandler.call(this.player, event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// Trigger custom and default handlers
|
// Trigger custom and default handlers
|
||||||
var bind = function bind(element, type, defaultHandler, customHandlerKey) {
|
|
||||||
|
}, {
|
||||||
|
key: 'bind',
|
||||||
|
value: function bind(element, type, defaultHandler, customHandlerKey) {
|
||||||
|
var _this4 = this;
|
||||||
|
|
||||||
var passive = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
|
var passive = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
|
||||||
|
|
||||||
var customHandler = _this4.player.config.listeners[customHandlerKey];
|
var customHandler = this.player.config.listeners[customHandlerKey];
|
||||||
var hasCustomHandler = is.function(customHandler);
|
var hasCustomHandler = is.function(customHandler);
|
||||||
|
|
||||||
on.call(_this4.player, element, type, function (event) {
|
on.call(this.player, element, type, function (event) {
|
||||||
return proxy(event, defaultHandler, customHandlerKey);
|
return _this4.proxy(event, defaultHandler, customHandlerKey);
|
||||||
}, passive && !hasCustomHandler);
|
}, passive && !hasCustomHandler);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// Listen for control events
|
||||||
|
|
||||||
|
}, {
|
||||||
|
key: 'controls',
|
||||||
|
value: function controls$$1() {
|
||||||
|
var _this5 = this;
|
||||||
|
|
||||||
|
// IE doesn't support input event, so we fallback to change
|
||||||
|
var inputEvent = browser.isIE ? 'change' : 'input';
|
||||||
|
|
||||||
// Play/pause toggle
|
// Play/pause toggle
|
||||||
Array.from(this.player.elements.buttons.play).forEach(function (button) {
|
Array.from(this.player.elements.buttons.play).forEach(function (button) {
|
||||||
bind(button, 'click', _this4.player.togglePlay, 'play');
|
_this5.bind(button, 'click', _this5.player.togglePlay, 'play');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Pause
|
// Pause
|
||||||
bind(this.player.elements.buttons.restart, 'click', this.player.restart, 'restart');
|
this.bind(this.player.elements.buttons.restart, 'click', this.player.restart, 'restart');
|
||||||
|
|
||||||
// Rewind
|
// Rewind
|
||||||
bind(this.player.elements.buttons.rewind, 'click', this.player.rewind, 'rewind');
|
this.bind(this.player.elements.buttons.rewind, 'click', this.player.rewind, 'rewind');
|
||||||
|
|
||||||
// Rewind
|
// Rewind
|
||||||
bind(this.player.elements.buttons.fastForward, 'click', this.player.forward, 'fastForward');
|
this.bind(this.player.elements.buttons.fastForward, 'click', this.player.forward, 'fastForward');
|
||||||
|
|
||||||
// Mute toggle
|
// Mute toggle
|
||||||
bind(this.player.elements.buttons.mute, 'click', function () {
|
this.bind(this.player.elements.buttons.mute, 'click', function () {
|
||||||
_this4.player.muted = !_this4.player.muted;
|
_this5.player.muted = !_this5.player.muted;
|
||||||
}, 'mute');
|
}, 'mute');
|
||||||
|
|
||||||
// Captions toggle
|
// Captions toggle
|
||||||
bind(this.player.elements.buttons.captions, 'click', function () {
|
this.bind(this.player.elements.buttons.captions, 'click', function () {
|
||||||
return _this4.player.toggleCaptions();
|
return _this5.player.toggleCaptions();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fullscreen toggle
|
// Fullscreen toggle
|
||||||
bind(this.player.elements.buttons.fullscreen, 'click', function () {
|
this.bind(this.player.elements.buttons.fullscreen, 'click', function () {
|
||||||
_this4.player.fullscreen.toggle();
|
_this5.player.fullscreen.toggle();
|
||||||
}, 'fullscreen');
|
}, 'fullscreen');
|
||||||
|
|
||||||
// Picture-in-Picture
|
// Picture-in-Picture
|
||||||
bind(this.player.elements.buttons.pip, 'click', function () {
|
this.bind(this.player.elements.buttons.pip, 'click', function () {
|
||||||
_this4.player.pip = 'toggle';
|
_this5.player.pip = 'toggle';
|
||||||
}, 'pip');
|
}, 'pip');
|
||||||
|
|
||||||
// Airplay
|
// Airplay
|
||||||
bind(this.player.elements.buttons.airplay, 'click', this.player.airplay, 'airplay');
|
this.bind(this.player.elements.buttons.airplay, 'click', this.player.airplay, 'airplay');
|
||||||
|
|
||||||
// Settings menu
|
// Settings menu
|
||||||
bind(this.player.elements.buttons.settings, 'click', function (event) {
|
this.bind(this.player.elements.buttons.settings, 'click', function (event) {
|
||||||
controls.toggleMenu.call(_this4.player, event);
|
controls.toggleMenu.call(_this5.player, event);
|
||||||
});
|
|
||||||
|
|
||||||
// Settings menu
|
|
||||||
bind(this.player.elements.settings.popup, 'click', function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
|
|
||||||
// Go back to home tab on click
|
|
||||||
var showHomeTab = function showHomeTab() {
|
|
||||||
controls.showMenuPanel.call(_this4.player, 'home');
|
|
||||||
};
|
|
||||||
|
|
||||||
// Settings menu items - use event delegation as items are added/removed
|
|
||||||
if (matches(event.target, _this4.player.config.selectors.inputs.language)) {
|
|
||||||
proxy(event, function () {
|
|
||||||
_this4.player.currentTrack = Number(event.target.value);
|
|
||||||
showHomeTab();
|
|
||||||
}, 'language');
|
|
||||||
} else if (matches(event.target, _this4.player.config.selectors.inputs.quality)) {
|
|
||||||
proxy(event, function () {
|
|
||||||
_this4.player.quality = event.target.value;
|
|
||||||
showHomeTab();
|
|
||||||
}, 'quality');
|
|
||||||
} else if (matches(event.target, _this4.player.config.selectors.inputs.speed)) {
|
|
||||||
proxy(event, function () {
|
|
||||||
_this4.player.speed = parseFloat(event.target.value);
|
|
||||||
showHomeTab();
|
|
||||||
}, 'speed');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set range input alternative "value", which matches the tooltip time (#954)
|
// Set range input alternative "value", which matches the tooltip time (#954)
|
||||||
bind(this.player.elements.inputs.seek, 'mousedown mousemove', function (event) {
|
this.bind(this.player.elements.inputs.seek, 'mousedown mousemove', function (event) {
|
||||||
var clientRect = _this4.player.elements.progress.getBoundingClientRect();
|
var clientRect = _this5.player.elements.progress.getBoundingClientRect();
|
||||||
var percent = 100 / clientRect.width * (event.pageX - clientRect.left);
|
var percent = 100 / clientRect.width * (event.pageX - clientRect.left);
|
||||||
event.currentTarget.setAttribute('seek-value', percent);
|
event.currentTarget.setAttribute('seek-value', percent);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Pause while seeking
|
// Pause while seeking
|
||||||
bind(this.player.elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', function (event) {
|
this.bind(this.player.elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', function (event) {
|
||||||
var seek = event.currentTarget;
|
var seek = event.currentTarget;
|
||||||
|
|
||||||
var code = event.keyCode ? event.keyCode : event.which;
|
var code = event.keyCode ? event.keyCode : event.which;
|
||||||
@ -4666,15 +4705,15 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
// If we're done seeking and it was playing, resume playback
|
// If we're done seeking and it was playing, resume playback
|
||||||
if (play && done) {
|
if (play && done) {
|
||||||
seek.removeAttribute('play-on-seeked');
|
seek.removeAttribute('play-on-seeked');
|
||||||
_this4.player.play();
|
_this5.player.play();
|
||||||
} else if (!done && _this4.player.playing) {
|
} else if (!done && _this5.player.playing) {
|
||||||
seek.setAttribute('play-on-seeked', '');
|
seek.setAttribute('play-on-seeked', '');
|
||||||
_this4.player.pause();
|
_this5.player.pause();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Seek
|
// Seek
|
||||||
bind(this.player.elements.inputs.seek, inputEvent, function (event) {
|
this.bind(this.player.elements.inputs.seek, inputEvent, function (event) {
|
||||||
var seek = event.currentTarget;
|
var seek = event.currentTarget;
|
||||||
|
|
||||||
// If it exists, use seek-value instead of "value" for consistency with tooltip time (#954)
|
// If it exists, use seek-value instead of "value" for consistency with tooltip time (#954)
|
||||||
@ -4686,56 +4725,56 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
seek.removeAttribute('seek-value');
|
seek.removeAttribute('seek-value');
|
||||||
|
|
||||||
_this4.player.currentTime = seekTo / seek.max * _this4.player.duration;
|
_this5.player.currentTime = seekTo / seek.max * _this5.player.duration;
|
||||||
}, 'seek');
|
}, 'seek');
|
||||||
|
|
||||||
// Current time invert
|
// Current time invert
|
||||||
// Only if one time element is used for both currentTime and duration
|
// Only if one time element is used for both currentTime and duration
|
||||||
if (this.player.config.toggleInvert && !is.element(this.player.elements.display.duration)) {
|
if (this.player.config.toggleInvert && !is.element(this.player.elements.display.duration)) {
|
||||||
bind(this.player.elements.display.currentTime, 'click', function () {
|
this.bind(this.player.elements.display.currentTime, 'click', function () {
|
||||||
// Do nothing if we're at the start
|
// Do nothing if we're at the start
|
||||||
if (_this4.player.currentTime === 0) {
|
if (_this5.player.currentTime === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_this4.player.config.invertTime = !_this4.player.config.invertTime;
|
_this5.player.config.invertTime = !_this5.player.config.invertTime;
|
||||||
|
|
||||||
controls.timeUpdate.call(_this4.player);
|
controls.timeUpdate.call(_this5.player);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Volume
|
// Volume
|
||||||
bind(this.player.elements.inputs.volume, inputEvent, function (event) {
|
this.bind(this.player.elements.inputs.volume, inputEvent, function (event) {
|
||||||
_this4.player.volume = event.target.value;
|
_this5.player.volume = event.target.value;
|
||||||
}, 'volume');
|
}, 'volume');
|
||||||
|
|
||||||
// Polyfill for lower fill in <input type="range"> for webkit
|
// Polyfill for lower fill in <input type="range"> for webkit
|
||||||
if (browser.isWebkit) {
|
if (browser.isWebkit) {
|
||||||
Array.from(getElements.call(this.player, 'input[type="range"]')).forEach(function (element) {
|
Array.from(getElements.call(this.player, 'input[type="range"]')).forEach(function (element) {
|
||||||
bind(element, 'input', function (event) {
|
_this5.bind(element, 'input', function (event) {
|
||||||
return controls.updateRangeFill.call(_this4.player, event.target);
|
return controls.updateRangeFill.call(_this5.player, event.target);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seek tooltip
|
// Seek tooltip
|
||||||
bind(this.player.elements.progress, 'mouseenter mouseleave mousemove', function (event) {
|
this.bind(this.player.elements.progress, 'mouseenter mouseleave mousemove', function (event) {
|
||||||
return controls.updateSeekTooltip.call(_this4.player, event);
|
return controls.updateSeekTooltip.call(_this5.player, event);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting)
|
// Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting)
|
||||||
bind(this.player.elements.controls, 'mouseenter mouseleave', function (event) {
|
this.bind(this.player.elements.controls, 'mouseenter mouseleave', function (event) {
|
||||||
_this4.player.elements.controls.hover = !_this4.player.touch && event.type === 'mouseenter';
|
_this5.player.elements.controls.hover = !_this5.player.touch && event.type === 'mouseenter';
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)
|
// Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)
|
||||||
bind(this.player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', function (event) {
|
this.bind(this.player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', function (event) {
|
||||||
_this4.player.elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);
|
_this5.player.elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Focus in/out on controls
|
// Focus in/out on controls
|
||||||
bind(this.player.elements.controls, 'focusin focusout', function (event) {
|
this.bind(this.player.elements.controls, 'focusin focusout', function (event) {
|
||||||
var _player = _this4.player,
|
var _player = _this5.player,
|
||||||
config = _player.config,
|
config = _player.config,
|
||||||
elements = _player.elements,
|
elements = _player.elements,
|
||||||
timers = _player.timers;
|
timers = _player.timers;
|
||||||
@ -4745,7 +4784,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
toggleClass(elements.controls, config.classNames.noTransition, event.type === 'focusin');
|
toggleClass(elements.controls, config.classNames.noTransition, event.type === 'focusin');
|
||||||
|
|
||||||
// Toggle
|
// Toggle
|
||||||
ui.toggleControls.call(_this4.player, event.type === 'focusin');
|
ui.toggleControls.call(_this5.player, event.type === 'focusin');
|
||||||
|
|
||||||
// If focusin, hide again after delay
|
// If focusin, hide again after delay
|
||||||
if (event.type === 'focusin') {
|
if (event.type === 'focusin') {
|
||||||
@ -4755,19 +4794,19 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
// Delay a little more for keyboard users
|
// Delay a little more for keyboard users
|
||||||
var delay = _this4.touch ? 3000 : 4000;
|
var delay = _this5.touch ? 3000 : 4000;
|
||||||
|
|
||||||
// Clear timer
|
// Clear timer
|
||||||
clearTimeout(timers.controls);
|
clearTimeout(timers.controls);
|
||||||
// Hide
|
// Hide
|
||||||
timers.controls = setTimeout(function () {
|
timers.controls = setTimeout(function () {
|
||||||
return ui.toggleControls.call(_this4.player, false);
|
return ui.toggleControls.call(_this5.player, false);
|
||||||
}, delay);
|
}, delay);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Mouse wheel for volume
|
// Mouse wheel for volume
|
||||||
bind(this.player.elements.inputs.volume, 'wheel', function (event) {
|
this.bind(this.player.elements.inputs.volume, 'wheel', function (event) {
|
||||||
// Detect "natural" scroll - suppored on OS X Safari only
|
// Detect "natural" scroll - suppored on OS X Safari only
|
||||||
// Other browsers on OS X will be inverted until support improves
|
// Other browsers on OS X will be inverted until support improves
|
||||||
var inverted = event.webkitDirectionInvertedFromDevice;
|
var inverted = event.webkitDirectionInvertedFromDevice;
|
||||||
@ -4777,10 +4816,10 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
// Scroll down (or up on natural) to decrease
|
// Scroll down (or up on natural) to decrease
|
||||||
if (event.deltaY < 0 || event.deltaX > 0) {
|
if (event.deltaY < 0 || event.deltaX > 0) {
|
||||||
if (inverted) {
|
if (inverted) {
|
||||||
_this4.player.decreaseVolume(step);
|
_this5.player.decreaseVolume(step);
|
||||||
direction = -1;
|
direction = -1;
|
||||||
} else {
|
} else {
|
||||||
_this4.player.increaseVolume(step);
|
_this5.player.increaseVolume(step);
|
||||||
direction = 1;
|
direction = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4788,16 +4827,16 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
// Scroll up (or down on natural) to increase
|
// Scroll up (or down on natural) to increase
|
||||||
if (event.deltaY > 0 || event.deltaX < 0) {
|
if (event.deltaY > 0 || event.deltaX < 0) {
|
||||||
if (inverted) {
|
if (inverted) {
|
||||||
_this4.player.increaseVolume(step);
|
_this5.player.increaseVolume(step);
|
||||||
direction = 1;
|
direction = 1;
|
||||||
} else {
|
} else {
|
||||||
_this4.player.decreaseVolume(step);
|
_this5.player.decreaseVolume(step);
|
||||||
direction = -1;
|
direction = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't break page scrolling at max and min
|
// Don't break page scrolling at max and min
|
||||||
if (direction === 1 && _this4.player.media.volume < 1 || direction === -1 && _this4.player.media.volume > 0) {
|
if (direction === 1 && _this5.player.media.volume < 1 || direction === -1 && _this5.player.media.volume > 0) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
}, 'volume', false);
|
}, 'volume', false);
|
||||||
|
2
dist/plyr.js.map
vendored
2
dist/plyr.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.min.js
vendored
2
dist/plyr.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.min.js.map
vendored
2
dist/plyr.min.js.map
vendored
File diff suppressed because one or more lines are too long
478
dist/plyr.polyfilled.js
vendored
478
dist/plyr.polyfilled.js
vendored
@ -7023,6 +7023,8 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Create a settings menu item
|
// Create a settings menu item
|
||||||
createMenuItem: function createMenuItem(_ref) {
|
createMenuItem: function createMenuItem(_ref) {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
var value = _ref.value,
|
var value = _ref.value,
|
||||||
list = _ref.list,
|
list = _ref.list,
|
||||||
type = _ref.type,
|
type = _ref.type,
|
||||||
@ -7038,17 +7040,21 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
type: 'button',
|
type: 'button',
|
||||||
role: 'menuitemradio',
|
role: 'menuitemradio',
|
||||||
class: (this.config.classNames.control + ' ' + (attributes.class ? attributes.class : '')).trim(),
|
class: (this.config.classNames.control + ' ' + (attributes.class ? attributes.class : '')).trim(),
|
||||||
value: value,
|
'aria-checked': checked,
|
||||||
'aria-checked': checked
|
value: value
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
var flex = createElement('span');
|
||||||
|
|
||||||
// We have to set as HTML incase of special characters
|
// We have to set as HTML incase of special characters
|
||||||
item.innerHTML = title;
|
flex.innerHTML = title;
|
||||||
|
|
||||||
if (is$1.element(badge)) {
|
if (is$1.element(badge)) {
|
||||||
item.appendChild(badge);
|
flex.appendChild(badge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item.appendChild(flex);
|
||||||
|
|
||||||
Object.defineProperty(item, 'checked', {
|
Object.defineProperty(item, 'checked', {
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
get: function get() {
|
get: function get() {
|
||||||
@ -7068,6 +7074,29 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.listeners.bind(item, 'click', function () {
|
||||||
|
item.checked = true;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'language':
|
||||||
|
_this.currentTrack = Number(value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'quality':
|
||||||
|
_this.quality = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'speed':
|
||||||
|
_this.speed = parseFloat(value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
controls.showMenuPanel.call(_this, 'home');
|
||||||
|
}, type);
|
||||||
|
|
||||||
list.appendChild(item);
|
list.appendChild(item);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -7141,7 +7170,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Update <progress> elements
|
// Update <progress> elements
|
||||||
updateProgress: function updateProgress(event) {
|
updateProgress: function updateProgress(event) {
|
||||||
var _this = this;
|
var _this2 = this;
|
||||||
|
|
||||||
if (!this.supported.ui || !is$1.event(event)) {
|
if (!this.supported.ui || !is$1.event(event)) {
|
||||||
return;
|
return;
|
||||||
@ -7151,7 +7180,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
var setProgress = function setProgress(target, input) {
|
var setProgress = function setProgress(target, input) {
|
||||||
var value = is$1.number(input) ? input : 0;
|
var value = is$1.number(input) ? input : 0;
|
||||||
var progress = is$1.element(target) ? target : _this.elements.display.buffer;
|
var progress = is$1.element(target) ? target : _this2.elements.display.buffer;
|
||||||
|
|
||||||
// Update value and label
|
// Update value and label
|
||||||
if (is$1.element(progress)) {
|
if (is$1.element(progress)) {
|
||||||
@ -7231,7 +7260,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Update hover tooltip for seeking
|
// Update hover tooltip for seeking
|
||||||
updateSeekTooltip: function updateSeekTooltip(event) {
|
updateSeekTooltip: function updateSeekTooltip(event) {
|
||||||
var _this2 = this;
|
var _this3 = this;
|
||||||
|
|
||||||
// Bail if setting not true
|
// Bail if setting not true
|
||||||
if (!this.config.tooltips.seek || !is$1.element(this.elements.inputs.seek) || !is$1.element(this.elements.display.seekTooltip) || this.duration === 0) {
|
if (!this.config.tooltips.seek || !is$1.element(this.elements.inputs.seek) || !is$1.element(this.elements.display.seekTooltip) || this.duration === 0) {
|
||||||
@ -7244,7 +7273,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
var visible = this.config.classNames.tooltip + '--visible';
|
var visible = this.config.classNames.tooltip + '--visible';
|
||||||
|
|
||||||
var toggle = function toggle(_toggle) {
|
var toggle = function toggle(_toggle) {
|
||||||
toggleClass(_this2.elements.display.seekTooltip, visible, _toggle);
|
toggleClass(_this3.elements.display.seekTooltip, visible, _toggle);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hide on touch
|
// Hide on touch
|
||||||
@ -7337,99 +7366,6 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
// Set the quality menu
|
|
||||||
setQualityMenu: function setQualityMenu(options) {
|
|
||||||
var _this3 = this;
|
|
||||||
|
|
||||||
// Menu required
|
|
||||||
if (!is$1.element(this.elements.settings.panels.quality)) {
|
|
||||||
console.warn('Not an element');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var type = 'quality';
|
|
||||||
var list = this.elements.settings.panels.quality.querySelector('[role="menu"]');
|
|
||||||
|
|
||||||
// Set options if passed and filter based on uniqueness and config
|
|
||||||
if (is$1.array(options)) {
|
|
||||||
this.options.quality = dedupe(options).filter(function (quality) {
|
|
||||||
return _this3.config.quality.options.includes(quality);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggle the pane and tab
|
|
||||||
console.warn(this.options.quality);
|
|
||||||
var toggle = !is$1.empty(this.options.quality) && this.options.quality.length > 1;
|
|
||||||
controls.toggleMenuButton.call(this, type, toggle);
|
|
||||||
|
|
||||||
// Check if we need to toggle the parent
|
|
||||||
controls.checkMenu.call(this);
|
|
||||||
|
|
||||||
// If we're hiding, nothing more to do
|
|
||||||
if (!toggle) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Empty the menu
|
|
||||||
emptyElement(list);
|
|
||||||
|
|
||||||
// Get the badge HTML for HD, 4K etc
|
|
||||||
var getBadge = function getBadge(quality) {
|
|
||||||
var label = i18n.get('qualityBadge.' + quality, _this3.config);
|
|
||||||
|
|
||||||
if (!label.length) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return controls.createBadge.call(_this3, label);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Sort options by the config and then render options
|
|
||||||
this.options.quality.sort(function (a, b) {
|
|
||||||
var sorting = _this3.config.quality.options;
|
|
||||||
return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1;
|
|
||||||
}).forEach(function (quality) {
|
|
||||||
controls.createMenuItem.call(_this3, {
|
|
||||||
value: quality,
|
|
||||||
list: list,
|
|
||||||
type: type,
|
|
||||||
title: controls.getLabel.call(_this3, 'quality', quality),
|
|
||||||
badge: getBadge(quality)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
controls.updateSetting.call(this, type, list);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// Translate a value into a nice label
|
|
||||||
getLabel: function getLabel(setting, value) {
|
|
||||||
switch (setting) {
|
|
||||||
case 'speed':
|
|
||||||
return value === 1 ? i18n.get('normal', this.config) : value + '×';
|
|
||||||
|
|
||||||
case 'quality':
|
|
||||||
if (is$1.number(value)) {
|
|
||||||
var label = i18n.get('qualityLabel.' + value, this.config);
|
|
||||||
|
|
||||||
if (!label.length) {
|
|
||||||
return value + 'p';
|
|
||||||
}
|
|
||||||
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
return toTitleCase(value);
|
|
||||||
|
|
||||||
case 'captions':
|
|
||||||
return captions.getLabel.call(this);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// Update the selected setting
|
// Update the selected setting
|
||||||
updateSetting: function updateSetting(setting, container, input) {
|
updateSetting: function updateSetting(setting, container, input) {
|
||||||
var pane = this.elements.settings.panels[setting];
|
var pane = this.elements.settings.panels[setting];
|
||||||
@ -7482,6 +7418,97 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// Translate a value into a nice label
|
||||||
|
getLabel: function getLabel(setting, value) {
|
||||||
|
switch (setting) {
|
||||||
|
case 'speed':
|
||||||
|
return value === 1 ? i18n.get('normal', this.config) : value + '×';
|
||||||
|
|
||||||
|
case 'quality':
|
||||||
|
if (is$1.number(value)) {
|
||||||
|
var label = i18n.get('qualityLabel.' + value, this.config);
|
||||||
|
|
||||||
|
if (!label.length) {
|
||||||
|
return value + 'p';
|
||||||
|
}
|
||||||
|
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
return toTitleCase(value);
|
||||||
|
|
||||||
|
case 'captions':
|
||||||
|
return captions.getLabel.call(this);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// Set the quality menu
|
||||||
|
setQualityMenu: function setQualityMenu(options) {
|
||||||
|
var _this4 = this;
|
||||||
|
|
||||||
|
// Menu required
|
||||||
|
if (!is$1.element(this.elements.settings.panels.quality)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var type = 'quality';
|
||||||
|
var list = this.elements.settings.panels.quality.querySelector('[role="menu"]');
|
||||||
|
|
||||||
|
// Set options if passed and filter based on uniqueness and config
|
||||||
|
if (is$1.array(options)) {
|
||||||
|
this.options.quality = dedupe(options).filter(function (quality) {
|
||||||
|
return _this4.config.quality.options.includes(quality);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle the pane and tab
|
||||||
|
var toggle = !is$1.empty(this.options.quality) && this.options.quality.length > 1;
|
||||||
|
controls.toggleMenuButton.call(this, type, toggle);
|
||||||
|
|
||||||
|
// Empty the menu
|
||||||
|
emptyElement(list);
|
||||||
|
|
||||||
|
// Check if we need to toggle the parent
|
||||||
|
controls.checkMenu.call(this);
|
||||||
|
|
||||||
|
// If we're hiding, nothing more to do
|
||||||
|
if (!toggle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the badge HTML for HD, 4K etc
|
||||||
|
var getBadge = function getBadge(quality) {
|
||||||
|
var label = i18n.get('qualityBadge.' + quality, _this4.config);
|
||||||
|
|
||||||
|
if (!label.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return controls.createBadge.call(_this4, label);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sort options by the config and then render options
|
||||||
|
this.options.quality.sort(function (a, b) {
|
||||||
|
var sorting = _this4.config.quality.options;
|
||||||
|
return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1;
|
||||||
|
}).forEach(function (quality) {
|
||||||
|
controls.createMenuItem.call(_this4, {
|
||||||
|
value: quality,
|
||||||
|
list: list,
|
||||||
|
type: type,
|
||||||
|
title: controls.getLabel.call(_this4, 'quality', quality),
|
||||||
|
badge: getBadge(quality)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
controls.updateSetting.call(this, type, list);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
// Set the looping options
|
// Set the looping options
|
||||||
/* setLoopMenu() {
|
/* setLoopMenu() {
|
||||||
// Menu required
|
// Menu required
|
||||||
@ -7523,15 +7550,21 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Set a list of available captions languages
|
// Set a list of available captions languages
|
||||||
setCaptionsMenu: function setCaptionsMenu() {
|
setCaptionsMenu: function setCaptionsMenu() {
|
||||||
var _this4 = this;
|
var _this5 = this;
|
||||||
|
|
||||||
|
// Menu required
|
||||||
|
if (!is$1.element(this.elements.settings.panels.captions)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Captions or language? Currently it's mixed
|
// TODO: Captions or language? Currently it's mixed
|
||||||
var type = 'captions';
|
var type = 'captions';
|
||||||
var list = this.elements.settings.panels.captions.querySelector('[role="menu"]');
|
var list = this.elements.settings.panels.captions.querySelector('[role="menu"]');
|
||||||
var tracks = captions.getTracks.call(this);
|
var tracks = captions.getTracks.call(this);
|
||||||
|
var toggle = Boolean(tracks.length);
|
||||||
|
|
||||||
// Toggle the pane and tab
|
// Toggle the pane and tab
|
||||||
controls.toggleMenuButton.call(this, type, tracks.length);
|
controls.toggleMenuButton.call(this, type, toggle);
|
||||||
|
|
||||||
// Empty the menu
|
// Empty the menu
|
||||||
emptyElement(list);
|
emptyElement(list);
|
||||||
@ -7540,7 +7573,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
controls.checkMenu.call(this);
|
controls.checkMenu.call(this);
|
||||||
|
|
||||||
// If there's no captions, bail
|
// If there's no captions, bail
|
||||||
if (!tracks.length) {
|
if (!toggle) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7548,9 +7581,9 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
var options = tracks.map(function (track, value) {
|
var options = tracks.map(function (track, value) {
|
||||||
return {
|
return {
|
||||||
value: value,
|
value: value,
|
||||||
checked: _this4.captions.toggled && _this4.currentTrack === value,
|
checked: _this5.captions.toggled && _this5.currentTrack === value,
|
||||||
title: captions.getLabel.call(_this4, track),
|
title: captions.getLabel.call(_this5, track),
|
||||||
badge: track.language && controls.createBadge.call(_this4, track.language.toUpperCase()),
|
badge: track.language && controls.createBadge.call(_this5, track.language.toUpperCase()),
|
||||||
list: list,
|
list: list,
|
||||||
type: 'language'
|
type: 'language'
|
||||||
};
|
};
|
||||||
@ -7574,12 +7607,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Set a list of available captions languages
|
// Set a list of available captions languages
|
||||||
setSpeedMenu: function setSpeedMenu(options) {
|
setSpeedMenu: function setSpeedMenu(options) {
|
||||||
var _this5 = this;
|
var _this6 = this;
|
||||||
|
|
||||||
// Do nothing if not selected
|
|
||||||
if (!this.config.controls.includes('settings') || !this.config.settings.includes('speed')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Menu required
|
// Menu required
|
||||||
if (!is$1.element(this.elements.settings.panels.speed)) {
|
if (!is$1.element(this.elements.settings.panels.speed)) {
|
||||||
@ -7587,6 +7615,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var type = 'speed';
|
var type = 'speed';
|
||||||
|
var list = this.elements.settings.panels.speed.querySelector('[role="menu"]');
|
||||||
|
|
||||||
// Set the speed options
|
// Set the speed options
|
||||||
if (is$1.array(options)) {
|
if (is$1.array(options)) {
|
||||||
@ -7597,13 +7626,16 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Set options if passed and filter based on config
|
// Set options if passed and filter based on config
|
||||||
this.options.speed = this.options.speed.filter(function (speed) {
|
this.options.speed = this.options.speed.filter(function (speed) {
|
||||||
return _this5.config.speed.options.includes(speed);
|
return _this6.config.speed.options.includes(speed);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Toggle the pane and tab
|
// Toggle the pane and tab
|
||||||
var toggle = !is$1.empty(this.options.speed) && this.options.speed.length > 1;
|
var toggle = !is$1.empty(this.options.speed) && this.options.speed.length > 1;
|
||||||
controls.toggleMenuButton.call(this, type, toggle);
|
controls.toggleMenuButton.call(this, type, toggle);
|
||||||
|
|
||||||
|
// Empty the menu
|
||||||
|
emptyElement(list);
|
||||||
|
|
||||||
// Check if we need to toggle the parent
|
// Check if we need to toggle the parent
|
||||||
controls.checkMenu.call(this);
|
controls.checkMenu.call(this);
|
||||||
|
|
||||||
@ -7612,19 +7644,13 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the list to populate
|
|
||||||
var list = this.elements.settings.panels.speed.querySelector('[role="menu"]');
|
|
||||||
|
|
||||||
// Empty the menu
|
|
||||||
emptyElement(list);
|
|
||||||
|
|
||||||
// Create items
|
// Create items
|
||||||
this.options.speed.forEach(function (speed) {
|
this.options.speed.forEach(function (speed) {
|
||||||
controls.createMenuItem.call(_this5, {
|
controls.createMenuItem.call(_this6, {
|
||||||
value: speed,
|
value: speed,
|
||||||
list: list,
|
list: list,
|
||||||
type: type,
|
type: type,
|
||||||
title: controls.getLabel.call(_this5, 'speed', speed)
|
title: controls.getLabel.call(_this6, 'speed', speed)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -7718,7 +7744,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Show a panel in the menu
|
// Show a panel in the menu
|
||||||
showMenuPanel: function showMenuPanel() {
|
showMenuPanel: function showMenuPanel() {
|
||||||
var _this6 = this;
|
var _this7 = this;
|
||||||
|
|
||||||
var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
||||||
|
|
||||||
@ -7756,7 +7782,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
container.style.height = '';
|
container.style.height = '';
|
||||||
|
|
||||||
// Only listen once
|
// Only listen once
|
||||||
off.call(_this6, container, transitionEndEvent, restore);
|
off.call(_this7, container, transitionEndEvent, restore);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Listen for the transition finishing and restore auto height/width
|
// Listen for the transition finishing and restore auto height/width
|
||||||
@ -7785,7 +7811,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
// Build the default HTML
|
// Build the default HTML
|
||||||
// TODO: Set order based on order in the config.controls array?
|
// TODO: Set order based on order in the config.controls array?
|
||||||
create: function create(data) {
|
create: function create(data) {
|
||||||
var _this7 = this;
|
var _this8 = this;
|
||||||
|
|
||||||
// Do nothing if we want no controls
|
// Do nothing if we want no controls
|
||||||
if (is$1.empty(this.config.controls)) {
|
if (is$1.empty(this.config.controls)) {
|
||||||
@ -7920,17 +7946,18 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Build the menu items
|
// Build the menu items
|
||||||
this.config.settings.forEach(function (type) {
|
this.config.settings.forEach(function (type) {
|
||||||
var menuItem = createElement('button', extend(getAttributesFromSelector(_this7.config.selectors.buttons.settings), {
|
var menuItem = createElement('button', extend(getAttributesFromSelector(_this8.config.selectors.buttons.settings), {
|
||||||
type: 'button',
|
type: 'button',
|
||||||
class: _this7.config.classNames.control + ' ' + _this7.config.classNames.control + '--forward',
|
class: _this8.config.classNames.control + ' ' + _this8.config.classNames.control + '--forward',
|
||||||
role: 'menuitem',
|
role: 'menuitem',
|
||||||
'aria-haspopup': true
|
'aria-haspopup': true,
|
||||||
|
hidden: ''
|
||||||
}));
|
}));
|
||||||
|
|
||||||
var flex = createElement('span', null, i18n.get(type, _this7.config));
|
var flex = createElement('span', null, i18n.get(type, _this8.config));
|
||||||
|
|
||||||
var value = createElement('span', {
|
var value = createElement('span', {
|
||||||
class: _this7.config.classNames.menu.value
|
class: _this8.config.classNames.menu.value
|
||||||
});
|
});
|
||||||
|
|
||||||
// Speed contains HTML entities
|
// Speed contains HTML entities
|
||||||
@ -7949,10 +7976,10 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
// Back button
|
// Back button
|
||||||
var back = createElement('button', {
|
var back = createElement('button', {
|
||||||
type: 'button',
|
type: 'button',
|
||||||
class: _this7.config.classNames.control + ' ' + _this7.config.classNames.control + '--back'
|
class: _this8.config.classNames.control + ' ' + _this8.config.classNames.control + '--back'
|
||||||
}, i18n.get(type, _this7.config));
|
}, i18n.get(type, _this8.config));
|
||||||
back.addEventListener('click', function () {
|
back.addEventListener('click', function () {
|
||||||
controls.showMenuPanel.call(_this7, 'home');
|
controls.showMenuPanel.call(_this8, 'home');
|
||||||
});
|
});
|
||||||
pane.appendChild(back);
|
pane.appendChild(back);
|
||||||
|
|
||||||
@ -7964,11 +7991,11 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
inner.appendChild(pane);
|
inner.appendChild(pane);
|
||||||
|
|
||||||
menuItem.addEventListener('click', function () {
|
menuItem.addEventListener('click', function () {
|
||||||
controls.showMenuPanel.call(_this7, type);
|
controls.showMenuPanel.call(_this8, type);
|
||||||
});
|
});
|
||||||
|
|
||||||
_this7.elements.settings.buttons[type] = menuItem;
|
_this8.elements.settings.buttons[type] = menuItem;
|
||||||
_this7.elements.settings.panels[type] = pane;
|
_this8.elements.settings.panels[type] = pane;
|
||||||
});
|
});
|
||||||
|
|
||||||
home.appendChild(menu);
|
home.appendChild(menu);
|
||||||
@ -8016,7 +8043,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Insert controls
|
// Insert controls
|
||||||
inject: function inject() {
|
inject: function inject() {
|
||||||
var _this8 = this;
|
var _this9 = this;
|
||||||
|
|
||||||
// Sprite
|
// Sprite
|
||||||
if (this.config.loadSprite) {
|
if (this.config.loadSprite) {
|
||||||
@ -8128,8 +8155,8 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
var labels = getElements.call(this, selector);
|
var labels = getElements.call(this, selector);
|
||||||
|
|
||||||
Array.from(labels).forEach(function (label) {
|
Array.from(labels).forEach(function (label) {
|
||||||
toggleClass(label, _this8.config.classNames.hidden, false);
|
toggleClass(label, _this9.config.classNames.hidden, false);
|
||||||
toggleClass(label, _this8.config.classNames.tooltip, true);
|
toggleClass(label, _this9.config.classNames.tooltip, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9760,7 +9787,8 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Clear timer
|
// Clear timer
|
||||||
clearTimeout(_this2.player.timers.controls);
|
clearTimeout(_this2.player.timers.controls);
|
||||||
// Timer to prevent flicker when seeking
|
|
||||||
|
// Set new timer to prevent flicker when seeking
|
||||||
_this2.player.timers.controls = setTimeout(function () {
|
_this2.player.timers.controls = setTimeout(function () {
|
||||||
return ui.toggleControls.call(_this2.player, false);
|
return ui.toggleControls.call(_this2.player, false);
|
||||||
}, delay);
|
}, delay);
|
||||||
@ -9917,124 +9945,104 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen for control events
|
// Run default and custom handlers
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: 'controls',
|
key: 'proxy',
|
||||||
value: function controls$$1() {
|
value: function proxy(event, defaultHandler, customHandlerKey) {
|
||||||
var _this4 = this;
|
var customHandler = this.player.config.listeners[customHandlerKey];
|
||||||
|
|
||||||
// IE doesn't support input event, so we fallback to change
|
|
||||||
var inputEvent = browser.isIE ? 'change' : 'input';
|
|
||||||
|
|
||||||
// Run default and custom handlers
|
|
||||||
var proxy = function proxy(event, defaultHandler, customHandlerKey) {
|
|
||||||
var customHandler = _this4.player.config.listeners[customHandlerKey];
|
|
||||||
var hasCustomHandler = is$1.function(customHandler);
|
var hasCustomHandler = is$1.function(customHandler);
|
||||||
var returned = true;
|
var returned = true;
|
||||||
|
|
||||||
// Execute custom handler
|
// Execute custom handler
|
||||||
if (hasCustomHandler) {
|
if (hasCustomHandler) {
|
||||||
returned = customHandler.call(_this4.player, event);
|
returned = customHandler.call(this.player, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only call default handler if not prevented in custom handler
|
// Only call default handler if not prevented in custom handler
|
||||||
if (returned && is$1.function(defaultHandler)) {
|
if (returned && is$1.function(defaultHandler)) {
|
||||||
defaultHandler.call(_this4.player, event);
|
defaultHandler.call(this.player, event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// Trigger custom and default handlers
|
// Trigger custom and default handlers
|
||||||
var bind = function bind(element, type, defaultHandler, customHandlerKey) {
|
|
||||||
|
}, {
|
||||||
|
key: 'bind',
|
||||||
|
value: function bind(element, type, defaultHandler, customHandlerKey) {
|
||||||
|
var _this4 = this;
|
||||||
|
|
||||||
var passive = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
|
var passive = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
|
||||||
|
|
||||||
var customHandler = _this4.player.config.listeners[customHandlerKey];
|
var customHandler = this.player.config.listeners[customHandlerKey];
|
||||||
var hasCustomHandler = is$1.function(customHandler);
|
var hasCustomHandler = is$1.function(customHandler);
|
||||||
|
|
||||||
on.call(_this4.player, element, type, function (event) {
|
on.call(this.player, element, type, function (event) {
|
||||||
return proxy(event, defaultHandler, customHandlerKey);
|
return _this4.proxy(event, defaultHandler, customHandlerKey);
|
||||||
}, passive && !hasCustomHandler);
|
}, passive && !hasCustomHandler);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// Listen for control events
|
||||||
|
|
||||||
|
}, {
|
||||||
|
key: 'controls',
|
||||||
|
value: function controls$$1() {
|
||||||
|
var _this5 = this;
|
||||||
|
|
||||||
|
// IE doesn't support input event, so we fallback to change
|
||||||
|
var inputEvent = browser.isIE ? 'change' : 'input';
|
||||||
|
|
||||||
// Play/pause toggle
|
// Play/pause toggle
|
||||||
Array.from(this.player.elements.buttons.play).forEach(function (button) {
|
Array.from(this.player.elements.buttons.play).forEach(function (button) {
|
||||||
bind(button, 'click', _this4.player.togglePlay, 'play');
|
_this5.bind(button, 'click', _this5.player.togglePlay, 'play');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Pause
|
// Pause
|
||||||
bind(this.player.elements.buttons.restart, 'click', this.player.restart, 'restart');
|
this.bind(this.player.elements.buttons.restart, 'click', this.player.restart, 'restart');
|
||||||
|
|
||||||
// Rewind
|
// Rewind
|
||||||
bind(this.player.elements.buttons.rewind, 'click', this.player.rewind, 'rewind');
|
this.bind(this.player.elements.buttons.rewind, 'click', this.player.rewind, 'rewind');
|
||||||
|
|
||||||
// Rewind
|
// Rewind
|
||||||
bind(this.player.elements.buttons.fastForward, 'click', this.player.forward, 'fastForward');
|
this.bind(this.player.elements.buttons.fastForward, 'click', this.player.forward, 'fastForward');
|
||||||
|
|
||||||
// Mute toggle
|
// Mute toggle
|
||||||
bind(this.player.elements.buttons.mute, 'click', function () {
|
this.bind(this.player.elements.buttons.mute, 'click', function () {
|
||||||
_this4.player.muted = !_this4.player.muted;
|
_this5.player.muted = !_this5.player.muted;
|
||||||
}, 'mute');
|
}, 'mute');
|
||||||
|
|
||||||
// Captions toggle
|
// Captions toggle
|
||||||
bind(this.player.elements.buttons.captions, 'click', function () {
|
this.bind(this.player.elements.buttons.captions, 'click', function () {
|
||||||
return _this4.player.toggleCaptions();
|
return _this5.player.toggleCaptions();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fullscreen toggle
|
// Fullscreen toggle
|
||||||
bind(this.player.elements.buttons.fullscreen, 'click', function () {
|
this.bind(this.player.elements.buttons.fullscreen, 'click', function () {
|
||||||
_this4.player.fullscreen.toggle();
|
_this5.player.fullscreen.toggle();
|
||||||
}, 'fullscreen');
|
}, 'fullscreen');
|
||||||
|
|
||||||
// Picture-in-Picture
|
// Picture-in-Picture
|
||||||
bind(this.player.elements.buttons.pip, 'click', function () {
|
this.bind(this.player.elements.buttons.pip, 'click', function () {
|
||||||
_this4.player.pip = 'toggle';
|
_this5.player.pip = 'toggle';
|
||||||
}, 'pip');
|
}, 'pip');
|
||||||
|
|
||||||
// Airplay
|
// Airplay
|
||||||
bind(this.player.elements.buttons.airplay, 'click', this.player.airplay, 'airplay');
|
this.bind(this.player.elements.buttons.airplay, 'click', this.player.airplay, 'airplay');
|
||||||
|
|
||||||
// Settings menu
|
// Settings menu
|
||||||
bind(this.player.elements.buttons.settings, 'click', function (event) {
|
this.bind(this.player.elements.buttons.settings, 'click', function (event) {
|
||||||
controls.toggleMenu.call(_this4.player, event);
|
controls.toggleMenu.call(_this5.player, event);
|
||||||
});
|
|
||||||
|
|
||||||
// Settings menu
|
|
||||||
bind(this.player.elements.settings.popup, 'click', function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
|
|
||||||
// Go back to home tab on click
|
|
||||||
var showHomeTab = function showHomeTab() {
|
|
||||||
controls.showMenuPanel.call(_this4.player, 'home');
|
|
||||||
};
|
|
||||||
|
|
||||||
// Settings menu items - use event delegation as items are added/removed
|
|
||||||
if (matches(event.target, _this4.player.config.selectors.inputs.language)) {
|
|
||||||
proxy(event, function () {
|
|
||||||
_this4.player.currentTrack = Number(event.target.value);
|
|
||||||
showHomeTab();
|
|
||||||
}, 'language');
|
|
||||||
} else if (matches(event.target, _this4.player.config.selectors.inputs.quality)) {
|
|
||||||
proxy(event, function () {
|
|
||||||
_this4.player.quality = event.target.value;
|
|
||||||
showHomeTab();
|
|
||||||
}, 'quality');
|
|
||||||
} else if (matches(event.target, _this4.player.config.selectors.inputs.speed)) {
|
|
||||||
proxy(event, function () {
|
|
||||||
_this4.player.speed = parseFloat(event.target.value);
|
|
||||||
showHomeTab();
|
|
||||||
}, 'speed');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set range input alternative "value", which matches the tooltip time (#954)
|
// Set range input alternative "value", which matches the tooltip time (#954)
|
||||||
bind(this.player.elements.inputs.seek, 'mousedown mousemove', function (event) {
|
this.bind(this.player.elements.inputs.seek, 'mousedown mousemove', function (event) {
|
||||||
var clientRect = _this4.player.elements.progress.getBoundingClientRect();
|
var clientRect = _this5.player.elements.progress.getBoundingClientRect();
|
||||||
var percent = 100 / clientRect.width * (event.pageX - clientRect.left);
|
var percent = 100 / clientRect.width * (event.pageX - clientRect.left);
|
||||||
event.currentTarget.setAttribute('seek-value', percent);
|
event.currentTarget.setAttribute('seek-value', percent);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Pause while seeking
|
// Pause while seeking
|
||||||
bind(this.player.elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', function (event) {
|
this.bind(this.player.elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', function (event) {
|
||||||
var seek = event.currentTarget;
|
var seek = event.currentTarget;
|
||||||
|
|
||||||
var code = event.keyCode ? event.keyCode : event.which;
|
var code = event.keyCode ? event.keyCode : event.which;
|
||||||
@ -10052,15 +10060,15 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
// If we're done seeking and it was playing, resume playback
|
// If we're done seeking and it was playing, resume playback
|
||||||
if (play && done) {
|
if (play && done) {
|
||||||
seek.removeAttribute('play-on-seeked');
|
seek.removeAttribute('play-on-seeked');
|
||||||
_this4.player.play();
|
_this5.player.play();
|
||||||
} else if (!done && _this4.player.playing) {
|
} else if (!done && _this5.player.playing) {
|
||||||
seek.setAttribute('play-on-seeked', '');
|
seek.setAttribute('play-on-seeked', '');
|
||||||
_this4.player.pause();
|
_this5.player.pause();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Seek
|
// Seek
|
||||||
bind(this.player.elements.inputs.seek, inputEvent, function (event) {
|
this.bind(this.player.elements.inputs.seek, inputEvent, function (event) {
|
||||||
var seek = event.currentTarget;
|
var seek = event.currentTarget;
|
||||||
|
|
||||||
// If it exists, use seek-value instead of "value" for consistency with tooltip time (#954)
|
// If it exists, use seek-value instead of "value" for consistency with tooltip time (#954)
|
||||||
@ -10072,56 +10080,56 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
seek.removeAttribute('seek-value');
|
seek.removeAttribute('seek-value');
|
||||||
|
|
||||||
_this4.player.currentTime = seekTo / seek.max * _this4.player.duration;
|
_this5.player.currentTime = seekTo / seek.max * _this5.player.duration;
|
||||||
}, 'seek');
|
}, 'seek');
|
||||||
|
|
||||||
// Current time invert
|
// Current time invert
|
||||||
// Only if one time element is used for both currentTime and duration
|
// Only if one time element is used for both currentTime and duration
|
||||||
if (this.player.config.toggleInvert && !is$1.element(this.player.elements.display.duration)) {
|
if (this.player.config.toggleInvert && !is$1.element(this.player.elements.display.duration)) {
|
||||||
bind(this.player.elements.display.currentTime, 'click', function () {
|
this.bind(this.player.elements.display.currentTime, 'click', function () {
|
||||||
// Do nothing if we're at the start
|
// Do nothing if we're at the start
|
||||||
if (_this4.player.currentTime === 0) {
|
if (_this5.player.currentTime === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_this4.player.config.invertTime = !_this4.player.config.invertTime;
|
_this5.player.config.invertTime = !_this5.player.config.invertTime;
|
||||||
|
|
||||||
controls.timeUpdate.call(_this4.player);
|
controls.timeUpdate.call(_this5.player);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Volume
|
// Volume
|
||||||
bind(this.player.elements.inputs.volume, inputEvent, function (event) {
|
this.bind(this.player.elements.inputs.volume, inputEvent, function (event) {
|
||||||
_this4.player.volume = event.target.value;
|
_this5.player.volume = event.target.value;
|
||||||
}, 'volume');
|
}, 'volume');
|
||||||
|
|
||||||
// Polyfill for lower fill in <input type="range"> for webkit
|
// Polyfill for lower fill in <input type="range"> for webkit
|
||||||
if (browser.isWebkit) {
|
if (browser.isWebkit) {
|
||||||
Array.from(getElements.call(this.player, 'input[type="range"]')).forEach(function (element) {
|
Array.from(getElements.call(this.player, 'input[type="range"]')).forEach(function (element) {
|
||||||
bind(element, 'input', function (event) {
|
_this5.bind(element, 'input', function (event) {
|
||||||
return controls.updateRangeFill.call(_this4.player, event.target);
|
return controls.updateRangeFill.call(_this5.player, event.target);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seek tooltip
|
// Seek tooltip
|
||||||
bind(this.player.elements.progress, 'mouseenter mouseleave mousemove', function (event) {
|
this.bind(this.player.elements.progress, 'mouseenter mouseleave mousemove', function (event) {
|
||||||
return controls.updateSeekTooltip.call(_this4.player, event);
|
return controls.updateSeekTooltip.call(_this5.player, event);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting)
|
// Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting)
|
||||||
bind(this.player.elements.controls, 'mouseenter mouseleave', function (event) {
|
this.bind(this.player.elements.controls, 'mouseenter mouseleave', function (event) {
|
||||||
_this4.player.elements.controls.hover = !_this4.player.touch && event.type === 'mouseenter';
|
_this5.player.elements.controls.hover = !_this5.player.touch && event.type === 'mouseenter';
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)
|
// Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)
|
||||||
bind(this.player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', function (event) {
|
this.bind(this.player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', function (event) {
|
||||||
_this4.player.elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);
|
_this5.player.elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Focus in/out on controls
|
// Focus in/out on controls
|
||||||
bind(this.player.elements.controls, 'focusin focusout', function (event) {
|
this.bind(this.player.elements.controls, 'focusin focusout', function (event) {
|
||||||
var _player = _this4.player,
|
var _player = _this5.player,
|
||||||
config = _player.config,
|
config = _player.config,
|
||||||
elements = _player.elements,
|
elements = _player.elements,
|
||||||
timers = _player.timers;
|
timers = _player.timers;
|
||||||
@ -10131,7 +10139,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
toggleClass(elements.controls, config.classNames.noTransition, event.type === 'focusin');
|
toggleClass(elements.controls, config.classNames.noTransition, event.type === 'focusin');
|
||||||
|
|
||||||
// Toggle
|
// Toggle
|
||||||
ui.toggleControls.call(_this4.player, event.type === 'focusin');
|
ui.toggleControls.call(_this5.player, event.type === 'focusin');
|
||||||
|
|
||||||
// If focusin, hide again after delay
|
// If focusin, hide again after delay
|
||||||
if (event.type === 'focusin') {
|
if (event.type === 'focusin') {
|
||||||
@ -10141,19 +10149,19 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
// Delay a little more for keyboard users
|
// Delay a little more for keyboard users
|
||||||
var delay = _this4.touch ? 3000 : 4000;
|
var delay = _this5.touch ? 3000 : 4000;
|
||||||
|
|
||||||
// Clear timer
|
// Clear timer
|
||||||
clearTimeout(timers.controls);
|
clearTimeout(timers.controls);
|
||||||
// Hide
|
// Hide
|
||||||
timers.controls = setTimeout(function () {
|
timers.controls = setTimeout(function () {
|
||||||
return ui.toggleControls.call(_this4.player, false);
|
return ui.toggleControls.call(_this5.player, false);
|
||||||
}, delay);
|
}, delay);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Mouse wheel for volume
|
// Mouse wheel for volume
|
||||||
bind(this.player.elements.inputs.volume, 'wheel', function (event) {
|
this.bind(this.player.elements.inputs.volume, 'wheel', function (event) {
|
||||||
// Detect "natural" scroll - suppored on OS X Safari only
|
// Detect "natural" scroll - suppored on OS X Safari only
|
||||||
// Other browsers on OS X will be inverted until support improves
|
// Other browsers on OS X will be inverted until support improves
|
||||||
var inverted = event.webkitDirectionInvertedFromDevice;
|
var inverted = event.webkitDirectionInvertedFromDevice;
|
||||||
@ -10163,10 +10171,10 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
// Scroll down (or up on natural) to decrease
|
// Scroll down (or up on natural) to decrease
|
||||||
if (event.deltaY < 0 || event.deltaX > 0) {
|
if (event.deltaY < 0 || event.deltaX > 0) {
|
||||||
if (inverted) {
|
if (inverted) {
|
||||||
_this4.player.decreaseVolume(step);
|
_this5.player.decreaseVolume(step);
|
||||||
direction = -1;
|
direction = -1;
|
||||||
} else {
|
} else {
|
||||||
_this4.player.increaseVolume(step);
|
_this5.player.increaseVolume(step);
|
||||||
direction = 1;
|
direction = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10174,16 +10182,16 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
// Scroll up (or down on natural) to increase
|
// Scroll up (or down on natural) to increase
|
||||||
if (event.deltaY > 0 || event.deltaX < 0) {
|
if (event.deltaY > 0 || event.deltaX < 0) {
|
||||||
if (inverted) {
|
if (inverted) {
|
||||||
_this4.player.increaseVolume(step);
|
_this5.player.increaseVolume(step);
|
||||||
direction = 1;
|
direction = 1;
|
||||||
} else {
|
} else {
|
||||||
_this4.player.decreaseVolume(step);
|
_this5.player.decreaseVolume(step);
|
||||||
direction = -1;
|
direction = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't break page scrolling at max and min
|
// Don't break page scrolling at max and min
|
||||||
if (direction === 1 && _this4.player.media.volume < 1 || direction === -1 && _this4.player.media.volume > 0) {
|
if (direction === 1 && _this5.player.media.volume < 1 || direction === -1 && _this5.player.media.volume > 0) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
}, 'volume', false);
|
}, 'volume', false);
|
||||||
|
2
dist/plyr.polyfilled.js.map
vendored
2
dist/plyr.polyfilled.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.polyfilled.min.js
vendored
2
dist/plyr.polyfilled.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.polyfilled.min.js.map
vendored
2
dist/plyr.polyfilled.min.js.map
vendored
File diff suppressed because one or more lines are too long
243
src/js/controls.js
vendored
243
src/js/controls.js
vendored
@ -370,18 +370,22 @@ const controls = {
|
|||||||
type: 'button',
|
type: 'button',
|
||||||
role: 'menuitemradio',
|
role: 'menuitemradio',
|
||||||
class: `${this.config.classNames.control} ${attributes.class ? attributes.class : ''}`.trim(),
|
class: `${this.config.classNames.control} ${attributes.class ? attributes.class : ''}`.trim(),
|
||||||
value,
|
|
||||||
'aria-checked': checked,
|
'aria-checked': checked,
|
||||||
})
|
value,
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const flex = createElement('span');
|
||||||
|
|
||||||
// We have to set as HTML incase of special characters
|
// We have to set as HTML incase of special characters
|
||||||
item.innerHTML = title;
|
flex.innerHTML = title;
|
||||||
|
|
||||||
if (is.element(badge)) {
|
if (is.element(badge)) {
|
||||||
item.appendChild(badge);
|
flex.appendChild(badge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item.appendChild(flex);
|
||||||
|
|
||||||
Object.defineProperty(item, 'checked', {
|
Object.defineProperty(item, 'checked', {
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
get() {
|
get() {
|
||||||
@ -399,6 +403,34 @@ const controls = {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.listeners.bind(
|
||||||
|
item,
|
||||||
|
'click',
|
||||||
|
() => {
|
||||||
|
item.checked = true;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'language':
|
||||||
|
this.currentTrack = Number(value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'quality':
|
||||||
|
this.quality = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'speed':
|
||||||
|
this.speed = parseFloat(value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
controls.showMenuPanel.call(this, 'home');
|
||||||
|
},
|
||||||
|
type,
|
||||||
|
);
|
||||||
|
|
||||||
list.appendChild(item);
|
list.appendChild(item);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -657,95 +689,6 @@ const controls = {
|
|||||||
toggleHidden(this.elements.settings.buttons[setting], !toggle);
|
toggleHidden(this.elements.settings.buttons[setting], !toggle);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Set the quality menu
|
|
||||||
setQualityMenu(options) {
|
|
||||||
// Menu required
|
|
||||||
if (!is.element(this.elements.settings.panels.quality)) {
|
|
||||||
console.warn('Not an element');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const type = 'quality';
|
|
||||||
const list = this.elements.settings.panels.quality.querySelector('[role="menu"]');
|
|
||||||
|
|
||||||
// Set options if passed and filter based on uniqueness and config
|
|
||||||
if (is.array(options)) {
|
|
||||||
this.options.quality = dedupe(options).filter(quality => this.config.quality.options.includes(quality));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggle the pane and tab
|
|
||||||
console.warn(this.options.quality);
|
|
||||||
const toggle = !is.empty(this.options.quality) && this.options.quality.length > 1;
|
|
||||||
controls.toggleMenuButton.call(this, type, toggle);
|
|
||||||
|
|
||||||
// Check if we need to toggle the parent
|
|
||||||
controls.checkMenu.call(this);
|
|
||||||
|
|
||||||
// If we're hiding, nothing more to do
|
|
||||||
if (!toggle) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Empty the menu
|
|
||||||
emptyElement(list);
|
|
||||||
|
|
||||||
// Get the badge HTML for HD, 4K etc
|
|
||||||
const getBadge = quality => {
|
|
||||||
const label = i18n.get(`qualityBadge.${quality}`, this.config);
|
|
||||||
|
|
||||||
if (!label.length) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return controls.createBadge.call(this, label);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Sort options by the config and then render options
|
|
||||||
this.options.quality
|
|
||||||
.sort((a, b) => {
|
|
||||||
const sorting = this.config.quality.options;
|
|
||||||
return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1;
|
|
||||||
})
|
|
||||||
.forEach(quality => {
|
|
||||||
controls.createMenuItem.call(this, {
|
|
||||||
value: quality,
|
|
||||||
list,
|
|
||||||
type,
|
|
||||||
title: controls.getLabel.call(this, 'quality', quality),
|
|
||||||
badge: getBadge(quality),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
controls.updateSetting.call(this, type, list);
|
|
||||||
},
|
|
||||||
|
|
||||||
// Translate a value into a nice label
|
|
||||||
getLabel(setting, value) {
|
|
||||||
switch (setting) {
|
|
||||||
case 'speed':
|
|
||||||
return value === 1 ? i18n.get('normal', this.config) : `${value}×`;
|
|
||||||
|
|
||||||
case 'quality':
|
|
||||||
if (is.number(value)) {
|
|
||||||
const label = i18n.get(`qualityLabel.${value}`, this.config);
|
|
||||||
|
|
||||||
if (!label.length) {
|
|
||||||
return `${value}p`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
return toTitleCase(value);
|
|
||||||
|
|
||||||
case 'captions':
|
|
||||||
return captions.getLabel.call(this);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Update the selected setting
|
// Update the selected setting
|
||||||
updateSetting(setting, container, input) {
|
updateSetting(setting, container, input) {
|
||||||
const pane = this.elements.settings.panels[setting];
|
const pane = this.elements.settings.panels[setting];
|
||||||
@ -797,6 +740,93 @@ const controls = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Translate a value into a nice label
|
||||||
|
getLabel(setting, value) {
|
||||||
|
switch (setting) {
|
||||||
|
case 'speed':
|
||||||
|
return value === 1 ? i18n.get('normal', this.config) : `${value}×`;
|
||||||
|
|
||||||
|
case 'quality':
|
||||||
|
if (is.number(value)) {
|
||||||
|
const label = i18n.get(`qualityLabel.${value}`, this.config);
|
||||||
|
|
||||||
|
if (!label.length) {
|
||||||
|
return `${value}p`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
return toTitleCase(value);
|
||||||
|
|
||||||
|
case 'captions':
|
||||||
|
return captions.getLabel.call(this);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Set the quality menu
|
||||||
|
setQualityMenu(options) {
|
||||||
|
// Menu required
|
||||||
|
if (!is.element(this.elements.settings.panels.quality)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const type = 'quality';
|
||||||
|
const list = this.elements.settings.panels.quality.querySelector('[role="menu"]');
|
||||||
|
|
||||||
|
// Set options if passed and filter based on uniqueness and config
|
||||||
|
if (is.array(options)) {
|
||||||
|
this.options.quality = dedupe(options).filter(quality => this.config.quality.options.includes(quality));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle the pane and tab
|
||||||
|
const toggle = !is.empty(this.options.quality) && this.options.quality.length > 1;
|
||||||
|
controls.toggleMenuButton.call(this, type, toggle);
|
||||||
|
|
||||||
|
// Empty the menu
|
||||||
|
emptyElement(list);
|
||||||
|
|
||||||
|
// Check if we need to toggle the parent
|
||||||
|
controls.checkMenu.call(this);
|
||||||
|
|
||||||
|
// If we're hiding, nothing more to do
|
||||||
|
if (!toggle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the badge HTML for HD, 4K etc
|
||||||
|
const getBadge = quality => {
|
||||||
|
const label = i18n.get(`qualityBadge.${quality}`, this.config);
|
||||||
|
|
||||||
|
if (!label.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return controls.createBadge.call(this, label);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sort options by the config and then render options
|
||||||
|
this.options.quality
|
||||||
|
.sort((a, b) => {
|
||||||
|
const sorting = this.config.quality.options;
|
||||||
|
return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1;
|
||||||
|
})
|
||||||
|
.forEach(quality => {
|
||||||
|
controls.createMenuItem.call(this, {
|
||||||
|
value: quality,
|
||||||
|
list,
|
||||||
|
type,
|
||||||
|
title: controls.getLabel.call(this, 'quality', quality),
|
||||||
|
badge: getBadge(quality),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
controls.updateSetting.call(this, type, list);
|
||||||
|
},
|
||||||
|
|
||||||
// Set the looping options
|
// Set the looping options
|
||||||
/* setLoopMenu() {
|
/* setLoopMenu() {
|
||||||
// Menu required
|
// Menu required
|
||||||
@ -846,13 +876,19 @@ const controls = {
|
|||||||
|
|
||||||
// Set a list of available captions languages
|
// Set a list of available captions languages
|
||||||
setCaptionsMenu() {
|
setCaptionsMenu() {
|
||||||
|
// Menu required
|
||||||
|
if (!is.element(this.elements.settings.panels.captions)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Captions or language? Currently it's mixed
|
// TODO: Captions or language? Currently it's mixed
|
||||||
const type = 'captions';
|
const type = 'captions';
|
||||||
const list = this.elements.settings.panels.captions.querySelector('[role="menu"]');
|
const list = this.elements.settings.panels.captions.querySelector('[role="menu"]');
|
||||||
const tracks = captions.getTracks.call(this);
|
const tracks = captions.getTracks.call(this);
|
||||||
|
const toggle = Boolean(tracks.length);
|
||||||
|
|
||||||
// Toggle the pane and tab
|
// Toggle the pane and tab
|
||||||
controls.toggleMenuButton.call(this, type, tracks.length);
|
controls.toggleMenuButton.call(this, type, toggle);
|
||||||
|
|
||||||
// Empty the menu
|
// Empty the menu
|
||||||
emptyElement(list);
|
emptyElement(list);
|
||||||
@ -861,7 +897,7 @@ const controls = {
|
|||||||
controls.checkMenu.call(this);
|
controls.checkMenu.call(this);
|
||||||
|
|
||||||
// If there's no captions, bail
|
// If there's no captions, bail
|
||||||
if (!tracks.length) {
|
if (!toggle) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -892,17 +928,13 @@ const controls = {
|
|||||||
|
|
||||||
// Set a list of available captions languages
|
// Set a list of available captions languages
|
||||||
setSpeedMenu(options) {
|
setSpeedMenu(options) {
|
||||||
// Do nothing if not selected
|
|
||||||
if (!this.config.controls.includes('settings') || !this.config.settings.includes('speed')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Menu required
|
// Menu required
|
||||||
if (!is.element(this.elements.settings.panels.speed)) {
|
if (!is.element(this.elements.settings.panels.speed)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const type = 'speed';
|
const type = 'speed';
|
||||||
|
const list = this.elements.settings.panels.speed.querySelector('[role="menu"]');
|
||||||
|
|
||||||
// Set the speed options
|
// Set the speed options
|
||||||
if (is.array(options)) {
|
if (is.array(options)) {
|
||||||
@ -918,6 +950,9 @@ const controls = {
|
|||||||
const toggle = !is.empty(this.options.speed) && this.options.speed.length > 1;
|
const toggle = !is.empty(this.options.speed) && this.options.speed.length > 1;
|
||||||
controls.toggleMenuButton.call(this, type, toggle);
|
controls.toggleMenuButton.call(this, type, toggle);
|
||||||
|
|
||||||
|
// Empty the menu
|
||||||
|
emptyElement(list);
|
||||||
|
|
||||||
// Check if we need to toggle the parent
|
// Check if we need to toggle the parent
|
||||||
controls.checkMenu.call(this);
|
controls.checkMenu.call(this);
|
||||||
|
|
||||||
@ -926,12 +961,6 @@ const controls = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the list to populate
|
|
||||||
const list = this.elements.settings.panels.speed.querySelector('[role="menu"]');
|
|
||||||
|
|
||||||
// Empty the menu
|
|
||||||
emptyElement(list);
|
|
||||||
|
|
||||||
// Create items
|
// Create items
|
||||||
this.options.speed.forEach(speed => {
|
this.options.speed.forEach(speed => {
|
||||||
controls.createMenuItem.call(this, {
|
controls.createMenuItem.call(this, {
|
||||||
@ -1069,7 +1098,6 @@ const controls = {
|
|||||||
|
|
||||||
// Set attributes on current tab
|
// Set attributes on current tab
|
||||||
toggleHidden(current, true);
|
toggleHidden(current, true);
|
||||||
// current.setAttribute('tabindex', -1);
|
|
||||||
|
|
||||||
// Set attributes on target
|
// Set attributes on target
|
||||||
toggleHidden(target, false);
|
toggleHidden(target, false);
|
||||||
@ -1238,6 +1266,7 @@ const controls = {
|
|||||||
class: `${this.config.classNames.control} ${this.config.classNames.control}--forward`,
|
class: `${this.config.classNames.control} ${this.config.classNames.control}--forward`,
|
||||||
role: 'menuitem',
|
role: 'menuitem',
|
||||||
'aria-haspopup': true,
|
'aria-haspopup': true,
|
||||||
|
hidden: '',
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -243,7 +243,8 @@ class Listeners {
|
|||||||
|
|
||||||
// Clear timer
|
// Clear timer
|
||||||
clearTimeout(this.player.timers.controls);
|
clearTimeout(this.player.timers.controls);
|
||||||
// Timer to prevent flicker when seeking
|
|
||||||
|
// Set new timer to prevent flicker when seeking
|
||||||
this.player.timers.controls = setTimeout(() => ui.toggleControls.call(this.player, false), delay);
|
this.player.timers.controls = setTimeout(() => ui.toggleControls.call(this.player, false), delay);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -394,13 +395,8 @@ class Listeners {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen for control events
|
|
||||||
controls() {
|
|
||||||
// IE doesn't support input event, so we fallback to change
|
|
||||||
const inputEvent = browser.isIE ? 'change' : 'input';
|
|
||||||
|
|
||||||
// Run default and custom handlers
|
// Run default and custom handlers
|
||||||
const proxy = (event, defaultHandler, customHandlerKey) => {
|
proxy(event, defaultHandler, customHandlerKey) {
|
||||||
const customHandler = this.player.config.listeners[customHandlerKey];
|
const customHandler = this.player.config.listeners[customHandlerKey];
|
||||||
const hasCustomHandler = is.function(customHandler);
|
const hasCustomHandler = is.function(customHandler);
|
||||||
let returned = true;
|
let returned = true;
|
||||||
@ -414,10 +410,10 @@ class Listeners {
|
|||||||
if (returned && is.function(defaultHandler)) {
|
if (returned && is.function(defaultHandler)) {
|
||||||
defaultHandler.call(this.player, event);
|
defaultHandler.call(this.player, event);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
// Trigger custom and default handlers
|
// Trigger custom and default handlers
|
||||||
const bind = (element, type, defaultHandler, customHandlerKey, passive = true) => {
|
bind(element, type, defaultHandler, customHandlerKey, passive = true) {
|
||||||
const customHandler = this.player.config.listeners[customHandlerKey];
|
const customHandler = this.player.config.listeners[customHandlerKey];
|
||||||
const hasCustomHandler = is.function(customHandler);
|
const hasCustomHandler = is.function(customHandler);
|
||||||
|
|
||||||
@ -425,27 +421,32 @@ class Listeners {
|
|||||||
this.player,
|
this.player,
|
||||||
element,
|
element,
|
||||||
type,
|
type,
|
||||||
event => proxy(event, defaultHandler, customHandlerKey),
|
event => this.proxy(event, defaultHandler, customHandlerKey),
|
||||||
passive && !hasCustomHandler,
|
passive && !hasCustomHandler,
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// Listen for control events
|
||||||
|
controls() {
|
||||||
|
// IE doesn't support input event, so we fallback to change
|
||||||
|
const inputEvent = browser.isIE ? 'change' : 'input';
|
||||||
|
|
||||||
// Play/pause toggle
|
// Play/pause toggle
|
||||||
Array.from(this.player.elements.buttons.play).forEach(button => {
|
Array.from(this.player.elements.buttons.play).forEach(button => {
|
||||||
bind(button, 'click', this.player.togglePlay, 'play');
|
this.bind(button, 'click', this.player.togglePlay, 'play');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Pause
|
// Pause
|
||||||
bind(this.player.elements.buttons.restart, 'click', this.player.restart, 'restart');
|
this.bind(this.player.elements.buttons.restart, 'click', this.player.restart, 'restart');
|
||||||
|
|
||||||
// Rewind
|
// Rewind
|
||||||
bind(this.player.elements.buttons.rewind, 'click', this.player.rewind, 'rewind');
|
this.bind(this.player.elements.buttons.rewind, 'click', this.player.rewind, 'rewind');
|
||||||
|
|
||||||
// Rewind
|
// Rewind
|
||||||
bind(this.player.elements.buttons.fastForward, 'click', this.player.forward, 'fastForward');
|
this.bind(this.player.elements.buttons.fastForward, 'click', this.player.forward, 'fastForward');
|
||||||
|
|
||||||
// Mute toggle
|
// Mute toggle
|
||||||
bind(
|
this.bind(
|
||||||
this.player.elements.buttons.mute,
|
this.player.elements.buttons.mute,
|
||||||
'click',
|
'click',
|
||||||
() => {
|
() => {
|
||||||
@ -455,10 +456,10 @@ class Listeners {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Captions toggle
|
// Captions toggle
|
||||||
bind(this.player.elements.buttons.captions, 'click', () => this.player.toggleCaptions());
|
this.bind(this.player.elements.buttons.captions, 'click', () => this.player.toggleCaptions());
|
||||||
|
|
||||||
// Fullscreen toggle
|
// Fullscreen toggle
|
||||||
bind(
|
this.bind(
|
||||||
this.player.elements.buttons.fullscreen,
|
this.player.elements.buttons.fullscreen,
|
||||||
'click',
|
'click',
|
||||||
() => {
|
() => {
|
||||||
@ -468,7 +469,7 @@ class Listeners {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Picture-in-Picture
|
// Picture-in-Picture
|
||||||
bind(
|
this.bind(
|
||||||
this.player.elements.buttons.pip,
|
this.player.elements.buttons.pip,
|
||||||
'click',
|
'click',
|
||||||
() => {
|
() => {
|
||||||
@ -478,62 +479,22 @@ class Listeners {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Airplay
|
// Airplay
|
||||||
bind(this.player.elements.buttons.airplay, 'click', this.player.airplay, 'airplay');
|
this.bind(this.player.elements.buttons.airplay, 'click', this.player.airplay, 'airplay');
|
||||||
|
|
||||||
// Settings menu
|
// Settings menu
|
||||||
bind(this.player.elements.buttons.settings, 'click', event => {
|
this.bind(this.player.elements.buttons.settings, 'click', event => {
|
||||||
controls.toggleMenu.call(this.player, event);
|
controls.toggleMenu.call(this.player, event);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Settings menu
|
|
||||||
bind(this.player.elements.settings.popup, 'click', event => {
|
|
||||||
event.stopPropagation();
|
|
||||||
|
|
||||||
// Go back to home tab on click
|
|
||||||
const showHomeTab = () => {
|
|
||||||
controls.showMenuPanel.call(this.player, 'home');
|
|
||||||
};
|
|
||||||
|
|
||||||
// Settings menu items - use event delegation as items are added/removed
|
|
||||||
if (matches(event.target, this.player.config.selectors.inputs.language)) {
|
|
||||||
proxy(
|
|
||||||
event,
|
|
||||||
() => {
|
|
||||||
this.player.currentTrack = Number(event.target.value);
|
|
||||||
showHomeTab();
|
|
||||||
},
|
|
||||||
'language',
|
|
||||||
);
|
|
||||||
} else if (matches(event.target, this.player.config.selectors.inputs.quality)) {
|
|
||||||
proxy(
|
|
||||||
event,
|
|
||||||
() => {
|
|
||||||
this.player.quality = event.target.value;
|
|
||||||
showHomeTab();
|
|
||||||
},
|
|
||||||
'quality',
|
|
||||||
);
|
|
||||||
} else if (matches(event.target, this.player.config.selectors.inputs.speed)) {
|
|
||||||
proxy(
|
|
||||||
event,
|
|
||||||
() => {
|
|
||||||
this.player.speed = parseFloat(event.target.value);
|
|
||||||
showHomeTab();
|
|
||||||
},
|
|
||||||
'speed',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set range input alternative "value", which matches the tooltip time (#954)
|
// Set range input alternative "value", which matches the tooltip time (#954)
|
||||||
bind(this.player.elements.inputs.seek, 'mousedown mousemove', event => {
|
this.bind(this.player.elements.inputs.seek, 'mousedown mousemove', event => {
|
||||||
const clientRect = this.player.elements.progress.getBoundingClientRect();
|
const clientRect = this.player.elements.progress.getBoundingClientRect();
|
||||||
const percent = 100 / clientRect.width * (event.pageX - clientRect.left);
|
const percent = 100 / clientRect.width * (event.pageX - clientRect.left);
|
||||||
event.currentTarget.setAttribute('seek-value', percent);
|
event.currentTarget.setAttribute('seek-value', percent);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Pause while seeking
|
// Pause while seeking
|
||||||
bind(this.player.elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', event => {
|
this.bind(this.player.elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', event => {
|
||||||
const seek = event.currentTarget;
|
const seek = event.currentTarget;
|
||||||
|
|
||||||
const code = event.keyCode ? event.keyCode : event.which;
|
const code = event.keyCode ? event.keyCode : event.which;
|
||||||
@ -559,7 +520,7 @@ class Listeners {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Seek
|
// Seek
|
||||||
bind(
|
this.bind(
|
||||||
this.player.elements.inputs.seek,
|
this.player.elements.inputs.seek,
|
||||||
inputEvent,
|
inputEvent,
|
||||||
event => {
|
event => {
|
||||||
@ -582,7 +543,7 @@ class Listeners {
|
|||||||
// Current time invert
|
// Current time invert
|
||||||
// Only if one time element is used for both currentTime and duration
|
// Only if one time element is used for both currentTime and duration
|
||||||
if (this.player.config.toggleInvert && !is.element(this.player.elements.display.duration)) {
|
if (this.player.config.toggleInvert && !is.element(this.player.elements.display.duration)) {
|
||||||
bind(this.player.elements.display.currentTime, 'click', () => {
|
this.bind(this.player.elements.display.currentTime, 'click', () => {
|
||||||
// Do nothing if we're at the start
|
// Do nothing if we're at the start
|
||||||
if (this.player.currentTime === 0) {
|
if (this.player.currentTime === 0) {
|
||||||
return;
|
return;
|
||||||
@ -595,7 +556,7 @@ class Listeners {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Volume
|
// Volume
|
||||||
bind(
|
this.bind(
|
||||||
this.player.elements.inputs.volume,
|
this.player.elements.inputs.volume,
|
||||||
inputEvent,
|
inputEvent,
|
||||||
event => {
|
event => {
|
||||||
@ -607,27 +568,27 @@ class Listeners {
|
|||||||
// Polyfill for lower fill in <input type="range"> for webkit
|
// Polyfill for lower fill in <input type="range"> for webkit
|
||||||
if (browser.isWebkit) {
|
if (browser.isWebkit) {
|
||||||
Array.from(getElements.call(this.player, 'input[type="range"]')).forEach(element => {
|
Array.from(getElements.call(this.player, 'input[type="range"]')).forEach(element => {
|
||||||
bind(element, 'input', event => controls.updateRangeFill.call(this.player, event.target));
|
this.bind(element, 'input', event => controls.updateRangeFill.call(this.player, event.target));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seek tooltip
|
// Seek tooltip
|
||||||
bind(this.player.elements.progress, 'mouseenter mouseleave mousemove', event =>
|
this.bind(this.player.elements.progress, 'mouseenter mouseleave mousemove', event =>
|
||||||
controls.updateSeekTooltip.call(this.player, event),
|
controls.updateSeekTooltip.call(this.player, event),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting)
|
// Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting)
|
||||||
bind(this.player.elements.controls, 'mouseenter mouseleave', event => {
|
this.bind(this.player.elements.controls, 'mouseenter mouseleave', event => {
|
||||||
this.player.elements.controls.hover = !this.player.touch && event.type === 'mouseenter';
|
this.player.elements.controls.hover = !this.player.touch && event.type === 'mouseenter';
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)
|
// Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)
|
||||||
bind(this.player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', event => {
|
this.bind(this.player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', event => {
|
||||||
this.player.elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);
|
this.player.elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Focus in/out on controls
|
// Focus in/out on controls
|
||||||
bind(this.player.elements.controls, 'focusin focusout', event => {
|
this.bind(this.player.elements.controls, 'focusin focusout', event => {
|
||||||
const { config, elements, timers } = this.player;
|
const { config, elements, timers } = this.player;
|
||||||
|
|
||||||
// Skip transition to prevent focus from scrolling the parent element
|
// Skip transition to prevent focus from scrolling the parent element
|
||||||
@ -654,7 +615,7 @@ class Listeners {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Mouse wheel for volume
|
// Mouse wheel for volume
|
||||||
bind(
|
this.bind(
|
||||||
this.player.elements.inputs.volume,
|
this.player.elements.inputs.volume,
|
||||||
'wheel',
|
'wheel',
|
||||||
event => {
|
event => {
|
||||||
|
@ -191,7 +191,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: -$plyr-control-padding;
|
margin-right: -($plyr-control-padding - 2);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding-left: ceil($plyr-control-padding * 3.5);
|
padding-left: ceil($plyr-control-padding * 3.5);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
@ -22,3 +22,7 @@
|
|||||||
width: 1px;
|
width: 1px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.plyr [hidden] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user