v3.2.4
This commit is contained in:
parent
fec7a77d6f
commit
a812650fea
@ -1,3 +1,12 @@
|
||||
## v3.2.4
|
||||
|
||||
* Fix issue wher player never reports as ready if controls is empty array
|
||||
* Fix issue where screen reader labels were removed from time displays
|
||||
* Fix issue where custom controls placeholders were not populated
|
||||
* Custom controls HTML example updated
|
||||
* Fix for aria-label being set to the initial state on toggle buttons, overriding the inner labels
|
||||
* Fix for hidden mute button on iOS (not functional for Vimeo due to API limitations) (fixes #656)
|
||||
|
||||
## v3.2.3
|
||||
|
||||
* Fix for iOS 9 throwing error for `name` property in fullscreen API (fixes #908)
|
||||
|
@ -121,7 +121,8 @@ const controls = `
|
||||
<progress class="plyr__progress--buffer" min="0" max="100" value="0">% buffered</progress>
|
||||
<span role="tooltip" class="plyr__tooltip">00:00</span>
|
||||
</div>
|
||||
<div class="plyr__time">00:00</div>
|
||||
<div class="plyr__time plyr__time--current" aria-label="Current time">00:00</div>
|
||||
<div class="plyr__time plyr__time--duration" aria-label="Duration">00:00</div>
|
||||
<button type="button" class="plyr__control" aria-pressed="false" aria-label="Mute" data-plyr="mute">
|
||||
<svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-muted"></use></svg>
|
||||
<svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-volume"></use></svg>
|
||||
|
2
demo/dist/demo.css
vendored
2
demo/dist/demo.css
vendored
File diff suppressed because one or more lines are too long
56
demo/dist/demo.js
vendored
56
demo/dist/demo.js
vendored
@ -245,7 +245,13 @@ function objectFrozen(obj) {
|
||||
}
|
||||
|
||||
function truncate(str, max) {
|
||||
return !max || str.length <= max ? str : str.substr(0, max) + '\u2026';
|
||||
if (typeof max !== 'number') {
|
||||
throw new Error('2nd argument to `truncate` function should be a number');
|
||||
}
|
||||
if (typeof str !== 'string' || max === 0) {
|
||||
return str;
|
||||
}
|
||||
return str.length <= max ? str : str.substr(0, max) + '\u2026';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -544,10 +550,9 @@ function jsonSize(value) {
|
||||
}
|
||||
|
||||
function serializeValue(value) {
|
||||
var maxLength = 40;
|
||||
|
||||
if (typeof value === 'string') {
|
||||
return value.length <= maxLength ? value : value.substr(0, maxLength - 1) + '\u2026';
|
||||
var maxLength = 40;
|
||||
return truncate(value, maxLength);
|
||||
} else if (
|
||||
typeof value === 'number' ||
|
||||
typeof value === 'boolean' ||
|
||||
@ -1777,7 +1782,7 @@ Raven.prototype = {
|
||||
// webpack (using a build step causes webpack #1617). Grunt verifies that
|
||||
// this value matches package.json during build.
|
||||
// See: https://github.com/getsentry/raven-js/issues/465
|
||||
VERSION: '3.24.0',
|
||||
VERSION: '3.24.2',
|
||||
|
||||
debug: false,
|
||||
|
||||
@ -2066,7 +2071,11 @@ Raven.prototype = {
|
||||
*/
|
||||
_promiseRejectionHandler: function(event) {
|
||||
this._logDebug('debug', 'Raven caught unhandled promise rejection:', event);
|
||||
this.captureException(event.reason);
|
||||
this.captureException(event.reason, {
|
||||
extra: {
|
||||
unhandledPromiseRejection: true
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
@ -2207,6 +2216,14 @@ Raven.prototype = {
|
||||
|
||||
// stack[0] is `throw new Error(msg)` call itself, we are interested in the frame that was just before that, stack[1]
|
||||
var initialCall = isArray$1(stack.stack) && stack.stack[1];
|
||||
|
||||
// if stack[1] is `Raven.captureException`, it means that someone passed a string to it and we redirected that call
|
||||
// to be handled by `captureMessage`, thus `initialCall` is the 3rd one, not 2nd
|
||||
// initialCall => captureException(string) => captureMessage(string)
|
||||
if (initialCall && initialCall.func === 'Raven.captureException') {
|
||||
initialCall = stack.stack[2];
|
||||
}
|
||||
|
||||
var fileurl = (initialCall && initialCall.url) || '';
|
||||
|
||||
if (
|
||||
@ -3004,7 +3021,9 @@ Raven.prototype = {
|
||||
status_code: null
|
||||
};
|
||||
|
||||
return origFetch.apply(this, args).then(function(response) {
|
||||
return origFetch
|
||||
.apply(this, args)
|
||||
.then(function(response) {
|
||||
fetchData.status_code = response.status;
|
||||
|
||||
self.captureBreadcrumb({
|
||||
@ -3014,6 +3033,17 @@ Raven.prototype = {
|
||||
});
|
||||
|
||||
return response;
|
||||
})
|
||||
['catch'](function(err) {
|
||||
// if there is an error performing the request
|
||||
self.captureBreadcrumb({
|
||||
type: 'http',
|
||||
category: 'fetch',
|
||||
data: fetchData,
|
||||
level: 'error'
|
||||
});
|
||||
|
||||
throw err;
|
||||
});
|
||||
};
|
||||
},
|
||||
@ -3027,7 +3057,7 @@ Raven.prototype = {
|
||||
if (_document.addEventListener) {
|
||||
_document.addEventListener('click', self._breadcrumbEventHandler('click'), false);
|
||||
_document.addEventListener('keypress', self._keypressEventHandler(), false);
|
||||
} else {
|
||||
} else if (_document.attachEvent) {
|
||||
// IE8 Compatibility
|
||||
_document.attachEvent('onclick', self._breadcrumbEventHandler('click'));
|
||||
_document.attachEvent('onkeypress', self._keypressEventHandler());
|
||||
@ -3750,7 +3780,11 @@ Raven.prototype = {
|
||||
},
|
||||
|
||||
_logDebug: function(level) {
|
||||
if (this._originalConsoleMethods[level] && this.debug) {
|
||||
// We allow `Raven.debug` and `Raven.config(DSN, { debug: true })` to not make backward incompatible API change
|
||||
if (
|
||||
this._originalConsoleMethods[level] &&
|
||||
(this.debug || this._globalOptions.debug)
|
||||
) {
|
||||
// In IE<10 console methods do not have their own 'apply' method
|
||||
Function.prototype.apply.call(
|
||||
this._originalConsoleMethods[level],
|
||||
@ -3823,11 +3857,11 @@ var singleton = Raven$1;
|
||||
* const someAppReporter = new Raven.Client();
|
||||
* const someOtherAppReporter = new Raven.Client();
|
||||
*
|
||||
* someAppReporter('__DSN__', {
|
||||
* someAppReporter.config('__DSN__', {
|
||||
* ...config goes here
|
||||
* });
|
||||
*
|
||||
* someOtherAppReporter('__OTHER_DSN__', {
|
||||
* someOtherAppReporter.config('__OTHER_DSN__', {
|
||||
* ...config goes here
|
||||
* });
|
||||
*
|
||||
|
2
demo/dist/demo.js.map
vendored
2
demo/dist/demo.js.map
vendored
File diff suppressed because one or more lines are too long
2
demo/dist/demo.min.js
vendored
2
demo/dist/demo.min.js
vendored
File diff suppressed because one or more lines are too long
2
demo/dist/demo.min.js.map
vendored
2
demo/dist/demo.min.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.css
vendored
2
dist/plyr.css
vendored
File diff suppressed because one or more lines are too long
75
dist/plyr.js
vendored
75
dist/plyr.js
vendored
@ -77,7 +77,7 @@ var defaults = {
|
||||
// Sprite (for icons)
|
||||
loadSprite: true,
|
||||
iconPrefix: 'plyr',
|
||||
iconUrl: 'https://cdn.plyr.io/3.2.2/plyr.svg',
|
||||
iconUrl: 'https://cdn.plyr.io/3.2.3/plyr.svg',
|
||||
|
||||
// Blank video (used to prevent errors on source change)
|
||||
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
||||
@ -1200,8 +1200,8 @@ var utils = {
|
||||
// Display
|
||||
this.elements.display = {
|
||||
buffer: utils.getElement.call(this, this.config.selectors.display.buffer),
|
||||
duration: utils.getElement.call(this, this.config.selectors.display.duration),
|
||||
currentTime: utils.getElement.call(this, this.config.selectors.display.currentTime)
|
||||
currentTime: utils.getElement.call(this, this.config.selectors.display.currentTime),
|
||||
duration: utils.getElement.call(this, this.config.selectors.display.duration)
|
||||
};
|
||||
|
||||
// Seek tooltip
|
||||
@ -1973,7 +1973,7 @@ var Fullscreen = function () {
|
||||
// Fullscreen toggle on double click
|
||||
utils.on(this.player.elements.container, 'dblclick', function (event) {
|
||||
// Ignore double click in controls
|
||||
if (_this.player.elements.controls.contains(event.target)) {
|
||||
if (utils.is.element(_this.player.elements.controls) && _this.player.elements.controls.contains(event.target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2486,11 +2486,6 @@ var ui = {
|
||||
this.listeners.controls();
|
||||
}
|
||||
|
||||
// If there's no controls, bail
|
||||
if (!utils.is.element(this.elements.controls)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove native controls
|
||||
ui.toggleNativeControls.call(this);
|
||||
|
||||
@ -2731,10 +2726,10 @@ var ui = {
|
||||
}
|
||||
|
||||
// Always display hours if duration is over an hour
|
||||
var displayHours = utils.getHours(this.duration) > 0;
|
||||
var forceHours = utils.getHours(this.duration) > 0;
|
||||
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
target.textContent = utils.formatTime(time, displayHours, inverted);
|
||||
target.textContent = utils.formatTime(time, forceHours, inverted);
|
||||
},
|
||||
|
||||
|
||||
@ -3132,7 +3127,6 @@ var controls = {
|
||||
|
||||
// Add aria attributes
|
||||
attributes['aria-pressed'] = false;
|
||||
attributes['aria-label'] = i18n.get(label, this.config);
|
||||
} else {
|
||||
button.appendChild(controls.createIcon.call(this, icon));
|
||||
button.appendChild(controls.createLabel.call(this, label));
|
||||
@ -3234,16 +3228,14 @@ var controls = {
|
||||
|
||||
// Create time display
|
||||
createTime: function createTime(type) {
|
||||
var container = utils.createElement('div', {
|
||||
class: 'plyr__time'
|
||||
});
|
||||
var attributes = utils.getAttributesFromSelector(this.config.selectors.display[type]);
|
||||
|
||||
container.appendChild(utils.createElement('span', {
|
||||
class: this.config.classNames.hidden
|
||||
}, i18n.get(type, this.config)));
|
||||
|
||||
container.appendChild(utils.createElement('span', utils.getAttributesFromSelector(this.config.selectors.display[type]), '00:00'));
|
||||
var container = utils.createElement('div', utils.extend(attributes, {
|
||||
class: 'plyr__time ' + attributes.class,
|
||||
'aria-label': i18n.get(type, this.config)
|
||||
}), '0:00');
|
||||
|
||||
// Reference for updates
|
||||
this.elements.display[type] = container;
|
||||
|
||||
return container;
|
||||
@ -4091,17 +4083,21 @@ var controls = {
|
||||
var container = null;
|
||||
this.elements.controls = null;
|
||||
|
||||
// HTML or Element passed as the option
|
||||
// Set template properties
|
||||
var props = {
|
||||
id: this.id,
|
||||
seektime: this.config.seekTime,
|
||||
title: this.config.title
|
||||
};
|
||||
var update = true;
|
||||
|
||||
if (utils.is.string(this.config.controls) || utils.is.element(this.config.controls)) {
|
||||
// String or HTMLElement passed as the option
|
||||
container = this.config.controls;
|
||||
} else if (utils.is.function(this.config.controls)) {
|
||||
// A custom function to build controls
|
||||
// The function can return a HTMLElement or String
|
||||
container = this.config.controls({
|
||||
id: this.id,
|
||||
seektime: this.config.seekTime,
|
||||
title: this.config.title
|
||||
});
|
||||
container = this.config.controls.call(this, props);
|
||||
} else {
|
||||
// Create controls
|
||||
container = controls.create.call(this, {
|
||||
@ -4113,6 +4109,31 @@ var controls = {
|
||||
// TODO: Looping
|
||||
// loop: 'None',
|
||||
});
|
||||
update = false;
|
||||
}
|
||||
|
||||
// Replace props with their value
|
||||
var replace = function replace(input) {
|
||||
var result = input;
|
||||
|
||||
Object.entries(props).forEach(function (_ref) {
|
||||
var _ref2 = slicedToArray(_ref, 2),
|
||||
key = _ref2[0],
|
||||
value = _ref2[1];
|
||||
|
||||
result = utils.replaceAll(result, '{' + key + '}', value);
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// Update markup
|
||||
if (update) {
|
||||
if (utils.is.string(this.config.controls)) {
|
||||
container = replace(container);
|
||||
} else if (utils.is.element(container)) {
|
||||
container.innerHTML = replace(container.innerHTML);
|
||||
}
|
||||
}
|
||||
|
||||
// Controls container
|
||||
@ -4414,7 +4435,7 @@ var Listeners = function () {
|
||||
});
|
||||
|
||||
// Display duration
|
||||
utils.on(this.player.media, 'durationchange loadedmetadata', function (event) {
|
||||
utils.on(this.player.media, 'durationchange loadeddata loadedmetadata', function (event) {
|
||||
return ui.durationUpdate.call(_this3.player, event);
|
||||
});
|
||||
|
||||
|
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
75
dist/plyr.polyfilled.js
vendored
75
dist/plyr.polyfilled.js
vendored
@ -5117,7 +5117,7 @@ var defaults = {
|
||||
// Sprite (for icons)
|
||||
loadSprite: true,
|
||||
iconPrefix: 'plyr',
|
||||
iconUrl: 'https://cdn.plyr.io/3.2.3/plyr.svg',
|
||||
iconUrl: 'https://cdn.plyr.io/3.2.4/plyr.svg',
|
||||
|
||||
// Blank video (used to prevent errors on source change)
|
||||
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
||||
@ -6234,8 +6234,8 @@ var utils = {
|
||||
// Display
|
||||
this.elements.display = {
|
||||
buffer: utils.getElement.call(this, this.config.selectors.display.buffer),
|
||||
duration: utils.getElement.call(this, this.config.selectors.display.duration),
|
||||
currentTime: utils.getElement.call(this, this.config.selectors.display.currentTime)
|
||||
currentTime: utils.getElement.call(this, this.config.selectors.display.currentTime),
|
||||
duration: utils.getElement.call(this, this.config.selectors.display.duration)
|
||||
};
|
||||
|
||||
// Seek tooltip
|
||||
@ -7007,7 +7007,7 @@ var Fullscreen = function () {
|
||||
// Fullscreen toggle on double click
|
||||
utils.on(this.player.elements.container, 'dblclick', function (event) {
|
||||
// Ignore double click in controls
|
||||
if (_this.player.elements.controls.contains(event.target)) {
|
||||
if (utils.is.element(_this.player.elements.controls) && _this.player.elements.controls.contains(event.target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -7520,11 +7520,6 @@ var ui = {
|
||||
this.listeners.controls();
|
||||
}
|
||||
|
||||
// If there's no controls, bail
|
||||
if (!utils.is.element(this.elements.controls)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove native controls
|
||||
ui.toggleNativeControls.call(this);
|
||||
|
||||
@ -7765,10 +7760,10 @@ var ui = {
|
||||
}
|
||||
|
||||
// Always display hours if duration is over an hour
|
||||
var displayHours = utils.getHours(this.duration) > 0;
|
||||
var forceHours = utils.getHours(this.duration) > 0;
|
||||
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
target.textContent = utils.formatTime(time, displayHours, inverted);
|
||||
target.textContent = utils.formatTime(time, forceHours, inverted);
|
||||
},
|
||||
|
||||
|
||||
@ -8166,7 +8161,6 @@ var controls = {
|
||||
|
||||
// Add aria attributes
|
||||
attributes['aria-pressed'] = false;
|
||||
attributes['aria-label'] = i18n.get(label, this.config);
|
||||
} else {
|
||||
button.appendChild(controls.createIcon.call(this, icon));
|
||||
button.appendChild(controls.createLabel.call(this, label));
|
||||
@ -8268,16 +8262,14 @@ var controls = {
|
||||
|
||||
// Create time display
|
||||
createTime: function createTime(type) {
|
||||
var container = utils.createElement('div', {
|
||||
class: 'plyr__time'
|
||||
});
|
||||
var attributes = utils.getAttributesFromSelector(this.config.selectors.display[type]);
|
||||
|
||||
container.appendChild(utils.createElement('span', {
|
||||
class: this.config.classNames.hidden
|
||||
}, i18n.get(type, this.config)));
|
||||
|
||||
container.appendChild(utils.createElement('span', utils.getAttributesFromSelector(this.config.selectors.display[type]), '00:00'));
|
||||
var container = utils.createElement('div', utils.extend(attributes, {
|
||||
class: 'plyr__time ' + attributes.class,
|
||||
'aria-label': i18n.get(type, this.config)
|
||||
}), '0:00');
|
||||
|
||||
// Reference for updates
|
||||
this.elements.display[type] = container;
|
||||
|
||||
return container;
|
||||
@ -9125,17 +9117,21 @@ var controls = {
|
||||
var container = null;
|
||||
this.elements.controls = null;
|
||||
|
||||
// HTML or Element passed as the option
|
||||
// Set template properties
|
||||
var props = {
|
||||
id: this.id,
|
||||
seektime: this.config.seekTime,
|
||||
title: this.config.title
|
||||
};
|
||||
var update = true;
|
||||
|
||||
if (utils.is.string(this.config.controls) || utils.is.element(this.config.controls)) {
|
||||
// String or HTMLElement passed as the option
|
||||
container = this.config.controls;
|
||||
} else if (utils.is.function(this.config.controls)) {
|
||||
// A custom function to build controls
|
||||
// The function can return a HTMLElement or String
|
||||
container = this.config.controls({
|
||||
id: this.id,
|
||||
seektime: this.config.seekTime,
|
||||
title: this.config.title
|
||||
});
|
||||
container = this.config.controls.call(this, props);
|
||||
} else {
|
||||
// Create controls
|
||||
container = controls.create.call(this, {
|
||||
@ -9147,6 +9143,31 @@ var controls = {
|
||||
// TODO: Looping
|
||||
// loop: 'None',
|
||||
});
|
||||
update = false;
|
||||
}
|
||||
|
||||
// Replace props with their value
|
||||
var replace = function replace(input) {
|
||||
var result = input;
|
||||
|
||||
Object.entries(props).forEach(function (_ref) {
|
||||
var _ref2 = slicedToArray(_ref, 2),
|
||||
key = _ref2[0],
|
||||
value = _ref2[1];
|
||||
|
||||
result = utils.replaceAll(result, '{' + key + '}', value);
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// Update markup
|
||||
if (update) {
|
||||
if (utils.is.string(this.config.controls)) {
|
||||
container = replace(container);
|
||||
} else if (utils.is.element(container)) {
|
||||
container.innerHTML = replace(container.innerHTML);
|
||||
}
|
||||
}
|
||||
|
||||
// Controls container
|
||||
@ -9448,7 +9469,7 @@ var Listeners = function () {
|
||||
});
|
||||
|
||||
// Display duration
|
||||
utils.on(this.player.media, 'durationchange loadedmetadata', function (event) {
|
||||
utils.on(this.player.media, 'durationchange loadeddata loadedmetadata', function (event) {
|
||||
return ui.durationUpdate.call(_this3.player, event);
|
||||
});
|
||||
|
||||
|
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
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "plyr",
|
||||
"version": "3.2.3",
|
||||
"version": "3.2.4",
|
||||
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
|
||||
"homepage": "https://plyr.io",
|
||||
"main": "./dist/plyr.js",
|
||||
@ -69,6 +69,7 @@
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"custom-event-polyfill": "^0.3.0",
|
||||
"loadjs": "^3.5.4",
|
||||
"raven-js": "^3.24.0"
|
||||
"npm": "^6.0.0",
|
||||
"raven-js": "^3.24.2"
|
||||
}
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ See [initialising](#initialising) for more information on advanced setups.
|
||||
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript, you can use the following:
|
||||
|
||||
```html
|
||||
<script src="https://cdn.plyr.io/3.2.3/plyr.js"></script>
|
||||
<script src="https://cdn.plyr.io/3.2.4/plyr.js"></script>
|
||||
```
|
||||
|
||||
_Note_: Be sure to read the [polyfills](#polyfills) section below about browser compatibility
|
||||
@ -144,13 +144,13 @@ Include the `plyr.css` stylsheet into your `<head>`
|
||||
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the default CSS, you can use the following:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="https://cdn.plyr.io/3.2.3/plyr.css">
|
||||
<link rel="stylesheet" href="https://cdn.plyr.io/3.2.4/plyr.css">
|
||||
```
|
||||
|
||||
### SVG Sprite
|
||||
|
||||
The SVG sprite is loaded automatically from our CDN (provided by [Fastly](https://www.fastly.com/)). To change this, see the [options](#options) below. For
|
||||
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.2.3/plyr.svg`.
|
||||
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.2.4/plyr.svg`.
|
||||
|
||||
## Ads
|
||||
|
||||
|
61
src/js/controls.js
vendored
61
src/js/controls.js
vendored
@ -210,7 +210,6 @@ const controls = {
|
||||
|
||||
// Add aria attributes
|
||||
attributes['aria-pressed'] = false;
|
||||
attributes['aria-label'] = i18n.get(label, this.config);
|
||||
} else {
|
||||
button.appendChild(controls.createIcon.call(this, icon));
|
||||
button.appendChild(controls.createLabel.call(this, label));
|
||||
@ -327,22 +326,14 @@ const controls = {
|
||||
|
||||
// Create time display
|
||||
createTime(type) {
|
||||
const container = utils.createElement('div', {
|
||||
class: 'plyr__time',
|
||||
});
|
||||
const attributes = utils.getAttributesFromSelector(this.config.selectors.display[type]);
|
||||
|
||||
container.appendChild(
|
||||
utils.createElement(
|
||||
'span',
|
||||
{
|
||||
class: this.config.classNames.hidden,
|
||||
},
|
||||
i18n.get(type, this.config),
|
||||
),
|
||||
);
|
||||
|
||||
container.appendChild(utils.createElement('span', utils.getAttributesFromSelector(this.config.selectors.display[type]), '00:00'));
|
||||
const container = utils.createElement('div', utils.extend(attributes, {
|
||||
class: `plyr__time ${attributes.class}`,
|
||||
'aria-label': i18n.get(type, this.config),
|
||||
}), '0:00');
|
||||
|
||||
// Reference for updates
|
||||
this.elements.display[type] = container;
|
||||
|
||||
return container;
|
||||
@ -1204,17 +1195,21 @@ const controls = {
|
||||
let container = null;
|
||||
this.elements.controls = null;
|
||||
|
||||
// HTML or Element passed as the option
|
||||
// Set template properties
|
||||
const props = {
|
||||
id: this.id,
|
||||
seektime: this.config.seekTime,
|
||||
title: this.config.title,
|
||||
};
|
||||
let update = true;
|
||||
|
||||
if (utils.is.string(this.config.controls) || utils.is.element(this.config.controls)) {
|
||||
// String or HTMLElement passed as the option
|
||||
container = this.config.controls;
|
||||
} else if (utils.is.function(this.config.controls)) {
|
||||
// A custom function to build controls
|
||||
// The function can return a HTMLElement or String
|
||||
container = this.config.controls({
|
||||
id: this.id,
|
||||
seektime: this.config.seekTime,
|
||||
title: this.config.title,
|
||||
});
|
||||
container = this.config.controls.call(this, props);
|
||||
} else {
|
||||
// Create controls
|
||||
container = controls.create.call(this, {
|
||||
@ -1226,6 +1221,30 @@ const controls = {
|
||||
// TODO: Looping
|
||||
// loop: 'None',
|
||||
});
|
||||
update = false;
|
||||
}
|
||||
|
||||
// Replace props with their value
|
||||
const replace = input => {
|
||||
let result = input;
|
||||
|
||||
Object.entries(props).forEach(([
|
||||
key,
|
||||
value,
|
||||
]) => {
|
||||
result = utils.replaceAll(result, `{${key}}`, value);
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// Update markup
|
||||
if (update) {
|
||||
if (utils.is.string(this.config.controls)) {
|
||||
container = replace(container);
|
||||
} else if (utils.is.element(container)) {
|
||||
container.innerHTML = replace(container.innerHTML);
|
||||
}
|
||||
}
|
||||
|
||||
// Controls container
|
||||
|
@ -56,7 +56,7 @@ const defaults = {
|
||||
// Sprite (for icons)
|
||||
loadSprite: true,
|
||||
iconPrefix: 'plyr',
|
||||
iconUrl: 'https://cdn.plyr.io/3.2.3/plyr.svg',
|
||||
iconUrl: 'https://cdn.plyr.io/3.2.4/plyr.svg',
|
||||
|
||||
// Blank video (used to prevent errors on source change)
|
||||
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
||||
|
@ -70,7 +70,7 @@ class Fullscreen {
|
||||
// Fullscreen toggle on double click
|
||||
utils.on(this.player.elements.container, 'dblclick', event => {
|
||||
// Ignore double click in controls
|
||||
if (this.player.elements.controls.contains(event.target)) {
|
||||
if (utils.is.element(this.player.elements.controls) && this.player.elements.controls.contains(event.target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -253,7 +253,7 @@ class Listeners {
|
||||
utils.on(this.player.media, 'timeupdate seeking', event => ui.timeUpdate.call(this.player, event));
|
||||
|
||||
// Display duration
|
||||
utils.on(this.player.media, 'durationchange loadedmetadata', event => ui.durationUpdate.call(this.player, event));
|
||||
utils.on(this.player.media, 'durationchange loadeddata loadedmetadata', event => ui.durationUpdate.call(this.player, event));
|
||||
|
||||
// Check for audio tracks on load
|
||||
// We can't use `loadedmetadata` as it doesn't seem to have audio tracks at that point
|
||||
|
@ -1,6 +1,6 @@
|
||||
// ==========================================================================
|
||||
// Plyr
|
||||
// plyr.js v3.2.3
|
||||
// plyr.js v3.2.4
|
||||
// https://github.com/sampotts/plyr
|
||||
// License: The MIT License (MIT)
|
||||
// ==========================================================================
|
||||
|
@ -1,6 +1,6 @@
|
||||
// ==========================================================================
|
||||
// Plyr Polyfilled Build
|
||||
// plyr.js v3.2.3
|
||||
// plyr.js v3.2.4
|
||||
// https://github.com/sampotts/plyr
|
||||
// License: The MIT License (MIT)
|
||||
// ==========================================================================
|
||||
|
@ -48,11 +48,6 @@ const ui = {
|
||||
this.listeners.controls();
|
||||
}
|
||||
|
||||
// If there's no controls, bail
|
||||
if (!utils.is.element(this.elements.controls)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove native controls
|
||||
ui.toggleNativeControls.call(this);
|
||||
|
||||
@ -277,10 +272,10 @@ const ui = {
|
||||
}
|
||||
|
||||
// Always display hours if duration is over an hour
|
||||
const displayHours = utils.getHours(this.duration) > 0;
|
||||
const forceHours = utils.getHours(this.duration) > 0;
|
||||
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
target.textContent = utils.formatTime(time, displayHours, inverted);
|
||||
target.textContent = utils.formatTime(time, forceHours, inverted);
|
||||
},
|
||||
|
||||
// Handle time change event
|
||||
|
@ -468,8 +468,8 @@ const utils = {
|
||||
// Display
|
||||
this.elements.display = {
|
||||
buffer: utils.getElement.call(this, this.config.selectors.display.buffer),
|
||||
duration: utils.getElement.call(this, this.config.selectors.display.duration),
|
||||
currentTime: utils.getElement.call(this, this.config.selectors.display.currentTime),
|
||||
duration: utils.getElement.call(this, this.config.selectors.display.duration),
|
||||
};
|
||||
|
||||
// Seek tooltip
|
||||
|
@ -23,7 +23,12 @@
|
||||
// Hide sound controls on iOS
|
||||
// It's not supported to change volume using JavaScript:
|
||||
// https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html
|
||||
.plyr--is-ios .plyr__volume,
|
||||
.plyr--is-ios [data-plyr='mute'] {
|
||||
.plyr--is-ios .plyr__volume {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
// Vimeo has no toggle mute method so hide mute button
|
||||
// https://github.com/vimeo/player.js/issues/236#issuecomment-384663183
|
||||
.plyr--is-ios.plyr--vimeo [data-plyr='mute'] {
|
||||
display: none !important;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user