Compare commits

...

5 Commits

Author SHA1 Message Date
cce143a7da v3.0.11 2018-03-30 23:14:07 +11:00
d593005b32 Muted and autoplay fixes, small bug fixes 2018-03-30 23:09:17 +11:00
7be9d5d4d3 v3.0.10 2018-03-30 00:16:42 +11:00
d7141d5ed7 Controls docs, package upgrades 2018-03-30 00:11:48 +11:00
0d0ece94d3 Fix regression 2018-03-29 20:20:37 +11:00
27 changed files with 926 additions and 1163 deletions

15
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost/dev/plyr/demo",
"webRoot": "${workspaceFolder}"
}
]
}

View File

@ -1,3 +1,18 @@
## v3.0.11
* Muted and autoplay fixes
* Small bug fixes from Sentry logs
## v3.0.10
* Docs fix
* Package upgrades
## v3.0.9
* Demo fix
* Fix Vimeo regression
## v3.0.8
* Vimeo hotfix for private videos

View File

@ -1,27 +1,72 @@
# Controls
This is the markup that is rendered for the Plyr controls. You can use the default controls or provide a customized version of markup based on your needs.
This is the markup that is rendered for the Plyr controls. You can use the default controls or provide a customized version of markup based on your needs. You can pass the following to the `controls` option:
## Internationalization using default controls
* `Array` of options (this builds the default controls based on your choices)
* `String` containing the desired HTML
* `Function` that will be executed and should return one of the above
## Using default controls
If you want to use the standard controls as they are, you don't need to pass any options. If you want to turn on off controls, here's the full list:
```javascript
controls: [
'play-large', // The large play button in the center
'restart', // Restart playback
'rewind', // Rewind by the seek time (default 10 seconds)
'play', // Play/pause playback
'fast-forward', // Fast forward by the seek time (default 10 seconds)
'progress', // The progress bar and scrubber for playback and buffering
'current-time', // The current time of playback
'duration', // The full duration of the media
'mute', // Toggle mute
'volume', // Volume control
'captions', // Toggle captions
'settings', // Settings menu
'pip', // Picture-in-picture (currently Safari only)
'airplay', // Airplay (currently Safari only)
'fullscreen', // Toggle fullscreen
];
```
### Internationalization using default controls
You can provide an `i18n` object as one of your options when initialising the plugin which we be used when rendering the controls.
### Example
#### Example
```javascript
i18n: {
restart: "Restart",
rewind: "Rewind {seektime} secs",
play: "Play",
pause: "Pause",
forward: "Forward {seektime} secs",
buffered: "buffered",
currentTime: "Current time",
duration: "Duration",
volume: "Volume",
toggleMute: "Toggle Mute",
toggleCaptions: "Toggle Captions",
toggleFullscreen: "Toggle Fullscreen"
restart: 'Restart',
rewind: 'Rewind {seektime} secs',
play: 'Play',
pause: 'Pause',
fastForward: 'Forward {seektime} secs',
seek: 'Seek',
played: 'Played',
buffered: 'Buffered',
currentTime: 'Current time',
duration: 'Duration',
volume: 'Volume',
mute: 'Mute',
unmute: 'Unmute',
enableCaptions: 'Enable captions',
disableCaptions: 'Disable captions',
enterFullscreen: 'Enter fullscreen',
exitFullscreen: 'Exit fullscreen',
frameTitle: 'Player for {title}',
captions: 'Captions',
settings: 'Settings',
speed: 'Speed',
quality: 'Quality',
loop: 'Loop',
start: 'Start',
end: 'End',
all: 'All',
reset: 'Reset',
disabled: 'Disabled',
advertisement: 'Ad',
}
```
@ -29,85 +74,78 @@ Note: `{seektime}` will be replaced with your configured seek time or the defaul
## Using custom HTML
You can specify the HTML for the controls using the `html` option.
You can specify the HTML as a `String` or your `Function` return for the controls using the `controls` option.
The classes and data attributes used in your template should match the `selectors` option.
The classes and data attributes used in your template should match the `selectors` option if you change any.
You need to add several placeholders to your html template that are replaced when rendering:
You need to add several placeholders to your HTML template that are replaced when rendering:
- `{id}` - the dynamically generated ID for the player (for form controls)
- `{seektime}` - the seek time specified in options for fast forward and rewind
- `{title}` - the title of your media, if specified
* `{id}` - the dynamically generated ID for the player (for form controls)
* `{seektime}` - the seek time specified in options for fast forward and rewind
* `{title}` - the title of your media, if specified
You can include only the controls you need when specifying custom html.
### Limitations
* Currently the settings menus are not supported with custom controls HTML
* AirPlay and PiP buttons can be added but you will have to manage feature detection
### Example
This is an example `html` option with all controls.
Here's an example of custom controls markup (this is just all default controls shown).
```javascript
var controls = ["<div class='plyr__controls'>",
"<button type='button' data-plyr='restart'>",
"<svg><use xlink:href='#plyr-restart'></use></svg>",
"<span class='plyr__sr-only'>Restart</span>",
"</button>",
"<button type='button' data-plyr='rewind'>",
"<svg><use xlink:href='#plyr-rewind'></use></svg>",
"<span class='plyr__sr-only'>Rewind {seektime} secs</span>",
"</button>",
"<button type='button' data-plyr='play'>",
"<svg><use xlink:href='#plyr-play'></use></svg>",
"<span class='plyr__sr-only'>Play</span>",
"</button>",
"<button type='button' data-plyr='pause'>",
"<svg><use xlink:href='#plyr-pause'></use></svg>",
"<span class='plyr__sr-only'>Pause</span>",
"</button>",
"<button type='button' data-plyr='fast-forward'>",
"<svg><use xlink:href='#plyr-fast-forward'></use></svg>",
"<span class='plyr__sr-only'>Forward {seektime} secs</span>",
"</button>",
"<span class='plyr__progress'>",
"<label for='seek{id}' class='plyr__sr-only'>Seek</label>",
"<input id='seek{id}' class='plyr__progress--seek' type='range' min='0' max='100' step='0.1' value='0' data-plyr='seek'>",
"<progress class='plyr__progress--played' max='100' value='0' role='presentation'></progress>",
"<progress class='plyr__progress--buffer' max='100' value='0'>",
"<span>0</span>% buffered",
"</progress>",
"<span class='plyr__tooltip'>00:00</span>",
"</span>",
"<span class='plyr__time'>",
"<span class='plyr__sr-only'>Current time</span>",
"<span class='plyr__time--current'>00:00</span>",
"</span>",
"<span class='plyr__time'>",
"<span class='plyr__sr-only'>Duration</span>",
"<span class='plyr__time--duration'>00:00</span>",
"</span>",
"<button type='button' data-plyr='mute'>",
"<svg class='icon--muted'><use xlink:href='#plyr-muted'></use></svg>",
"<svg><use xlink:href='#plyr-volume'></use></svg>",
"<span class='plyr__sr-only'>Toggle Mute</span>",
"</button>",
"<span class='plyr__volume'>",
"<label for='volume{id}' class='plyr__sr-only'>Volume</label>",
"<input id='volume{id}' class='plyr__volume--input' type='range' min='0' max='10' value='5' data-plyr='volume'>",
"<progress class='plyr__volume--display' max='10' value='0' role='presentation'></progress>",
"</span>",
"<button type='button' data-plyr='captions'>",
"<svg class='icon--captions-on'><use xlink:href='#plyr-captions-on'></use></svg>",
"<svg><use xlink:href='#plyr-captions-off'></use></svg>",
"<span class='plyr__sr-only'>Toggle Captions</span>",
"</button>",
"<button type='button' data-plyr='fullscreen'>",
"<svg class='icon--exit-fullscreen'><use xlink:href='#plyr-exit-fullscreen'></use></svg>",
"<svg><use xlink:href='#plyr-enter-fullscreen'></use></svg>",
"<span class='plyr__sr-only'>Toggle Fullscreen</span>",
"</button>",
"</div>"].join("");
const controls = `
<div class="plyr__controls">
<button type="button" class="plyr__control" data-plyr="restart">
<svg role="presentation"><use xlink:href="#plyr-restart"></use></svg>
<span class="plyr__tooltip" role="tooltip">Restart</span>
</button>
<button type="button" class="plyr__control" data-plyr="rewind">
<svg role="presentation"><use xlink:href="#plyr-rewind"></use></svg>
<span class="plyr__tooltip" role="tooltip">Rewind {seektime} secs</span>
</button>
<button type="button" class="plyr__control" aria-pressed="false" aria-label="Play, {title}" data-plyr="play">
<svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-pause"></use></svg>
<svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-play"></use></svg>
<span class="label--pressed plyr__tooltip" role="tooltip">Pause</span>
<span class="label--not-pressed plyr__tooltip" role="tooltip">Play</span>
</button>
<button type="button" class="plyr__control" data-plyr="fast-forward">
<svg role="presentation"><use xlink:href="#plyr-fast-forward"></use></svg>
<span class="plyr__tooltip" role="tooltip">Forward {seektime} secs</span>
</button>
<div class="plyr__progress">
<label for="plyr-seek-{id}" class="plyr__sr-only">Seek</label>
<input data-plyr="seek" type="range" min="0" max="100" step="0.01" value="0" id="plyr-seek-{id}">
<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>
<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>
<span class="label--pressed plyr__tooltip" role="tooltip">Unmute</span>
<span class="label--not-pressed plyr__tooltip" role="tooltip">Mute</span>
</button>
<div class="plyr__volume">
<label for="plyr-volume-{id}" class="plyr__sr-only">Volume</label>
<input data-plyr="volume" type="range" min="0" max="1" step="0.05" value="1" autocomplete="off" id="plyr-volume-{id}">
</div>
<button type="button" class="plyr__control" aria-pressed="true" aria-label="Enable captions" data-plyr="captions">
<svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-captions-on"></use></svg>
<svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-captions-off"></use></svg>
<span class="label--pressed plyr__tooltip" role="tooltip">Disable captions</span>
<span class="label--not-pressed plyr__tooltip" role="tooltip">Enable captions</span>
</button>
<button type="button" class="plyr__control" aria-pressed="false" aria-label="Enter fullscreen" data-plyr="fullscreen">
<svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-exit-fullscreen"></use></svg>
<svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-enter-fullscreen"></use></svg>
<span class="label--pressed plyr__tooltip" role="tooltip">Exit fullscreen</span>
<span class="label--not-pressed plyr__tooltip" role="tooltip">Enter fullscreen</span>
</button>
</div>
`;
// Setup the player
plyr.setup('.js-player', {
html: controls
});
const player = new Plyr('#player', { controls });
```

557
demo/dist/demo.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -169,7 +169,8 @@
</aside>
<!-- Polyfills -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=es6,Array.prototype.includes,CustomEvent" crossorigin="anonymous"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=es6,Array.prototype.includes,CustomEvent,Object.entries"
crossorigin="anonymous"></script>
<!-- Plyr core script -->
<script src="../dist/plyr.js" crossorigin="anonymous"></script>

View File

@ -65,6 +65,7 @@ import Raven from 'raven-js';
'fast-forward',
'progress',
'current-time',
'duration',
'mute',
'volume',
'captions',
@ -83,9 +84,6 @@ import Raven from 'raven-js';
enabled: true,
publisherId: '918848828995742',
},
/* listeners: {
seek: () => false,
}, */
});
// Expose for tinkering in the console
@ -179,7 +177,7 @@ import Raven from 'raven-js';
player.source = {
type: 'video',
sources: [{
src: 'https://vimeo.com/25345658',
src: 'https://vimeo.com/76979871',
provider: 'vimeo',
}],
};

370
dist/plyr.js vendored
View File

@ -77,7 +77,7 @@ var defaults = {
// Sprite (for icons)
loadSprite: true,
iconPrefix: 'plyr',
iconUrl: 'https://cdn.plyr.io/3.0.8/plyr.svg',
iconUrl: 'https://cdn.plyr.io/3.0.10/plyr.svg',
// Blank video (used to prevent errors on source change)
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
@ -336,10 +336,6 @@ var defaults = {
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
@ -456,6 +452,7 @@ function loadFile(path, callbackFn, args, numTries) {
async = args.async,
maxTries = (args.numRetries || 0) + 1,
beforeCallbackFn = args.before || devnull,
pathStripped = path.replace(/^(css|img)!/, ''),
isCss,
e;
@ -467,7 +464,11 @@ function loadFile(path, callbackFn, args, numTries) {
// css
e = doc.createElement('link');
e.rel = 'stylesheet';
e.href = path.replace(/^css!/, ''); // remove "css!" prefix
e.href = pathStripped; //.replace(/^css!/, ''); // remove "css!" prefix
} else if (/(^img!|\.(png|gif|jpg|svg)$)/.test(path)) {
// image
e = doc.createElement('img');
e.src = pathStripped;
} else {
// javascript
e = doc.createElement('script');
@ -633,123 +634,6 @@ return loadjs;
}));
});
var asyncGenerator = function () {
function AwaitValue(value) {
this.value = value;
}
function AsyncGenerator(gen) {
var front, back;
function send(key, arg) {
return new Promise(function (resolve, reject) {
var request = {
key: key,
arg: arg,
resolve: resolve,
reject: reject,
next: null
};
if (back) {
back = back.next = request;
} else {
front = back = request;
resume(key, arg);
}
});
}
function resume(key, arg) {
try {
var result = gen[key](arg);
var value = result.value;
if (value instanceof AwaitValue) {
Promise.resolve(value.value).then(function (arg) {
resume("next", arg);
}, function (arg) {
resume("throw", arg);
});
} else {
settle(result.done ? "return" : "normal", result.value);
}
} catch (err) {
settle("throw", err);
}
}
function settle(type, value) {
switch (type) {
case "return":
front.resolve({
value: value,
done: true
});
break;
case "throw":
front.reject(value);
break;
default:
front.resolve({
value: value,
done: false
});
break;
}
front = front.next;
if (front) {
resume(front.key, front.arg);
} else {
back = null;
}
}
this._invoke = send;
if (typeof gen.return !== "function") {
this.return = undefined;
}
}
if (typeof Symbol === "function" && Symbol.asyncIterator) {
AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
return this;
};
}
AsyncGenerator.prototype.next = function (arg) {
return this._invoke("next", arg);
};
AsyncGenerator.prototype.throw = function (arg) {
return this._invoke("throw", arg);
};
AsyncGenerator.prototype.return = function (arg) {
return this._invoke("return", arg);
};
return {
wrap: function (fn) {
return function () {
return new AsyncGenerator(fn.apply(this, arguments));
};
},
await: function (value) {
return new AwaitValue(value);
}
};
}();
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
@ -774,10 +658,6 @@ var createClass = function () {
};
}();
var defineProperty = function (obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
@ -792,26 +672,6 @@ var defineProperty = function (obj, key, value) {
return obj;
};
var slicedToArray = function () {
function sliceIterator(arr, i) {
@ -851,18 +711,6 @@ var slicedToArray = function () {
};
}();
var toConsumableArray = function (arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
@ -873,8 +721,6 @@ var toConsumableArray = function (arr) {
}
};
// ==========================================================================
// Plyr utils
// ==========================================================================
var utils = {
@ -1818,8 +1664,6 @@ var utils = {
}
};
// ==========================================================================
// Plyr support checks
// ==========================================================================
// Check for feature support
@ -2015,9 +1859,6 @@ var Console = function () {
return Console;
}();
// ==========================================================================
// Fullscreen wrapper
// https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API#prefixing
// ==========================================================================
var browser = utils.getBrowser();
@ -2253,9 +2094,6 @@ var Fullscreen = function () {
return Fullscreen;
}();
// ==========================================================================
// Plyr Captions
// TODO: Create as class
// ==========================================================================
var captions = {
@ -2487,8 +2325,6 @@ var captions = {
}
};
// ==========================================================================
// Plyr internationalization
// ==========================================================================
var i18n = {
@ -2519,8 +2355,6 @@ var i18n = {
}
};
// ==========================================================================
// Plyr UI
// ==========================================================================
var ui = {
@ -2596,6 +2430,9 @@ var ui = {
// Reset quality options
this.options.quality = [];
// Reset volume display
ui.updateVolume.call(this);
// Reset time display
ui.timeUpdate.call(this);
@ -2861,18 +2698,16 @@ var ui = {
}
};
// ==========================================================================
// Plyr controls
// ==========================================================================
// Sniff out the browser
var browser$2 = utils.getBrowser();
var browser$1 = utils.getBrowser();
var controls = {
// Webkit polyfill for lower fill range
updateRangeFill: function updateRangeFill(target) {
// WebKit only
if (!browser$2.isWebkit) {
if (!browser$1.isWebkit) {
return;
}
@ -2893,7 +2728,7 @@ var controls = {
getIconUrl: function getIconUrl() {
return {
url: this.config.iconUrl,
absolute: this.config.iconUrl.indexOf('http') === 0 || browser$2.isIE && !window.svg4everybody
absolute: this.config.iconUrl.indexOf('http') === 0 || browser$1.isIE && !window.svg4everybody
};
},
@ -3990,9 +3825,7 @@ var controls = {
this.elements.controls = container;
if (this.isHTML5) {
controls.setSpeedMenu.call(this);
}
controls.setSpeedMenu.call(this);
return container;
},
@ -4086,12 +3919,10 @@ var controls = {
}
};
// ==========================================================================
// Plyr Event Listeners
// ==========================================================================
// Sniff out the browser
var browser$1 = utils.getBrowser();
var browser$2 = utils.getBrowser();
var Listeners = function () {
function Listeners(player) {
@ -4372,17 +4203,17 @@ var Listeners = function () {
return ui.updateProgress.call(_this3.player, event);
});
// Handle native mute
// Handle volume changes
utils.on(this.player.media, 'volumechange', function (event) {
return ui.updateVolume.call(_this3.player, event);
});
// Handle native play/pause
// Handle play/pause
utils.on(this.player.media, 'playing play pause ended emptied', function (event) {
return ui.checkPlaying.call(_this3.player, event);
});
// Loading
// Loading state
utils.on(this.player.media, 'waiting canplay seeked playing', function (event) {
return ui.checkLoading.call(_this3.player, event);
});
@ -4390,6 +4221,20 @@ var Listeners = function () {
// Check if media failed to load
// utils.on(this.player.media, 'play', event => ui.checkFailed.call(this.player, event));
// If autoplay, then load advertisement if required
// TODO: Show some sort of loading state while the ad manager loads else there's a delay before ad shows
utils.on(this.player.media, 'playing', function () {
// If ads are enabled, wait for them first
if (_this3.player.ads.enabled && !_this3.player.ads.initialized) {
// Wait for manager response
_this3.player.ads.managerPromise.then(function () {
return _this3.player.ads.play();
}).catch(function () {
return _this3.player.play();
});
}
});
// Click video
if (this.player.supported.ui && this.player.config.clickToPlay && !this.player.isAudio) {
// Re-fetch the wrapper
@ -4489,7 +4334,7 @@ var Listeners = function () {
var _this4 = this;
// IE doesn't support input event, so we fallback to change
var inputEvent = browser$1.isIE ? 'change' : 'input';
var inputEvent = browser$2.isIE ? 'change' : 'input';
// Run default and custom handlers
var proxy = function proxy(event, defaultHandler, customHandlerKey) {
@ -4605,7 +4450,7 @@ var Listeners = function () {
}, 'volume');
// Polyfill for lower fill in <input type="range"> for webkit
if (browser$1.isWebkit) {
if (browser$2.isWebkit) {
on(utils.getElements.call(this.player, 'input[type="range"]'), 'input', function (event) {
controls.updateRangeFill.call(_this4.player, event.target);
});
@ -4682,8 +4527,6 @@ var Listeners = function () {
return Listeners;
}();
// ==========================================================================
// Plyr storage
// ==========================================================================
var Storage = function () {
@ -4766,12 +4609,6 @@ var Storage = function () {
}();
// ==========================================================================
// Advertisement plugin using Google IMA HTML5 SDK
// Create an account with our ad partner, vi here:
// https://www.vi.ai/publisher-video-monetization/
// ==========================================================================
/* global google */
var Ads = function () {
/**
@ -4993,21 +4830,23 @@ var Ads = function () {
this.cuePoints = this.manager.getCuePoints();
// Add advertisement cue's within the time line if available
this.cuePoints.forEach(function (cuePoint) {
if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < _this6.player.duration) {
var seekElement = _this6.player.elements.progress;
if (!utils.is.empty(this.cuePoints)) {
this.cuePoints.forEach(function (cuePoint) {
if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < _this6.player.duration) {
var seekElement = _this6.player.elements.progress;
if (seekElement) {
var cuePercentage = 100 / _this6.player.duration * cuePoint;
var cue = utils.createElement('span', {
class: _this6.player.config.classNames.cues
});
if (utils.is.element(seekElement)) {
var cuePercentage = 100 / _this6.player.duration * cuePoint;
var cue = utils.createElement('span', {
class: _this6.player.config.classNames.cues
});
cue.style.left = cuePercentage.toString() + '%';
seekElement.appendChild(cue);
cue.style.left = cuePercentage.toString() + '%';
seekElement.appendChild(cue);
}
}
}
});
});
}
// Get skippable state
// TODO: Skip button
@ -5191,6 +5030,10 @@ var Ads = function () {
this.player.on('seeked', function () {
var seekedTime = _this8.player.currentTime;
if (utils.is.empty(_this8.cuePoints)) {
return;
}
_this8.cuePoints.forEach(function (cuePoint, index) {
if (time < cuePoint && cuePoint < seekedTime) {
_this8.manager.discardAdBreak();
@ -5202,7 +5045,9 @@ var Ads = function () {
// Listen to the resizing of the window. And resize ad accordingly
// TODO: eventually implement ResizeObserver
window.addEventListener('resize', function () {
_this8.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);
if (_this8.manager) {
_this8.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);
}
});
}
@ -5433,8 +5278,6 @@ var Ads = function () {
return Ads;
}();
// ==========================================================================
// YouTube plugin
// ==========================================================================
var youtube = {
@ -5862,8 +5705,6 @@ var youtube = {
}
};
// ==========================================================================
// Vimeo plugin
// ==========================================================================
var vimeo = {
@ -6193,8 +6034,6 @@ var vimeo = {
}
};
// ==========================================================================
// Plyr Media
// ==========================================================================
// Sniff out the browser
@ -6293,8 +6132,6 @@ var media = {
}
};
// ==========================================================================
// Plyr source update
// ==========================================================================
var source = {
@ -6435,11 +6272,6 @@ var source = {
}
};
// ==========================================================================
// Plyr
// plyr.js v3.0.8
// https://github.com/sampotts/plyr
// License: The MIT License (MIT)
// ==========================================================================
// Private properties
@ -6553,7 +6385,17 @@ var Plyr = function () {
}
// Cache original element state for .destroy()
this.elements.original = this.media.cloneNode(true);
// TODO: Investigate a better solution as I suspect this causes reported double load issues?
setTimeout(function () {
var clone = _this.media.cloneNode(true);
// Prevent the clone autoplaying
if (clone.getAttribute('autoplay')) {
clone.pause();
}
_this.elements.original = clone;
}, 0);
// Set media type based on tag or data attribute
// Supported: video, audio, vimeo, youtube
@ -6703,6 +6545,11 @@ var Plyr = function () {
// Setup ads if provided
this.ads = new Ads(this);
// Autoplay if required
if (this.config.autoplay) {
this.play();
}
}
// ---------------------------------------
@ -6722,20 +6569,14 @@ var Plyr = function () {
* Play the media, or play the advertisement (if they are not blocked)
*/
value: function play() {
var _this2 = this;
if (!utils.is.function(this.media.play)) {
return null;
}
// If ads are enabled, wait for them first
if (this.ads.enabled && !this.ads.initialized) {
return this.ads.managerPromise.then(function () {
return _this2.ads.play();
}).catch(function () {
return _this2.media.play();
});
}
/* if (this.ads.enabled && !this.ads.initialized) {
return this.ads.managerPromise.then(() => this.ads.play()).catch(() => this.media.play());
} */
// Return the promise (for HTML5)
return this.media.play();
@ -6787,7 +6628,7 @@ var Plyr = function () {
value: function stop() {
if (this.isHTML5) {
this.media.load();
} else {
} else if (utils.is.function(this.media.stop)) {
this.media.stop();
}
}
@ -6922,7 +6763,7 @@ var Plyr = function () {
}, {
key: 'toggleControls',
value: function toggleControls(toggle) {
var _this3 = this;
var _this2 = this;
// We need controls of course...
if (!utils.is.element(this.elements.controls)) {
@ -6996,25 +6837,30 @@ var Plyr = function () {
// then set the timer to hide the controls
if (!show || this.playing) {
this.timers.controls = setTimeout(function () {
// We need controls of course...
if (!utils.is.element(_this2.elements.controls)) {
return;
}
// If the mouse is over the controls (and not entering fullscreen), bail
if ((_this3.elements.controls.pressed || _this3.elements.controls.hover) && !isEnterFullscreen) {
if ((_this2.elements.controls.pressed || _this2.elements.controls.hover) && !isEnterFullscreen) {
return;
}
// Restore transition behaviour
if (!utils.hasClass(_this3.elements.container, _this3.config.classNames.hideControls)) {
utils.toggleClass(_this3.elements.controls, _this3.config.classNames.noTransition, false);
if (!utils.hasClass(_this2.elements.container, _this2.config.classNames.hideControls)) {
utils.toggleClass(_this2.elements.controls, _this2.config.classNames.noTransition, false);
}
// Check if controls toggled
var toggled = utils.toggleClass(_this3.elements.container, _this3.config.classNames.hideControls, true);
var toggled = utils.toggleClass(_this2.elements.container, _this2.config.classNames.hideControls, true);
// Trigger event and close menu
if (toggled) {
utils.dispatchEvent.call(_this3, _this3.media, 'controlshidden');
utils.dispatchEvent.call(_this2, _this2.media, 'controlshidden');
if (_this3.config.controls.includes('settings') && !utils.is.empty(_this3.config.settings)) {
controls.toggleMenu.call(_this3, false);
if (_this2.config.controls.includes('settings') && !utils.is.empty(_this2.config.settings)) {
controls.toggleMenu.call(_this2, false);
}
}
}, delay);
@ -7056,7 +6902,7 @@ var Plyr = function () {
}, {
key: 'destroy',
value: function destroy(callback) {
var _this4 = this;
var _this3 = this;
var soft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
@ -7069,22 +6915,22 @@ var Plyr = function () {
document.body.style.overflow = '';
// GC for embed
_this4.embed = null;
_this3.embed = null;
// If it's a soft destroy, make minimal changes
if (soft) {
if (Object.keys(_this4.elements).length) {
if (Object.keys(_this3.elements).length) {
// Remove elements
utils.removeElement(_this4.elements.buttons.play);
utils.removeElement(_this4.elements.captions);
utils.removeElement(_this4.elements.controls);
utils.removeElement(_this4.elements.wrapper);
utils.removeElement(_this3.elements.buttons.play);
utils.removeElement(_this3.elements.captions);
utils.removeElement(_this3.elements.controls);
utils.removeElement(_this3.elements.wrapper);
// Clear for GC
_this4.elements.buttons.play = null;
_this4.elements.captions = null;
_this4.elements.controls = null;
_this4.elements.wrapper = null;
_this3.elements.buttons.play = null;
_this3.elements.captions = null;
_this3.elements.controls = null;
_this3.elements.wrapper = null;
}
// Callback
@ -7093,26 +6939,26 @@ var Plyr = function () {
}
} else {
// Unbind listeners
_this4.listeners.clear();
_this3.listeners.clear();
// Replace the container with the original element provided
utils.replaceElement(_this4.elements.original, _this4.elements.container);
utils.replaceElement(_this3.elements.original, _this3.elements.container);
// Event
utils.dispatchEvent.call(_this4, _this4.elements.original, 'destroyed', true);
utils.dispatchEvent.call(_this3, _this3.elements.original, 'destroyed', true);
// Callback
if (utils.is.function(callback)) {
callback.call(_this4.elements.original);
callback.call(_this3.elements.original);
}
// Reset state
_this4.ready = false;
_this3.ready = false;
// Clear for garbage collection
setTimeout(function () {
_this4.elements = null;
_this4.media = null;
_this3.elements = null;
_this3.media = null;
}, 200);
}
};
@ -7364,8 +7210,8 @@ var Plyr = function () {
// Set the player volume
this.media.volume = volume;
// If muted, and we're increasing volume, reset muted state
if (this.muted && volume > 0) {
// If muted, and we're increasing volume manually, reset muted state
if (!utils.is.empty(value) && this.muted && volume > 0) {
this.muted = false;
}
}

2
dist/plyr.js.map vendored

File diff suppressed because one or more lines are too long

2
dist/plyr.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{
"name": "plyr",
"version": "3.0.8",
"version": "3.0.11",
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
"homepage": "https://plyr.io",
"main": "./dist/plyr.js",
@ -13,22 +13,22 @@
"babel-plugin-external-helpers": "^6.22.0",
"babel-preset-env": "^1.6.1",
"del": "^3.0.0",
"eslint": "^4.19.0",
"eslint": "^4.19.1",
"eslint-config-airbnb-base": "^12.1.0",
"eslint-config-prettier": "^2.9.0",
"eslint-plugin-import": "^2.9.0",
"git-branch": "^2.0.1",
"gulp": "^3.9.1",
"gulp-autoprefixer": "^5.0.0",
"gulp-better-rollup": "^3.0.0",
"gulp-better-rollup": "^3.1.0",
"gulp-clean-css": "^3.9.3",
"gulp-concat": "^2.6.1",
"gulp-filter": "^5.1.0",
"gulp-open": "^3.0.0",
"gulp-open": "^3.0.1",
"gulp-rename": "^1.2.2",
"gulp-replace": "^0.6.1",
"gulp-s3": "^0.11.0",
"gulp-sass": "^3.1.0",
"gulp-sass": "^3.2.1",
"gulp-size": "^3.0.0",
"gulp-sourcemaps": "^2.6.4",
"gulp-svgmin": "^1.2.4",
@ -38,8 +38,8 @@
"prettier-eslint": "^8.8.1",
"prettier-stylelint": "^0.4.2",
"rollup-plugin-babel": "^3.0.3",
"rollup-plugin-commonjs": "^8.4.1",
"rollup-plugin-node-resolve": "^3.2.0",
"rollup-plugin-commonjs": "^9.1.0",
"rollup-plugin-node-resolve": "^3.3.0",
"run-sequence": "^2.2.1",
"stylelint": "^9.1.3",
"stylelint-config-prettier": "^3.0.4",
@ -68,7 +68,7 @@
"dependencies": {
"babel-polyfill": "^6.26.0",
"custom-event-polyfill": "^0.3.0",
"loadjs": "^3.5.2",
"raven-js": "^3.23.3"
"loadjs": "^3.5.4",
"raven-js": "^3.24.0"
}
}

View File

@ -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.0.8/plyr.js"></script>
<script src="https://cdn.plyr.io/3.0.11/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.0.8/plyr.css">
<link rel="stylesheet" href="https://cdn.plyr.io/3.0.11/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.0.8/plyr.svg`.
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.0.11/plyr.svg`.
## Ads

4
src/js/controls.js vendored
View File

@ -1177,9 +1177,7 @@ const controls = {
this.elements.controls = container;
if (this.isHTML5) {
controls.setSpeedMenu.call(this);
}
controls.setSpeedMenu.call(this);
return container;
},

View File

@ -56,7 +56,7 @@ const defaults = {
// Sprite (for icons)
loadSprite: true,
iconPrefix: 'plyr',
iconUrl: 'https://cdn.plyr.io/3.0.8/plyr.svg',
iconUrl: 'https://cdn.plyr.io/3.0.11/plyr.svg',
// Blank video (used to prevent errors on source change)
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',

View File

@ -278,18 +278,28 @@ class Listeners {
// Check for buffer progress
utils.on(this.player.media, 'progress playing', event => ui.updateProgress.call(this.player, event));
// Handle native mute
// Handle volume changes
utils.on(this.player.media, 'volumechange', event => ui.updateVolume.call(this.player, event));
// Handle native play/pause
// Handle play/pause
utils.on(this.player.media, 'playing play pause ended emptied', event => ui.checkPlaying.call(this.player, event));
// Loading
// Loading state
utils.on(this.player.media, 'waiting canplay seeked playing', event => ui.checkLoading.call(this.player, event));
// Check if media failed to load
// utils.on(this.player.media, 'play', event => ui.checkFailed.call(this.player, event));
// If autoplay, then load advertisement if required
// TODO: Show some sort of loading state while the ad manager loads else there's a delay before ad shows
utils.on(this.player.media, 'playing', () => {
// If ads are enabled, wait for them first
if (this.player.ads.enabled && !this.player.ads.initialized) {
// Wait for manager response
this.player.ads.managerPromise.then(() => this.player.ads.play()).catch(() => this.player.play());
}
});
// Click video
if (this.player.supported.ui && this.player.config.clickToPlay && !this.player.isAudio) {
// Re-fetch the wrapper

View File

@ -206,21 +206,23 @@ class Ads {
this.cuePoints = this.manager.getCuePoints();
// Add advertisement cue's within the time line if available
this.cuePoints.forEach(cuePoint => {
if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < this.player.duration) {
const seekElement = this.player.elements.progress;
if (!utils.is.empty(this.cuePoints)) {
this.cuePoints.forEach(cuePoint => {
if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < this.player.duration) {
const seekElement = this.player.elements.progress;
if (seekElement) {
const cuePercentage = 100 / this.player.duration * cuePoint;
const cue = utils.createElement('span', {
class: this.player.config.classNames.cues,
});
if (utils.is.element(seekElement)) {
const cuePercentage = 100 / this.player.duration * cuePoint;
const cue = utils.createElement('span', {
class: this.player.config.classNames.cues,
});
cue.style.left = `${cuePercentage.toString()}%`;
seekElement.appendChild(cue);
cue.style.left = `${cuePercentage.toString()}%`;
seekElement.appendChild(cue);
}
}
}
});
});
}
// Get skippable state
// TODO: Skip button
@ -385,6 +387,10 @@ class Ads {
this.player.on('seeked', () => {
const seekedTime = this.player.currentTime;
if (utils.is.empty(this.cuePoints)) {
return;
}
this.cuePoints.forEach((cuePoint, index) => {
if (time < cuePoint && cuePoint < seekedTime) {
this.manager.discardAdBreak();
@ -396,7 +402,9 @@ class Ads {
// Listen to the resizing of the window. And resize ad accordingly
// TODO: eventually implement ResizeObserver
window.addEventListener('resize', () => {
this.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);
if (this.manager) {
this.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);
}
});
}

View File

@ -1,6 +1,6 @@
// ==========================================================================
// Plyr
// plyr.js v3.0.8
// plyr.js v3.0.11
// https://github.com/sampotts/plyr
// License: The MIT License (MIT)
// ==========================================================================
@ -133,7 +133,17 @@ class Plyr {
}
// Cache original element state for .destroy()
this.elements.original = this.media.cloneNode(true);
// TODO: Investigate a better solution as I suspect this causes reported double load issues?
setTimeout(() => {
const clone = this.media.cloneNode(true);
// Prevent the clone autoplaying
if (clone.getAttribute('autoplay')) {
clone.pause();
}
this.elements.original = clone;
}, 0);
// Set media type based on tag or data attribute
// Supported: video, audio, vimeo, youtube
@ -286,6 +296,11 @@ class Plyr {
// Setup ads if provided
this.ads = new Ads(this);
// Autoplay if required
if (this.config.autoplay) {
this.play();
}
}
// ---------------------------------------
@ -323,9 +338,9 @@ class Plyr {
}
// If ads are enabled, wait for them first
if (this.ads.enabled && !this.ads.initialized) {
/* if (this.ads.enabled && !this.ads.initialized) {
return this.ads.managerPromise.then(() => this.ads.play()).catch(() => this.media.play());
}
} */
// Return the promise (for HTML5)
return this.media.play();
@ -384,7 +399,7 @@ class Plyr {
stop() {
if (this.isHTML5) {
this.media.load();
} else {
} else if (utils.is.function(this.media.stop)) {
this.media.stop();
}
}
@ -524,8 +539,8 @@ class Plyr {
// Set the player volume
this.media.volume = volume;
// If muted, and we're increasing volume, reset muted state
if (this.muted && volume > 0) {
// If muted, and we're increasing volume manually, reset muted state
if (!utils.is.empty(value) && this.muted && volume > 0) {
this.muted = false;
}
}
@ -1019,6 +1034,11 @@ class Plyr {
// then set the timer to hide the controls
if (!show || this.playing) {
this.timers.controls = setTimeout(() => {
// We need controls of course...
if (!utils.is.element(this.elements.controls)) {
return;
}
// If the mouse is over the controls (and not entering fullscreen), bail
if ((this.elements.controls.pressed || this.elements.controls.hover) && !isEnterFullscreen) {
return;

View File

@ -1,6 +1,6 @@
// ==========================================================================
// Plyr Polyfilled Build
// plyr.js v3.0.8
// plyr.js v3.0.11
// https://github.com/sampotts/plyr
// License: The MIT License (MIT)
// ==========================================================================

View File

@ -74,6 +74,9 @@ const ui = {
// Reset quality options
this.options.quality = [];
// Reset volume display
ui.updateVolume.call(this);
// Reset time display
ui.timeUpdate.call(this);

122
yarn.lock
View File

@ -105,7 +105,7 @@ acorn-jsx@^3.0.0:
dependencies:
acorn "^3.0.4"
acorn@5.X, acorn@^5.0.3, acorn@^5.2.1, acorn@^5.5.0:
acorn@5.X, acorn@^5.0.3, acorn@^5.5.0:
version "5.5.3"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9"
@ -1775,7 +1775,7 @@ eslint-visitor-keys@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
eslint@^4.0.0, eslint@^4.19.0:
eslint@^4.0.0:
version "4.19.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.0.tgz#9e900efb5506812ac374557034ef6f5c3642fc4c"
dependencies:
@ -1818,6 +1818,49 @@ eslint@^4.0.0, eslint@^4.19.0:
table "4.0.2"
text-table "~0.2.0"
eslint@^4.19.1:
version "4.19.1"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300"
dependencies:
ajv "^5.3.0"
babel-code-frame "^6.22.0"
chalk "^2.1.0"
concat-stream "^1.6.0"
cross-spawn "^5.1.0"
debug "^3.1.0"
doctrine "^2.1.0"
eslint-scope "^3.7.1"
eslint-visitor-keys "^1.0.0"
espree "^3.5.4"
esquery "^1.0.0"
esutils "^2.0.2"
file-entry-cache "^2.0.0"
functional-red-black-tree "^1.0.1"
glob "^7.1.2"
globals "^11.0.1"
ignore "^3.3.3"
imurmurhash "^0.1.4"
inquirer "^3.0.6"
is-resolvable "^1.0.0"
js-yaml "^3.9.1"
json-stable-stringify-without-jsonify "^1.0.1"
levn "^0.3.0"
lodash "^4.17.4"
minimatch "^3.0.2"
mkdirp "^0.5.1"
natural-compare "^1.4.0"
optionator "^0.8.2"
path-is-inside "^1.0.2"
pluralize "^7.0.0"
progress "^2.0.0"
regexpp "^1.0.1"
require-uncached "^1.0.3"
semver "^5.3.0"
strip-ansi "^4.0.0"
strip-json-comments "~2.0.1"
table "4.0.2"
text-table "~0.2.0"
espree@^3.5.4:
version "3.5.4"
resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7"
@ -1857,7 +1900,7 @@ estree-walker@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.3.1.tgz#e6b1a51cf7292524e7237c312e5fe6660c1ce1aa"
estree-walker@^0.5.0:
estree-walker@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.5.1.tgz#64fc375053abc6f57d73e9bd2f004644ad3c5854"
@ -2444,13 +2487,13 @@ gulp-autoprefixer@^5.0.0:
through2 "^2.0.0"
vinyl-sourcemaps-apply "^0.2.0"
gulp-better-rollup@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/gulp-better-rollup/-/gulp-better-rollup-3.0.0.tgz#2bf5c2d0e7908fae72bba1f2496d24eb3c482e33"
gulp-better-rollup@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/gulp-better-rollup/-/gulp-better-rollup-3.1.0.tgz#b226ba0c672882075472158b82d22ba9976d4ecb"
dependencies:
lodash.camelcase "^4.3.0"
plugin-error "^0.1.2"
rollup "^0.50.0"
rollup ">=0.48 <0.57"
vinyl "^2.1.0"
vinyl-sourcemaps-apply "^0.2.1"
@ -2479,9 +2522,9 @@ gulp-filter@^5.1.0:
plugin-error "^0.1.2"
streamfilter "^1.0.5"
gulp-open@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/gulp-open/-/gulp-open-3.0.0.tgz#5a572a99044fdc461685d0eb8f7529b34bf9a62c"
gulp-open@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/gulp-open/-/gulp-open-3.0.1.tgz#a2f747b4aa31abec9399b527158b0368c57e2102"
dependencies:
colors "^1.1.2"
opn "5.2.0"
@ -2510,13 +2553,13 @@ gulp-s3@^0.11.0:
knox ""
mime "~1.2.11"
gulp-sass@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/gulp-sass/-/gulp-sass-3.1.0.tgz#53dc4b68a1f5ddfe4424ab4c247655269a8b74b7"
gulp-sass@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/gulp-sass/-/gulp-sass-3.2.1.tgz#2e3688a96fd8be1c0c01340750c191b2e79fab94"
dependencies:
gulp-util "^3.0"
lodash.clonedeep "^4.3.2"
node-sass "^4.2.0"
node-sass "^4.8.3"
through2 "^2.0.0"
vinyl-sourcemaps-apply "^0.2.0"
@ -3402,9 +3445,9 @@ load-json-file@^4.0.0:
pify "^3.0.0"
strip-bom "^3.0.0"
loadjs@^3.5.2:
version "3.5.2"
resolved "https://registry.yarnpkg.com/loadjs/-/loadjs-3.5.2.tgz#add0e0e0322859840b362598f762c02f5539ce0b"
loadjs@^3.5.4:
version "3.5.4"
resolved "https://registry.yarnpkg.com/loadjs/-/loadjs-3.5.4.tgz#ef0f4eb5a6ac2b86c7597a3d4de97b83816e36b8"
locate-path@^2.0.0:
version "2.0.0"
@ -3957,9 +4000,9 @@ mute-stream@0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
nan@^2.3.2:
version "2.9.2"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.9.2.tgz#f564d75f5f8f36a6d9456cca7a6c4fe488ab7866"
nan@^2.10.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f"
nanomatch@^1.2.9:
version "1.2.9"
@ -4008,9 +4051,9 @@ node-gyp@^3.3.1:
tar "^2.0.0"
which "1"
node-sass@^4.2.0:
version "4.7.2"
resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.7.2.tgz#9366778ba1469eb01438a9e8592f4262bcb6794e"
node-sass@^4.8.3:
version "4.8.3"
resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.8.3.tgz#d077cc20a08ac06f661ca44fb6f19cd2ed41debb"
dependencies:
async-foreach "^0.1.3"
chalk "^1.1.1"
@ -4024,7 +4067,7 @@ node-sass@^4.2.0:
lodash.mergewith "^4.6.0"
meow "^3.7.0"
mkdirp "^0.5.1"
nan "^2.3.2"
nan "^2.10.0"
node-gyp "^3.3.1"
npmlog "^4.0.0"
request "~2.79.0"
@ -4662,9 +4705,9 @@ randomatic@^1.1.3:
is-number "^3.0.0"
kind-of "^4.0.0"
raven-js@^3.23.3:
version "3.23.3"
resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.23.3.tgz#6174f506c7362eb8bb72b291af5f22edb44ef165"
raven-js@^3.24.0:
version "3.24.0"
resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.24.0.tgz#59464d8bc4b3812ae87a282e9bb98ecad5b4b047"
rc@^1.0.1, rc@^1.1.6:
version "1.2.6"
@ -5070,7 +5113,7 @@ resolve-url@^0.2.1, resolve-url@~0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
resolve@^1.1.6, resolve@^1.1.7, resolve@^1.4.0, resolve@^1.5.0:
resolve@^1.1.6, resolve@^1.1.7, resolve@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
dependencies:
@ -5099,19 +5142,18 @@ rollup-plugin-babel@^3.0.3:
dependencies:
rollup-pluginutils "^1.5.0"
rollup-plugin-commonjs@^8.4.1:
version "8.4.1"
resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-8.4.1.tgz#5c9cea2b2c3de322f5fbccd147e07ed5e502d7a0"
rollup-plugin-commonjs@^9.1.0:
version "9.1.0"
resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-9.1.0.tgz#468341aab32499123ee9a04b22f51d9bf26fdd94"
dependencies:
acorn "^5.2.1"
estree-walker "^0.5.0"
estree-walker "^0.5.1"
magic-string "^0.22.4"
resolve "^1.4.0"
resolve "^1.5.0"
rollup-pluginutils "^2.0.1"
rollup-plugin-node-resolve@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.2.0.tgz#31534952f3ab21f9473c1d092be7ed43937ea4d4"
rollup-plugin-node-resolve@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.3.0.tgz#c26d110a36812cbefa7ce117cadcd3439aa1c713"
dependencies:
builtin-modules "^2.0.0"
is-module "^1.0.0"
@ -5131,9 +5173,9 @@ rollup-pluginutils@^2.0.1:
estree-walker "^0.3.0"
micromatch "^2.3.11"
rollup@^0.50.0:
version "0.50.1"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.50.1.tgz#e4dafcbf8d2bb0d9f5589d0cc6f64d76b8815730"
"rollup@>=0.48 <0.57":
version "0.56.5"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.56.5.tgz#40fe3cf0cd1659d469baad11f4d5b6336c14ce84"
run-async@^2.2.0:
version "2.3.0"