From 78a8eb0219944f3a39898bb526497d5e2eb44eac Mon Sep 17 00:00:00 2001 From: shagi Date: Sat, 25 Jan 2020 17:44:53 +0100 Subject: [PATCH] Actualizar videojs, preparar la playlist para la guitarra --- .../static/js/videojs-ass/src/videojs.ass.css | 19 + .../static/js/videojs-ass/src/videojs.ass.js | 203 +- .../static/js/videojs/alt/video-js-cdn.css | 1180 +- .../js/videojs/alt/video-js-cdn.min.css | 2 +- .../static/js/videojs/alt/video.core.js | 16950 ++++--- .../static/js/videojs/alt/video.core.min.js | 11 +- .../static/js/videojs/alt/video.core.novtt.js | 16236 ++++--- .../js/videojs/alt/video.core.novtt.min.js | 11 +- .../static/js/videojs/alt/video.novtt.js | 36602 ++++++++------- .../static/js/videojs/alt/video.novtt.min.js | 20 +- .../examples/elephantsdream/index.html | 4 +- .../videojs/examples/simple-embed/index.html | 4 +- .../static/js/videojs/font/VideoJS.svg | 6 + .../static/js/videojs/font/VideoJS.ttf | Bin 6788 -> 7080 bytes .../static/js/videojs/font/VideoJS.woff | Bin 4168 -> 4324 bytes web/negromateweb/static/js/videojs/lang/ar.js | 66 +- .../static/js/videojs/lang/ar.json | 34 + web/negromateweb/static/js/videojs/lang/ba.js | 50 +- .../static/js/videojs/lang/ba.json | 26 + web/negromateweb/static/js/videojs/lang/bg.js | 50 +- .../static/js/videojs/lang/bg.json | 26 + web/negromateweb/static/js/videojs/lang/ca.js | 50 +- .../static/js/videojs/lang/ca.json | 26 + web/negromateweb/static/js/videojs/lang/cs.js | 168 +- .../static/js/videojs/lang/cs.json | 85 + web/negromateweb/static/js/videojs/lang/cy.js | 85 + .../static/js/videojs/lang/cy.json | 85 + web/negromateweb/static/js/videojs/lang/da.js | 50 +- .../static/js/videojs/lang/da.json | 26 + web/negromateweb/static/js/videojs/lang/de.js | 169 +- .../static/js/videojs/lang/de.json | 88 + web/negromateweb/static/js/videojs/lang/el.js | 78 +- .../static/js/videojs/lang/el.json | 40 + web/negromateweb/static/js/videojs/lang/en.js | 170 +- .../static/js/videojs/lang/en.json | 87 + web/negromateweb/static/js/videojs/lang/es.js | 112 +- .../static/js/videojs/lang/es.json | 87 + web/negromateweb/static/js/videojs/lang/fa.js | 166 +- .../static/js/videojs/lang/fa.json | 84 + web/negromateweb/static/js/videojs/lang/fi.js | 50 +- .../static/js/videojs/lang/fi.json | 26 + web/negromateweb/static/js/videojs/lang/fr.js | 166 +- .../static/js/videojs/lang/fr.json | 84 + web/negromateweb/static/js/videojs/lang/gd.js | 87 + .../static/js/videojs/lang/gd.json | 87 + web/negromateweb/static/js/videojs/lang/gl.js | 112 +- .../static/js/videojs/lang/gl.json | 87 + web/negromateweb/static/js/videojs/lang/he.js | 166 +- .../static/js/videojs/lang/he.json | 84 + web/negromateweb/static/js/videojs/lang/hr.js | 50 +- .../static/js/videojs/lang/hr.json | 26 + web/negromateweb/static/js/videojs/lang/hu.js | 50 +- .../static/js/videojs/lang/hu.json | 26 + web/negromateweb/static/js/videojs/lang/it.js | 50 +- .../static/js/videojs/lang/it.json | 26 + web/negromateweb/static/js/videojs/lang/ja.js | 50 +- .../static/js/videojs/lang/ja.json | 26 + web/negromateweb/static/js/videojs/lang/ko.js | 50 +- .../static/js/videojs/lang/ko.json | 26 + web/negromateweb/static/js/videojs/lang/nb.js | 111 +- .../static/js/videojs/lang/nb.json | 87 + web/negromateweb/static/js/videojs/lang/nl.js | 166 +- .../static/js/videojs/lang/nl.json | 84 + web/negromateweb/static/js/videojs/lang/nn.js | 111 +- .../static/js/videojs/lang/nn.json | 87 + web/negromateweb/static/js/videojs/lang/oc.js | 87 + .../static/js/videojs/lang/oc.json | 87 + web/negromateweb/static/js/videojs/lang/pl.js | 66 +- .../static/js/videojs/lang/pl.json | 34 + .../static/js/videojs/lang/pt-BR.js | 168 +- .../static/js/videojs/lang/pt-BR.json | 86 + .../static/js/videojs/lang/pt-PT.js | 80 +- .../static/js/videojs/lang/pt-PT.json | 41 + web/negromateweb/static/js/videojs/lang/ru.js | 167 +- .../static/js/videojs/lang/ru.json | 85 + web/negromateweb/static/js/videojs/lang/sk.js | 168 +- .../static/js/videojs/lang/sk.json | 85 + web/negromateweb/static/js/videojs/lang/sr.js | 50 +- .../static/js/videojs/lang/sr.json | 26 + web/negromateweb/static/js/videojs/lang/sv.js | 111 +- .../static/js/videojs/lang/sv.json | 87 + web/negromateweb/static/js/videojs/lang/tr.js | 150 +- .../static/js/videojs/lang/tr.json | 76 + web/negromateweb/static/js/videojs/lang/uk.js | 123 +- .../static/js/videojs/lang/uk.json | 85 + web/negromateweb/static/js/videojs/lang/vi.js | 166 +- .../static/js/videojs/lang/vi.json | 84 + .../static/js/videojs/lang/zh-CN.js | 168 +- .../static/js/videojs/lang/zh-CN.json | 87 + .../static/js/videojs/lang/zh-Hans.js | 87 + .../static/js/videojs/lang/zh-Hans.json | 87 + .../static/js/videojs/lang/zh-Hant.js | 87 + .../static/js/videojs/lang/zh-Hant.json | 87 + .../static/js/videojs/lang/zh-TW.js | 168 +- .../static/js/videojs/lang/zh-TW.json | 87 + .../static/js/videojs/video-js.css | 1180 +- .../static/js/videojs/video-js.min.css | 2 +- .../static/js/videojs/video.cjs.js | 25018 +++++----- .../static/js/videojs/video.es.js | 25016 +++++----- web/negromateweb/static/js/videojs/video.js | 37660 ++++++++-------- .../static/js/videojs/video.min.js | 20 +- web/negromateweb/templates/base.html | 5 +- web/negromateweb/templates/playlist.html | 62 +- web/negromateweb/templates/song.html | 13 +- web/requirements.txt | 1 + 105 files changed, 89456 insertions(+), 77622 deletions(-) mode change 100644 => 100755 web/negromateweb/static/js/videojs/font/VideoJS.svg mode change 100644 => 100755 web/negromateweb/static/js/videojs/font/VideoJS.ttf mode change 100644 => 100755 web/negromateweb/static/js/videojs/font/VideoJS.woff create mode 100644 web/negromateweb/static/js/videojs/lang/ar.json create mode 100644 web/negromateweb/static/js/videojs/lang/ba.json create mode 100644 web/negromateweb/static/js/videojs/lang/bg.json create mode 100644 web/negromateweb/static/js/videojs/lang/ca.json create mode 100644 web/negromateweb/static/js/videojs/lang/cs.json create mode 100644 web/negromateweb/static/js/videojs/lang/cy.js create mode 100644 web/negromateweb/static/js/videojs/lang/cy.json create mode 100644 web/negromateweb/static/js/videojs/lang/da.json create mode 100644 web/negromateweb/static/js/videojs/lang/de.json create mode 100644 web/negromateweb/static/js/videojs/lang/el.json create mode 100644 web/negromateweb/static/js/videojs/lang/en.json create mode 100644 web/negromateweb/static/js/videojs/lang/es.json create mode 100644 web/negromateweb/static/js/videojs/lang/fa.json create mode 100644 web/negromateweb/static/js/videojs/lang/fi.json create mode 100644 web/negromateweb/static/js/videojs/lang/fr.json create mode 100644 web/negromateweb/static/js/videojs/lang/gd.js create mode 100755 web/negromateweb/static/js/videojs/lang/gd.json create mode 100644 web/negromateweb/static/js/videojs/lang/gl.json create mode 100644 web/negromateweb/static/js/videojs/lang/he.json create mode 100644 web/negromateweb/static/js/videojs/lang/hr.json create mode 100644 web/negromateweb/static/js/videojs/lang/hu.json create mode 100644 web/negromateweb/static/js/videojs/lang/it.json create mode 100644 web/negromateweb/static/js/videojs/lang/ja.json create mode 100644 web/negromateweb/static/js/videojs/lang/ko.json create mode 100644 web/negromateweb/static/js/videojs/lang/nb.json create mode 100644 web/negromateweb/static/js/videojs/lang/nl.json create mode 100644 web/negromateweb/static/js/videojs/lang/nn.json create mode 100644 web/negromateweb/static/js/videojs/lang/oc.js create mode 100644 web/negromateweb/static/js/videojs/lang/oc.json create mode 100644 web/negromateweb/static/js/videojs/lang/pl.json create mode 100644 web/negromateweb/static/js/videojs/lang/pt-BR.json create mode 100644 web/negromateweb/static/js/videojs/lang/pt-PT.json create mode 100644 web/negromateweb/static/js/videojs/lang/ru.json create mode 100644 web/negromateweb/static/js/videojs/lang/sk.json create mode 100644 web/negromateweb/static/js/videojs/lang/sr.json create mode 100644 web/negromateweb/static/js/videojs/lang/sv.json create mode 100644 web/negromateweb/static/js/videojs/lang/tr.json create mode 100644 web/negromateweb/static/js/videojs/lang/uk.json create mode 100644 web/negromateweb/static/js/videojs/lang/vi.json create mode 100644 web/negromateweb/static/js/videojs/lang/zh-CN.json create mode 100644 web/negromateweb/static/js/videojs/lang/zh-Hans.js create mode 100644 web/negromateweb/static/js/videojs/lang/zh-Hans.json create mode 100644 web/negromateweb/static/js/videojs/lang/zh-Hant.js create mode 100644 web/negromateweb/static/js/videojs/lang/zh-Hant.json create mode 100644 web/negromateweb/static/js/videojs/lang/zh-TW.json diff --git a/web/negromateweb/static/js/videojs-ass/src/videojs.ass.css b/web/negromateweb/static/js/videojs-ass/src/videojs.ass.css index 782a569..a9e2218 100644 --- a/web/negromateweb/static/js/videojs-ass/src/videojs.ass.css +++ b/web/negromateweb/static/js/videojs-ass/src/videojs.ass.css @@ -7,3 +7,22 @@ pointer-events: none; } + +.vjs-default-skin .vjs-ass-button { + cursor: pointer; +} + +.vjs-default-skin .vjs-ass-button:before { + font-family: VideoJS; + content: '\f10c'; +} + +.vjs-default-skin .vjs-ass-button.inactive { + color: grey; +} + +/* Backport from libjass v0.11 */ +.libjass-subs, .libjass-subs * { + -webkit-animation-fill-mode: both; + animation-fill-mode: both; +} diff --git a/web/negromateweb/static/js/videojs-ass/src/videojs.ass.js b/web/negromateweb/static/js/videojs-ass/src/videojs.ass.js index 85f8f65..d940382 100644 --- a/web/negromateweb/static/js/videojs-ass/src/videojs.ass.js +++ b/web/negromateweb/static/js/videojs-ass/src/videojs.ass.js @@ -6,112 +6,69 @@ 'use strict'; var vjs_ass = function (options) { - var cur_id = 0, - id_count = 0, - overlay = document.createElement('div'), - clocks = [], + var overlay = document.createElement('div'), + clock = null, clockRate = options.rate || 1, delay = options.delay || 0, player = this, - renderers = [], - rendererSettings = null, - OverlayComponent = null, - assTrackIdMap = {}, - tracks = player.textTracks(), - isTrackSwitching = false; + renderer = null, + AssButton = null, + AssButtonInstance = null, + VjsButton = null; if (!options.src) { return; } overlay.className = 'vjs-ass'; - - OverlayComponent = { - name: function () { - return 'AssOverlay'; - }, - el: function () { - return overlay; - } - } - - player.addChild(OverlayComponent, {}, 3); + player.el().insertBefore(overlay, player.el().firstChild.nextSibling); function getCurrentTime() { return player.currentTime() - delay; } - clocks[cur_id] = new libjass.renderers.AutoClock(getCurrentTime, 500); + clock = new libjass.renderers.AutoClock(getCurrentTime, 500); player.on('play', function () { - clocks[cur_id].play(); + clock.play(); }); player.on('pause', function () { - clocks[cur_id].pause(); + clock.pause(); }); player.on('seeking', function () { - clocks[cur_id].seeking(); + clock.seeking(); }); function updateClockRate() { - clocks[cur_id].setRate(player.playbackRate() * clockRate); + clock.setRate(player.playbackRate() * clockRate); } - + updateClockRate(); player.on('ratechange', updateClockRate); function updateDisplayArea() { setTimeout(function () { - // player might not have information on video dimensions when using external providers - var videoWidth = options.videoWidth || player.videoWidth() || player.el().offsetWidth, - videoHeight = options.videoHeight || player.videoHeight() || player.el().offsetHeight, - videoOffsetWidth = player.el().offsetWidth, - videoOffsetHeight = player.el().offsetHeight, - - ratio = Math.min(videoOffsetWidth / videoWidth, videoOffsetHeight / videoHeight), - subsWrapperWidth = videoWidth * ratio, - subsWrapperHeight = videoHeight * ratio, - subsWrapperLeft = (videoOffsetWidth - subsWrapperWidth) / 2, - subsWrapperTop = (videoOffsetHeight - subsWrapperHeight) / 2; - - renderers[cur_id].resize(subsWrapperWidth, subsWrapperHeight, subsWrapperLeft, subsWrapperTop); + renderer.resize(player.el().offsetWidth, player.el().offsetHeight); }, 100); } + + if (player.fluid()) { + window.addEventListener('resize', updateDisplayArea); + } - window.addEventListener('resize', updateDisplayArea); player.on('loadedmetadata', updateDisplayArea); player.on('resize', updateDisplayArea); player.on('fullscreenchange', updateDisplayArea); player.on('dispose', function () { - for (var i = 0; i < clocks.length; i++) { - clocks[i].disable(); - } - window.removeEventListener('resize', updateDisplayArea); + clock.disable(); }); - tracks.on('change', function () { - if (isTrackSwitching) { - return; - } - - var activeTrack = this.tracks_.find(function (track) { - return track.mode === 'showing'; - }); - - if (activeTrack) { - overlay.style.display = ''; - switchTrackTo(assTrackIdMap[activeTrack.language + activeTrack.label]); - } else { - overlay.style.display = 'none'; - } - }) - - rendererSettings = new libjass.renderers.RendererSettings(); libjass.ASS.fromUrl(options.src, libjass.Format.ASS).then( function (ass) { + var rendererSettings = new libjass.renderers.RendererSettings(); if (options.hasOwnProperty('enableSvg')) { rendererSettings.enableSvg = options.enableSvg; } @@ -122,101 +79,43 @@ .makeFontMapFromStyleElement(document.getElementById(options.fontMapById)); } - addTrack(options.src, { label: options.label, srclang: options.srclang, switchImmediately: true }); - renderers[cur_id] = new libjass.renderers.WebRenderer(ass, clocks[cur_id], overlay, rendererSettings); + renderer = new libjass.renderers.WebRenderer(ass, clock, overlay, rendererSettings); + console.debug(renderer); } ); - function addTrack(url, opts) { - var newTrack = player.addRemoteTextTrack({ - src: "", - kind: 'subtitles', - label: opts.label || 'ASS #' + cur_id, - srclang: opts.srclang || 'vjs-ass-' + cur_id, - default: opts.switchImmediately + // Visibility Toggle Button + if (!options.hasOwnProperty('button') || options.button) { + VjsButton = videojs.getComponent('Button'); + AssButton = videojs.extend(VjsButton, { + constructor: function (player, options) { + options.name = options.name || 'assToggleButton'; + VjsButton.call(this, player, options); + + this.addClass('vjs-ass-button'); + + this.on('click', this.onClick); + }, + onClick: function () { + if (!this.hasClass('inactive')) { + this.addClass('inactive'); + overlay.style.display = "none"; + } else { + this.removeClass('inactive'); + overlay.style.display = ""; + } + } }); - assTrackIdMap[newTrack.srclang + newTrack.label] = cur_id; - - if(!opts.switchImmediately) { - // fix multiple track selected highlight issue - for (var t = 0; t < tracks.length; t++) { - if (tracks[t].mode === "showing") { - tracks[t].mode = "showing"; - } - } - return; - } - - isTrackSwitching = true; - for (var t = 0; t < tracks.length; t++) { - if (tracks[t].label == newTrack.label && tracks[t].language == newTrack.srclang) { - if (tracks[t].mode !== "showing") { - tracks[t].mode = "showing"; - } - } else { - if (tracks[t].mode === "showing") { - tracks[t].mode = "disabled"; - } - } - } - isTrackSwitching = false; + player.ready(function () { + AssButtonInstance = new AssButton(player, options); + player.controlBar.addChild(AssButtonInstance); + player.controlBar.el().insertBefore( + AssButtonInstance.el(), + player.controlBar.getChild('customControlSpacer').el().nextSibling + ); + }); } - - function switchTrackTo(selected_track_id) { - renderers[cur_id]._removeAllSubs(); - renderers[cur_id]._preRenderedSubs.clear(); - renderers[cur_id].clock.disable(); - - cur_id = selected_track_id; - if (cur_id == undefined) { - // case when we switche to regular non ASS closed captioning - return; - } - - renderers[cur_id].clock.enable(); - updateDisplayArea(); - clocks[cur_id].play(); - } - - /* - Experimental API use at your own risk!! - */ - function loadNewSubtitle(url, label, srclang, switchImmediately) { - var old_id = cur_id; - if (switchImmediately) { - renderers[cur_id]._removeAllSubs(); - renderers[cur_id]._preRenderedSubs.clear(); - renderers[cur_id].clock.disable(); - } - - libjass.ASS.fromUrl(url, libjass.Format.ASS).then( - function (ass) { - cur_id = ++id_count; - clocks[cur_id] = new libjass.renderers.AutoClock(getCurrentTime, 500); - renderers[cur_id] = new libjass.renderers.WebRenderer(ass, clocks[cur_id], overlay, rendererSettings); - updateDisplayArea(); - - if (switchImmediately) { - clocks[cur_id].play(); - } else { - renderers[cur_id]._removeAllSubs(); - renderers[cur_id]._preRenderedSubs.clear(); - renderers[cur_id].clock.disable(); - } - - addTrack(options.src, { label: label, srclang: srclang, switchImmediately: switchImmediately }); - - if (!switchImmediately) { - cur_id = old_id; - } - } - ); - }; - - return { - loadNewSubtitle: loadNewSubtitle - }; }; videojs.plugin('ass', vjs_ass); diff --git a/web/negromateweb/static/js/videojs/alt/video-js-cdn.css b/web/negromateweb/static/js/videojs/alt/video-js-cdn.css index 1402829..5b0e3b9 100644 --- a/web/negromateweb/static/js/videojs/alt/video-js-cdn.css +++ b/web/negromateweb/static/js/videojs/alt/video-js-cdn.css @@ -1,252 +1,337 @@ -.video-js .vjs-big-play-button .vjs-icon-placeholder:before, .vjs-button > .vjs-icon-placeholder:before, .video-js .vjs-modal-dialog, .vjs-modal-dialog .vjs-modal-dialog-content { +@charset "UTF-8"; +.vjs-modal-dialog .vjs-modal-dialog-content, .video-js .vjs-modal-dialog, .vjs-button > .vjs-icon-placeholder:before, .video-js .vjs-big-play-button .vjs-icon-placeholder:before { position: absolute; top: 0; left: 0; width: 100%; - height: 100%; } + height: 100%; +} -.video-js .vjs-big-play-button .vjs-icon-placeholder:before, .vjs-button > .vjs-icon-placeholder:before { - text-align: center; } +.vjs-button > .vjs-icon-placeholder:before, .video-js .vjs-big-play-button .vjs-icon-placeholder:before { + text-align: center; +} @font-face { font-family: VideoJS; - src: url(data:application/font-woff;charset=utf-8;base64,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) format("woff"); + src: url(data:application/font-woff;charset=utf-8;base64,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) format("woff"); font-weight: normal; - font-style: normal; } - -.vjs-icon-play, .video-js .vjs-big-play-button .vjs-icon-placeholder:before, .video-js .vjs-play-control .vjs-icon-placeholder { + font-style: normal; +} +.vjs-icon-play, .video-js .vjs-play-control .vjs-icon-placeholder, .video-js .vjs-big-play-button .vjs-icon-placeholder:before { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-play:before, .video-js .vjs-big-play-button .vjs-icon-placeholder:before, .video-js .vjs-play-control .vjs-icon-placeholder:before { - content: "\f101"; } + font-style: normal; +} +.vjs-icon-play:before, .video-js .vjs-play-control .vjs-icon-placeholder:before, .video-js .vjs-big-play-button .vjs-icon-placeholder:before { + content: "\f101"; +} .vjs-icon-play-circle { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-play-circle:before { - content: "\f102"; } + font-style: normal; +} +.vjs-icon-play-circle:before { + content: "\f102"; +} .vjs-icon-pause, .video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-pause:before, .video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder:before { - content: "\f103"; } + font-style: normal; +} +.vjs-icon-pause:before, .video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder:before { + content: "\f103"; +} .vjs-icon-volume-mute, .video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-volume-mute:before, .video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder:before { - content: "\f104"; } + font-style: normal; +} +.vjs-icon-volume-mute:before, .video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder:before { + content: "\f104"; +} .vjs-icon-volume-low, .video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-volume-low:before, .video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder:before { - content: "\f105"; } + font-style: normal; +} +.vjs-icon-volume-low:before, .video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder:before { + content: "\f105"; +} .vjs-icon-volume-mid, .video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-volume-mid:before, .video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder:before { - content: "\f106"; } + font-style: normal; +} +.vjs-icon-volume-mid:before, .video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder:before { + content: "\f106"; +} .vjs-icon-volume-high, .video-js .vjs-mute-control .vjs-icon-placeholder { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-volume-high:before, .video-js .vjs-mute-control .vjs-icon-placeholder:before { - content: "\f107"; } + font-style: normal; +} +.vjs-icon-volume-high:before, .video-js .vjs-mute-control .vjs-icon-placeholder:before { + content: "\f107"; +} .vjs-icon-fullscreen-enter, .video-js .vjs-fullscreen-control .vjs-icon-placeholder { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-fullscreen-enter:before, .video-js .vjs-fullscreen-control .vjs-icon-placeholder:before { - content: "\f108"; } + font-style: normal; +} +.vjs-icon-fullscreen-enter:before, .video-js .vjs-fullscreen-control .vjs-icon-placeholder:before { + content: "\f108"; +} .vjs-icon-fullscreen-exit, .video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-fullscreen-exit:before, .video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder:before { - content: "\f109"; } + font-style: normal; +} +.vjs-icon-fullscreen-exit:before, .video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder:before { + content: "\f109"; +} .vjs-icon-square { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-square:before { - content: "\f10a"; } + font-style: normal; +} +.vjs-icon-square:before { + content: "\f10a"; +} .vjs-icon-spinner { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-spinner:before { - content: "\f10b"; } + font-style: normal; +} +.vjs-icon-spinner:before { + content: "\f10b"; +} -.vjs-icon-subtitles, .video-js .vjs-subtitles-button .vjs-icon-placeholder, .video-js .vjs-subs-caps-button .vjs-icon-placeholder, +.vjs-icon-subtitles, .video-js .vjs-subs-caps-button .vjs-icon-placeholder, .video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder, .video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder, .video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder, -.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder { +.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder, .video-js .vjs-subtitles-button .vjs-icon-placeholder { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-subtitles:before, .video-js .vjs-subtitles-button .vjs-icon-placeholder:before, .video-js .vjs-subs-caps-button .vjs-icon-placeholder:before, - .video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder:before, - .video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder:before, - .video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder:before, - .video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder:before { - content: "\f10c"; } + font-style: normal; +} +.vjs-icon-subtitles:before, .video-js .vjs-subs-caps-button .vjs-icon-placeholder:before, +.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder:before, +.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder:before, +.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder:before, +.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder:before, .video-js .vjs-subtitles-button .vjs-icon-placeholder:before { + content: "\f10c"; +} -.vjs-icon-captions, .video-js .vjs-captions-button .vjs-icon-placeholder, .video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder, -.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder { +.vjs-icon-captions, .video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder, +.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder, .video-js .vjs-captions-button .vjs-icon-placeholder { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-captions:before, .video-js .vjs-captions-button .vjs-icon-placeholder:before, .video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder:before, - .video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder:before { - content: "\f10d"; } + font-style: normal; +} +.vjs-icon-captions:before, .video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder:before, +.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder:before, .video-js .vjs-captions-button .vjs-icon-placeholder:before { + content: "\f10d"; +} .vjs-icon-chapters, .video-js .vjs-chapters-button .vjs-icon-placeholder { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-chapters:before, .video-js .vjs-chapters-button .vjs-icon-placeholder:before { - content: "\f10e"; } + font-style: normal; +} +.vjs-icon-chapters:before, .video-js .vjs-chapters-button .vjs-icon-placeholder:before { + content: "\f10e"; +} .vjs-icon-share { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-share:before { - content: "\f10f"; } + font-style: normal; +} +.vjs-icon-share:before { + content: "\f10f"; +} .vjs-icon-cog { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-cog:before { - content: "\f110"; } + font-style: normal; +} +.vjs-icon-cog:before { + content: "\f110"; +} -.vjs-icon-circle, .video-js .vjs-play-progress, .video-js .vjs-volume-level { +.vjs-icon-circle, .vjs-seek-to-live-control .vjs-icon-placeholder, .video-js .vjs-volume-level, .video-js .vjs-play-progress { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-circle:before, .video-js .vjs-play-progress:before, .video-js .vjs-volume-level:before { - content: "\f111"; } + font-style: normal; +} +.vjs-icon-circle:before, .vjs-seek-to-live-control .vjs-icon-placeholder:before, .video-js .vjs-volume-level:before, .video-js .vjs-play-progress:before { + content: "\f111"; +} .vjs-icon-circle-outline { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-circle-outline:before { - content: "\f112"; } + font-style: normal; +} +.vjs-icon-circle-outline:before { + content: "\f112"; +} .vjs-icon-circle-inner-circle { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-circle-inner-circle:before { - content: "\f113"; } + font-style: normal; +} +.vjs-icon-circle-inner-circle:before { + content: "\f113"; +} .vjs-icon-hd { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-hd:before { - content: "\f114"; } + font-style: normal; +} +.vjs-icon-hd:before { + content: "\f114"; +} .vjs-icon-cancel, .video-js .vjs-control.vjs-close-button .vjs-icon-placeholder { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-cancel:before, .video-js .vjs-control.vjs-close-button .vjs-icon-placeholder:before { - content: "\f115"; } + font-style: normal; +} +.vjs-icon-cancel:before, .video-js .vjs-control.vjs-close-button .vjs-icon-placeholder:before { + content: "\f115"; +} .vjs-icon-replay, .video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-replay:before, .video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder:before { - content: "\f116"; } + font-style: normal; +} +.vjs-icon-replay:before, .video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder:before { + content: "\f116"; +} .vjs-icon-facebook { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-facebook:before { - content: "\f117"; } + font-style: normal; +} +.vjs-icon-facebook:before { + content: "\f117"; +} .vjs-icon-gplus { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-gplus:before { - content: "\f118"; } + font-style: normal; +} +.vjs-icon-gplus:before { + content: "\f118"; +} .vjs-icon-linkedin { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-linkedin:before { - content: "\f119"; } + font-style: normal; +} +.vjs-icon-linkedin:before { + content: "\f119"; +} .vjs-icon-twitter { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-twitter:before { - content: "\f11a"; } + font-style: normal; +} +.vjs-icon-twitter:before { + content: "\f11a"; +} .vjs-icon-tumblr { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-tumblr:before { - content: "\f11b"; } + font-style: normal; +} +.vjs-icon-tumblr:before { + content: "\f11b"; +} .vjs-icon-pinterest { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-pinterest:before { - content: "\f11c"; } + font-style: normal; +} +.vjs-icon-pinterest:before { + content: "\f11c"; +} .vjs-icon-audio-description, .video-js .vjs-descriptions-button .vjs-icon-placeholder { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-audio-description:before, .video-js .vjs-descriptions-button .vjs-icon-placeholder:before { - content: "\f11d"; } + font-style: normal; +} +.vjs-icon-audio-description:before, .video-js .vjs-descriptions-button .vjs-icon-placeholder:before { + content: "\f11d"; +} .vjs-icon-audio, .video-js .vjs-audio-button .vjs-icon-placeholder { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-audio:before, .video-js .vjs-audio-button .vjs-icon-placeholder:before { - content: "\f11e"; } + font-style: normal; +} +.vjs-icon-audio:before, .video-js .vjs-audio-button .vjs-icon-placeholder:before { + content: "\f11e"; +} .vjs-icon-next-item { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-next-item:before { - content: "\f11f"; } + font-style: normal; +} +.vjs-icon-next-item:before { + content: "\f11f"; +} .vjs-icon-previous-item { font-family: VideoJS; font-weight: normal; - font-style: normal; } - .vjs-icon-previous-item:before { - content: "\f120"; } + font-style: normal; +} +.vjs-icon-previous-item:before { + content: "\f120"; +} + +.vjs-icon-picture-in-picture-enter, .video-js .vjs-picture-in-picture-control .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-picture-in-picture-enter:before, .video-js .vjs-picture-in-picture-control .vjs-icon-placeholder:before { + content: "\f121"; +} + +.vjs-icon-picture-in-picture-exit, .video-js.vjs-picture-in-picture .vjs-picture-in-picture-control .vjs-icon-placeholder { + font-family: VideoJS; + font-weight: normal; + font-style: normal; +} +.vjs-icon-picture-in-picture-exit:before, .video-js.vjs-picture-in-picture .vjs-picture-in-picture-control .vjs-icon-placeholder:before { + content: "\f122"; +} .video-js { display: block; @@ -261,20 +346,25 @@ font-weight: normal; font-style: normal; font-family: Arial, Helvetica, sans-serif; - word-break: initial; } - .video-js:-moz-full-screen { - position: absolute; } - .video-js:-webkit-full-screen { - width: 100% !important; - height: 100% !important; } + word-break: initial; +} +.video-js:-moz-full-screen { + position: absolute; +} +.video-js:-webkit-full-screen { + width: 100% !important; + height: 100% !important; +} .video-js[tabindex="-1"] { - outline: none; } + outline: none; +} .video-js *, .video-js *:before, .video-js *:after { - box-sizing: inherit; } + box-sizing: inherit; +} .video-js ul { font-family: inherit; @@ -284,36 +374,43 @@ margin-left: 0; margin-right: 0; margin-top: 0; - margin-bottom: 0; } + margin-bottom: 0; +} .video-js.vjs-fluid, .video-js.vjs-16-9, .video-js.vjs-4-3 { width: 100%; max-width: 100%; - height: 0; } + height: 0; +} .video-js.vjs-16-9 { - padding-top: 56.25%; } + padding-top: 56.25%; +} .video-js.vjs-4-3 { - padding-top: 75%; } + padding-top: 75%; +} .video-js.vjs-fill { width: 100%; - height: 100%; } + height: 100%; +} .video-js .vjs-tech { position: absolute; top: 0; left: 0; width: 100%; - height: 100%; } + height: 100%; +} body.vjs-full-window { padding: 0; margin: 0; - height: 100%; } + height: 100%; +} .vjs-full-window .video-js.vjs-fullscreen { position: fixed; @@ -322,34 +419,41 @@ body.vjs-full-window { left: 0; top: 0; bottom: 0; - right: 0; } + right: 0; +} .video-js.vjs-fullscreen { width: 100% !important; height: 100% !important; - padding-top: 0 !important; } + padding-top: 0 !important; +} .video-js.vjs-fullscreen.vjs-user-inactive { - cursor: none; } + cursor: none; +} .vjs-hidden { - display: none !important; } + display: none !important; +} .vjs-disabled { opacity: 0.5; - cursor: default; } + cursor: default; +} .video-js .vjs-offscreen { height: 1px; left: -9999px; position: absolute; top: 0; - width: 1px; } + width: 1px; +} .vjs-lock-showing { display: block !important; opacity: 1; - visibility: visible; } + visibility: visible; +} .vjs-no-js { padding: 20px; @@ -360,16 +464,18 @@ body.vjs-full-window { text-align: center; width: 300px; height: 150px; - margin: 0px auto; } + margin: 0px auto; +} .vjs-no-js a, .vjs-no-js a:visited { - color: #66A8CC; } + color: #66A8CC; +} .video-js .vjs-big-play-button { font-size: 3em; line-height: 1.5em; - height: 1.5em; + height: 1.63332em; width: 3em; display: block; position: absolute; @@ -382,29 +488,33 @@ body.vjs-full-window { background-color: #2B333F; background-color: rgba(43, 51, 63, 0.7); border-radius: 0.3em; - transition: all 0.4s; } - + transition: all 0.4s; +} .vjs-big-play-centered .vjs-big-play-button { top: 50%; left: 50%; - margin-top: -0.75em; - margin-left: -1.5em; } + margin-top: -0.81666em; + margin-left: -1.5em; +} .video-js:hover .vjs-big-play-button, .video-js .vjs-big-play-button:focus { border-color: #fff; background-color: #73859f; background-color: rgba(115, 133, 159, 0.5); - transition: all 0s; } + transition: all 0s; +} .vjs-controls-disabled .vjs-big-play-button, .vjs-has-started .vjs-big-play-button, .vjs-using-native-controls .vjs-big-play-button, .vjs-error .vjs-big-play-button { - display: none; } + display: none; +} .vjs-has-started.vjs-paused.vjs-show-big-play-button-on-pause .vjs-big-play-button { - display: block; } + display: block; +} .video-js button { background: none; @@ -418,11 +528,13 @@ body.vjs-full-window { transition: none; -webkit-appearance: none; -moz-appearance: none; - appearance: none; } + appearance: none; +} .vjs-control .vjs-button { width: 100%; - height: 100%; } + height: 100%; +} .video-js .vjs-control.vjs-close-button { cursor: pointer; @@ -430,43 +542,52 @@ body.vjs-full-window { position: absolute; right: 0; top: 0.5em; - z-index: 2; } - + z-index: 2; +} .video-js .vjs-modal-dialog { background: rgba(0, 0, 0, 0.8); background: linear-gradient(180deg, rgba(0, 0, 0, 0.8), rgba(255, 255, 255, 0)); - overflow: auto; } + overflow: auto; +} .video-js .vjs-modal-dialog > * { - box-sizing: border-box; } + box-sizing: border-box; +} .vjs-modal-dialog .vjs-modal-dialog-content { font-size: 1.2em; line-height: 1.5; padding: 20px 24px; - z-index: 1; } + z-index: 1; +} .vjs-menu-button { - cursor: pointer; } + cursor: pointer; +} .vjs-menu-button.vjs-disabled { - cursor: default; } + cursor: default; +} .vjs-workinghover .vjs-menu-button.vjs-disabled:hover .vjs-menu { - display: none; } + display: none; +} .vjs-menu .vjs-menu-content { display: block; padding: 0; margin: 0; font-family: Arial, Helvetica, sans-serif; - overflow: auto; } + overflow: auto; +} .vjs-menu .vjs-menu-content > * { - box-sizing: border-box; } + box-sizing: border-box; +} .vjs-scrubbing .vjs-control.vjs-menu-button:hover .vjs-menu { - display: none; } + display: none; +} .vjs-menu li { list-style: none; @@ -475,18 +596,23 @@ body.vjs-full-window { line-height: 1.4em; font-size: 1.2em; text-align: center; - text-transform: lowercase; } + text-transform: lowercase; +} .vjs-menu li.vjs-menu-item:focus, -.vjs-menu li.vjs-menu-item:hover { +.vjs-menu li.vjs-menu-item:hover, +.js-focus-visible .vjs-menu li.vjs-menu-item:hover { background-color: #73859f; - background-color: rgba(115, 133, 159, 0.5); } + background-color: rgba(115, 133, 159, 0.5); +} .vjs-menu li.vjs-selected, .vjs-menu li.vjs-selected:focus, -.vjs-menu li.vjs-selected:hover { +.vjs-menu li.vjs-selected:hover, +.js-focus-visible .vjs-menu li.vjs-selected:hover { background-color: #fff; - color: #2B333F; } + color: #2B333F; +} .vjs-menu li.vjs-menu-title { text-align: center; @@ -496,7 +622,8 @@ body.vjs-full-window { padding: 0; margin: 0 0 0.3em 0; font-weight: bold; - cursor: default; } + cursor: default; +} .vjs-menu-button-popup .vjs-menu { display: none; @@ -506,7 +633,8 @@ body.vjs-full-window { left: -3em; height: 0em; margin-bottom: 1.5em; - border-top-color: rgba(43, 51, 63, 0.7); } + border-top-color: rgba(43, 51, 63, 0.7); +} .vjs-menu-button-popup .vjs-menu .vjs-menu-content { background-color: #2B333F; @@ -514,24 +642,48 @@ body.vjs-full-window { position: absolute; width: 100%; bottom: 1.5em; - max-height: 15em; } + max-height: 15em; +} -.vjs-workinghover .vjs-menu-button-popup:hover .vjs-menu, +.vjs-layout-tiny .vjs-menu-button-popup .vjs-menu .vjs-menu-content, +.vjs-layout-x-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content { + max-height: 5em; +} + +.vjs-layout-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content { + max-height: 10em; +} + +.vjs-layout-medium .vjs-menu-button-popup .vjs-menu .vjs-menu-content { + max-height: 14em; +} + +.vjs-layout-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content, +.vjs-layout-x-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content, +.vjs-layout-huge .vjs-menu-button-popup .vjs-menu .vjs-menu-content { + max-height: 25em; +} + +.vjs-workinghover .vjs-menu-button-popup.vjs-hover .vjs-menu, .vjs-menu-button-popup .vjs-menu.vjs-lock-showing { - display: block; } + display: block; +} .video-js .vjs-menu-button-inline { transition: all 0.4s; - overflow: hidden; } + overflow: hidden; +} .video-js .vjs-menu-button-inline:before { - width: 2.222222222em; } + width: 2.222222222em; +} .video-js .vjs-menu-button-inline:hover, .video-js .vjs-menu-button-inline:focus, .video-js .vjs-menu-button-inline.vjs-slider-active, .video-js.vjs-no-flex .vjs-menu-button-inline { - width: 12em; } + width: 12em; +} .vjs-menu-button-inline .vjs-menu { opacity: 0; @@ -542,30 +694,35 @@ body.vjs-full-window { top: 0; padding: 0; margin: 0; - transition: all 0.4s; } + transition: all 0.4s; +} .vjs-menu-button-inline:hover .vjs-menu, .vjs-menu-button-inline:focus .vjs-menu, .vjs-menu-button-inline.vjs-slider-active .vjs-menu { display: block; - opacity: 1; } + opacity: 1; +} .vjs-no-flex .vjs-menu-button-inline .vjs-menu { display: block; opacity: 1; position: relative; - width: auto; } + width: auto; +} .vjs-no-flex .vjs-menu-button-inline:hover .vjs-menu, .vjs-no-flex .vjs-menu-button-inline:focus .vjs-menu, .vjs-no-flex .vjs-menu-button-inline.vjs-slider-active .vjs-menu { - width: auto; } + width: auto; +} .vjs-menu-button-inline .vjs-menu-content { width: auto; height: 100%; margin: 0; - overflow: hidden; } + overflow: hidden; +} .video-js .vjs-control-bar { display: none; @@ -574,32 +731,38 @@ body.vjs-full-window { bottom: 0; left: 0; right: 0; - height: 3.0em; + height: 3em; background-color: #2B333F; - background-color: rgba(43, 51, 63, 0.7); } + background-color: rgba(43, 51, 63, 0.7); +} .vjs-has-started .vjs-control-bar { display: flex; visibility: visible; opacity: 1; - transition: visibility 0.1s, opacity 0.1s; } + transition: visibility 0.1s, opacity 0.1s; +} .vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar { visibility: visible; opacity: 0; - transition: visibility 1s, opacity 1s; } + transition: visibility 1s, opacity 1s; +} .vjs-controls-disabled .vjs-control-bar, .vjs-using-native-controls .vjs-control-bar, .vjs-error .vjs-control-bar { - display: none !important; } + display: none !important; +} .vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar { opacity: 1; - visibility: visible; } + visibility: visible; +} .vjs-has-started.vjs-no-flex .vjs-control-bar { - display: table; } + display: table; +} .video-js .vjs-control { position: relative; @@ -608,16 +771,19 @@ body.vjs-full-window { padding: 0; height: 100%; width: 4em; - flex: none; } + flex: none; +} .vjs-button > .vjs-icon-placeholder:before { font-size: 1.8em; - line-height: 1.67; } + line-height: 1.67; +} .video-js .vjs-control:focus:before, .video-js .vjs-control:hover:before, .video-js .vjs-control:focus { - text-shadow: 0em 0em 1em white; } + text-shadow: 0em 0em 1em white; +} .video-js .vjs-control-text { border: 0; @@ -626,14 +792,17 @@ body.vjs-full-window { overflow: hidden; padding: 0; position: absolute; - width: 1px; } + width: 1px; +} .vjs-no-flex .vjs-control { display: table-cell; - vertical-align: middle; } + vertical-align: middle; +} .video-js .vjs-custom-control-spacer { - display: none; } + display: none; +} .video-js .vjs-progress-control { cursor: pointer; @@ -641,30 +810,43 @@ body.vjs-full-window { display: flex; align-items: center; min-width: 4em; - touch-action: none; } + touch-action: none; +} .video-js .vjs-progress-control.disabled { - cursor: default; } + cursor: default; +} .vjs-live .vjs-progress-control { - display: none; } + display: none; +} + +.vjs-liveui .vjs-progress-control { + display: flex; + align-items: center; +} .vjs-no-flex .vjs-progress-control { - width: auto; } + width: auto; +} .video-js .vjs-progress-holder { flex: auto; transition: all 0.2s; - height: 0.3em; } + height: 0.3em; +} .video-js .vjs-progress-control .vjs-progress-holder { - margin: 0 10px; } + margin: 0 10px; +} .video-js .vjs-progress-control:hover .vjs-progress-holder { - font-size: 1.666666666666666666em; } + font-size: 1.6666666667em; +} .video-js .vjs-progress-control:hover .vjs-progress-holder.disabled { - font-size: 1em; } + font-size: 1em; +} .video-js .vjs-progress-holder .vjs-play-progress, .video-js .vjs-progress-holder .vjs-load-progress, @@ -674,22 +856,27 @@ body.vjs-full-window { height: 100%; margin: 0; padding: 0; - width: 0; } + width: 0; +} .video-js .vjs-play-progress { - background-color: #fff; } - .video-js .vjs-play-progress:before { - font-size: 0.9em; - position: absolute; - right: -0.5em; - top: -0.333333333333333em; - z-index: 1; } + background-color: #fff; +} +.video-js .vjs-play-progress:before { + font-size: 0.9em; + position: absolute; + right: -0.5em; + top: -0.3333333333em; + z-index: 1; +} .video-js .vjs-load-progress { - background: rgba(115, 133, 159, 0.5); } + background: rgba(115, 133, 159, 0.5); +} .video-js .vjs-load-progress div { - background: rgba(115, 133, 159, 0.75); } + background: rgba(115, 133, 159, 0.75); +} .video-js .vjs-time-tooltip { background-color: #fff; @@ -704,19 +891,23 @@ body.vjs-full-window { position: absolute; top: -3.4em; visibility: hidden; - z-index: 1; } + z-index: 1; +} .video-js .vjs-progress-holder:focus .vjs-time-tooltip { - display: none; } + display: none; +} .video-js .vjs-progress-control:hover .vjs-time-tooltip, .video-js .vjs-progress-control:hover .vjs-progress-holder:focus .vjs-time-tooltip { display: block; font-size: 0.6em; - visibility: visible; } + visibility: visible; +} .video-js .vjs-progress-control.disabled:hover .vjs-time-tooltip { - font-size: 1em; } + font-size: 1em; +} .video-js .vjs-progress-control .vjs-mouse-display { display: none; @@ -724,26 +915,32 @@ body.vjs-full-window { width: 1px; height: 100%; background-color: #000; - z-index: 1; } + z-index: 1; +} .vjs-no-flex .vjs-progress-control .vjs-mouse-display { - z-index: 0; } + z-index: 0; +} .video-js .vjs-progress-control:hover .vjs-mouse-display { - display: block; } + display: block; +} .video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display { visibility: hidden; opacity: 0; - transition: visibility 1s, opacity 1s; } + transition: visibility 1s, opacity 1s; +} .video-js.vjs-user-inactive.vjs-no-flex .vjs-progress-control .vjs-mouse-display { - display: none; } + display: none; +} .vjs-mouse-display .vjs-time-tooltip { color: #fff; background-color: #000; - background-color: rgba(0, 0, 0, 0.8); } + background-color: rgba(0, 0, 0, 0.8); +} .video-js .vjs-slider { position: relative; @@ -762,70 +959,76 @@ body.vjs-full-window { /* Non-prefixed version, currently supported by Chrome and Opera */ user-select: none; background-color: #73859f; - background-color: rgba(115, 133, 159, 0.5); } + background-color: rgba(115, 133, 159, 0.5); +} .video-js .vjs-slider.disabled { - cursor: default; } + cursor: default; +} .video-js .vjs-slider:focus { text-shadow: 0em 0em 1em white; - box-shadow: 0 0 1em #fff; } + box-shadow: 0 0 1em #fff; +} .video-js .vjs-mute-control { cursor: pointer; - flex: none; } - + flex: none; +} .video-js .vjs-volume-control { cursor: pointer; margin-right: 1em; - display: flex; } + display: flex; +} .video-js .vjs-volume-control.vjs-volume-horizontal { - width: 5em; } + width: 5em; +} .video-js .vjs-volume-panel .vjs-volume-control { visibility: visible; opacity: 0; width: 1px; height: 1px; - margin-left: -1px; } + margin-left: -1px; +} .video-js .vjs-volume-panel { - transition: width 1s; } - .video-js .vjs-volume-panel:hover .vjs-volume-control, - .video-js .vjs-volume-panel:active .vjs-volume-control, - .video-js .vjs-volume-panel:focus .vjs-volume-control, - .video-js .vjs-volume-panel .vjs-volume-control:hover, - .video-js .vjs-volume-panel .vjs-volume-control:active, - .video-js .vjs-volume-panel .vjs-mute-control:hover ~ .vjs-volume-control, - .video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active { - visibility: visible; - opacity: 1; - position: relative; - transition: visibility 0.1s, opacity 0.1s, height 0.1s, width 0.1s, left 0s, top 0s; } - .video-js .vjs-volume-panel:hover .vjs-volume-control.vjs-volume-horizontal, - .video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-horizontal, - .video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-horizontal, - .video-js .vjs-volume-panel .vjs-volume-control:hover.vjs-volume-horizontal, - .video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-horizontal, - .video-js .vjs-volume-panel .vjs-mute-control:hover ~ .vjs-volume-control.vjs-volume-horizontal, - .video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-horizontal { - width: 5em; - height: 3em; } - .video-js .vjs-volume-panel.vjs-volume-panel-horizontal:hover, .video-js .vjs-volume-panel.vjs-volume-panel-horizontal:active, .video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active { - width: 9em; - transition: width 0.1s; } - .video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-mute-toggle-only { - width: 4em; } + transition: width 1s; +} +.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control, .video-js .vjs-volume-panel:active .vjs-volume-control, .video-js .vjs-volume-panel:focus .vjs-volume-control, .video-js .vjs-volume-panel .vjs-volume-control:active, .video-js .vjs-volume-panel.vjs-hover .vjs-mute-control ~ .vjs-volume-control, .video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active { + visibility: visible; + opacity: 1; + position: relative; + transition: visibility 0.1s, opacity 0.1s, height 0.1s, width 0.1s, left 0s, top 0s; +} +.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-horizontal, .video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-horizontal, .video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-horizontal, .video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-horizontal, .video-js .vjs-volume-panel.vjs-hover .vjs-mute-control ~ .vjs-volume-control.vjs-volume-horizontal, .video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-horizontal { + width: 5em; + height: 3em; + margin-right: 0; +} +.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-vertical, .video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-vertical, .video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-vertical, .video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-vertical, .video-js .vjs-volume-panel.vjs-hover .vjs-mute-control ~ .vjs-volume-control.vjs-volume-vertical, .video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-vertical { + left: -3.5em; + transition: left 0s; +} +.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-hover, .video-js .vjs-volume-panel.vjs-volume-panel-horizontal:active, .video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active { + width: 10em; + transition: width 0.1s; +} +.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-mute-toggle-only { + width: 4em; +} .video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical { height: 8em; width: 3em; - left: -3.5em; - transition: visibility 1s, opacity 1s, height 1s 1s, width 1s 1s, left 1s 1s, top 1s 1s; } + left: -3000em; + transition: visibility 1s, opacity 1s, height 1s 1s, width 1s 1s, left 1s 1s, top 1s 1s; +} .video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal { - transition: visibility 1s, opacity 1s, height 1s 1s, width 1s, left 1s 1s, top 1s 1s; } + transition: visibility 1s, opacity 1s, height 1s 1s, width 1s, left 1s 1s, top 1s 1s; +} .video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal { width: 5em; @@ -833,68 +1036,85 @@ body.vjs-full-window { visibility: visible; opacity: 1; position: relative; - transition: none; } + transition: none; +} .video-js.vjs-no-flex .vjs-volume-control.vjs-volume-vertical, .video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical { position: absolute; bottom: 3em; - left: 0.5em; } + left: 0.5em; +} .video-js .vjs-volume-panel { - display: flex; } + display: flex; +} .video-js .vjs-volume-bar { - margin: 1.35em 0.45em; } + margin: 1.35em 0.45em; +} .vjs-volume-bar.vjs-slider-horizontal { width: 5em; - height: 0.3em; } + height: 0.3em; +} .vjs-volume-bar.vjs-slider-vertical { width: 0.3em; height: 5em; - margin: 1.35em auto; } + margin: 1.35em auto; +} .video-js .vjs-volume-level { position: absolute; bottom: 0; left: 0; - background-color: #fff; } - .video-js .vjs-volume-level:before { - position: absolute; - font-size: 0.9em; } + background-color: #fff; +} +.video-js .vjs-volume-level:before { + position: absolute; + font-size: 0.9em; +} .vjs-slider-vertical .vjs-volume-level { - width: 0.3em; } - .vjs-slider-vertical .vjs-volume-level:before { - top: -0.5em; - left: -0.3em; } + width: 0.3em; +} +.vjs-slider-vertical .vjs-volume-level:before { + top: -0.5em; + left: -0.3em; +} .vjs-slider-horizontal .vjs-volume-level { - height: 0.3em; } - .vjs-slider-horizontal .vjs-volume-level:before { - top: -0.3em; - right: -0.5em; } + height: 0.3em; +} +.vjs-slider-horizontal .vjs-volume-level:before { + top: -0.3em; + right: -0.5em; +} .video-js .vjs-volume-panel.vjs-volume-panel-vertical { - width: 4em; } + width: 4em; +} .vjs-volume-bar.vjs-slider-vertical .vjs-volume-level { - height: 100%; } + height: 100%; +} .vjs-volume-bar.vjs-slider-horizontal .vjs-volume-level { - width: 100%; } + width: 100%; +} .video-js .vjs-volume-vertical { width: 3em; height: 8em; bottom: 8em; background-color: #2B333F; - background-color: rgba(43, 51, 63, 0.7); } + background-color: rgba(43, 51, 63, 0.7); +} .video-js .vjs-volume-horizontal .vjs-menu { - left: -2em; } + left: -2em; +} .vjs-poster { display: inline-block; @@ -911,28 +1131,76 @@ body.vjs-full-window { right: 0; bottom: 0; left: 0; - height: 100%; } + height: 100%; +} .vjs-has-started .vjs-poster { - display: none; } + display: none; +} .vjs-audio.vjs-has-started .vjs-poster { - display: block; } + display: block; +} .vjs-using-native-controls .vjs-poster { - display: none; } + display: none; +} .video-js .vjs-live-control { display: flex; align-items: flex-start; flex: auto; font-size: 1em; - line-height: 3em; } + line-height: 3em; +} .vjs-no-flex .vjs-live-control { display: table-cell; width: auto; - text-align: left; } + text-align: left; +} + +.video-js:not(.vjs-live) .vjs-live-control, +.video-js.vjs-liveui .vjs-live-control { + display: none; +} + +.video-js .vjs-seek-to-live-control { + cursor: pointer; + flex: none; + display: inline-flex; + height: 100%; + padding-left: 0.5em; + padding-right: 0.5em; + font-size: 1em; + line-height: 3em; + width: auto; + min-width: 4em; +} + +.vjs-no-flex .vjs-seek-to-live-control { + display: table-cell; + width: auto; + text-align: left; +} + +.video-js.vjs-live:not(.vjs-liveui) .vjs-seek-to-live-control, +.video-js:not(.vjs-live) .vjs-seek-to-live-control { + display: none; +} + +.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge { + cursor: auto; +} + +.vjs-seek-to-live-control .vjs-icon-placeholder { + margin-right: 0.5em; + color: #888; +} + +.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge .vjs-icon-placeholder { + color: red; +} .video-js .vjs-time-control { flex: none; @@ -941,29 +1209,39 @@ body.vjs-full-window { min-width: 2em; width: auto; padding-left: 1em; - padding-right: 1em; } + padding-right: 1em; +} .vjs-live .vjs-time-control { - display: none; } + display: none; +} .video-js .vjs-current-time, .vjs-no-flex .vjs-current-time { - display: none; } + display: none; +} .video-js .vjs-duration, .vjs-no-flex .vjs-duration { - display: none; } + display: none; +} .vjs-time-divider { display: none; - line-height: 3em; } + line-height: 3em; +} .vjs-live .vjs-time-divider { - display: none; } + display: none; +} + +.video-js .vjs-play-control { + cursor: pointer; +} .video-js .vjs-play-control .vjs-icon-placeholder { - cursor: pointer; - flex: none; } + flex: none; +} .vjs-text-track-display { position: absolute; @@ -971,62 +1249,76 @@ body.vjs-full-window { left: 0; right: 0; top: 0; - pointer-events: none; } + pointer-events: none; +} .video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display { - bottom: 1em; } + bottom: 1em; +} .video-js .vjs-text-track { font-size: 1.4em; text-align: center; - margin-bottom: 0.1em; } + margin-bottom: 0.1em; +} .vjs-subtitles { - color: #fff; } + color: #fff; +} .vjs-captions { - color: #fc6; } + color: #fc6; +} .vjs-tt-cue { - display: block; } + display: block; +} video::-webkit-media-text-track-display { - -webkit-transform: translateY(-3em); - transform: translateY(-3em); } + transform: translateY(-3em); +} .video-js.vjs-user-inactive.vjs-playing video::-webkit-media-text-track-display { - -webkit-transform: translateY(-1.5em); - transform: translateY(-1.5em); } + transform: translateY(-1.5em); +} +.video-js .vjs-picture-in-picture-control { + cursor: pointer; + flex: none; +} .video-js .vjs-fullscreen-control { cursor: pointer; - flex: none; } - + flex: none; +} .vjs-playback-rate > .vjs-menu-button, .vjs-playback-rate .vjs-playback-rate-value { position: absolute; top: 0; left: 0; width: 100%; - height: 100%; } + height: 100%; +} .vjs-playback-rate .vjs-playback-rate-value { pointer-events: none; font-size: 1.5em; line-height: 2; - text-align: center; } + text-align: center; +} .vjs-playback-rate .vjs-menu { width: 4em; - left: 0em; } + left: 0em; +} .vjs-error .vjs-error-display .vjs-modal-dialog-content { font-size: 1.4em; - text-align: center; } + text-align: center; +} .vjs-error .vjs-error-display:before { color: #fff; - content: 'X'; + content: "X"; font-family: Arial, Helvetica, sans-serif; font-size: 4em; left: 0; @@ -1037,7 +1329,8 @@ video::-webkit-media-text-track-display { text-align: center; top: 50%; vertical-align: middle; - width: 100%; } + width: 100%; +} .vjs-loading-spinner { display: none; @@ -1053,13 +1346,15 @@ video::-webkit-media-text-track-display { width: 50px; height: 50px; border-radius: 25px; - visibility: hidden; } + visibility: hidden; +} .vjs-seeking .vjs-loading-spinner, .vjs-waiting .vjs-loading-spinner { display: block; - -webkit-animation: 0s linear 0.3s forwards vjs-spinner-show; - animation: 0s linear 0.3s forwards vjs-spinner-show; } + -webkit-animation: vjs-spinner-show 0s linear 0.3s forwards; + animation: vjs-spinner-show 0s linear 0.3s forwards; +} .vjs-loading-spinner:before, .vjs-loading-spinner:after { @@ -1073,166 +1368,237 @@ video::-webkit-media-text-track-display { opacity: 1; border: inherit; border-color: transparent; - border-top-color: white; } + border-top-color: white; +} .vjs-seeking .vjs-loading-spinner:before, .vjs-seeking .vjs-loading-spinner:after, .vjs-waiting .vjs-loading-spinner:before, .vjs-waiting .vjs-loading-spinner:after { -webkit-animation: vjs-spinner-spin 1.1s cubic-bezier(0.6, 0.2, 0, 0.8) infinite, vjs-spinner-fade 1.1s linear infinite; - animation: vjs-spinner-spin 1.1s cubic-bezier(0.6, 0.2, 0, 0.8) infinite, vjs-spinner-fade 1.1s linear infinite; } + animation: vjs-spinner-spin 1.1s cubic-bezier(0.6, 0.2, 0, 0.8) infinite, vjs-spinner-fade 1.1s linear infinite; +} .vjs-seeking .vjs-loading-spinner:before, .vjs-waiting .vjs-loading-spinner:before { - border-top-color: white; } + border-top-color: white; +} .vjs-seeking .vjs-loading-spinner:after, .vjs-waiting .vjs-loading-spinner:after { border-top-color: white; -webkit-animation-delay: 0.44s; - animation-delay: 0.44s; } + animation-delay: 0.44s; +} @keyframes vjs-spinner-show { to { - visibility: visible; } } - + visibility: visible; + } +} @-webkit-keyframes vjs-spinner-show { to { - visibility: visible; } } - + visibility: visible; + } +} @keyframes vjs-spinner-spin { 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); } } - + transform: rotate(360deg); + } +} @-webkit-keyframes vjs-spinner-spin { 100% { - -webkit-transform: rotate(360deg); } } - + -webkit-transform: rotate(360deg); + } +} @keyframes vjs-spinner-fade { 0% { - border-top-color: #73859f; } + border-top-color: #73859f; + } 20% { - border-top-color: #73859f; } + border-top-color: #73859f; + } 35% { - border-top-color: white; } + border-top-color: white; + } 60% { - border-top-color: #73859f; } + border-top-color: #73859f; + } 100% { - border-top-color: #73859f; } } - + border-top-color: #73859f; + } +} @-webkit-keyframes vjs-spinner-fade { 0% { - border-top-color: #73859f; } + border-top-color: #73859f; + } 20% { - border-top-color: #73859f; } + border-top-color: #73859f; + } 35% { - border-top-color: white; } + border-top-color: white; + } 60% { - border-top-color: #73859f; } + border-top-color: #73859f; + } 100% { - border-top-color: #73859f; } } - + border-top-color: #73859f; + } +} .vjs-chapters-button .vjs-menu ul { - width: 24em; } + width: 24em; +} .video-js .vjs-subs-caps-button + .vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder { vertical-align: middle; display: inline-block; - margin-bottom: -0.1em; } + margin-bottom: -0.1em; +} .video-js .vjs-subs-caps-button + .vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before { font-family: VideoJS; - content: "\f10d"; + content: ""; font-size: 1.5em; - line-height: inherit; } + line-height: inherit; +} .video-js .vjs-audio-button + .vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder { vertical-align: middle; display: inline-block; - margin-bottom: -0.1em; } + margin-bottom: -0.1em; +} .video-js .vjs-audio-button + .vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before { font-family: VideoJS; - content: " \f11d"; + content: " "; font-size: 1.5em; - line-height: inherit; } + line-height: inherit; +} -.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-custom-control-spacer { - flex: auto; } - -.video-js.vjs-layout-tiny:not(.vjs-fullscreen).vjs-no-flex .vjs-custom-control-spacer { - width: auto; } - -.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-current-time, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-time-divider, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-duration, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-remaining-time, -.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-playback-rate, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-progress-control, -.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-mute-control, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-volume-control, -.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-chapters-button, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-descriptions-button, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-captions-button, -.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-subtitles-button, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-audio-button { - display: none; } - -.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-current-time, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-time-divider, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-duration, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-remaining-time, -.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-playback-rate, -.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-mute-control, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-volume-control, -.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-chapters-button, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-descriptions-button, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-captions-button, -.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-subtitles-button, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-audio-button { - display: none; } - -.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-current-time, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-time-divider, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-duration, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-remaining-time, -.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-playback-rate, -.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-mute-control, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-volume-control, -.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-chapters-button, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-descriptions-button, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-captions-button, -.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-subtitles-button .vjs-audio-button { - display: none; } +.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-current-time, +.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-time-divider, +.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-duration, +.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-remaining-time, +.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-playback-rate, +.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-chapters-button, +.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-descriptions-button, +.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-captions-button, +.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-subtitles-button, +.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-audio-button, +.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-control, .video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-current-time, +.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-time-divider, +.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-duration, +.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-remaining-time, +.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-playback-rate, +.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-chapters-button, +.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-descriptions-button, +.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-captions-button, +.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-subtitles-button, +.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-audio-button, +.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-control, .video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-current-time, +.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-time-divider, +.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-duration, +.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-remaining-time, +.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-playback-rate, +.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-chapters-button, +.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-descriptions-button, +.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-captions-button, +.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-subtitles-button, +.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-audio-button, +.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-control { + display: none; +} +.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:hover, +.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:active, +.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active, .video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal:hover, +.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal:active, +.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active, .video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:hover, +.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:active, +.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active { + width: auto; + width: initial; +} +.video-js:not(.vjs-fullscreen).vjs-layout-x-small:not(.vjs-liveui) .vjs-subs-caps-button, .video-js:not(.vjs-fullscreen).vjs-layout-x-small:not(.vjs-live) .vjs-subs-caps-button, .video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-subs-caps-button { + display: none; +} +.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui .vjs-custom-control-spacer, .video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-custom-control-spacer { + flex: auto; + display: block; +} +.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui.vjs-no-flex .vjs-custom-control-spacer, .video-js:not(.vjs-fullscreen).vjs-layout-tiny.vjs-no-flex .vjs-custom-control-spacer { + width: auto; +} +.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui .vjs-progress-control, .video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-progress-control { + display: none; +} .vjs-modal-dialog.vjs-text-track-settings { background-color: #2B333F; background-color: rgba(43, 51, 63, 0.75); color: #fff; - height: 70%; } + height: 70%; +} .vjs-text-track-settings .vjs-modal-dialog-content { - display: table; } + display: table; +} .vjs-text-track-settings .vjs-track-settings-colors, .vjs-text-track-settings .vjs-track-settings-font, .vjs-text-track-settings .vjs-track-settings-controls { - display: table-cell; } + display: table-cell; +} .vjs-text-track-settings .vjs-track-settings-controls { text-align: right; - vertical-align: bottom; } + vertical-align: bottom; +} @supports (display: grid) { .vjs-text-track-settings .vjs-modal-dialog-content { display: grid; grid-template-columns: 1fr 1fr; - grid-template-rows: 1fr auto; } - .vjs-text-track-settings .vjs-track-settings-colors { - display: block; - grid-column: 1; - grid-row: 1; } - .vjs-text-track-settings .vjs-track-settings-font { - grid-column: 2; - grid-row: 1; } - .vjs-text-track-settings .vjs-track-settings-controls { - grid-column: 2; - grid-row: 2; } } + grid-template-rows: 1fr; + padding: 20px 24px 0px 24px; + } + .vjs-track-settings-controls .vjs-default-button { + margin-bottom: 20px; + } + + .vjs-text-track-settings .vjs-track-settings-controls { + grid-column: 1/-1; + } + + .vjs-layout-small .vjs-text-track-settings .vjs-modal-dialog-content, +.vjs-layout-x-small .vjs-text-track-settings .vjs-modal-dialog-content, +.vjs-layout-tiny .vjs-text-track-settings .vjs-modal-dialog-content { + grid-template-columns: 1fr; + } +} .vjs-track-setting > select { - margin-right: 5px; } + margin-right: 1em; + margin-bottom: 0.5em; +} .vjs-text-track-settings fieldset { margin: 5px; padding: 3px; - border: none; } + border: none; +} .vjs-text-track-settings fieldset span { - display: inline-block; } + display: inline-block; +} + +.vjs-text-track-settings fieldset span > select { + max-width: 7.3em; +} .vjs-text-track-settings legend { color: #fff; - margin: 0 0 5px 0; } + margin: 0 0 5px 0; +} .vjs-text-track-settings .vjs-label { position: absolute; @@ -1244,31 +1610,37 @@ video::-webkit-media-text-track-display { border: 0; height: 1px; width: 1px; - overflow: hidden; } + overflow: hidden; +} .vjs-track-settings-controls button:focus, .vjs-track-settings-controls button:active { outline-style: solid; outline-width: medium; - background-image: linear-gradient(0deg, #fff 88%, #73859f 100%); } + background-image: linear-gradient(0deg, #fff 88%, #73859f 100%); +} .vjs-track-settings-controls button:hover { - color: rgba(43, 51, 63, 0.75); } + color: rgba(43, 51, 63, 0.75); +} .vjs-track-settings-controls button { background-color: #fff; background-image: linear-gradient(-180deg, #fff 88%, #73859f 100%); color: #2B333F; cursor: pointer; - border-radius: 2px; } + border-radius: 2px; +} .vjs-track-settings-controls .vjs-default-button { - margin-right: 1em; } + margin-right: 1em; +} @media print { .video-js > *:not(.vjs-tech):not(.vjs-poster) { - visibility: hidden; } } - + visibility: hidden; + } +} .vjs-resize-manager { position: absolute; top: 0; @@ -1276,4 +1648,16 @@ video::-webkit-media-text-track-display { width: 100%; height: 100%; border: none; - visibility: hidden; } + z-index: -1000; +} + +.js-focus-visible .video-js *:focus:not(.focus-visible) { + outline: none; + background: none; +} + +.video-js *:focus:not(:focus-visible), +.video-js .vjs-menu *:focus:not(:focus-visible) { + outline: none; + background: none; +} diff --git a/web/negromateweb/static/js/videojs/alt/video-js-cdn.min.css b/web/negromateweb/static/js/videojs/alt/video-js-cdn.min.css index 3ff1c7f..b453b88 100644 --- a/web/negromateweb/static/js/videojs/alt/video-js-cdn.min.css +++ b/web/negromateweb/static/js/videojs/alt/video-js-cdn.min.css @@ -1 +1 @@ -.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-modal-dialog,.vjs-button>.vjs-icon-placeholder:before,.vjs-modal-dialog .vjs-modal-dialog-content{position:absolute;top:0;left:0;width:100%;height:100%}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.vjs-button>.vjs-icon-placeholder:before{text-align:center}@font-face{font-family:VideoJS;src:url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAABBIAAsAAAAAGoQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADsAAABUIIslek9TLzIAAAFEAAAAPgAAAFZRiV3RY21hcAAAAYQAAADQAAADIjn098ZnbHlmAAACVAAACv4AABEIAwnSw2hlYWQAAA1UAAAAKgAAADYUHzoRaGhlYQAADYAAAAAbAAAAJA4DByFobXR4AAANnAAAAA8AAACE4AAAAGxvY2EAAA2sAAAARAAAAEQ9NEHGbWF4cAAADfAAAAAfAAAAIAEyAIFuYW1lAAAOEAAAASUAAAIK1cf1oHBvc3QAAA84AAABDwAAAZ5AAl/0eJxjYGRgYOBiMGCwY2BycfMJYeDLSSzJY5BiYGGAAJA8MpsxJzM9kYEDxgPKsYBpDiBmg4gCACY7BUgAeJxjYGQ7xTiBgZWBgaWQ5RkDA8MvCM0cwxDOeI6BgYmBlZkBKwhIc01hcPjI+FGBHcRdyA4RZgQRAC4HCwEAAHic7dFprsIgAEXhg8U61XmeWcBb1FuQP4w7ZQXK5boMm3yclFDSANAHmuKviBBeBPQ8ymyo8w3jOh/5r2ui5nN6v8sYNJb3WMdeWRvLji0DhozKdxM6psyYs2DJijUbtuzYc+DIiTMXrty4k8oGLb+n0xCe37ekM7Z66j1DbUy3l6PpHnLfdLO5NdSBoQ4NdWSoY9ON54mhdqa/y1NDnRnq3FAXhro01JWhrg11Y6hbQ90Z6t5QD4Z6NNSToZ4N9WKoV0O9GerdUJORPqkhTd54nJ1YDXBU1RV+576/JBs2bPYPkrDZt5vsJrv53V/I5mclhGDCTwgGBQQSTEji4hCkYIAGd4TGIWFAhV0RQTpWmQp1xv6hA4OTOlNr2zFANbHUYbq2OtNCpViRqsk+e+7bTQAhzti8vPfuPffcc88959zznbcMMPjHD/KDDGEY0ABpYX384NhlomIYlo4JISGEY9mMh2FSidYiqkEUphtNYDSY/dXg9023l4DdxlqUl0chuZRhncJKrsCQHIwcGuwfnhMIzBnuH4Sym+1D2zaGjheXlhYfD238z80mKYMmvJ5XeOTzd8z9eujbMxJNhu4C9xPE/bCMiDuSNIWgkTQwBE55hLSAE7ZwhrHLnAHZOGV/kmBGTiNjZxzI77Hb7Hqjz68TjT6vh+5JT/cCIkqS0D6CqPf5jX4Qjdx5j6vlDfZM4aZFdbVXIxtOlJaP/WottMnH6CJQ3bTiue3PrY23HjnChtuamxwvvzFjxkPrNj3z0tG9T561HDYf6OgmRWvlY3JQHoQb8ltV2Yet7YfWctEjR1AtxS/cSX6U4alf6NJEBQ7YKg9wrXQKd0IeZCb2ux75Uhh1Un+Nz+9LTOE7PK777nN5xqdTneTBhCbx446mZrhnUkrCz2YhA9dSMxaG0SYmT8hi9ZPu1E94PJYQSH6LRmhxec7Q7ZeXntgQuVpbh+a4qWNsckVyTdn0P7o7DpgPW84+uRcq0BITflBikGdUjAZ9wYBVI3mtrNvr9kpg1UsaK6t3690aoorC1lg0GpMH2HAMtkZjsSi5Ig9ESVosOh7GQfLjKNLvKpMKkLSKNFAka710GdgSi8oDMSoNhqjkKBXTgn3swtaxyzGkUzIzae9RtLdWkSlZ1KDX6EzgllzV4NV4SoDFSOGD4+HCeQUF8wrZ5Hs8zIb5EaVxy8DYFTbMCJPnLIWZxugZE2NlivC0gc1qEQUR8jEKgZcAXeH18BiCgl5nlHh0CrjB4Hb5fX4gb0J7c9PuHVsfgkx2n/vTY/JV8kn8PGxf7faOZ8qX8JVByuIf4whk9sqXli2hvPJV9hrp0hY7l8r2x37ydaVsb4xvXv/47v2NjfCl8m5oRDJclFMoE1yk0Uh1Te4/m8lFXe9qBZD0EkheicebXvzI2PLCuoKCukLuhPIeKwaHPEouxw3kMqaIUXDQ1p0mip+MyCORSCQaoUsnY1VZ38nUTrG21WvVo4f1OsEJFhvSfAFwGfT8VHRMeAVUpwLOoLzjT/REIj3O3FhuURE+nERF+0pTId5Fyxv5sfwGyg4O+my4vZv0sZm7oeQlFZORiB+tG0MweVNraeitl7yxiPIHTk4/diVxs94o5lEYishB2iAtkchEnsActoEpx44Fo8XnsQMaA22BlqC20RmhBKzYojZyYaxg+JggMc4HHY2m+L9EkWSYljirOisrO7d3VorxzyZ6Vc4lJqITAu1b2wOBdrLElAP+bFc2eGaZFVbkmJktv5uT6Jlz5D/MnBFor6ig/JPnRViBsV3LNKGGqB1ChJ0tgQywlVLFJIuQgTFttwkiKxhyQdAZMdMYtSaoAewqfvXVYPAbDT6/1mez85YS8FSDywQ6NfAnef6FNEGMilnppyvn5rB6tTyq1pOceRWnp2WJEZFXHeX5oyoem1nTTgdqc4heDY7bOeKz63vnz+/dRx+s31Ht2JGanQ5seirfWJL9tjozU/12TnEjn5oux9OzU3ckGbBzBwNOyk69JykKH0n/0LM9A72tuwM3zQpIRu4AxiToseEpgPOmbROyFe9/X2yeUvoUsCyEvjcgs7fpWP3/aKlFN0+6HFUe6D9HFz/XPwBlN9tTqNyZjFJ8UO2RUT5/h4CptCctEyeisnOyXjALEp7dXKaQKf6O7IMnGjNNACRMLxqdYJX8eMLvmmd68D+ayBLyKKYZwYxDt/GNhzETDJ05Qxlyi3pi3/Z93ndYVSumgj0V/KkIFlO6+1K3fF2+3g0q+YtuSIf0bvmLqV09nnobI6hwcjIP8aPCKayjsF5JBY3LaKAeRLSyYB1h81oTwe9SlPMkXB7G0mfL9q71gaqqwPqu67QRKS1+ObTx+sbQy9QV2OQHEScGkdFBeT7v7qisqqrs6N52i78/R+6S0qQONVj26agOVoswCyQWIV5D86vH53bxNUeXV0K+XZaHv/nm/KsHhOvylwsWnJX/HE8l/4WCv5x+l5n08z6UU8bUMa3MBpSmM7F63AxntdC9eBCKEZW9Hr+ABNqtxgAQrSbMtmrW7lKQuoSgBhSrTazWVU2QAKWY8wiiuhqFmQgWJBgoXiuWIm42N7hqZbBsgXz52O5P5uSvaNgFGnOuvsRw8I8Laha91wMvDuxqWFheN7/8GVtTltdS83DQsXRmqc5ZtcJXEVrlV2doTWk5+Yunm71dG5f55m/qY0MjI93vv9/NfpxXV9sUXrxy2fbNy1or65cOlDRnOoKFeeXcbw42H/bNDT5Qs3flgs31gWC1lD1nfUV/X7NdCnSUdHY2e8afzfKsqZ5ZljfDqjLOmk3UebNXB+aHArPYDRs+/HDDxeT5DiP+sFg7OpRaVQMGBV89PpeBdj22hCE0Uub0UqwLrNWsG0cuyadgLXTeR5rbO4+3c/vl15cur2nRq+TXCQDcS3SO+s6ak+e5/eMS+1dw3btu3YG2tvFL8XdIZvdjdW6TO/4B7IdrZWVPmctm5/59AgsPItTSbCiIBr2OqIGzmu20SMKAS7yqwGBUfGfgjDYlLLDeF0SfcLB2LSx8flT+08/kzz6yOj96rft4rpTjdPQcmLd47uKibbDq7ZSz/XtbH2nN717Nd62rU+c8Icevvv7I09wA6WvjVcafb+FsbNG+ZQ80Rn6ZZsvrP7teP2dzTdoETvNhjCmsr8FID2sJ69VYvdUcxk4AzYRlKcaE38eXNRlfW9H1as9i6acLHp1XpuNB5K7DIvkX08y1ZYvh3KfWaiCzH+ztrSDmD7LuX73x/mJelB8Yj39t8nhNQJJ2CAthpoFGLsGgtSOCJooCGoaJAMTjSWHVZ08YAa1Fg9lPI5U6DOsGVjDasJeZZ+YyhfCwfOzCxlBA69M9XLXtza7H/rav+9Tjq5xNi0wpKQIRNO4Lrzz7yp5QVYM6Jd/oc1Uvn/mQhhuWh6ENXoS2YTZ8QT42bF5d/559zp5r0Uff2VnR2tdf2/WCOd2cO0Mw6qpWPnvxpV0nrt5fZd2yItc199GWe8vlNfNDq+CH/7yAAnB9hn7T4QO4c1g9ScxsZgmzntnE/IDGndtHMw69lFwoCnYsMGx+rBp8JSBqdLzBr9QRPq/PbhWMWFtQZp1xguy/haw3TEHm3TWAnxFWQQWgt7M5OV0lCz1VRYucpWliy7z6Zd4urwPIyeZQqli2Lgg7szJV09PysATbOQtYIrB2YzbkJYkGgJ0m4AjPUap1pvYu1K9qr97z0Yl3p332b2LYB78ncYIlRkau/8GObSsOlZancACE5d5ily+c2+7h5Yj4lqhVmXXB+iXLfvdqSgqfKtQvfHDV0OnvQR1qhw42XS/vkvsh/hXcrDFP0a+SJNIomEfD1nsrYGO+1bgTOJhM8Hv6ek+7vVglxuSRwoKn17S937bm6YJCeSSG0Op1n+7tE37tcZ/p7dsTv4EUrGpDbWueKigsLHhqTVsoEj+JU0kaSjnj9tz8/gryQWwJ9BcJXBC/7smO+I/IFURJetFPrdt5WcoL6DbEJaygI8CTHfQTjf40ofD+DwalTqIAAHicY2BkYGAA4uByr8R4fpuvDNzsDCBw7f/3LmSanREszsHABKIAKi0J7gAAeJxjYGRgYGcAARD5/z87IwMjAypQBAAtgwI4AHicY2BgYGAfYAwAOkQA4QAAAAAAAA4AaAB+AMwA4AECAUIBbAGYAcICGAJYArQC4AMwA7AD3gQwBJYE3AUkBWYFigYgBmYGtAbqB1gIEghYCG4IhHicY2BkYGBQZChlYGcAASYg5gJCBob/YD4DABfTAbQAeJxdkE1qg0AYhl8Tk9AIoVDaVSmzahcF87PMARLIMoFAl0ZHY1BHdBJIT9AT9AQ9RQ9Qeqy+yteNMzDzfM+88w0K4BY/cNAMB6N2bUaPPBLukybCLvleeAAPj8JD+hfhMV7hC3u4wxs7OO4NzQSZcI/8Ltwnfwi75E/hAR7wJTyk/xYeY49fYQ/PztM+jbTZ7LY6OWdBJdX/pqs6NYWa+zMxa13oKrA6Uoerqi/JwtpYxZXJ1coUVmeZUWVlTjq0/tHacjmdxuL90OR8O0UEDYMNdtiSEpz5XQGqzlm30kzUdAYFFOb8R7NOZk0q2lwAyz1i7oAr1xoXvrOgtYhZx8wY5KRV269JZ5yGpmzPTjQhvY9je6vEElPOuJP3mWKnP5M3V+YAAAB4nG2PyXLCMBBE3YCNDWEL2ffk7o8S8oCnkCVHC5C/jzBQlUP6IHVPzYyekl5y0iL5X5/ooY8BUmQYIkeBEca4wgRTzDDHAtdY4ga3uMM9HvCIJzzjBa94wzs+8ImvZNAq8TM+HqVkKxWlrQiOxjujQkNlEzyNzl6Z/cU2XF06at7U83VQyklLpEvSnuzsb+HAPnPfQVgaupa1Jlu4sPLsFblcitaz0dHU0ZF1qatjZ1+aTXYCmp6u0gSvWNPyHLtFZ+ZeXWVSaEkqs3T8S74WklbGbNNNq4LL4+CWKtZDv2cfX8l8aFbKFhEnJnJ+IULFpqwoQnNHlHaVQtPBl+ypmbSWdmyC61KS/AKZC3Y+AA==) format("woff");font-weight:400;font-style:normal}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-play-control .vjs-icon-placeholder,.vjs-icon-play{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-play-control .vjs-icon-placeholder:before,.vjs-icon-play:before{content:"\f101"}.vjs-icon-play-circle{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-play-circle:before{content:"\f102"}.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder,.vjs-icon-pause{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder:before,.vjs-icon-pause:before{content:"\f103"}.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder,.vjs-icon-volume-mute{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder:before,.vjs-icon-volume-mute:before{content:"\f104"}.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder,.vjs-icon-volume-low{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder:before,.vjs-icon-volume-low:before{content:"\f105"}.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder,.vjs-icon-volume-mid{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder:before,.vjs-icon-volume-mid:before{content:"\f106"}.video-js .vjs-mute-control .vjs-icon-placeholder,.vjs-icon-volume-high{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control .vjs-icon-placeholder:before,.vjs-icon-volume-high:before{content:"\f107"}.video-js .vjs-fullscreen-control .vjs-icon-placeholder,.vjs-icon-fullscreen-enter{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-fullscreen-control .vjs-icon-placeholder:before,.vjs-icon-fullscreen-enter:before{content:"\f108"}.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder,.vjs-icon-fullscreen-exit{font-family:VideoJS;font-weight:400;font-style:normal}.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder:before,.vjs-icon-fullscreen-exit:before{content:"\f109"}.vjs-icon-square{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-square:before{content:"\f10a"}.vjs-icon-spinner{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-spinner:before{content:"\f10b"}.video-js .vjs-subs-caps-button .vjs-icon-placeholder,.video-js .vjs-subtitles-button .vjs-icon-placeholder,.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder,.vjs-icon-subtitles{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js .vjs-subtitles-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder:before,.vjs-icon-subtitles:before{content:"\f10c"}.video-js .vjs-captions-button .vjs-icon-placeholder,.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder,.vjs-icon-captions{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-captions-button .vjs-icon-placeholder:before,.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder:before,.vjs-icon-captions:before{content:"\f10d"}.video-js .vjs-chapters-button .vjs-icon-placeholder,.vjs-icon-chapters{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-chapters-button .vjs-icon-placeholder:before,.vjs-icon-chapters:before{content:"\f10e"}.vjs-icon-share{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-share:before{content:"\f10f"}.vjs-icon-cog{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-cog:before{content:"\f110"}.video-js .vjs-play-progress,.video-js .vjs-volume-level,.vjs-icon-circle{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-progress:before,.video-js .vjs-volume-level:before,.vjs-icon-circle:before{content:"\f111"}.vjs-icon-circle-outline{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-circle-outline:before{content:"\f112"}.vjs-icon-circle-inner-circle{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-circle-inner-circle:before{content:"\f113"}.vjs-icon-hd{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-hd:before{content:"\f114"}.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder,.vjs-icon-cancel{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder:before,.vjs-icon-cancel:before{content:"\f115"}.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder,.vjs-icon-replay{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder:before,.vjs-icon-replay:before{content:"\f116"}.vjs-icon-facebook{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-facebook:before{content:"\f117"}.vjs-icon-gplus{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-gplus:before{content:"\f118"}.vjs-icon-linkedin{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-linkedin:before{content:"\f119"}.vjs-icon-twitter{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-twitter:before{content:"\f11a"}.vjs-icon-tumblr{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-tumblr:before{content:"\f11b"}.vjs-icon-pinterest{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-pinterest:before{content:"\f11c"}.video-js .vjs-descriptions-button .vjs-icon-placeholder,.vjs-icon-audio-description{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-descriptions-button .vjs-icon-placeholder:before,.vjs-icon-audio-description:before{content:"\f11d"}.video-js .vjs-audio-button .vjs-icon-placeholder,.vjs-icon-audio{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-audio-button .vjs-icon-placeholder:before,.vjs-icon-audio:before{content:"\f11e"}.vjs-icon-next-item{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-next-item:before{content:"\f11f"}.vjs-icon-previous-item{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-previous-item:before{content:"\f120"}.video-js{display:block;vertical-align:top;box-sizing:border-box;color:#fff;background-color:#000;position:relative;padding:0;font-size:10px;line-height:1;font-weight:400;font-style:normal;font-family:Arial,Helvetica,sans-serif;word-break:initial}.video-js:-moz-full-screen{position:absolute}.video-js:-webkit-full-screen{width:100%!important;height:100%!important}.video-js[tabindex="-1"]{outline:0}.video-js *,.video-js :after,.video-js :before{box-sizing:inherit}.video-js ul{font-family:inherit;font-size:inherit;line-height:inherit;list-style-position:outside;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}.video-js.vjs-16-9,.video-js.vjs-4-3,.video-js.vjs-fluid{width:100%;max-width:100%;height:0}.video-js.vjs-16-9{padding-top:56.25%}.video-js.vjs-4-3{padding-top:75%}.video-js.vjs-fill{width:100%;height:100%}.video-js .vjs-tech{position:absolute;top:0;left:0;width:100%;height:100%}body.vjs-full-window{padding:0;margin:0;height:100%}.vjs-full-window .video-js.vjs-fullscreen{position:fixed;overflow:hidden;z-index:1000;left:0;top:0;bottom:0;right:0}.video-js.vjs-fullscreen{width:100%!important;height:100%!important;padding-top:0!important}.video-js.vjs-fullscreen.vjs-user-inactive{cursor:none}.vjs-hidden{display:none!important}.vjs-disabled{opacity:.5;cursor:default}.video-js .vjs-offscreen{height:1px;left:-9999px;position:absolute;top:0;width:1px}.vjs-lock-showing{display:block!important;opacity:1;visibility:visible}.vjs-no-js{padding:20px;color:#fff;background-color:#000;font-size:18px;font-family:Arial,Helvetica,sans-serif;text-align:center;width:300px;height:150px;margin:0 auto}.vjs-no-js a,.vjs-no-js a:visited{color:#66a8cc}.video-js .vjs-big-play-button{font-size:3em;line-height:1.5em;height:1.5em;width:3em;display:block;position:absolute;top:10px;left:10px;padding:0;cursor:pointer;opacity:1;border:.06666em solid #fff;background-color:#2b333f;background-color:rgba(43,51,63,.7);border-radius:.3em;transition:all .4s}.vjs-big-play-centered .vjs-big-play-button{top:50%;left:50%;margin-top:-.75em;margin-left:-1.5em}.video-js .vjs-big-play-button:focus,.video-js:hover .vjs-big-play-button{border-color:#fff;background-color:#73859f;background-color:rgba(115,133,159,.5);transition:all 0s}.vjs-controls-disabled .vjs-big-play-button,.vjs-error .vjs-big-play-button,.vjs-has-started .vjs-big-play-button,.vjs-using-native-controls .vjs-big-play-button{display:none}.vjs-has-started.vjs-paused.vjs-show-big-play-button-on-pause .vjs-big-play-button{display:block}.video-js button{background:0 0;border:none;color:inherit;display:inline-block;font-size:inherit;line-height:inherit;text-transform:none;text-decoration:none;transition:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.vjs-control .vjs-button{width:100%;height:100%}.video-js .vjs-control.vjs-close-button{cursor:pointer;height:3em;position:absolute;right:0;top:.5em;z-index:2}.video-js .vjs-modal-dialog{background:rgba(0,0,0,.8);background:linear-gradient(180deg,rgba(0,0,0,.8),rgba(255,255,255,0));overflow:auto}.video-js .vjs-modal-dialog>*{box-sizing:border-box}.vjs-modal-dialog .vjs-modal-dialog-content{font-size:1.2em;line-height:1.5;padding:20px 24px;z-index:1}.vjs-menu-button{cursor:pointer}.vjs-menu-button.vjs-disabled{cursor:default}.vjs-workinghover .vjs-menu-button.vjs-disabled:hover .vjs-menu{display:none}.vjs-menu .vjs-menu-content{display:block;padding:0;margin:0;font-family:Arial,Helvetica,sans-serif;overflow:auto}.vjs-menu .vjs-menu-content>*{box-sizing:border-box}.vjs-scrubbing .vjs-control.vjs-menu-button:hover .vjs-menu{display:none}.vjs-menu li{list-style:none;margin:0;padding:.2em 0;line-height:1.4em;font-size:1.2em;text-align:center;text-transform:lowercase}.vjs-menu li.vjs-menu-item:focus,.vjs-menu li.vjs-menu-item:hover{background-color:#73859f;background-color:rgba(115,133,159,.5)}.vjs-menu li.vjs-selected,.vjs-menu li.vjs-selected:focus,.vjs-menu li.vjs-selected:hover{background-color:#fff;color:#2b333f}.vjs-menu li.vjs-menu-title{text-align:center;text-transform:uppercase;font-size:1em;line-height:2em;padding:0;margin:0 0 .3em 0;font-weight:700;cursor:default}.vjs-menu-button-popup .vjs-menu{display:none;position:absolute;bottom:0;width:10em;left:-3em;height:0;margin-bottom:1.5em;border-top-color:rgba(43,51,63,.7)}.vjs-menu-button-popup .vjs-menu .vjs-menu-content{background-color:#2b333f;background-color:rgba(43,51,63,.7);position:absolute;width:100%;bottom:1.5em;max-height:15em}.vjs-menu-button-popup .vjs-menu.vjs-lock-showing,.vjs-workinghover .vjs-menu-button-popup:hover .vjs-menu{display:block}.video-js .vjs-menu-button-inline{transition:all .4s;overflow:hidden}.video-js .vjs-menu-button-inline:before{width:2.222222222em}.video-js .vjs-menu-button-inline.vjs-slider-active,.video-js .vjs-menu-button-inline:focus,.video-js .vjs-menu-button-inline:hover,.video-js.vjs-no-flex .vjs-menu-button-inline{width:12em}.vjs-menu-button-inline .vjs-menu{opacity:0;height:100%;width:auto;position:absolute;left:4em;top:0;padding:0;margin:0;transition:all .4s}.vjs-menu-button-inline.vjs-slider-active .vjs-menu,.vjs-menu-button-inline:focus .vjs-menu,.vjs-menu-button-inline:hover .vjs-menu{display:block;opacity:1}.vjs-no-flex .vjs-menu-button-inline .vjs-menu{display:block;opacity:1;position:relative;width:auto}.vjs-no-flex .vjs-menu-button-inline.vjs-slider-active .vjs-menu,.vjs-no-flex .vjs-menu-button-inline:focus .vjs-menu,.vjs-no-flex .vjs-menu-button-inline:hover .vjs-menu{width:auto}.vjs-menu-button-inline .vjs-menu-content{width:auto;height:100%;margin:0;overflow:hidden}.video-js .vjs-control-bar{display:none;width:100%;position:absolute;bottom:0;left:0;right:0;height:3em;background-color:#2b333f;background-color:rgba(43,51,63,.7)}.vjs-has-started .vjs-control-bar{display:flex;visibility:visible;opacity:1;transition:visibility .1s,opacity .1s}.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{visibility:visible;opacity:0;transition:visibility 1s,opacity 1s}.vjs-controls-disabled .vjs-control-bar,.vjs-error .vjs-control-bar,.vjs-using-native-controls .vjs-control-bar{display:none!important}.vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{opacity:1;visibility:visible}.vjs-has-started.vjs-no-flex .vjs-control-bar{display:table}.video-js .vjs-control{position:relative;text-align:center;margin:0;padding:0;height:100%;width:4em;flex:none}.vjs-button>.vjs-icon-placeholder:before{font-size:1.8em;line-height:1.67}.video-js .vjs-control:focus,.video-js .vjs-control:focus:before,.video-js .vjs-control:hover:before{text-shadow:0 0 1em #fff}.video-js .vjs-control-text{border:0;clip:rect(0 0 0 0);height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.vjs-no-flex .vjs-control{display:table-cell;vertical-align:middle}.video-js .vjs-custom-control-spacer{display:none}.video-js .vjs-progress-control{cursor:pointer;flex:auto;display:flex;align-items:center;min-width:4em;touch-action:none}.video-js .vjs-progress-control.disabled{cursor:default}.vjs-live .vjs-progress-control{display:none}.vjs-no-flex .vjs-progress-control{width:auto}.video-js .vjs-progress-holder{flex:auto;transition:all .2s;height:.3em}.video-js .vjs-progress-control .vjs-progress-holder{margin:0 10px}.video-js .vjs-progress-control:hover .vjs-progress-holder{font-size:1.666666666666666666em}.video-js .vjs-progress-control:hover .vjs-progress-holder.disabled{font-size:1em}.video-js .vjs-progress-holder .vjs-load-progress,.video-js .vjs-progress-holder .vjs-load-progress div,.video-js .vjs-progress-holder .vjs-play-progress{position:absolute;display:block;height:100%;margin:0;padding:0;width:0}.video-js .vjs-play-progress{background-color:#fff}.video-js .vjs-play-progress:before{font-size:.9em;position:absolute;right:-.5em;top:-.333333333333333em;z-index:1}.video-js .vjs-load-progress{background:rgba(115,133,159,.5)}.video-js .vjs-load-progress div{background:rgba(115,133,159,.75)}.video-js .vjs-time-tooltip{background-color:#fff;background-color:rgba(255,255,255,.8);border-radius:.3em;color:#000;float:right;font-family:Arial,Helvetica,sans-serif;font-size:1em;padding:6px 8px 8px 8px;pointer-events:none;position:absolute;top:-3.4em;visibility:hidden;z-index:1}.video-js .vjs-progress-holder:focus .vjs-time-tooltip{display:none}.video-js .vjs-progress-control:hover .vjs-progress-holder:focus .vjs-time-tooltip,.video-js .vjs-progress-control:hover .vjs-time-tooltip{display:block;font-size:.6em;visibility:visible}.video-js .vjs-progress-control.disabled:hover .vjs-time-tooltip{font-size:1em}.video-js .vjs-progress-control .vjs-mouse-display{display:none;position:absolute;width:1px;height:100%;background-color:#000;z-index:1}.vjs-no-flex .vjs-progress-control .vjs-mouse-display{z-index:0}.video-js .vjs-progress-control:hover .vjs-mouse-display{display:block}.video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display{visibility:hidden;opacity:0;transition:visibility 1s,opacity 1s}.video-js.vjs-user-inactive.vjs-no-flex .vjs-progress-control .vjs-mouse-display{display:none}.vjs-mouse-display .vjs-time-tooltip{color:#fff;background-color:#000;background-color:rgba(0,0,0,.8)}.video-js .vjs-slider{position:relative;cursor:pointer;padding:0;margin:0 .45em 0 .45em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#73859f;background-color:rgba(115,133,159,.5)}.video-js .vjs-slider.disabled{cursor:default}.video-js .vjs-slider:focus{text-shadow:0 0 1em #fff;box-shadow:0 0 1em #fff}.video-js .vjs-mute-control{cursor:pointer;flex:none}.video-js .vjs-volume-control{cursor:pointer;margin-right:1em;display:flex}.video-js .vjs-volume-control.vjs-volume-horizontal{width:5em}.video-js .vjs-volume-panel .vjs-volume-control{visibility:visible;opacity:0;width:1px;height:1px;margin-left:-1px}.video-js .vjs-volume-panel{transition:width 1s}.video-js .vjs-volume-panel .vjs-mute-control:hover~.vjs-volume-control,.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active,.video-js .vjs-volume-panel .vjs-volume-control:active,.video-js .vjs-volume-panel .vjs-volume-control:hover,.video-js .vjs-volume-panel:active .vjs-volume-control,.video-js .vjs-volume-panel:focus .vjs-volume-control,.video-js .vjs-volume-panel:hover .vjs-volume-control{visibility:visible;opacity:1;position:relative;transition:visibility .1s,opacity .1s,height .1s,width .1s,left 0s,top 0s}.video-js .vjs-volume-panel .vjs-mute-control:hover~.vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-horizontal,.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-horizontal,.video-js .vjs-volume-panel .vjs-volume-control:hover.vjs-volume-horizontal,.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel:hover .vjs-volume-control.vjs-volume-horizontal{width:5em;height:3em}.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js .vjs-volume-panel.vjs-volume-panel-horizontal:hover{width:9em;transition:width .1s}.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-mute-toggle-only{width:4em}.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical{height:8em;width:3em;left:-3.5em;transition:visibility 1s,opacity 1s,height 1s 1s,width 1s 1s,left 1s 1s,top 1s 1s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal{transition:visibility 1s,opacity 1s,height 1s 1s,width 1s,left 1s 1s,top 1s 1s}.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal{width:5em;height:3em;visibility:visible;opacity:1;position:relative;transition:none}.video-js.vjs-no-flex .vjs-volume-control.vjs-volume-vertical,.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical{position:absolute;bottom:3em;left:.5em}.video-js .vjs-volume-panel{display:flex}.video-js .vjs-volume-bar{margin:1.35em .45em}.vjs-volume-bar.vjs-slider-horizontal{width:5em;height:.3em}.vjs-volume-bar.vjs-slider-vertical{width:.3em;height:5em;margin:1.35em auto}.video-js .vjs-volume-level{position:absolute;bottom:0;left:0;background-color:#fff}.video-js .vjs-volume-level:before{position:absolute;font-size:.9em}.vjs-slider-vertical .vjs-volume-level{width:.3em}.vjs-slider-vertical .vjs-volume-level:before{top:-.5em;left:-.3em}.vjs-slider-horizontal .vjs-volume-level{height:.3em}.vjs-slider-horizontal .vjs-volume-level:before{top:-.3em;right:-.5em}.video-js .vjs-volume-panel.vjs-volume-panel-vertical{width:4em}.vjs-volume-bar.vjs-slider-vertical .vjs-volume-level{height:100%}.vjs-volume-bar.vjs-slider-horizontal .vjs-volume-level{width:100%}.video-js .vjs-volume-vertical{width:3em;height:8em;bottom:8em;background-color:#2b333f;background-color:rgba(43,51,63,.7)}.video-js .vjs-volume-horizontal .vjs-menu{left:-2em}.vjs-poster{display:inline-block;vertical-align:middle;background-repeat:no-repeat;background-position:50% 50%;background-size:contain;background-color:#000;cursor:pointer;margin:0;padding:0;position:absolute;top:0;right:0;bottom:0;left:0;height:100%}.vjs-has-started .vjs-poster{display:none}.vjs-audio.vjs-has-started .vjs-poster{display:block}.vjs-using-native-controls .vjs-poster{display:none}.video-js .vjs-live-control{display:flex;align-items:flex-start;flex:auto;font-size:1em;line-height:3em}.vjs-no-flex .vjs-live-control{display:table-cell;width:auto;text-align:left}.video-js .vjs-time-control{flex:none;font-size:1em;line-height:3em;min-width:2em;width:auto;padding-left:1em;padding-right:1em}.vjs-live .vjs-time-control{display:none}.video-js .vjs-current-time,.vjs-no-flex .vjs-current-time{display:none}.video-js .vjs-duration,.vjs-no-flex .vjs-duration{display:none}.vjs-time-divider{display:none;line-height:3em}.vjs-live .vjs-time-divider{display:none}.video-js .vjs-play-control .vjs-icon-placeholder{cursor:pointer;flex:none}.vjs-text-track-display{position:absolute;bottom:3em;left:0;right:0;top:0;pointer-events:none}.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display{bottom:1em}.video-js .vjs-text-track{font-size:1.4em;text-align:center;margin-bottom:.1em}.vjs-subtitles{color:#fff}.vjs-captions{color:#fc6}.vjs-tt-cue{display:block}video::-webkit-media-text-track-display{-webkit-transform:translateY(-3em);transform:translateY(-3em)}.video-js.vjs-user-inactive.vjs-playing video::-webkit-media-text-track-display{-webkit-transform:translateY(-1.5em);transform:translateY(-1.5em)}.video-js .vjs-fullscreen-control{cursor:pointer;flex:none}.vjs-playback-rate .vjs-playback-rate-value,.vjs-playback-rate>.vjs-menu-button{position:absolute;top:0;left:0;width:100%;height:100%}.vjs-playback-rate .vjs-playback-rate-value{pointer-events:none;font-size:1.5em;line-height:2;text-align:center}.vjs-playback-rate .vjs-menu{width:4em;left:0}.vjs-error .vjs-error-display .vjs-modal-dialog-content{font-size:1.4em;text-align:center}.vjs-error .vjs-error-display:before{color:#fff;content:'X';font-family:Arial,Helvetica,sans-serif;font-size:4em;left:0;line-height:1;margin-top:-.5em;position:absolute;text-shadow:.05em .05em .1em #000;text-align:center;top:50%;vertical-align:middle;width:100%}.vjs-loading-spinner{display:none;position:absolute;top:50%;left:50%;margin:-25px 0 0 -25px;opacity:.85;text-align:left;border:6px solid rgba(43,51,63,.7);box-sizing:border-box;background-clip:padding-box;width:50px;height:50px;border-radius:25px;visibility:hidden}.vjs-seeking .vjs-loading-spinner,.vjs-waiting .vjs-loading-spinner{display:block;-webkit-animation:0s linear .3s forwards vjs-spinner-show;animation:0s linear .3s forwards vjs-spinner-show}.vjs-loading-spinner:after,.vjs-loading-spinner:before{content:"";position:absolute;margin:-6px;box-sizing:inherit;width:inherit;height:inherit;border-radius:inherit;opacity:1;border:inherit;border-color:transparent;border-top-color:#fff}.vjs-seeking .vjs-loading-spinner:after,.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:before{-webkit-animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite;animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite}.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:before{border-top-color:#fff}.vjs-seeking .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:after{border-top-color:#fff;-webkit-animation-delay:.44s;animation-delay:.44s}@keyframes vjs-spinner-show{to{visibility:visible}}@-webkit-keyframes vjs-spinner-show{to{visibility:visible}}@keyframes vjs-spinner-spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes vjs-spinner-spin{100%{-webkit-transform:rotate(360deg)}}@keyframes vjs-spinner-fade{0%{border-top-color:#73859f}20%{border-top-color:#73859f}35%{border-top-color:#fff}60%{border-top-color:#73859f}100%{border-top-color:#73859f}}@-webkit-keyframes vjs-spinner-fade{0%{border-top-color:#73859f}20%{border-top-color:#73859f}35%{border-top-color:#fff}60%{border-top-color:#73859f}100%{border-top-color:#73859f}}.vjs-chapters-button .vjs-menu ul{width:24em}.video-js .vjs-subs-caps-button+.vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder{vertical-align:middle;display:inline-block;margin-bottom:-.1em}.video-js .vjs-subs-caps-button+.vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before{font-family:VideoJS;content:"\f10d";font-size:1.5em;line-height:inherit}.video-js .vjs-audio-button+.vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder{vertical-align:middle;display:inline-block;margin-bottom:-.1em}.video-js .vjs-audio-button+.vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before{font-family:VideoJS;content:" \f11d";font-size:1.5em;line-height:inherit}.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-custom-control-spacer{flex:auto}.video-js.vjs-layout-tiny:not(.vjs-fullscreen).vjs-no-flex .vjs-custom-control-spacer{width:auto}.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-audio-button,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-captions-button,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-chapters-button,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-current-time,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-descriptions-button,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-duration,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-mute-control,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-playback-rate,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-progress-control,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-remaining-time,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-subtitles-button,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-time-divider,.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-volume-control{display:none}.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-audio-button,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-captions-button,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-chapters-button,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-current-time,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-descriptions-button,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-duration,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-mute-control,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-playback-rate,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-remaining-time,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-subtitles-button,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-time-divider,.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-volume-control{display:none}.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-captions-button,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-chapters-button,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-current-time,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-descriptions-button,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-duration,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-mute-control,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-playback-rate,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-remaining-time,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-subtitles-button .vjs-audio-button,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-time-divider,.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-volume-control{display:none}.vjs-modal-dialog.vjs-text-track-settings{background-color:#2b333f;background-color:rgba(43,51,63,.75);color:#fff;height:70%}.vjs-text-track-settings .vjs-modal-dialog-content{display:table}.vjs-text-track-settings .vjs-track-settings-colors,.vjs-text-track-settings .vjs-track-settings-controls,.vjs-text-track-settings .vjs-track-settings-font{display:table-cell}.vjs-text-track-settings .vjs-track-settings-controls{text-align:right;vertical-align:bottom}@supports (display:grid){.vjs-text-track-settings .vjs-modal-dialog-content{display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr auto}.vjs-text-track-settings .vjs-track-settings-colors{display:block;grid-column:1;grid-row:1}.vjs-text-track-settings .vjs-track-settings-font{grid-column:2;grid-row:1}.vjs-text-track-settings .vjs-track-settings-controls{grid-column:2;grid-row:2}}.vjs-track-setting>select{margin-right:5px}.vjs-text-track-settings fieldset{margin:5px;padding:3px;border:none}.vjs-text-track-settings fieldset span{display:inline-block}.vjs-text-track-settings legend{color:#fff;margin:0 0 5px 0}.vjs-text-track-settings .vjs-label{position:absolute;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);display:block;margin:0 0 5px 0;padding:0;border:0;height:1px;width:1px;overflow:hidden}.vjs-track-settings-controls button:active,.vjs-track-settings-controls button:focus{outline-style:solid;outline-width:medium;background-image:linear-gradient(0deg,#fff 88%,#73859f 100%)}.vjs-track-settings-controls button:hover{color:rgba(43,51,63,.75)}.vjs-track-settings-controls button{background-color:#fff;background-image:linear-gradient(-180deg,#fff 88%,#73859f 100%);color:#2b333f;cursor:pointer;border-radius:2px}.vjs-track-settings-controls .vjs-default-button{margin-right:1em}@media print{.video-js>:not(.vjs-tech):not(.vjs-poster){visibility:hidden}}.vjs-resize-manager{position:absolute;top:0;left:0;width:100%;height:100%;border:none;visibility:hidden} \ No newline at end of file +@charset "UTF-8";.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-modal-dialog,.vjs-button>.vjs-icon-placeholder:before,.vjs-modal-dialog .vjs-modal-dialog-content{position:absolute;top:0;left:0;width:100%;height:100%}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.vjs-button>.vjs-icon-placeholder:before{text-align:center}@font-face{font-family:VideoJS;src:url(data:application/font-woff;charset=utf-8;base64,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) format("woff");font-weight:400;font-style:normal}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-play-control .vjs-icon-placeholder,.vjs-icon-play{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-play-control .vjs-icon-placeholder:before,.vjs-icon-play:before{content:"\f101"}.vjs-icon-play-circle{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-play-circle:before{content:"\f102"}.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder,.vjs-icon-pause{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder:before,.vjs-icon-pause:before{content:"\f103"}.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder,.vjs-icon-volume-mute{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder:before,.vjs-icon-volume-mute:before{content:"\f104"}.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder,.vjs-icon-volume-low{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder:before,.vjs-icon-volume-low:before{content:"\f105"}.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder,.vjs-icon-volume-mid{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder:before,.vjs-icon-volume-mid:before{content:"\f106"}.video-js .vjs-mute-control .vjs-icon-placeholder,.vjs-icon-volume-high{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control .vjs-icon-placeholder:before,.vjs-icon-volume-high:before{content:"\f107"}.video-js .vjs-fullscreen-control .vjs-icon-placeholder,.vjs-icon-fullscreen-enter{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-fullscreen-control .vjs-icon-placeholder:before,.vjs-icon-fullscreen-enter:before{content:"\f108"}.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder,.vjs-icon-fullscreen-exit{font-family:VideoJS;font-weight:400;font-style:normal}.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder:before,.vjs-icon-fullscreen-exit:before{content:"\f109"}.vjs-icon-square{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-square:before{content:"\f10a"}.vjs-icon-spinner{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-spinner:before{content:"\f10b"}.video-js .vjs-subs-caps-button .vjs-icon-placeholder,.video-js .vjs-subtitles-button .vjs-icon-placeholder,.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder,.vjs-icon-subtitles{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js .vjs-subtitles-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder:before,.vjs-icon-subtitles:before{content:"\f10c"}.video-js .vjs-captions-button .vjs-icon-placeholder,.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder,.vjs-icon-captions{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-captions-button .vjs-icon-placeholder:before,.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder:before,.vjs-icon-captions:before{content:"\f10d"}.video-js .vjs-chapters-button .vjs-icon-placeholder,.vjs-icon-chapters{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-chapters-button .vjs-icon-placeholder:before,.vjs-icon-chapters:before{content:"\f10e"}.vjs-icon-share{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-share:before{content:"\f10f"}.vjs-icon-cog{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-cog:before{content:"\f110"}.video-js .vjs-play-progress,.video-js .vjs-volume-level,.vjs-icon-circle,.vjs-seek-to-live-control .vjs-icon-placeholder{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-progress:before,.video-js .vjs-volume-level:before,.vjs-icon-circle:before,.vjs-seek-to-live-control .vjs-icon-placeholder:before{content:"\f111"}.vjs-icon-circle-outline{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-circle-outline:before{content:"\f112"}.vjs-icon-circle-inner-circle{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-circle-inner-circle:before{content:"\f113"}.vjs-icon-hd{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-hd:before{content:"\f114"}.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder,.vjs-icon-cancel{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder:before,.vjs-icon-cancel:before{content:"\f115"}.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder,.vjs-icon-replay{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder:before,.vjs-icon-replay:before{content:"\f116"}.vjs-icon-facebook{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-facebook:before{content:"\f117"}.vjs-icon-gplus{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-gplus:before{content:"\f118"}.vjs-icon-linkedin{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-linkedin:before{content:"\f119"}.vjs-icon-twitter{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-twitter:before{content:"\f11a"}.vjs-icon-tumblr{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-tumblr:before{content:"\f11b"}.vjs-icon-pinterest{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-pinterest:before{content:"\f11c"}.video-js .vjs-descriptions-button .vjs-icon-placeholder,.vjs-icon-audio-description{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-descriptions-button .vjs-icon-placeholder:before,.vjs-icon-audio-description:before{content:"\f11d"}.video-js .vjs-audio-button .vjs-icon-placeholder,.vjs-icon-audio{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-audio-button .vjs-icon-placeholder:before,.vjs-icon-audio:before{content:"\f11e"}.vjs-icon-next-item{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-next-item:before{content:"\f11f"}.vjs-icon-previous-item{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-previous-item:before{content:"\f120"}.video-js .vjs-picture-in-picture-control .vjs-icon-placeholder,.vjs-icon-picture-in-picture-enter{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-picture-in-picture-control .vjs-icon-placeholder:before,.vjs-icon-picture-in-picture-enter:before{content:"\f121"}.video-js.vjs-picture-in-picture .vjs-picture-in-picture-control .vjs-icon-placeholder,.vjs-icon-picture-in-picture-exit{font-family:VideoJS;font-weight:400;font-style:normal}.video-js.vjs-picture-in-picture .vjs-picture-in-picture-control .vjs-icon-placeholder:before,.vjs-icon-picture-in-picture-exit:before{content:"\f122"}.video-js{display:block;vertical-align:top;box-sizing:border-box;color:#fff;background-color:#000;position:relative;padding:0;font-size:10px;line-height:1;font-weight:400;font-style:normal;font-family:Arial,Helvetica,sans-serif;word-break:initial}.video-js:-moz-full-screen{position:absolute}.video-js:-webkit-full-screen{width:100%!important;height:100%!important}.video-js[tabindex="-1"]{outline:0}.video-js *,.video-js :after,.video-js :before{box-sizing:inherit}.video-js ul{font-family:inherit;font-size:inherit;line-height:inherit;list-style-position:outside;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}.video-js.vjs-16-9,.video-js.vjs-4-3,.video-js.vjs-fluid{width:100%;max-width:100%;height:0}.video-js.vjs-16-9{padding-top:56.25%}.video-js.vjs-4-3{padding-top:75%}.video-js.vjs-fill{width:100%;height:100%}.video-js .vjs-tech{position:absolute;top:0;left:0;width:100%;height:100%}body.vjs-full-window{padding:0;margin:0;height:100%}.vjs-full-window .video-js.vjs-fullscreen{position:fixed;overflow:hidden;z-index:1000;left:0;top:0;bottom:0;right:0}.video-js.vjs-fullscreen{width:100%!important;height:100%!important;padding-top:0!important}.video-js.vjs-fullscreen.vjs-user-inactive{cursor:none}.vjs-hidden{display:none!important}.vjs-disabled{opacity:.5;cursor:default}.video-js .vjs-offscreen{height:1px;left:-9999px;position:absolute;top:0;width:1px}.vjs-lock-showing{display:block!important;opacity:1;visibility:visible}.vjs-no-js{padding:20px;color:#fff;background-color:#000;font-size:18px;font-family:Arial,Helvetica,sans-serif;text-align:center;width:300px;height:150px;margin:0 auto}.vjs-no-js a,.vjs-no-js a:visited{color:#66a8cc}.video-js .vjs-big-play-button{font-size:3em;line-height:1.5em;height:1.63332em;width:3em;display:block;position:absolute;top:10px;left:10px;padding:0;cursor:pointer;opacity:1;border:.06666em solid #fff;background-color:#2b333f;background-color:rgba(43,51,63,.7);border-radius:.3em;transition:all .4s}.vjs-big-play-centered .vjs-big-play-button{top:50%;left:50%;margin-top:-.81666em;margin-left:-1.5em}.video-js .vjs-big-play-button:focus,.video-js:hover .vjs-big-play-button{border-color:#fff;background-color:#73859f;background-color:rgba(115,133,159,.5);transition:all 0s}.vjs-controls-disabled .vjs-big-play-button,.vjs-error .vjs-big-play-button,.vjs-has-started .vjs-big-play-button,.vjs-using-native-controls .vjs-big-play-button{display:none}.vjs-has-started.vjs-paused.vjs-show-big-play-button-on-pause .vjs-big-play-button{display:block}.video-js button{background:0 0;border:none;color:inherit;display:inline-block;font-size:inherit;line-height:inherit;text-transform:none;text-decoration:none;transition:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.vjs-control .vjs-button{width:100%;height:100%}.video-js .vjs-control.vjs-close-button{cursor:pointer;height:3em;position:absolute;right:0;top:.5em;z-index:2}.video-js .vjs-modal-dialog{background:rgba(0,0,0,.8);background:linear-gradient(180deg,rgba(0,0,0,.8),rgba(255,255,255,0));overflow:auto}.video-js .vjs-modal-dialog>*{box-sizing:border-box}.vjs-modal-dialog .vjs-modal-dialog-content{font-size:1.2em;line-height:1.5;padding:20px 24px;z-index:1}.vjs-menu-button{cursor:pointer}.vjs-menu-button.vjs-disabled{cursor:default}.vjs-workinghover .vjs-menu-button.vjs-disabled:hover .vjs-menu{display:none}.vjs-menu .vjs-menu-content{display:block;padding:0;margin:0;font-family:Arial,Helvetica,sans-serif;overflow:auto}.vjs-menu .vjs-menu-content>*{box-sizing:border-box}.vjs-scrubbing .vjs-control.vjs-menu-button:hover .vjs-menu{display:none}.vjs-menu li{list-style:none;margin:0;padding:.2em 0;line-height:1.4em;font-size:1.2em;text-align:center;text-transform:lowercase}.js-focus-visible .vjs-menu li.vjs-menu-item:hover,.vjs-menu li.vjs-menu-item:focus,.vjs-menu li.vjs-menu-item:hover{background-color:#73859f;background-color:rgba(115,133,159,.5)}.js-focus-visible .vjs-menu li.vjs-selected:hover,.vjs-menu li.vjs-selected,.vjs-menu li.vjs-selected:focus,.vjs-menu li.vjs-selected:hover{background-color:#fff;color:#2b333f}.vjs-menu li.vjs-menu-title{text-align:center;text-transform:uppercase;font-size:1em;line-height:2em;padding:0;margin:0 0 .3em 0;font-weight:700;cursor:default}.vjs-menu-button-popup .vjs-menu{display:none;position:absolute;bottom:0;width:10em;left:-3em;height:0;margin-bottom:1.5em;border-top-color:rgba(43,51,63,.7)}.vjs-menu-button-popup .vjs-menu .vjs-menu-content{background-color:#2b333f;background-color:rgba(43,51,63,.7);position:absolute;width:100%;bottom:1.5em;max-height:15em}.vjs-layout-tiny .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-x-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:5em}.vjs-layout-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:10em}.vjs-layout-medium .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:14em}.vjs-layout-huge .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-x-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:25em}.vjs-menu-button-popup .vjs-menu.vjs-lock-showing,.vjs-workinghover .vjs-menu-button-popup.vjs-hover .vjs-menu{display:block}.video-js .vjs-menu-button-inline{transition:all .4s;overflow:hidden}.video-js .vjs-menu-button-inline:before{width:2.222222222em}.video-js .vjs-menu-button-inline.vjs-slider-active,.video-js .vjs-menu-button-inline:focus,.video-js .vjs-menu-button-inline:hover,.video-js.vjs-no-flex .vjs-menu-button-inline{width:12em}.vjs-menu-button-inline .vjs-menu{opacity:0;height:100%;width:auto;position:absolute;left:4em;top:0;padding:0;margin:0;transition:all .4s}.vjs-menu-button-inline.vjs-slider-active .vjs-menu,.vjs-menu-button-inline:focus .vjs-menu,.vjs-menu-button-inline:hover .vjs-menu{display:block;opacity:1}.vjs-no-flex .vjs-menu-button-inline .vjs-menu{display:block;opacity:1;position:relative;width:auto}.vjs-no-flex .vjs-menu-button-inline.vjs-slider-active .vjs-menu,.vjs-no-flex .vjs-menu-button-inline:focus .vjs-menu,.vjs-no-flex .vjs-menu-button-inline:hover .vjs-menu{width:auto}.vjs-menu-button-inline .vjs-menu-content{width:auto;height:100%;margin:0;overflow:hidden}.video-js .vjs-control-bar{display:none;width:100%;position:absolute;bottom:0;left:0;right:0;height:3em;background-color:#2b333f;background-color:rgba(43,51,63,.7)}.vjs-has-started .vjs-control-bar{display:flex;visibility:visible;opacity:1;transition:visibility .1s,opacity .1s}.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{visibility:visible;opacity:0;transition:visibility 1s,opacity 1s}.vjs-controls-disabled .vjs-control-bar,.vjs-error .vjs-control-bar,.vjs-using-native-controls .vjs-control-bar{display:none!important}.vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{opacity:1;visibility:visible}.vjs-has-started.vjs-no-flex .vjs-control-bar{display:table}.video-js .vjs-control{position:relative;text-align:center;margin:0;padding:0;height:100%;width:4em;flex:none}.vjs-button>.vjs-icon-placeholder:before{font-size:1.8em;line-height:1.67}.video-js .vjs-control:focus,.video-js .vjs-control:focus:before,.video-js .vjs-control:hover:before{text-shadow:0 0 1em #fff}.video-js .vjs-control-text{border:0;clip:rect(0 0 0 0);height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.vjs-no-flex .vjs-control{display:table-cell;vertical-align:middle}.video-js .vjs-custom-control-spacer{display:none}.video-js .vjs-progress-control{cursor:pointer;flex:auto;display:flex;align-items:center;min-width:4em;touch-action:none}.video-js .vjs-progress-control.disabled{cursor:default}.vjs-live .vjs-progress-control{display:none}.vjs-liveui .vjs-progress-control{display:flex;align-items:center}.vjs-no-flex .vjs-progress-control{width:auto}.video-js .vjs-progress-holder{flex:auto;transition:all .2s;height:.3em}.video-js .vjs-progress-control .vjs-progress-holder{margin:0 10px}.video-js .vjs-progress-control:hover .vjs-progress-holder{font-size:1.6666666667em}.video-js .vjs-progress-control:hover .vjs-progress-holder.disabled{font-size:1em}.video-js .vjs-progress-holder .vjs-load-progress,.video-js .vjs-progress-holder .vjs-load-progress div,.video-js .vjs-progress-holder .vjs-play-progress{position:absolute;display:block;height:100%;margin:0;padding:0;width:0}.video-js .vjs-play-progress{background-color:#fff}.video-js .vjs-play-progress:before{font-size:.9em;position:absolute;right:-.5em;top:-.3333333333em;z-index:1}.video-js .vjs-load-progress{background:rgba(115,133,159,.5)}.video-js .vjs-load-progress div{background:rgba(115,133,159,.75)}.video-js .vjs-time-tooltip{background-color:#fff;background-color:rgba(255,255,255,.8);border-radius:.3em;color:#000;float:right;font-family:Arial,Helvetica,sans-serif;font-size:1em;padding:6px 8px 8px 8px;pointer-events:none;position:absolute;top:-3.4em;visibility:hidden;z-index:1}.video-js .vjs-progress-holder:focus .vjs-time-tooltip{display:none}.video-js .vjs-progress-control:hover .vjs-progress-holder:focus .vjs-time-tooltip,.video-js .vjs-progress-control:hover .vjs-time-tooltip{display:block;font-size:.6em;visibility:visible}.video-js .vjs-progress-control.disabled:hover .vjs-time-tooltip{font-size:1em}.video-js .vjs-progress-control .vjs-mouse-display{display:none;position:absolute;width:1px;height:100%;background-color:#000;z-index:1}.vjs-no-flex .vjs-progress-control .vjs-mouse-display{z-index:0}.video-js .vjs-progress-control:hover .vjs-mouse-display{display:block}.video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display{visibility:hidden;opacity:0;transition:visibility 1s,opacity 1s}.video-js.vjs-user-inactive.vjs-no-flex .vjs-progress-control .vjs-mouse-display{display:none}.vjs-mouse-display .vjs-time-tooltip{color:#fff;background-color:#000;background-color:rgba(0,0,0,.8)}.video-js .vjs-slider{position:relative;cursor:pointer;padding:0;margin:0 .45em 0 .45em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#73859f;background-color:rgba(115,133,159,.5)}.video-js .vjs-slider.disabled{cursor:default}.video-js .vjs-slider:focus{text-shadow:0 0 1em #fff;box-shadow:0 0 1em #fff}.video-js .vjs-mute-control{cursor:pointer;flex:none}.video-js .vjs-volume-control{cursor:pointer;margin-right:1em;display:flex}.video-js .vjs-volume-control.vjs-volume-horizontal{width:5em}.video-js .vjs-volume-panel .vjs-volume-control{visibility:visible;opacity:0;width:1px;height:1px;margin-left:-1px}.video-js .vjs-volume-panel{transition:width 1s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active,.video-js .vjs-volume-panel .vjs-volume-control:active,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control,.video-js .vjs-volume-panel:active .vjs-volume-control,.video-js .vjs-volume-panel:focus .vjs-volume-control{visibility:visible;opacity:1;position:relative;transition:visibility .1s,opacity .1s,height .1s,width .1s,left 0s,top 0s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-horizontal,.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-horizontal,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-horizontal{width:5em;height:3em;margin-right:0}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-vertical,.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-vertical,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-vertical{left:-3.5em;transition:left 0s}.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-hover,.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js .vjs-volume-panel.vjs-volume-panel-horizontal:active{width:10em;transition:width .1s}.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-mute-toggle-only{width:4em}.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical{height:8em;width:3em;left:-3000em;transition:visibility 1s,opacity 1s,height 1s 1s,width 1s 1s,left 1s 1s,top 1s 1s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal{transition:visibility 1s,opacity 1s,height 1s 1s,width 1s,left 1s 1s,top 1s 1s}.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal{width:5em;height:3em;visibility:visible;opacity:1;position:relative;transition:none}.video-js.vjs-no-flex .vjs-volume-control.vjs-volume-vertical,.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical{position:absolute;bottom:3em;left:.5em}.video-js .vjs-volume-panel{display:flex}.video-js .vjs-volume-bar{margin:1.35em .45em}.vjs-volume-bar.vjs-slider-horizontal{width:5em;height:.3em}.vjs-volume-bar.vjs-slider-vertical{width:.3em;height:5em;margin:1.35em auto}.video-js .vjs-volume-level{position:absolute;bottom:0;left:0;background-color:#fff}.video-js .vjs-volume-level:before{position:absolute;font-size:.9em}.vjs-slider-vertical .vjs-volume-level{width:.3em}.vjs-slider-vertical .vjs-volume-level:before{top:-.5em;left:-.3em}.vjs-slider-horizontal .vjs-volume-level{height:.3em}.vjs-slider-horizontal .vjs-volume-level:before{top:-.3em;right:-.5em}.video-js .vjs-volume-panel.vjs-volume-panel-vertical{width:4em}.vjs-volume-bar.vjs-slider-vertical .vjs-volume-level{height:100%}.vjs-volume-bar.vjs-slider-horizontal .vjs-volume-level{width:100%}.video-js .vjs-volume-vertical{width:3em;height:8em;bottom:8em;background-color:#2b333f;background-color:rgba(43,51,63,.7)}.video-js .vjs-volume-horizontal .vjs-menu{left:-2em}.vjs-poster{display:inline-block;vertical-align:middle;background-repeat:no-repeat;background-position:50% 50%;background-size:contain;background-color:#000;cursor:pointer;margin:0;padding:0;position:absolute;top:0;right:0;bottom:0;left:0;height:100%}.vjs-has-started .vjs-poster{display:none}.vjs-audio.vjs-has-started .vjs-poster{display:block}.vjs-using-native-controls .vjs-poster{display:none}.video-js .vjs-live-control{display:flex;align-items:flex-start;flex:auto;font-size:1em;line-height:3em}.vjs-no-flex .vjs-live-control{display:table-cell;width:auto;text-align:left}.video-js.vjs-liveui .vjs-live-control,.video-js:not(.vjs-live) .vjs-live-control{display:none}.video-js .vjs-seek-to-live-control{cursor:pointer;flex:none;display:inline-flex;height:100%;padding-left:.5em;padding-right:.5em;font-size:1em;line-height:3em;width:auto;min-width:4em}.vjs-no-flex .vjs-seek-to-live-control{display:table-cell;width:auto;text-align:left}.video-js.vjs-live:not(.vjs-liveui) .vjs-seek-to-live-control,.video-js:not(.vjs-live) .vjs-seek-to-live-control{display:none}.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge{cursor:auto}.vjs-seek-to-live-control .vjs-icon-placeholder{margin-right:.5em;color:#888}.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge .vjs-icon-placeholder{color:red}.video-js .vjs-time-control{flex:none;font-size:1em;line-height:3em;min-width:2em;width:auto;padding-left:1em;padding-right:1em}.vjs-live .vjs-time-control{display:none}.video-js .vjs-current-time,.vjs-no-flex .vjs-current-time{display:none}.video-js .vjs-duration,.vjs-no-flex .vjs-duration{display:none}.vjs-time-divider{display:none;line-height:3em}.vjs-live .vjs-time-divider{display:none}.video-js .vjs-play-control{cursor:pointer}.video-js .vjs-play-control .vjs-icon-placeholder{flex:none}.vjs-text-track-display{position:absolute;bottom:3em;left:0;right:0;top:0;pointer-events:none}.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display{bottom:1em}.video-js .vjs-text-track{font-size:1.4em;text-align:center;margin-bottom:.1em}.vjs-subtitles{color:#fff}.vjs-captions{color:#fc6}.vjs-tt-cue{display:block}video::-webkit-media-text-track-display{transform:translateY(-3em)}.video-js.vjs-user-inactive.vjs-playing video::-webkit-media-text-track-display{transform:translateY(-1.5em)}.video-js .vjs-picture-in-picture-control{cursor:pointer;flex:none}.video-js .vjs-fullscreen-control{cursor:pointer;flex:none}.vjs-playback-rate .vjs-playback-rate-value,.vjs-playback-rate>.vjs-menu-button{position:absolute;top:0;left:0;width:100%;height:100%}.vjs-playback-rate .vjs-playback-rate-value{pointer-events:none;font-size:1.5em;line-height:2;text-align:center}.vjs-playback-rate .vjs-menu{width:4em;left:0}.vjs-error .vjs-error-display .vjs-modal-dialog-content{font-size:1.4em;text-align:center}.vjs-error .vjs-error-display:before{color:#fff;content:"X";font-family:Arial,Helvetica,sans-serif;font-size:4em;left:0;line-height:1;margin-top:-.5em;position:absolute;text-shadow:.05em .05em .1em #000;text-align:center;top:50%;vertical-align:middle;width:100%}.vjs-loading-spinner{display:none;position:absolute;top:50%;left:50%;margin:-25px 0 0 -25px;opacity:.85;text-align:left;border:6px solid rgba(43,51,63,.7);box-sizing:border-box;background-clip:padding-box;width:50px;height:50px;border-radius:25px;visibility:hidden}.vjs-seeking .vjs-loading-spinner,.vjs-waiting .vjs-loading-spinner{display:block;-webkit-animation:vjs-spinner-show 0s linear .3s forwards;animation:vjs-spinner-show 0s linear .3s forwards}.vjs-loading-spinner:after,.vjs-loading-spinner:before{content:"";position:absolute;margin:-6px;box-sizing:inherit;width:inherit;height:inherit;border-radius:inherit;opacity:1;border:inherit;border-color:transparent;border-top-color:#fff}.vjs-seeking .vjs-loading-spinner:after,.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:before{-webkit-animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite;animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite}.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:before{border-top-color:#fff}.vjs-seeking .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:after{border-top-color:#fff;-webkit-animation-delay:.44s;animation-delay:.44s}@keyframes vjs-spinner-show{to{visibility:visible}}@-webkit-keyframes vjs-spinner-show{to{visibility:visible}}@keyframes vjs-spinner-spin{100%{transform:rotate(360deg)}}@-webkit-keyframes vjs-spinner-spin{100%{-webkit-transform:rotate(360deg)}}@keyframes vjs-spinner-fade{0%{border-top-color:#73859f}20%{border-top-color:#73859f}35%{border-top-color:#fff}60%{border-top-color:#73859f}100%{border-top-color:#73859f}}@-webkit-keyframes vjs-spinner-fade{0%{border-top-color:#73859f}20%{border-top-color:#73859f}35%{border-top-color:#fff}60%{border-top-color:#73859f}100%{border-top-color:#73859f}}.vjs-chapters-button .vjs-menu ul{width:24em}.video-js .vjs-subs-caps-button+.vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder{vertical-align:middle;display:inline-block;margin-bottom:-.1em}.video-js .vjs-subs-caps-button+.vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before{font-family:VideoJS;content:"";font-size:1.5em;line-height:inherit}.video-js .vjs-audio-button+.vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder{vertical-align:middle;display:inline-block;margin-bottom:-.1em}.video-js .vjs-audio-button+.vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before{font-family:VideoJS;content:" ";font-size:1.5em;line-height:inherit}.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-audio-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-captions-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-chapters-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-current-time,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-descriptions-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-duration,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-playback-rate,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-remaining-time,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-subtitles-button,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-time-divider,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-control,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-audio-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-captions-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-chapters-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-current-time,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-descriptions-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-duration,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-playback-rate,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-remaining-time,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-subtitles-button,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-time-divider,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-control,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-audio-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-captions-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-chapters-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-current-time,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-descriptions-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-duration,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-playback-rate,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-remaining-time,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-subtitles-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-time-divider,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-control{display:none}.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js:not(.vjs-fullscreen).vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:hover,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:hover,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js:not(.vjs-fullscreen).vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal:hover{width:auto;width:initial}.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-subs-caps-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small:not(.vjs-live) .vjs-subs-caps-button,.video-js:not(.vjs-fullscreen).vjs-layout-x-small:not(.vjs-liveui) .vjs-subs-caps-button{display:none}.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-custom-control-spacer,.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui .vjs-custom-control-spacer{flex:auto;display:block}.video-js:not(.vjs-fullscreen).vjs-layout-tiny.vjs-no-flex .vjs-custom-control-spacer,.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui.vjs-no-flex .vjs-custom-control-spacer{width:auto}.video-js:not(.vjs-fullscreen).vjs-layout-tiny .vjs-progress-control,.video-js:not(.vjs-fullscreen).vjs-layout-x-small.vjs-liveui .vjs-progress-control{display:none}.vjs-modal-dialog.vjs-text-track-settings{background-color:#2b333f;background-color:rgba(43,51,63,.75);color:#fff;height:70%}.vjs-text-track-settings .vjs-modal-dialog-content{display:table}.vjs-text-track-settings .vjs-track-settings-colors,.vjs-text-track-settings .vjs-track-settings-controls,.vjs-text-track-settings .vjs-track-settings-font{display:table-cell}.vjs-text-track-settings .vjs-track-settings-controls{text-align:right;vertical-align:bottom}@supports (display:grid){.vjs-text-track-settings .vjs-modal-dialog-content{display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr;padding:20px 24px 0 24px}.vjs-track-settings-controls .vjs-default-button{margin-bottom:20px}.vjs-text-track-settings .vjs-track-settings-controls{grid-column:1/-1}.vjs-layout-small .vjs-text-track-settings .vjs-modal-dialog-content,.vjs-layout-tiny .vjs-text-track-settings .vjs-modal-dialog-content,.vjs-layout-x-small .vjs-text-track-settings .vjs-modal-dialog-content{grid-template-columns:1fr}}.vjs-track-setting>select{margin-right:1em;margin-bottom:.5em}.vjs-text-track-settings fieldset{margin:5px;padding:3px;border:none}.vjs-text-track-settings fieldset span{display:inline-block}.vjs-text-track-settings fieldset span>select{max-width:7.3em}.vjs-text-track-settings legend{color:#fff;margin:0 0 5px 0}.vjs-text-track-settings .vjs-label{position:absolute;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);display:block;margin:0 0 5px 0;padding:0;border:0;height:1px;width:1px;overflow:hidden}.vjs-track-settings-controls button:active,.vjs-track-settings-controls button:focus{outline-style:solid;outline-width:medium;background-image:linear-gradient(0deg,#fff 88%,#73859f 100%)}.vjs-track-settings-controls button:hover{color:rgba(43,51,63,.75)}.vjs-track-settings-controls button{background-color:#fff;background-image:linear-gradient(-180deg,#fff 88%,#73859f 100%);color:#2b333f;cursor:pointer;border-radius:2px}.vjs-track-settings-controls .vjs-default-button{margin-right:1em}@media print{.video-js>:not(.vjs-tech):not(.vjs-poster){visibility:hidden}}.vjs-resize-manager{position:absolute;top:0;left:0;width:100%;height:100%;border:none;z-index:-1000}.js-focus-visible .video-js :focus:not(.focus-visible){outline:0;background:0 0}.video-js .vjs-menu :focus:not(:focus-visible),.video-js :focus:not(:focus-visible){outline:0;background:0 0} \ No newline at end of file diff --git a/web/negromateweb/static/js/videojs/alt/video.core.js b/web/negromateweb/static/js/videojs/alt/video.core.js index d82fd51..5573328 100644 --- a/web/negromateweb/static/js/videojs/alt/video.core.js +++ b/web/negromateweb/static/js/videojs/alt/video.core.js @@ -1,6 +1,6 @@ /** * @license - * Video.js 7.2.2 + * Video.js 7.7.4 * Copyright Brightcove, Inc. * Available under Apache License Version 2.0 * @@ -11,69 +11,22 @@ */ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.videojs = factory()); -}(this, (function () { - var version = "7.2.2"; + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('global/window'), require('global/document')) : + typeof define === 'function' && define.amd ? define(['global/window', 'global/document'], factory) : + (global = global || self, global.videojs = factory(global.window, global.document)); +}(this, function (window$1, document) { 'use strict'; - var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + window$1 = window$1 && window$1.hasOwnProperty('default') ? window$1['default'] : window$1; + document = document && document.hasOwnProperty('default') ? document['default'] : document; - function createCommonjsModule(fn, module) { - return module = { exports: {} }, fn(module, module.exports), module.exports; - } - - var win; - - if (typeof window !== "undefined") { - win = window; - } else if (typeof commonjsGlobal !== "undefined") { - win = commonjsGlobal; - } else if (typeof self !== "undefined") { - win = self; - } else { - win = {}; - } - - var window_1 = win; - - var empty = {}; - - var empty$1 = /*#__PURE__*/Object.freeze({ - default: empty - }); - - var minDoc = ( empty$1 && empty ) || empty$1; - - var topLevel = typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : typeof window !== 'undefined' ? window : {}; - - var doccy; - - if (typeof document !== 'undefined') { - doccy = document; - } else { - doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4']; - - if (!doccy) { - doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc; - } - } - - var document_1 = doccy; + var version = "7.7.4"; /** - * @file log.js - * @module log + * @file create-logger.js + * @module create-logger */ - var log = void 0; - - // This is the private tracking variable for logging level. - var level = 'info'; - - // This is the private tracking variable for the logging history. var history = []; - /** * Log messages to the console and history based on the type of message * @@ -84,255 +37,307 @@ * @param {Array} args * The arguments to be passed to the matching console method. */ - var logByType = function logByType(type, args) { - var lvl = log.levels[level]; - var lvlRegExp = new RegExp('^(' + lvl + ')$'); - if (type !== 'log') { + var LogByTypeFactory = function LogByTypeFactory(name, log) { + return function (type, level, args) { + var lvl = log.levels[level]; + var lvlRegExp = new RegExp("^(" + lvl + ")$"); - // Add the type to the front of the message when it's not "log". - args.unshift(type.toUpperCase() + ':'); - } + if (type !== 'log') { + // Add the type to the front of the message when it's not "log". + args.unshift(type.toUpperCase() + ':'); + } // Add console prefix after adding to history. - // Add a clone of the args at this point to history. - if (history) { - history.push([].concat(args)); - } - // Add console prefix after adding to history. - args.unshift('VIDEOJS:'); + args.unshift(name + ':'); // Add a clone of the args at this point to history. - // If there's no console then don't try to output messages, but they will - // still be stored in history. - if (!window_1.console) { - return; - } + if (history) { + history.push([].concat(args)); // only store 1000 history entries - // Was setting these once outside of this function, but containing them - // in the function makes it easier to test cases where console doesn't exist - // when the module is executed. - var fn = window_1.console[type]; + var splice = history.length - 1000; + history.splice(0, splice > 0 ? splice : 0); + } // If there's no console then don't try to output messages, but they will + // still be stored in history. - if (!fn && type === 'debug') { - // Certain browsers don't have support for console.debug. For those, we - // should default to the closest comparable log. - fn = window_1.console.info || window_1.console.log; - } - // Bail out if there's no console or if this type is not allowed by the - // current logging level. - if (!fn || !lvl || !lvlRegExp.test(type)) { - return; - } + if (!window$1.console) { + return; + } // Was setting these once outside of this function, but containing them + // in the function makes it easier to test cases where console doesn't exist + // when the module is executed. - fn[Array.isArray(args) ? 'apply' : 'call'](window_1.console, args); - }; - /** - * Logs plain debug messages. Similar to `console.log`. - * - * @class - * @param {Mixed[]} args - * One or more messages or objects that should be logged. - */ - log = function log() { - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } + var fn = window$1.console[type]; - logByType('log', args); - }; + if (!fn && type === 'debug') { + // Certain browsers don't have support for console.debug. For those, we + // should default to the closest comparable log. + fn = window$1.console.info || window$1.console.log; + } // Bail out if there's no console or if this type is not allowed by the + // current logging level. - /** - * Enumeration of available logging levels, where the keys are the level names - * and the values are `|`-separated strings containing logging methods allowed - * in that logging level. These strings are used to create a regular expression - * matching the function name being called. - * - * Levels provided by video.js are: - * - * - `off`: Matches no calls. Any value that can be cast to `false` will have - * this effect. The most restrictive. - * - `all`: Matches only Video.js-provided functions (`debug`, `log`, - * `log.warn`, and `log.error`). - * - `debug`: Matches `log.debug`, `log`, `log.warn`, and `log.error` calls. - * - `info` (default): Matches `log`, `log.warn`, and `log.error` calls. - * - `warn`: Matches `log.warn` and `log.error` calls. - * - `error`: Matches only `log.error` calls. - * - * @type {Object} - */ - log.levels = { - all: 'debug|log|warn|error', - off: '', - debug: 'debug|log|warn|error', - info: 'log|warn|error', - warn: 'warn|error', - error: 'error', - DEFAULT: level - }; - /** - * Get or set the current logging level. If a string matching a key from - * {@link log.levels} is provided, acts as a setter. Regardless of argument, - * returns the current logging level. - * - * @param {string} [lvl] - * Pass to set a new logging level. - * - * @return {string} - * The current logging level. - */ - log.level = function (lvl) { - if (typeof lvl === 'string') { - if (!log.levels.hasOwnProperty(lvl)) { - throw new Error('"' + lvl + '" in not a valid log level'); + if (!fn || !lvl || !lvlRegExp.test(type)) { + return; } - level = lvl; - } - return level; + + fn[Array.isArray(args) ? 'apply' : 'call'](window$1.console, args); + }; }; - /** - * Returns an array containing everything that has been logged to the history. - * - * This array is a shallow clone of the internal history record. However, its - * contents are _not_ cloned; so, mutating objects inside this array will - * mutate them in history. - * - * @return {Array} - */ - log.history = function () { - return history ? [].concat(history) : []; - }; + function createLogger(name) { + // This is the private tracking variable for logging level. + var level = 'info'; // the curried logByType bound to the specific log and history - /** - * Clears the internal history tracking, but does not prevent further history - * tracking. - */ - log.history.clear = function () { - if (history) { - history.length = 0; - } - }; + var logByType; + /** + * Logs plain debug messages. Similar to `console.log`. + * + * Due to [limitations](https://github.com/jsdoc3/jsdoc/issues/955#issuecomment-313829149) + * of our JSDoc template, we cannot properly document this as both a function + * and a namespace, so its function signature is documented here. + * + * #### Arguments + * ##### *args + * Mixed[] + * + * Any combination of values that could be passed to `console.log()`. + * + * #### Return Value + * + * `undefined` + * + * @namespace + * @param {Mixed[]} args + * One or more messages or objects that should be logged. + */ - /** - * Disable history tracking if it is currently enabled. - */ - log.history.disable = function () { - if (history !== null) { - history.length = 0; - history = null; - } - }; + var log = function log() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } - /** - * Enable history tracking if it is currently disabled. - */ - log.history.enable = function () { - if (history === null) { - history = []; - } - }; + logByType('log', level, args); + }; // This is the logByType helper that the logging methods below use - /** - * Logs error messages. Similar to `console.error`. - * - * @param {Mixed[]} args - * One or more messages or objects that should be logged as an error - */ - log.error = function () { - for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args[_key2] = arguments[_key2]; - } - return logByType('error', args); - }; + logByType = LogByTypeFactory(name, log); + /** + * Create a new sublogger which chains the old name to the new name. + * + * For example, doing `videojs.log.createLogger('player')` and then using that logger will log the following: + * ```js + * mylogger('foo'); + * // > VIDEOJS: player: foo + * ``` + * + * @param {string} name + * The name to add call the new logger + * @return {Object} + */ - /** - * Logs warning messages. Similar to `console.warn`. - * - * @param {Mixed[]} args - * One or more messages or objects that should be logged as a warning. - */ - log.warn = function () { - for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { - args[_key3] = arguments[_key3]; - } + log.createLogger = function (subname) { + return createLogger(name + ': ' + subname); + }; + /** + * Enumeration of available logging levels, where the keys are the level names + * and the values are `|`-separated strings containing logging methods allowed + * in that logging level. These strings are used to create a regular expression + * matching the function name being called. + * + * Levels provided by Video.js are: + * + * - `off`: Matches no calls. Any value that can be cast to `false` will have + * this effect. The most restrictive. + * - `all`: Matches only Video.js-provided functions (`debug`, `log`, + * `log.warn`, and `log.error`). + * - `debug`: Matches `log.debug`, `log`, `log.warn`, and `log.error` calls. + * - `info` (default): Matches `log`, `log.warn`, and `log.error` calls. + * - `warn`: Matches `log.warn` and `log.error` calls. + * - `error`: Matches only `log.error` calls. + * + * @type {Object} + */ - return logByType('warn', args); - }; - /** - * Logs debug messages. Similar to `console.debug`, but may also act as a comparable - * log if `console.debug` is not available - * - * @param {Mixed[]} args - * One or more messages or objects that should be logged as debug. - */ - log.debug = function () { - for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { - args[_key4] = arguments[_key4]; - } + log.levels = { + all: 'debug|log|warn|error', + off: '', + debug: 'debug|log|warn|error', + info: 'log|warn|error', + warn: 'warn|error', + error: 'error', + DEFAULT: level + }; + /** + * Get or set the current logging level. + * + * If a string matching a key from {@link module:log.levels} is provided, acts + * as a setter. + * + * @param {string} [lvl] + * Pass a valid level to set a new logging level. + * + * @return {string} + * The current logging level. + */ - return logByType('debug', args); - }; + log.level = function (lvl) { + if (typeof lvl === 'string') { + if (!log.levels.hasOwnProperty(lvl)) { + throw new Error("\"" + lvl + "\" in not a valid log level"); + } - var log$1 = log; + level = lvl; + } - function clean(s) { - return s.replace(/\n\r?\s*/g, ''); + return level; + }; + /** + * Returns an array containing everything that has been logged to the history. + * + * This array is a shallow clone of the internal history record. However, its + * contents are _not_ cloned; so, mutating objects inside this array will + * mutate them in history. + * + * @return {Array} + */ + + + log.history = function () { + return history ? [].concat(history) : []; + }; + /** + * Allows you to filter the history by the given logger name + * + * @param {string} fname + * The name to filter by + * + * @return {Array} + * The filtered list to return + */ + + + log.history.filter = function (fname) { + return (history || []).filter(function (historyItem) { + // if the first item in each historyItem includes `fname`, then it's a match + return new RegExp(".*" + fname + ".*").test(historyItem[0]); + }); + }; + /** + * Clears the internal history tracking, but does not prevent further history + * tracking. + */ + + + log.history.clear = function () { + if (history) { + history.length = 0; + } + }; + /** + * Disable history tracking if it is currently enabled. + */ + + + log.history.disable = function () { + if (history !== null) { + history.length = 0; + history = null; + } + }; + /** + * Enable history tracking if it is currently disabled. + */ + + + log.history.enable = function () { + if (history === null) { + history = []; + } + }; + /** + * Logs error messages. Similar to `console.error`. + * + * @param {Mixed[]} args + * One or more messages or objects that should be logged as an error + */ + + + log.error = function () { + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + return logByType('error', level, args); + }; + /** + * Logs warning messages. Similar to `console.warn`. + * + * @param {Mixed[]} args + * One or more messages or objects that should be logged as a warning. + */ + + + log.warn = function () { + for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args[_key3] = arguments[_key3]; + } + + return logByType('warn', level, args); + }; + /** + * Logs debug messages. Similar to `console.debug`, but may also act as a comparable + * log if `console.debug` is not available + * + * @param {Mixed[]} args + * One or more messages or objects that should be logged as debug. + */ + + + log.debug = function () { + for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; + } + + return logByType('debug', level, args); + }; + + return log; } - var tsml = function tsml(sa) { - var s = '', - i = 0; + /** + * @file log.js + * @module log + */ + var log = createLogger('VIDEOJS'); + var createLogger$1 = log.createLogger; - for (; i < arguments.length; i++) { - s += clean(sa[i]) + (arguments[i + 1] || ''); - }return s; - }; + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } - var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { - return typeof obj; - } : function (obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }; + var _extends_1 = createCommonjsModule(function (module) { + function _extends() { + module.exports = _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; - var classCallCheck = function (instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - }; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } - var inherits = function (subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); + return target; + }; + + return _extends.apply(this, arguments); } - subClass.prototype = Object.create(superClass && superClass.prototype, { - constructor: { - value: subClass, - enumerable: false, - writable: true, - configurable: true - } - }); - if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; - }; - - var possibleConstructorReturn = function (self, call) { - if (!self) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); - } - - return call && (typeof call === "object" || typeof call === "function") ? call : self; - }; - - var taggedTemplateLiteralLoose = function (strings, raw) { - strings.raw = raw; - return strings; - }; + module.exports = _extends; + }); /** * @file obj.js @@ -365,7 +370,6 @@ * The new accumulated value. */ var toString = Object.prototype.toString; - /** * Get the keys of an Object * @@ -378,10 +382,10 @@ * * @private */ + var keys = function keys(object) { return isObject(object) ? Object.keys(object) : []; }; - /** * Array-like iteration for objects. * @@ -391,12 +395,13 @@ * @param {obj:EachCallback} fn * The callback function which is called for each key in the object. */ + + function each(object, fn) { keys(object).forEach(function (key) { return fn(object[key], key); }); } - /** * Array-like reduce for objects. * @@ -414,14 +419,16 @@ * @return {Mixed} * The final accumulated value. */ - function reduce(object, fn) { - var initial = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + + function reduce(object, fn, initial) { + if (initial === void 0) { + initial = 0; + } return keys(object).reduce(function (accum, key) { return fn(accum, object[key], key); }, initial); } - /** * Object.assign-style object shallow merge/extend. * @@ -429,13 +436,14 @@ * @param {Object} ...sources * @return {Object} */ + function assign(target) { - for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + for (var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { sources[_key - 1] = arguments[_key]; } if (Object.assign) { - return Object.assign.apply(Object, [target].concat(sources)); + return _extends_1.apply(void 0, [target].concat(sources)); } sources.forEach(function (source) { @@ -447,10 +455,8 @@ target[key] = value; }); }); - return target; } - /** * Returns whether a value is an object of any kind - including DOM nodes, * arrays, regular expressions, etc. Not functions, though. @@ -459,19 +465,20 @@ * results in `'object'`. * * @param {Object} value - * @return {Boolean} + * @return {boolean} */ - function isObject(value) { - return !!value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object'; - } + function isObject(value) { + return !!value && typeof value === 'object'; + } /** * Returns whether an object appears to be a "plain" object - that is, a * direct instance of `Object`. * * @param {Object} value - * @return {Boolean} + * @return {boolean} */ + function isPlain(value) { return isObject(value) && toString.call(value) === '[object Object]' && value.constructor === Object; } @@ -480,197 +487,211 @@ * @file computed-style.js * @module computed-style */ - /** * A safe getComputedStyle. * * This is needed because in Firefox, if the player is loaded in an iframe with - * `display:none`, then `getComputedStyle` returns `null`, so, we do a null-check to - * make sure that the player doesn't break in these cases. + * `display:none`, then `getComputedStyle` returns `null`, so, we do a + * null-check to make sure that the player doesn't break in these cases. * - * @param {Element} el - * The element you want the computed style of + * @function + * @param {Element} el + * The element you want the computed style of * - * @param {string} prop - * The property name you want + * @param {string} prop + * The property name you want * - * @see https://bugzilla.mozilla.org/show_bug.cgi?id=548397 - * - * @static - * @const + * @see https://bugzilla.mozilla.org/show_bug.cgi?id=548397 */ + function computedStyle(el, prop) { if (!el || !prop) { return ''; } - if (typeof window_1.getComputedStyle === 'function') { - var cs = window_1.getComputedStyle(el); - - return cs ? cs[prop] : ''; + if (typeof window$1.getComputedStyle === 'function') { + var computedStyleValue = window$1.getComputedStyle(el); + return computedStyleValue ? computedStyleValue.getPropertyValue(prop) || computedStyleValue[prop] : ''; } return ''; } - var _templateObject = taggedTemplateLiteralLoose(['Setting attributes in the second argument of createEl()\n has been deprecated. Use the third argument instead.\n createEl(type, properties, attributes). Attempting to set ', ' to ', '.'], ['Setting attributes in the second argument of createEl()\n has been deprecated. Use the third argument instead.\n createEl(type, properties, attributes). Attempting to set ', ' to ', '.']); - + /** + * @file dom.js + * @module dom + */ /** * Detect if a value is a string with any non-whitespace characters. * - * @param {string} str - * The string to check + * @private + * @param {string} str + * The string to check * * @return {boolean} - * - True if the string is non-blank - * - False otherwise + * Will be `true` if the string is non-blank, `false` otherwise. * */ - function isNonBlankString(str) { - return typeof str === 'string' && /\S/.test(str); - } + function isNonBlankString(str) { + // we use str.trim as it will trim any whitespace characters + // from the front or back of non-whitespace characters. aka + // Any string that contains non-whitespace characters will + // still contain them after `trim` but whitespace only strings + // will have a length of 0, failing this check. + return typeof str === 'string' && Boolean(str.trim()); + } /** * Throws an error if the passed string has whitespace. This is used by * class methods to be relatively consistent with the classList API. * - * @param {string} str + * @private + * @param {string} str * The string to check for whitespace. * * @throws {Error} * Throws an error if there is whitespace in the string. - * */ + + function throwIfWhitespace(str) { - if (/\s/.test(str)) { + // str.indexOf instead of regex because str.indexOf is faster performance wise. + if (str.indexOf(' ') >= 0) { throw new Error('class has illegal whitespace characters'); } } - /** * Produce a regular expression for matching a className within an elements className. * - * @param {string} className + * @private + * @param {string} className * The className to generate the RegExp for. * * @return {RegExp} * The RegExp that will check for a specific `className` in an elements * className. */ + + function classRegExp(className) { return new RegExp('(^|\\s)' + className + '($|\\s)'); } - /** - * Whether the current DOM interface appears to be real. + * Whether the current DOM interface appears to be real (i.e. not simulated). * - * @return {Boolean} + * @return {boolean} + * Will be `true` if the DOM appears to be real, `false` otherwise. */ + + function isReal() { // Both document and window will never be undefined thanks to `global`. - return document_1 === window_1.document; + return document === window$1.document; } - /** * Determines, via duck typing, whether or not a value is a DOM element. * - * @param {Mixed} value - * The thing to check + * @param {Mixed} value + * The value to check. * * @return {boolean} - * - True if it is a DOM element - * - False otherwise + * Will be `true` if the value is a DOM element, `false` otherwise. */ + function isEl(value) { return isObject(value) && value.nodeType === 1; } - /** * Determines if the current DOM is embedded in an iframe. * * @return {boolean} - * + * Will be `true` if the DOM is embedded in an iframe, `false` + * otherwise. */ - function isInFrame() { + function isInFrame() { // We need a try/catch here because Safari will throw errors when attempting // to get either `parent` or `self` try { - return window_1.parent !== window_1.self; + return window$1.parent !== window$1.self; } catch (x) { return true; } } - /** * Creates functions to query the DOM using a given method. * - * @param {string} method - * The method to create the query with. + * @private + * @param {string} method + * The method to create the query with. * - * @return {Function} - * The query method + * @return {Function} + * The query method */ + function createQuerier(method) { return function (selector, context) { if (!isNonBlankString(selector)) { - return document_1[method](null); + return document[method](null); } + if (isNonBlankString(context)) { - context = document_1.querySelector(context); + context = document.querySelector(context); } - var ctx = isEl(context) ? context : document_1; - + var ctx = isEl(context) ? context : document; return ctx[method] && ctx[method](selector); }; } - /** - * Creates an element and applies properties. + * Creates an element and applies properties, attributes, and inserts content. * - * @param {string} [tagName='div'] + * @param {string} [tagName='div'] * Name of tag to be created. * - * @param {Object} [properties={}] + * @param {Object} [properties={}] * Element properties to be applied. * - * @param {Object} [attributes={}] + * @param {Object} [attributes={}] * Element attributes to be applied. * - * @param {String|Element|TextNode|Array|Function} [content] - * Contents for the element (see: {@link dom:normalizeContent}) + * @param {module:dom~ContentDescriptor} content + * A content descriptor object. * * @return {Element} * The element that was created. */ - function createEl() { - var tagName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div'; - var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - var content = arguments[3]; - var el = document_1.createElement(tagName); + function createEl(tagName, properties, attributes, content) { + if (tagName === void 0) { + tagName = 'div'; + } + + if (properties === void 0) { + properties = {}; + } + + if (attributes === void 0) { + attributes = {}; + } + + var el = document.createElement(tagName); Object.getOwnPropertyNames(properties).forEach(function (propName) { - var val = properties[propName]; - - // See #2176 + var val = properties[propName]; // See #2176 // We originally were accepting both properties and attributes in the // same object, but that doesn't work so well. - if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') { - log$1.warn(tsml(_templateObject, propName, val)); - el.setAttribute(propName, val); - // Handle textContent since it's not supported everywhere and we have a + if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') { + log.warn('Setting attributes in the second argument of createEl()\n' + 'has been deprecated. Use the third argument instead.\n' + ("createEl(type, properties, attributes). Attempting to set " + propName + " to " + val + ".")); + el.setAttribute(propName, val); // Handle textContent since it's not supported everywhere and we have a // method for it. } else if (propName === 'textContent') { textContent(el, val); - } else { + } else if (el[propName] !== val) { el[propName] = val; } }); - Object.getOwnPropertyNames(attributes).forEach(function (attrName) { el.setAttribute(attrName, attributes[attrName]); }); @@ -681,28 +702,28 @@ return el; } - /** * Injects text into an element, replacing any existing contents entirely. * - * @param {Element} el - * The element to add text content into + * @param {Element} el + * The element to add text content into * - * @param {string} text - * The text content to add. + * @param {string} text + * The text content to add. * * @return {Element} * The element with added text content. */ + function textContent(el, text) { if (typeof el.textContent === 'undefined') { el.innerText = text; } else { el.textContent = text; } + return el; } - /** * Insert an element as the first child node of another * @@ -712,6 +733,7 @@ * @param {Element} parent * Element to insert child into */ + function prependTo(child, parent) { if (parent.firstChild) { parent.insertBefore(child, parent.firstChild); @@ -719,48 +741,47 @@ parent.appendChild(child); } } - /** - * Check if an element has a CSS class + * Check if an element has a class name. * - * @param {Element} element - * Element to check + * @param {Element} element + * Element to check * - * @param {string} classToCheck - * Class name to check for + * @param {string} classToCheck + * Class name to check for * * @return {boolean} - * - True if the element had the class - * - False otherwise. + * Will be `true` if the element has a class, `false` otherwise. * * @throws {Error} * Throws an error if `classToCheck` has white space. */ + function hasClass(element, classToCheck) { throwIfWhitespace(classToCheck); + if (element.classList) { return element.classList.contains(classToCheck); } + return classRegExp(classToCheck).test(element.className); } - /** - * Add a CSS class name to an element + * Add a class name to an element. * - * @param {Element} element - * Element to add class name to. + * @param {Element} element + * Element to add class name to. * - * @param {string} classToAdd - * Class name to add. + * @param {string} classToAdd + * Class name to add. * * @return {Element} - * The dom element with the added class name. + * The DOM element with the added class name. */ + function addClass(element, classToAdd) { if (element.classList) { - element.classList.add(classToAdd); - - // Don't need to `throwIfWhitespace` here because `hasElClass` will do it + element.classList.add(classToAdd); // Don't need to `throwIfWhitespace` here because `hasElClass` will do it // in the case of classList not being supported. } else if (!hasClass(element, classToAdd)) { element.className = (element.className + ' ' + classToAdd).trim(); @@ -768,19 +789,19 @@ return element; } - /** - * Remove a CSS class name from an element + * Remove a class name from an element. * - * @param {Element} element - * Element to remove a class name from. + * @param {Element} element + * Element to remove a class name from. * - * @param {string} classToRemove - * Class name to remove + * @param {string} classToRemove + * Class name to remove * * @return {Element} - * The dom element with class name removed. + * The DOM element with class name removed. */ + function removeClass(element, classToRemove) { if (element.classList) { element.classList.remove(classToRemove); @@ -793,41 +814,40 @@ return element; } - /** - * The callback definition for toggleElClass. + * The callback definition for toggleClass. * - * @callback Dom~PredicateCallback - * @param {Element} element - * The DOM element of the Component. + * @callback module:dom~PredicateCallback + * @param {Element} element + * The DOM element of the Component. * - * @param {string} classToToggle - * The `className` that wants to be toggled + * @param {string} classToToggle + * The `className` that wants to be toggled * - * @return {boolean|undefined} - * - If true the `classToToggle` will get added to `element`. - * - If false the `classToToggle` will get removed from `element`. - * - If undefined this callback will be ignored + * @return {boolean|undefined} + * If `true` is returned, the `classToToggle` will be added to the + * `element`. If `false`, the `classToToggle` will be removed from + * the `element`. If `undefined`, the callback will be ignored. */ /** - * Adds or removes a CSS class name on an element depending on an optional + * Adds or removes a class name to/from an element depending on an optional * condition or the presence/absence of the class name. * - * @param {Element} element - * The element to toggle a class name on. + * @param {Element} element + * The element to toggle a class name on. * - * @param {string} classToToggle - * The class that should be toggled + * @param {string} classToToggle + * The class that should be toggled. * - * @param {boolean|PredicateCallback} [predicate] - * See the return value for {@link Dom~PredicateCallback} + * @param {boolean|module:dom~PredicateCallback} [predicate] + * See the return value for {@link module:dom~PredicateCallback} * * @return {Element} * The element with a class that has been toggled. */ - function toggleClass(element, classToToggle, predicate) { + function toggleClass(element, classToToggle, predicate) { // This CANNOT use `classList` internally because IE11 does not support the // second parameter to the `classList.toggle()` method! Which is fine because // `classList` will be used by the add/remove functions. @@ -839,10 +859,10 @@ if (typeof predicate !== 'boolean') { predicate = !has; - } - - // If the necessary class operation matches the current state of the + } // If the necessary class operation matches the current state of the // element, no action is required. + + if (predicate === has) { return; } @@ -855,7 +875,6 @@ return element; } - /** * Apply attributes to an HTML element. * @@ -865,6 +884,7 @@ * @param {Object} [attributes] * Attributes to be applied. */ + function setAttributes(el, attributes) { Object.getOwnPropertyNames(attributes).forEach(function (attrName) { var attrValue = attributes[attrName]; @@ -876,25 +896,25 @@ } }); } - /** - * Get an element's attribute values, as defined on the HTML tag - * Attributes are not the same as properties. They're defined on the tag - * or with setAttribute (which shouldn't be used with HTML) - * This will return true or false for boolean attributes. + * Get an element's attribute values, as defined on the HTML tag. * - * @param {Element} tag - * Element from which to get tag attributes. + * Attributes are not the same as properties. They're defined on the tag + * or with setAttribute. + * + * @param {Element} tag + * Element from which to get tag attributes. * * @return {Object} - * All attributes of the element. + * All attributes of the element. Boolean attributes will be `true` or + * `false`, others will be strings. */ - function getAttributes(tag) { - var obj = {}; - // known boolean attributes + function getAttributes(tag) { + var obj = {}; // known boolean attributes // we can check for matching boolean properties, but not all browsers // and not all tags know about these attributes, so, we still want to check them manually + var knownBooleans = ',' + 'autoplay,controls,playsinline,loop,muted,default,defaultMuted' + ','; if (tag && tag.attributes && tag.attributes.length > 0) { @@ -902,10 +922,9 @@ for (var i = attrs.length - 1; i >= 0; i--) { var attrName = attrs[i].name; - var attrVal = attrs[i].value; - - // check for known booleans + var attrVal = attrs[i].value; // check for known booleans // the matching element property will return a value for typeof + if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) { // the value of an included boolean attribute is typically an empty // string ('') which would equal false if we just check for a false value. @@ -919,71 +938,71 @@ return obj; } - /** - * Get the value of an element's attribute + * Get the value of an element's attribute. * * @param {Element} el - * A DOM element + * A DOM element. * * @param {string} attribute - * Attribute to get the value of + * Attribute to get the value of. * * @return {string} - * value of the attribute + * The value of the attribute. */ + function getAttribute(el, attribute) { return el.getAttribute(attribute); } - /** - * Set the value of an element's attribute + * Set the value of an element's attribute. * * @param {Element} el - * A DOM element + * A DOM element. * * @param {string} attribute - * Attribute to set + * Attribute to set. * * @param {string} value - * Value to set the attribute to + * Value to set the attribute to. */ + function setAttribute(el, attribute, value) { el.setAttribute(attribute, value); } - /** - * Remove an element's attribute + * Remove an element's attribute. * * @param {Element} el - * A DOM element + * A DOM element. * * @param {string} attribute - * Attribute to remove + * Attribute to remove. */ + function removeAttribute(el, attribute) { el.removeAttribute(attribute); } - /** - * Attempt to block the ability to select text while dragging controls + * Attempt to block the ability to select text. */ + function blockTextSelection() { - document_1.body.focus(); - document_1.onselectstart = function () { + document.body.focus(); + + document.onselectstart = function () { return false; }; } - /** - * Turn off text selection blocking + * Turn off text selection blocking. */ + function unblockTextSelection() { - document_1.onselectstart = function () { + document.onselectstart = function () { return true; }; } - /** * Identical to the native `getBoundingClientRect` function, but ensures that * the method is supported at all (it is in all browsers we claim to support) @@ -1001,13 +1020,13 @@ * Element whose `ClientRect` we want to calculate. * * @return {Object|undefined} - * Always returns a plain + * Always returns a plain object - or `undefined` if it cannot. */ + function getBoundingClientRect(el) { if (el && el.getBoundingClientRect && el.parentNode) { var rect = el.getBoundingClientRect(); var result = {}; - ['bottom', 'height', 'left', 'right', 'top', 'width'].forEach(function (k) { if (rect[k] !== undefined) { result[k] = rect[k]; @@ -1025,34 +1044,34 @@ return result; } } - /** - * The postion of a DOM element on the page. + * Represents the position of a DOM element on the page. * - * @typedef {Object} module:dom~Position + * @typedef {Object} module:dom~Position * * @property {number} left - * Pixels to the left + * Pixels to the left. * * @property {number} top - * Pixels on top + * Pixels from the top. */ /** - * Offset Left. - * getBoundingClientRect technique from - * John Resig + * Get the position of an element in the DOM. + * + * Uses `getBoundingClientRect` technique from John Resig. * * @see http://ejohn.org/blog/getboundingclientrect-is-awesome/ * - * @param {Element} el - * Element from which to get offset + * @param {Element} el + * Element from which to get offset. * * @return {module:dom~Position} * The position of the element that was passed in. */ + function findPosition(el) { - var box = void 0; + var box; if (el.getBoundingClientRect && el.parentNode) { box = el.getBoundingClientRect(); @@ -1065,28 +1084,24 @@ }; } - var docEl = document_1.documentElement; - var body = document_1.body; - + var docEl = document.documentElement; + var body = document.body; var clientLeft = docEl.clientLeft || body.clientLeft || 0; - var scrollLeft = window_1.pageXOffset || body.scrollLeft; + var scrollLeft = window$1.pageXOffset || body.scrollLeft; var left = box.left + scrollLeft - clientLeft; - var clientTop = docEl.clientTop || body.clientTop || 0; - var scrollTop = window_1.pageYOffset || body.scrollTop; - var top = box.top + scrollTop - clientTop; + var scrollTop = window$1.pageYOffset || body.scrollTop; + var top = box.top + scrollTop - clientTop; // Android sometimes returns slightly off decimal values, so need to round - // Android sometimes returns slightly off decimal values, so need to round return { left: Math.round(left), top: Math.round(top) }; } - /** - * x and y coordinates for a dom element or mouse pointer + * Represents x and y coordinates for a DOM element or mouse pointer. * - * @typedef {Object} Dom~Coordinates + * @typedef {Object} module:dom~Coordinates * * @property {number} x * x coordinate in pixels @@ -1096,26 +1111,26 @@ */ /** - * Get pointer position in element - * Returns an object with x and y coordinates. + * Get the pointer position within an element. + * * The base on the coordinates are the bottom left of the element. * - * @param {Element} el - * Element on which to get the pointer position on + * @param {Element} el + * Element on which to get the pointer position on. * - * @param {EventTarget~Event} event - * Event object + * @param {EventTarget~Event} event + * Event object. * - * @return {Dom~Coordinates} - * A Coordinates object corresponding to the mouse position. + * @return {module:dom~Coordinates} + * A coordinates object corresponding to the mouse position. * */ + function getPointerPosition(el, event) { var position = {}; var box = findPosition(el); var boxW = el.offsetWidth; var boxH = el.offsetHeight; - var boxY = box.top; var boxX = box.left; var pageY = event.pageY; @@ -1128,73 +1143,81 @@ position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / boxH)); position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW)); - return position; } - /** * Determines, via duck typing, whether or not a value is a text node. * - * @param {Mixed} value - * Check if this value is a text node. + * @param {Mixed} value + * Check if this value is a text node. * * @return {boolean} - * - True if it is a text node - * - False otherwise + * Will be `true` if the value is a text node, `false` otherwise. */ + function isTextNode(value) { return isObject(value) && value.nodeType === 3; } - /** * Empties the contents of an element. * - * @param {Element} el - * The element to empty children from + * @param {Element} el + * The element to empty children from * * @return {Element} * The element with no children */ + function emptyEl(el) { while (el.firstChild) { el.removeChild(el.firstChild); } + return el; } + /** + * This is a mixed value that describes content to be injected into the DOM + * via some method. It can be of the following types: + * + * Type | Description + * -----------|------------- + * `string` | The value will be normalized into a text node. + * `Element` | The value will be accepted as-is. + * `TextNode` | The value will be accepted as-is. + * `Array` | A one-dimensional array of strings, elements, text nodes, or functions. These functions should return a string, element, or text node (any other return value, like an array, will be ignored). + * `Function` | A function, which is expected to return a string, element, text node, or array - any of the other possible values described above. This means that a content descriptor could be a function that returns an array of functions, but those second-level functions must return strings, elements, or text nodes. + * + * @typedef {string|Element|TextNode|Array|Function} module:dom~ContentDescriptor + */ /** * Normalizes content for eventual insertion into the DOM. * - * This allows a wide range of content definition methods, but protects - * from falling into the trap of simply writing to `innerHTML`, which is - * an XSS concern. + * This allows a wide range of content definition methods, but helps protect + * from falling into the trap of simply writing to `innerHTML`, which could + * be an XSS concern. * * The content for an element can be passed in multiple types and * combinations, whose behavior is as follows: * - * @param {String|Element|TextNode|Array|Function} content - * - String: Normalized into a text node. - * - Element/TextNode: Passed through. - * - Array: A one-dimensional array of strings, elements, nodes, or functions - * (which return single strings, elements, or nodes). - * - Function: If the sole argument, is expected to produce a string, element, - * node, or array as defined above. + * @param {module:dom~ContentDescriptor} content + * A content descriptor value. * * @return {Array} - * All of the content that was passed in normalized. + * All of the content that was passed in, normalized to an array of + * elements or text nodes. */ - function normalizeContent(content) { + function normalizeContent(content) { // First, invoke content if it is a function. If it produces an array, // that needs to happen before normalization. if (typeof content === 'function') { content = content(); - } - - // Next up, normalize to an array, so one or many items can be normalized, + } // Next up, normalize to an array, so one or many items can be normalized, // filtered, and returned. - return (Array.isArray(content) ? content : [content]).map(function (value) { + + return (Array.isArray(content) ? content : [content]).map(function (value) { // First, invoke value if it is a function to produce a new value, // which will be subsequently normalized to a Node of some kind. if (typeof value === 'function') { @@ -1206,33 +1229,31 @@ } if (typeof value === 'string' && /\S/.test(value)) { - return document_1.createTextNode(value); + return document.createTextNode(value); } }).filter(function (value) { return value; }); } - /** * Normalizes and appends content to an element. * - * @param {Element} el - * Element to append normalized content to. + * @param {Element} el + * Element to append normalized content to. * - * - * @param {String|Element|TextNode|Array|Function} content - * See the `content` argument of {@link dom:normalizeContent} + * @param {module:dom~ContentDescriptor} content + * A content descriptor value. * * @return {Element} * The element with appended normalized content. */ + function appendContent(el, content) { normalizeContent(content).forEach(function (node) { return el.appendChild(node); }); return el; } - /** * Normalizes and inserts content into an element; this is identical to * `appendContent()`, except it empties the element first. @@ -1240,32 +1261,30 @@ * @param {Element} el * Element to insert normalized content into. * - * @param {String|Element|TextNode|Array|Function} content - * See the `content` argument of {@link dom:normalizeContent} + * @param {module:dom~ContentDescriptor} content + * A content descriptor value. * * @return {Element} * The element with inserted normalized content. - * */ + function insertContent(el, content) { return appendContent(emptyEl(el), content); } - /** - * Check if event was a single left click + * Check if an event was a single left click. * - * @param {EventTarget~Event} event - * Event object + * @param {EventTarget~Event} event + * Event object. * * @return {boolean} - * - True if a left click - * - False if not a left click + * Will be `true` if a single left click, `false` otherwise. */ + function isSingleLeftClick(event) { // Note: if you create something draggable, be sure to // call it on both `mousedown` and `mousemove` event, // otherwise `mousedown` should be enough for a button - if (event.button === undefined && event.buttons === undefined) { // Why do we need `buttons` ? // Because, middle mouse sometimes have this: @@ -1274,18 +1293,21 @@ // HOLD middlemouse then left click, that would be // e.button === 0, e.buttons === 5 // just `button` is not gonna work - // Alright, then what this block does ? // this is for chrome `simulate mobile devices` // I want to support this as well - return true; } if (event.button === 0 && event.buttons === undefined) { // Touch screen, sometimes on some specific device, `buttons` // doesn't have anything (safari on ios, blackberry...) + return true; + } // `mouseup` event on a single left click has + // `button` and `buttons` equal to 0 + + if (event.type === 'mouseup' && event.button === 0 && event.buttons === 0) { return true; } @@ -1294,48 +1316,48 @@ // if any special case we can catch and let it slide // we do it above, when get to here, this definitely // is-not-left-click - return false; } return true; } - /** * Finds a single DOM element matching `selector` within the optional * `context` of another DOM element (defaulting to `document`). * - * @param {string} selector - * A valid CSS selector, which will be passed to `querySelector`. + * @param {string} selector + * A valid CSS selector, which will be passed to `querySelector`. * - * @param {Element|String} [context=document] - * A DOM element within which to query. Can also be a selector - * string in which case the first matching element will be used - * as context. If missing (or no element matches selector), falls - * back to `document`. + * @param {Element|String} [context=document] + * A DOM element within which to query. Can also be a selector + * string in which case the first matching element will be used + * as context. If missing (or no element matches selector), falls + * back to `document`. * * @return {Element|null} * The element that was found or null. */ - var $ = createQuerier('querySelector'); + var $ = createQuerier('querySelector'); /** * Finds a all DOM elements matching `selector` within the optional * `context` of another DOM element (defaulting to `document`). * - * @param {string} selector - * A valid CSS selector, which will be passed to `querySelectorAll`. + * @param {string} selector + * A valid CSS selector, which will be passed to `querySelectorAll`. * - * @param {Element|String} [context=document] - * A DOM element within which to query. Can also be a selector - * string in which case the first matching element will be used - * as context. If missing (or no element matches selector), falls - * back to `document`. + * @param {Element|String} [context=document] + * A DOM element within which to query. Can also be a selector + * string in which case the first matching element will be used + * as context. If missing (or no element matches selector), falls + * back to `document`. * * @return {NodeList} - * A element list of elements that were found. Will be empty if none were found. + * A element list of elements that were found. Will be empty if none + * were found. * */ + var $$ = createQuerier('querySelectorAll'); var Dom = /*#__PURE__*/Object.freeze({ @@ -1369,23 +1391,164 @@ $$: $$ }); + /** + * @file setup.js - Functions for setting up a player without + * user interaction based on the data-setup `attribute` of the video tag. + * + * @module setup + */ + var _windowLoaded = false; + var videojs; + /** + * Set up any tags that have a data-setup `attribute` when the player is started. + */ + + var autoSetup = function autoSetup() { + // Protect against breakage in non-browser environments and check global autoSetup option. + if (!isReal() || videojs.options.autoSetup === false) { + return; + } + + var vids = Array.prototype.slice.call(document.getElementsByTagName('video')); + var audios = Array.prototype.slice.call(document.getElementsByTagName('audio')); + var divs = Array.prototype.slice.call(document.getElementsByTagName('video-js')); + var mediaEls = vids.concat(audios, divs); // Check if any media elements exist + + if (mediaEls && mediaEls.length > 0) { + for (var i = 0, e = mediaEls.length; i < e; i++) { + var mediaEl = mediaEls[i]; // Check if element exists, has getAttribute func. + + if (mediaEl && mediaEl.getAttribute) { + // Make sure this player hasn't already been set up. + if (mediaEl.player === undefined) { + var options = mediaEl.getAttribute('data-setup'); // Check if data-setup attr exists. + // We only auto-setup if they've added the data-setup attr. + + if (options !== null) { + // Create new video.js instance. + videojs(mediaEl); + } + } // If getAttribute isn't defined, we need to wait for the DOM. + + } else { + autoSetupTimeout(1); + break; + } + } // No videos were found, so keep looping unless page is finished loading. + + } else if (!_windowLoaded) { + autoSetupTimeout(1); + } + }; + /** + * Wait until the page is loaded before running autoSetup. This will be called in + * autoSetup if `hasLoaded` returns false. + * + * @param {number} wait + * How long to wait in ms + * + * @param {module:videojs} [vjs] + * The videojs library function + */ + + + function autoSetupTimeout(wait, vjs) { + if (vjs) { + videojs = vjs; + } + + window$1.setTimeout(autoSetup, wait); + } + /** + * Used to set the internal tracking of window loaded state to true. + * + * @private + */ + + + function setWindowLoaded() { + _windowLoaded = true; + window$1.removeEventListener('load', setWindowLoaded); + } + + if (isReal()) { + if (document.readyState === 'complete') { + setWindowLoaded(); + } else { + /** + * Listen for the load event on window, and set _windowLoaded to true. + * + * We use a standard event listener here to avoid incrementing the GUID + * before any players are created. + * + * @listens load + */ + window$1.addEventListener('load', setWindowLoaded); + } + } + + /** + * @file stylesheet.js + * @module stylesheet + */ + /** + * Create a DOM syle element given a className for it. + * + * @param {string} className + * The className to add to the created style element. + * + * @return {Element} + * The element that was created. + */ + + var createStyleElement = function createStyleElement(className) { + var style = document.createElement('style'); + style.className = className; + return style; + }; + /** + * Add text to a DOM element. + * + * @param {Element} el + * The Element to add text content to. + * + * @param {string} content + * The text to add to the element. + */ + + var setTextContent = function setTextContent(el, content) { + if (el.styleSheet) { + el.styleSheet.cssText = content; + } else { + el.textContent = content; + } + }; + /** * @file guid.js * @module guid */ - + // Default value for GUIDs. This allows us to reset the GUID counter in tests. + // + // The initial GUID is 3 because some users have come to rely on the first + // default player ID ending up as `vjs_video_3`. + // + // See: https://github.com/videojs/video.js/pull/6216 + var _initialGuid = 3; /** * Unique ID for an element or function + * * @type {Number} */ - var _guid = 1; + var _guid = _initialGuid; /** * Get a unique auto-incrementing ID by number that has not been returned before. * * @return {number} * A new unique ID. */ + function newGUID() { return _guid++; } @@ -1394,7 +1557,60 @@ * @file dom-data.js * @module dom-data */ + var FakeWeakMap; + if (!window$1.WeakMap) { + FakeWeakMap = + /*#__PURE__*/ + function () { + function FakeWeakMap() { + this.vdata = 'vdata' + Math.floor(window$1.performance && window$1.performance.now() || Date.now()); + this.data = {}; + } + + var _proto = FakeWeakMap.prototype; + + _proto.set = function set(key, value) { + var access = key[this.vdata] || newGUID(); + + if (!key[this.vdata]) { + key[this.vdata] = access; + } + + this.data[access] = value; + return this; + }; + + _proto.get = function get(key) { + var access = key[this.vdata]; // we have data, return it + + if (access) { + return this.data[access]; + } // we don't have data, return nothing. + // return undefined explicitly as that's the contract for this method + + + log('We have no data for this element', key); + return undefined; + }; + + _proto.has = function has(key) { + var access = key[this.vdata]; + return access in this.data; + }; + + _proto["delete"] = function _delete(key) { + var access = key[this.vdata]; + + if (access) { + delete this.data[access]; + delete key[this.vdata]; + } + }; + + return FakeWeakMap; + }(); + } /** * Element Data Store. * @@ -1405,88 +1621,9 @@ * @type {Object} * @private */ - var elData = {}; - /* - * Unique attribute name to store an element's guid in - * - * @type {String} - * @constant - * @private - */ - var elIdAttr = 'vdata' + new Date().getTime(); - /** - * Returns the cache object where data for an element is stored - * - * @param {Element} el - * Element to store data for. - * - * @return {Object} - * The cache object for that el that was passed in. - */ - function getData(el) { - var id = el[elIdAttr]; - - if (!id) { - id = el[elIdAttr] = newGUID(); - } - - if (!elData[id]) { - elData[id] = {}; - } - - return elData[id]; - } - - /** - * Returns whether or not an element has cached data - * - * @param {Element} el - * Check if this element has cached data. - * - * @return {boolean} - * - True if the DOM element has cached data. - * - False otherwise. - */ - function hasData(el) { - var id = el[elIdAttr]; - - if (!id) { - return false; - } - - return !!Object.getOwnPropertyNames(elData[id]).length; - } - - /** - * Delete data for the element from the cache and the guid attr from getElementById - * - * @param {Element} el - * Remove cached data for this element. - */ - function removeData(el) { - var id = el[elIdAttr]; - - if (!id) { - return; - } - - // Remove all stored data - delete elData[id]; - - // Remove the elIdAttr property from the DOM node - try { - delete el[elIdAttr]; - } catch (e) { - if (el.removeAttribute) { - el.removeAttribute(elIdAttr); - } else { - // IE doesn't appear to support removeAttribute on the document element - el[elIdAttr] = null; - } - } - } + var DomData = window$1.WeakMap ? new WeakMap() : new FakeWeakMap(); /** * @file events.js. An Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/) @@ -1494,9 +1631,9 @@ * This should work very similarly to jQuery's events, however it's based off the book version which isn't as * robust as jquery's, so there's probably some differences. * + * @file events.js * @module events */ - /** * Clean up the listener cache and dispatchers * @@ -1506,36 +1643,38 @@ * @param {string} type * Type of event to clean up */ + function _cleanUpEvents(elem, type) { - var data = getData(elem); + if (!DomData.has(elem)) { + return; + } + + var data = DomData.get(elem); // Remove the events of a particular type if there are none left - // Remove the events of a particular type if there are none left if (data.handlers[type].length === 0) { - delete data.handlers[type]; - // data.handlers[type] = null; + delete data.handlers[type]; // data.handlers[type] = null; // Setting to null was causing an error with data.handlers - // Remove the meta-handler from the element + if (elem.removeEventListener) { elem.removeEventListener(type, data.dispatcher, false); } else if (elem.detachEvent) { elem.detachEvent('on' + type, data.dispatcher); } - } + } // Remove the events object if there are no types left + - // Remove the events object if there are no types left if (Object.getOwnPropertyNames(data.handlers).length <= 0) { delete data.handlers; delete data.dispatcher; delete data.disabled; - } + } // Finally remove the element data if there is no data left + - // Finally remove the element data if there is no data left if (Object.getOwnPropertyNames(data).length === 0) { - removeData(elem); + DomData["delete"](elem); } } - /** * Loops through an array of event types and calls the requested method for each type. * @@ -1551,13 +1690,14 @@ * @param {EventTarget~EventListener} callback * Event listener. */ + + function _handleMultipleEvents(fn, elem, types, callback) { types.forEach(function (type) { // Call the event method for each one of the types fn(elem, type, callback); }); } - /** * Fix a native event to have standard property values * @@ -1567,7 +1707,12 @@ * @return {Object} * Fixed event object. */ + + function fixEvent(event) { + if (event.fixed_) { + return event; + } function returnTrue() { return true; @@ -1575,22 +1720,21 @@ function returnFalse() { return false; - } - - // Test if fixing up is needed + } // Test if fixing up is needed // Used to check if !event.stopPropagation instead of isPropagationStopped // But native events return true for stopPropagation, but don't have // other expected methods like isPropagationStopped. Seems to be a problem // with the Javascript Ninja code. So we're just overriding all events now. - if (!event || !event.isPropagationStopped) { - var old = event || window_1.event; - event = {}; - // Clone the old object so that we can modify the values event = {}; + + if (!event || !event.isPropagationStopped) { + var old = event || window$1.event; + event = {}; // Clone the old object so that we can modify the values event = {}; // IE8 Doesn't like when you mess with native event properties // Firefox returns false for event.hasOwnProperty('type') and other props // which makes copying more difficult. // TODO: Probably best to create a whitelist of event props + for (var key in old) { // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation @@ -1602,106 +1746,109 @@ event[key] = old[key]; } } - } + } // The event occurred on this element + - // The event occurred on this element if (!event.target) { - event.target = event.srcElement || document_1; - } + event.target = event.srcElement || document; + } // Handle which other element the event is related to + - // Handle which other element the event is related to if (!event.relatedTarget) { event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; - } + } // Stop the default browser action + - // Stop the default browser action event.preventDefault = function () { if (old.preventDefault) { old.preventDefault(); } + event.returnValue = false; old.returnValue = false; event.defaultPrevented = true; }; - event.defaultPrevented = false; + event.defaultPrevented = false; // Stop the event from bubbling - // Stop the event from bubbling event.stopPropagation = function () { if (old.stopPropagation) { old.stopPropagation(); } + event.cancelBubble = true; old.cancelBubble = true; event.isPropagationStopped = returnTrue; }; - event.isPropagationStopped = returnFalse; + event.isPropagationStopped = returnFalse; // Stop the event from bubbling and executing other handlers - // Stop the event from bubbling and executing other handlers event.stopImmediatePropagation = function () { if (old.stopImmediatePropagation) { old.stopImmediatePropagation(); } + event.isImmediatePropagationStopped = returnTrue; event.stopPropagation(); }; - event.isImmediatePropagationStopped = returnFalse; + event.isImmediatePropagationStopped = returnFalse; // Handle mouse position - // Handle mouse position if (event.clientX !== null && event.clientX !== undefined) { - var doc = document_1.documentElement; - var body = document_1.body; - + var doc = document.documentElement; + var body = document.body; event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); - } + } // Handle key presses - // Handle key presses - event.which = event.charCode || event.keyCode; - // Fix button for mouse clicks: + event.which = event.charCode || event.keyCode; // Fix button for mouse clicks: // 0 == left; 1 == middle; 2 == right - if (event.button !== null && event.button !== undefined) { + if (event.button !== null && event.button !== undefined) { // The following is disabled because it does not pass videojs-standard // and... yikes. + /* eslint-disable */ event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0; /* eslint-enable */ } } - // Returns fixed-up instance + event.fixed_ = true; // Returns fixed-up instance + return event; } - /** * Whether passive event listeners are supported */ - var _supportsPassive = false; - (function () { - try { - var opts = Object.defineProperty({}, 'passive', { - get: function get() { - _supportsPassive = true; - } - }); + var _supportsPassive; - window_1.addEventListener('test', null, opts); - window_1.removeEventListener('test', null, opts); - } catch (e) { - // disregard + var supportsPassive = function supportsPassive() { + if (typeof _supportsPassive !== 'boolean') { + _supportsPassive = false; + + try { + var opts = Object.defineProperty({}, 'passive', { + get: function get() { + _supportsPassive = true; + } + }); + window$1.addEventListener('test', null, opts); + window$1.removeEventListener('test', null, opts); + } catch (e) {// disregard + } } - })(); + return _supportsPassive; + }; /** * Touch events Chrome expects to be passive */ - var passiveEvents = ['touchstart', 'touchmove']; + + var passiveEvents = ['touchstart', 'touchmove']; /** * Add an event listener to element * It stores the handler function in a separate cache object @@ -1717,14 +1864,18 @@ * @param {EventTarget~EventListener} fn * Event listener. */ + function on(elem, type, fn) { if (Array.isArray(type)) { return _handleMultipleEvents(on, elem, type, fn); } - var data = getData(elem); + if (!DomData.has(elem)) { + DomData.set(elem, {}); + } + + var data = DomData.get(elem); // We need a place to store all our handler data - // We need a place to store all our handler data if (!data.handlers) { data.handlers = {}; } @@ -1743,13 +1894,11 @@ data.disabled = false; data.dispatcher = function (event, hash) { - if (data.disabled) { return; } event = fixEvent(event); - var handlers = data.handlers[event.type]; if (handlers) { @@ -1763,7 +1912,7 @@ try { handlersCopy[m].call(elem, event, hash); } catch (e) { - log$1.error(e); + log.error(e); } } } @@ -1775,16 +1924,18 @@ if (elem.addEventListener) { var options = false; - if (_supportsPassive && passiveEvents.indexOf(type) > -1) { - options = { passive: true }; + if (supportsPassive() && passiveEvents.indexOf(type) > -1) { + options = { + passive: true + }; } + elem.addEventListener(type, data.dispatcher, options); } else if (elem.attachEvent) { elem.attachEvent('on' + type, data.dispatcher); } } } - /** * Removes event listeners from an element * @@ -1798,53 +1949,54 @@ * Specific listener to remove. Don't include to remove listeners for an event * type. */ + function off(elem, type, fn) { // Don't want to add a cache object through getElData if not needed - if (!hasData(elem)) { + if (!DomData.has(elem)) { return; } - var data = getData(elem); + var data = DomData.get(elem); // If no events exist, nothing to unbind - // If no events exist, nothing to unbind if (!data.handlers) { return; } if (Array.isArray(type)) { return _handleMultipleEvents(off, elem, type, fn); - } + } // Utility function + - // Utility function var removeType = function removeType(el, t) { data.handlers[t] = []; - _cleanUpEvents(el, t); - }; - // Are we removing all bound events? + _cleanUpEvents(el, t); + }; // Are we removing all bound events? + + if (type === undefined) { for (var t in data.handlers) { if (Object.prototype.hasOwnProperty.call(data.handlers || {}, t)) { removeType(elem, t); } } + return; } - var handlers = data.handlers[type]; + var handlers = data.handlers[type]; // If no handlers exist, nothing to unbind - // If no handlers exist, nothing to unbind if (!handlers) { return; - } + } // If no listener was provided, remove all listeners for type + - // If no listener was provided, remove all listeners for type if (!fn) { removeType(elem, type); return; - } + } // We're only removing a single handler + - // We're only removing a single handler if (fn.guid) { for (var n = 0; n < handlers.length; n++) { if (handlers[n].guid === fn.guid) { @@ -1855,7 +2007,6 @@ _cleanUpEvents(elem, type); } - /** * Trigger an event for an element * @@ -1869,61 +2020,64 @@ * data hash to pass along with the event * * @return {boolean|undefined} - * - Returns the opposite of `defaultPrevented` if default was prevented - * - Otherwise returns undefined + * Returns the opposite of `defaultPrevented` if default was + * prevented. Otherwise, returns `undefined` */ + function trigger(elem, event, hash) { // Fetches element data and a reference to the parent (for bubbling). // Don't want to add a data object to cache for every parent, // so checking hasElData first. - var elemData = hasData(elem) ? getData(elem) : {}; - var parent = elem.parentNode || elem.ownerDocument; - // type = event.type || event, + var elemData = DomData.has(elem) ? DomData.get(elem) : {}; + var parent = elem.parentNode || elem.ownerDocument; // type = event.type || event, // handler; - // If an event name was passed as a string, creates an event out of it + if (typeof event === 'string') { - event = { type: event, target: elem }; + event = { + type: event, + target: elem + }; } else if (!event.target) { event.target = elem; - } + } // Normalizes the event properties. - // Normalizes the event properties. - event = fixEvent(event); - // If the passed element has a dispatcher, executes the established handlers. + event = fixEvent(event); // If the passed element has a dispatcher, executes the established handlers. + if (elemData.dispatcher) { elemData.dispatcher.call(elem, event, hash); - } - - // Unless explicitly stopped or the event does not bubble (e.g. media events) + } // Unless explicitly stopped or the event does not bubble (e.g. media events) // recursively calls this function to bubble the event up the DOM. + + if (parent && !event.isPropagationStopped() && event.bubbles === true) { - trigger.call(null, parent, event, hash); + trigger.call(null, parent, event, hash); // If at the top of the DOM, triggers the default action unless disabled. + } else if (!parent && !event.defaultPrevented && event.target && event.target[event.type]) { + if (!DomData.has(event.target)) { + DomData.set(event.target, {}); + } - // If at the top of the DOM, triggers the default action unless disabled. - } else if (!parent && !event.defaultPrevented) { - var targetData = getData(event.target); + var targetData = DomData.get(event.target); // Checks if the target has a default action for this event. - // Checks if the target has a default action for this event. if (event.target[event.type]) { // Temporarily disables event dispatching on the target as we have already executed the handler. - targetData.disabled = true; - // Executes the default action. + targetData.disabled = true; // Executes the default action. + if (typeof event.target[event.type] === 'function') { event.target[event.type](); - } - // Re-enables event dispatching. + } // Re-enables event dispatching. + + targetData.disabled = false; } - } + } // Inform the triggerer if the default was prevented by returning false + - // Inform the triggerer if the default was prevented by returning false return !event.defaultPrevented; } - /** - * Trigger a listener only once for an event + * Trigger a listener only once for an event. * * @param {Element|Object} elem * Element or object to bind to. @@ -1932,229 +2086,129 @@ * Name/type of event * * @param {Event~EventListener} fn - * Event Listener function + * Event listener function */ + function one(elem, type, fn) { if (Array.isArray(type)) { return _handleMultipleEvents(one, elem, type, fn); } + var func = function func() { off(elem, type, func); fn.apply(this, arguments); - }; + }; // copy the guid to the new function so it can removed using the original function's ID + - // copy the guid to the new function so it can removed using the original function's ID func.guid = fn.guid = fn.guid || newGUID(); on(elem, type, func); } + /** + * Trigger a listener only once and then turn if off for all + * configured events + * + * @param {Element|Object} elem + * Element or object to bind to. + * + * @param {string|string[]} type + * Name/type of event + * + * @param {Event~EventListener} fn + * Event listener function + */ + + function any(elem, type, fn) { + var func = function func() { + off(elem, type, func); + fn.apply(this, arguments); + }; // copy the guid to the new function so it can removed using the original function's ID + + + func.guid = fn.guid = fn.guid || newGUID(); // multiple ons, but one off for everything + + on(elem, type, func); + } var Events = /*#__PURE__*/Object.freeze({ fixEvent: fixEvent, on: on, off: off, trigger: trigger, - one: one + one: one, + any: any }); - /** - * @file setup.js - Functions for setting up a player without - * user interaction based on the data-setup `attribute` of the video tag. - * - * @module setup - */ - - var _windowLoaded = false; - var videojs = void 0; - - /** - * Set up any tags that have a data-setup `attribute` when the player is started. - */ - var autoSetup = function autoSetup() { - - // Protect against breakage in non-browser environments and check global autoSetup option. - if (!isReal() || videojs.options.autoSetup === false) { - return; - } - - var vids = Array.prototype.slice.call(document_1.getElementsByTagName('video')); - var audios = Array.prototype.slice.call(document_1.getElementsByTagName('audio')); - var divs = Array.prototype.slice.call(document_1.getElementsByTagName('video-js')); - var mediaEls = vids.concat(audios, divs); - - // Check if any media elements exist - if (mediaEls && mediaEls.length > 0) { - - for (var i = 0, e = mediaEls.length; i < e; i++) { - var mediaEl = mediaEls[i]; - - // Check if element exists, has getAttribute func. - if (mediaEl && mediaEl.getAttribute) { - - // Make sure this player hasn't already been set up. - if (mediaEl.player === undefined) { - var options = mediaEl.getAttribute('data-setup'); - - // Check if data-setup attr exists. - // We only auto-setup if they've added the data-setup attr. - if (options !== null) { - // Create new video.js instance. - videojs(mediaEl); - } - } - - // If getAttribute isn't defined, we need to wait for the DOM. - } else { - autoSetupTimeout(1); - break; - } - } - - // No videos were found, so keep looping unless page is finished loading. - } else if (!_windowLoaded) { - autoSetupTimeout(1); - } - }; - - /** - * Wait until the page is loaded before running autoSetup. This will be called in - * autoSetup if `hasLoaded` returns false. - * - * @param {number} wait - * How long to wait in ms - * - * @param {module:videojs} [vjs] - * The videojs library function - */ - function autoSetupTimeout(wait, vjs) { - if (vjs) { - videojs = vjs; - } - - window_1.setTimeout(autoSetup, wait); - } - - if (isReal() && document_1.readyState === 'complete') { - _windowLoaded = true; - } else { - /** - * Listen for the load event on window, and set _windowLoaded to true. - * - * @listens load - */ - one(window_1, 'load', function () { - _windowLoaded = true; - }); - } - - /** - * @file stylesheet.js - * @module stylesheet - */ - - /** - * Create a DOM syle element given a className for it. - * - * @param {string} className - * The className to add to the created style element. - * - * @return {Element} - * The element that was created. - */ - var createStyleElement = function createStyleElement(className) { - var style = document_1.createElement('style'); - - style.className = className; - - return style; - }; - - /** - * Add text to a DOM element. - * - * @param {Element} el - * The Element to add text content to. - * - * @param {string} content - * The text to add to the element. - */ - var setTextContent = function setTextContent(el, content) { - if (el.styleSheet) { - el.styleSheet.cssText = content; - } else { - el.textContent = content; - } - }; - /** * @file fn.js * @module fn */ - + var UPDATE_REFRESH_INTERVAL = 30; /** - * Bind (a.k.a proxy or Context). A simple method for changing the context of a function - * It also stores a unique id on the function so it can be easily removed from events. + * Bind (a.k.a proxy or context). A simple method for changing the context of + * a function. * - * @param {Mixed} context - * The object to bind as scope. + * It also stores a unique id on the function so it can be easily removed from + * events. * - * @param {Function} fn - * The function to be bound to a scope. + * @function + * @param {Mixed} context + * The object to bind as scope. * - * @param {number} [uid] - * An optional unique ID for the function to be set + * @param {Function} fn + * The function to be bound to a scope. * - * @return {Function} - * The new function that will be bound into the context given + * @param {number} [uid] + * An optional unique ID for the function to be set + * + * @return {Function} + * The new function that will be bound into the context given */ + var bind = function bind(context, fn, uid) { // Make sure the function has a unique ID if (!fn.guid) { fn.guid = newGUID(); - } + } // Create the new function that changes the context - // Create the new function that changes the context - var bound = function bound() { - return fn.apply(context, arguments); - }; - // Allow for the ability to individualize this function + var bound = fn.bind(context); // Allow for the ability to individualize this function // Needed in the case where multiple objects might share the same prototype // IF both items add an event listener with the same function, then you try to remove just one // it will remove both because they both have the same guid. // when using this, you need to use the bind method when you remove the listener as well. // currently used in text tracks - bound.guid = uid ? uid + '_' + fn.guid : fn.guid; + bound.guid = uid ? uid + '_' + fn.guid : fn.guid; return bound; }; - /** * Wraps the given function, `fn`, with a new function that only invokes `fn` * at most once per every `wait` milliseconds. * - * @param {Function} fn - * The function to be throttled. + * @function + * @param {Function} fn + * The function to be throttled. * - * @param {Number} wait - * The number of milliseconds by which to throttle. + * @param {number} wait + * The number of milliseconds by which to throttle. * - * @return {Function} + * @return {Function} */ + var throttle = function throttle(fn, wait) { - var last = Date.now(); + var last = window$1.performance.now(); var throttled = function throttled() { - var now = Date.now(); + var now = window$1.performance.now(); if (now - last >= wait) { - fn.apply(undefined, arguments); + fn.apply(void 0, arguments); last = now; } }; return throttled; }; - /** * Creates a debounced function that delays invoking `func` until after `wait` * milliseconds have elapsed since the last time the debounced function was @@ -2162,35 +2216,40 @@ * * Inspired by lodash and underscore implementations. * - * @param {Function} func - * The function to wrap with debounce behavior. + * @function + * @param {Function} func + * The function to wrap with debounce behavior. * - * @param {number} wait - * The number of milliseconds to wait after the last invocation. + * @param {number} wait + * The number of milliseconds to wait after the last invocation. * - * @param {boolean} [immediate] - * Whether or not to invoke the function immediately upon creation. + * @param {boolean} [immediate] + * Whether or not to invoke the function immediately upon creation. * - * @param {Object} [context=window] - * The "context" in which the debounced function should debounce. For - * example, if this function should be tied to a Video.js player, - * the player can be passed here. Alternatively, defaults to the - * global `window` object. + * @param {Object} [context=window] + * The "context" in which the debounced function should debounce. For + * example, if this function should be tied to a Video.js player, + * the player can be passed here. Alternatively, defaults to the + * global `window` object. * - * @return {Function} - * A debounced function. + * @return {Function} + * A debounced function. */ - var debounce = function debounce(func, wait, immediate) { - var context = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : window_1; - var timeout = void 0; + var debounce = function debounce(func, wait, immediate, context) { + if (context === void 0) { + context = window$1; + } + + var timeout; var cancel = function cancel() { context.clearTimeout(timeout); timeout = null; }; - /* eslint-disable consistent-this */ + + var debounced = function debounced() { var self = this; var args = arguments; @@ -2198,6 +2257,7 @@ var _later = function later() { timeout = null; _later = null; + if (!immediate) { func.apply(self, args); } @@ -2212,15 +2272,14 @@ }; /* eslint-enable consistent-this */ - debounced.cancel = cancel; + debounced.cancel = cancel; return debounced; }; /** * @file src/js/event-target.js */ - /** * `EventTarget` is a class that can have the same API as the DOM `EventTarget`. It * adds shorthand functions that wrap around lengthy functions. For example: @@ -2229,8 +2288,8 @@ * @see [EventTarget Spec]{@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget} * @class EventTarget */ - var EventTarget = function EventTarget() {}; + var EventTarget = function EventTarget() {}; /** * A Custom DOM event. * @@ -2260,8 +2319,9 @@ * @property EventTarget.prototype.allowedEvents_ * @private */ - EventTarget.prototype.allowedEvents_ = {}; + + EventTarget.prototype.allowedEvents_ = {}; /** * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a * function that will get called when an event with a certain name gets triggered. @@ -2272,16 +2332,17 @@ * @param {EventTarget~EventListener} fn * The function to call with `EventTarget`s */ + EventTarget.prototype.on = function (type, fn) { // Remove the addEventListener alias before calling Events.on // so we don't get into an infinite type loop var ael = this.addEventListener; this.addEventListener = function () {}; + on(this, type, fn); this.addEventListener = ael; }; - /** * An alias of {@link EventTarget#on}. Allows `EventTarget` to mimic * the standard DOM API. @@ -2289,8 +2350,9 @@ * @function * @see {@link EventTarget#on} */ - EventTarget.prototype.addEventListener = EventTarget.prototype.on; + + EventTarget.prototype.addEventListener = EventTarget.prototype.on; /** * Removes an `event listener` for a specific event from an instance of `EventTarget`. * This makes it so that the `event listener` will no longer get called when the @@ -2302,10 +2364,10 @@ * @param {EventTarget~EventListener} fn * The function to remove. */ + EventTarget.prototype.off = function (type, fn) { off(this, type, fn); }; - /** * An alias of {@link EventTarget#off}. Allows `EventTarget` to mimic * the standard DOM API. @@ -2313,8 +2375,9 @@ * @function * @see {@link EventTarget#off} */ - EventTarget.prototype.removeEventListener = EventTarget.prototype.off; + + EventTarget.prototype.removeEventListener = EventTarget.prototype.off; /** * This function will add an `event listener` that gets triggered only once. After the * first trigger it will get removed. This is like adding an `event listener` @@ -2326,16 +2389,28 @@ * @param {EventTarget~EventListener} fn * The function to be called once for each event name. */ + EventTarget.prototype.one = function (type, fn) { - // Remove the addEventListener alialing Events.on + // Remove the addEventListener aliasing Events.on // so we don't get into an infinite type loop var ael = this.addEventListener; this.addEventListener = function () {}; + one(this, type, fn); this.addEventListener = ael; }; + EventTarget.prototype.any = function (type, fn) { + // Remove the addEventListener aliasing Events.on + // so we don't get into an infinite type loop + var ael = this.addEventListener; + + this.addEventListener = function () {}; + + any(this, type, fn); + this.addEventListener = ael; + }; /** * This function causes an event to happen. This will then cause any `event listeners` * that are waiting for that event, to get called. If there are no `event listeners` @@ -2352,12 +2427,21 @@ * The name of the event, an `Event`, or an object with a key of type set to * an event name. */ + + EventTarget.prototype.trigger = function (event) { - var type = event.type || event; + var type = event.type || event; // deprecation + // In a future version we should default target to `this` + // similar to how we default the target to `elem` in + // `Events.trigger`. Right now the default `target` will be + // `document` due to the `Event.fixEvent` call. if (typeof event === 'string') { - event = { type: type }; + event = { + type: type + }; } + event = fixEvent(event); if (this.allowedEvents_[type] && this['on' + type]) { @@ -2366,7 +2450,6 @@ trigger(this, event); }; - /** * An alias of {@link EventTarget#trigger}. Allows `EventTarget` to mimic * the standard DOM API. @@ -2374,9 +2457,10 @@ * @function * @see {@link EventTarget#trigger} */ - EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger; - var EVENT_MAP = void 0; + + EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger; + var EVENT_MAP; EventTarget.prototype.queueTrigger = function (event) { var _this = this; @@ -2395,20 +2479,17 @@ } var oldTimeout = map.get(type); - - map.delete(type); - window_1.clearTimeout(oldTimeout); - - var timeout = window_1.setTimeout(function () { + map["delete"](type); + window$1.clearTimeout(oldTimeout); + var timeout = window$1.setTimeout(function () { // if we cleared out all timeouts for the current target, delete its map if (map.size === 0) { map = null; - EVENT_MAP.delete(_this); + EVENT_MAP["delete"](_this); } _this.trigger(event); }, 0); - map.set(type, timeout); }; @@ -2416,7 +2497,6 @@ * @file mixins/evented.js * @module evented */ - /** * Returns whether or not an object has had the evented mixin applied. * @@ -2426,12 +2506,33 @@ * @return {boolean} * Whether or not the object appears to be evented. */ + var isEvented = function isEvented(object) { return object instanceof EventTarget || !!object.eventBusEl_ && ['on', 'one', 'off', 'trigger'].every(function (k) { return typeof object[k] === 'function'; }); }; + /** + * Adds a callback to run after the evented mixin applied. + * + * @param {Object} object + * An object to Add + * @param {Function} callback + * The callback to run. + */ + + var addEventedCallback = function addEventedCallback(target, callback) { + if (isEvented(target)) { + callback(); + } else { + if (!target.eventedCallbacks) { + target.eventedCallbacks = []; + } + + target.eventedCallbacks.push(callback); + } + }; /** * Whether a value is a valid event type - non-empty string or array. * @@ -2442,14 +2543,14 @@ * @return {boolean} * Whether or not the type is a valid event type. */ + + var isValidEventType = function isValidEventType(type) { - return ( - // The regex here verifies that the `type` contains at least one non- + return (// The regex here verifies that the `type` contains at least one non- // whitespace character. typeof type === 'string' && /\S/.test(type) || Array.isArray(type) && !!type.length ); }; - /** * Validates a value to determine if it is a valid event target. Throws if not. * @@ -2460,12 +2561,13 @@ * @param {Object} target * The object to test. */ + + var validateTarget = function validateTarget(target) { if (!target.nodeName && !isEvented(target)) { throw new Error('Invalid target; must be a DOM node or evented object.'); } }; - /** * Validates a value to determine if it is a valid event target. Throws if not. * @@ -2476,12 +2578,13 @@ * @param {string|Array} type * The type to test. */ + + var validateEventType = function validateEventType(type) { if (!isValidEventType(type)) { throw new Error('Invalid event type; must be a non-empty string or array.'); } }; - /** * Validates a value to determine if it is a valid listener. Throws if not. * @@ -2492,12 +2595,13 @@ * @param {Function} listener * The listener to test. */ + + var validateListener = function validateListener(listener) { if (typeof listener !== 'function') { throw new Error('Invalid listener; must be a function.'); } }; - /** * Takes an array of arguments given to `on()` or `one()`, validates them, and * normalizes them into an object. @@ -2513,20 +2617,20 @@ * @return {Object} * An object containing useful values for `on()` or `one()` calls. */ - var normalizeListenArgs = function normalizeListenArgs(self, args) { + + var normalizeListenArgs = function normalizeListenArgs(self, args) { // If the number of arguments is less than 3, the target is always the // evented object itself. var isTargetingSelf = args.length < 3 || args[0] === self || args[0] === self.eventBusEl_; - var target = void 0; - var type = void 0; - var listener = void 0; + var target; + var type; + var listener; if (isTargetingSelf) { - target = self.eventBusEl_; - - // Deal with cases where we got 3 arguments, but we are still listening to + target = self.eventBusEl_; // Deal with cases where we got 3 arguments, but we are still listening to // the evented object itself. + if (args.length >= 3) { args.shift(); } @@ -2542,12 +2646,14 @@ validateTarget(target); validateEventType(type); validateListener(listener); - listener = bind(self, listener); - - return { isTargetingSelf: isTargetingSelf, target: target, type: type, listener: listener }; + return { + isTargetingSelf: isTargetingSelf, + target: target, + type: type, + listener: listener + }; }; - /** * Adds the listener to the event type(s) on the target, normalizing for * the type of target. @@ -2565,6 +2671,8 @@ * @param {Function} listener * A listener function. */ + + var listen = function listen(target, method, type, listener) { validateTarget(target); @@ -2574,15 +2682,15 @@ target[method](type, listener); } }; - /** * Contains methods that provide event capabilities to an object which is passed * to {@link module:evented|evented}. * * @mixin EventedMixin */ - var EventedMixin = { + + var EventedMixin = { /** * Add a listener to an event (or events) on this object or another evented * object. @@ -2606,10 +2714,10 @@ * If the first argument was another evented object, this will be * the listener function. */ - on: function on$$1() { + on: function on() { var _this = this; - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } @@ -2619,40 +2727,35 @@ type = _normalizeListenArgs.type, listener = _normalizeListenArgs.listener; - listen(target, 'on', type, listener); + listen(target, 'on', type, listener); // If this object is listening to another evented object. - // If this object is listening to another evented object. if (!isTargetingSelf) { - // If this object is disposed, remove the listener. var removeListenerOnDispose = function removeListenerOnDispose() { return _this.off(target, type, listener); - }; - - // Use the same function ID as the listener so we can remove it later it + }; // Use the same function ID as the listener so we can remove it later it // using the ID of the original listener. - removeListenerOnDispose.guid = listener.guid; - // Add a listener to the target's dispose event as well. This ensures + + removeListenerOnDispose.guid = listener.guid; // Add a listener to the target's dispose event as well. This ensures // that if the target is disposed BEFORE this object, we remove the // removal listener that was just added. Otherwise, we create a memory leak. + var removeRemoverOnTargetDispose = function removeRemoverOnTargetDispose() { return _this.off('dispose', removeListenerOnDispose); - }; - - // Use the same function ID as the listener so we can remove it later + }; // Use the same function ID as the listener so we can remove it later // it using the ID of the original listener. - removeRemoverOnTargetDispose.guid = listener.guid; + + removeRemoverOnTargetDispose.guid = listener.guid; listen(this, 'on', 'dispose', removeListenerOnDispose); listen(target, 'on', 'dispose', removeRemoverOnTargetDispose); } }, - /** * Add a listener to an event (or events) on this object or another evented - * object. The listener will only be called once and then removed. + * object. The listener will be called once per event and then removed. * * @param {string|Array|Element|Object} targetOrType * If this is a string or array, it represents the event type(s) @@ -2673,10 +2776,10 @@ * If the first argument was another evented object, this will be * the listener function. */ - one: function one$$1() { + one: function one() { var _this2 = this; - for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } @@ -2684,32 +2787,90 @@ isTargetingSelf = _normalizeListenArgs2.isTargetingSelf, target = _normalizeListenArgs2.target, type = _normalizeListenArgs2.type, - listener = _normalizeListenArgs2.listener; - - // Targeting this evented object. + listener = _normalizeListenArgs2.listener; // Targeting this evented object. if (isTargetingSelf) { - listen(target, 'one', type, listener); - - // Targeting another evented object. + listen(target, 'one', type, listener); // Targeting another evented object. } else { + // TODO: This wrapper is incorrect! It should only + // remove the wrapper for the event type that called it. + // Instead all listners are removed on the first trigger! + // see https://github.com/videojs/video.js/issues/5962 var wrapper = function wrapper() { - for (var _len3 = arguments.length, largs = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + _this2.off(target, type, wrapper); + + for (var _len3 = arguments.length, largs = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { largs[_key3] = arguments[_key3]; } - _this2.off(target, type, wrapper); listener.apply(null, largs); - }; - - // Use the same function ID as the listener so we can remove it later + }; // Use the same function ID as the listener so we can remove it later // it using the ID of the original listener. + + wrapper.guid = listener.guid; listen(target, 'one', type, wrapper); } }, + /** + * Add a listener to an event (or events) on this object or another evented + * object. The listener will only be called once for the first event that is triggered + * then removed. + * + * @param {string|Array|Element|Object} targetOrType + * If this is a string or array, it represents the event type(s) + * that will trigger the listener. + * + * Another evented object can be passed here instead, which will + * cause the listener to listen for events on _that_ object. + * + * In either case, the listener's `this` value will be bound to + * this object. + * + * @param {string|Array|Function} typeOrListener + * If the first argument was a string or array, this should be the + * listener function. Otherwise, this is a string or array of event + * type(s). + * + * @param {Function} [listener] + * If the first argument was another evented object, this will be + * the listener function. + */ + any: function any() { + var _this3 = this; + + for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; + } + + var _normalizeListenArgs3 = normalizeListenArgs(this, args), + isTargetingSelf = _normalizeListenArgs3.isTargetingSelf, + target = _normalizeListenArgs3.target, + type = _normalizeListenArgs3.type, + listener = _normalizeListenArgs3.listener; // Targeting this evented object. + + + if (isTargetingSelf) { + listen(target, 'any', type, listener); // Targeting another evented object. + } else { + var wrapper = function wrapper() { + _this3.off(target, type, wrapper); + + for (var _len5 = arguments.length, largs = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) { + largs[_key5] = arguments[_key5]; + } + + listener.apply(null, largs); + }; // Use the same function ID as the listener so we can remove it later + // it using the ID of the original listener. + + + wrapper.guid = listener.guid; + listen(target, 'any', type, wrapper); + } + }, /** * Removes listener(s) from event(s) on an evented object. @@ -2730,27 +2891,21 @@ * the listener function; otherwise, _all_ listeners bound to the * event type(s) will be removed. */ - off: function off$$1(targetOrType, typeOrListener, listener) { - + off: function off$1(targetOrType, typeOrListener, listener) { // Targeting this evented object. if (!targetOrType || isValidEventType(targetOrType)) { - off(this.eventBusEl_, targetOrType, typeOrListener); - - // Targeting another evented object. + off(this.eventBusEl_, targetOrType, typeOrListener); // Targeting another evented object. } else { var target = targetOrType; - var type = typeOrListener; + var type = typeOrListener; // Fail fast and in a meaningful way! - // Fail fast and in a meaningful way! validateTarget(target); validateEventType(type); - validateListener(listener); + validateListener(listener); // Ensure there's at least a guid, even if the function hasn't been used - // Ensure there's at least a guid, even if the function hasn't been used - listener = bind(this, listener); - - // Remove the dispose listener on this evented object, which was given + listener = bind(this, listener); // Remove the dispose listener on this evented object, which was given // the same guid as the event listener in on(). + this.off('dispose', listener); if (target.nodeName) { @@ -2763,7 +2918,6 @@ } }, - /** * Fire an event on this evented object, causing its listeners to be called. * @@ -2773,14 +2927,13 @@ * @param {Object} [hash] * An additional object to pass along to listeners. * - * @returns {boolean} + * @return {boolean} * Whether or not the default behavior was prevented. */ - trigger: function trigger$$1(event, hash) { + trigger: function trigger$1(event, hash) { return trigger(this.eventBusEl_, event, hash); } }; - /** * Applies {@link module:evented~EventedMixin|EventedMixin} to a target object. * @@ -2790,7 +2943,7 @@ * @param {Object} [options={}] * Options for customizing the mixin behavior. * - * @param {String} [options.eventBusKey] + * @param {string} [options.eventBusKey] * By default, adds a `eventBusEl_` DOM element to the target object, * which is used as an event bus. If the target object already has a * DOM element that should be used, pass its key here. @@ -2798,31 +2951,42 @@ * @return {Object} * The target object. */ - function evented(target) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var eventBusKey = options.eventBusKey; - // Set or create the eventBusEl_. + function evented(target, options) { + if (options === void 0) { + options = {}; + } + + var _options = options, + eventBusKey = _options.eventBusKey; // Set or create the eventBusEl_. if (eventBusKey) { if (!target[eventBusKey].nodeName) { - throw new Error('The eventBusKey "' + eventBusKey + '" does not refer to an element.'); + throw new Error("The eventBusKey \"" + eventBusKey + "\" does not refer to an element."); } + target.eventBusEl_ = target[eventBusKey]; } else { - target.eventBusEl_ = createEl('span', { className: 'vjs-event-bus' }); + target.eventBusEl_ = createEl('span', { + className: 'vjs-event-bus' + }); } assign(target, EventedMixin); - // When any evented object is disposed, it removes all its listeners. + if (target.eventedCallbacks) { + target.eventedCallbacks.forEach(function (callback) { + callback(); + }); + } // When any evented object is disposed, it removes all its listeners. + + target.on('dispose', function () { target.off(); - window_1.setTimeout(function () { + window$1.setTimeout(function () { target.eventBusEl_ = null; }, 0); }); - return target; } @@ -2830,15 +2994,14 @@ * @file mixins/stateful.js * @module stateful */ - /** * Contains methods that provide statefulness to an object which is passed * to {@link module:stateful}. * * @mixin StatefulMixin */ - var StatefulMixin = { + var StatefulMixin = { /** * A hash containing arbitrary keys and values representing the state of * the object. @@ -2856,7 +3019,7 @@ * A new set of properties to shallow-merge into the plugin state. * Can be a plain object or a function returning a plain object. * - * @returns {Object|undefined} + * @return {Object|undefined} * An object containing changes that occurred. If no changes * occurred, returns `undefined`. */ @@ -2868,10 +3031,8 @@ stateUpdates = stateUpdates(); } - var changes = void 0; - + var changes; each(stateUpdates, function (value, key) { - // Record the change if the value is different from what's in the // current state. if (_this.state[key] !== value) { @@ -2883,13 +3044,11 @@ } _this.state[key] = value; - }); - - // Only trigger "statechange" if there were changes AND we have a trigger + }); // Only trigger "statechange" if there were changes AND we have a trigger // function. This allows us to not require that the target object be an // evented object. - if (changes && isEvented(this)) { + if (changes && isEvented(this)) { /** * An event triggered on an object that is both * {@link module:stateful|stateful} and {@link module:evented|evented} @@ -2910,7 +3069,6 @@ return changes; } }; - /** * Applies {@link module:stateful~StatefulMixin|StatefulMixin} to a target * object. @@ -2926,17 +3084,16 @@ * A default set of properties to populate the newly-stateful object's * `state` property. * - * @returns {Object} + * @return {Object} * Returns the `target`. */ + function stateful(target, defaultState) { - assign(target, StatefulMixin); - - // This happens after the mixing-in because we need to replace the `state` + assign(target, StatefulMixin); // This happens after the mixing-in because we need to replace the `state` // added in that step. - target.state = assign({}, target.state, defaultState); - // Auto-bind the `handleStateChanged` method of the target object if it exists. + target.state = assign({}, target.state, defaultState); // Auto-bind the `handleStateChanged` method of the target object if it exists. + if (typeof target.handleStateChanged === 'function' && isEvented(target)) { target.on('statechanged', target.handleStateChanged); } @@ -2945,10 +3102,28 @@ } /** - * @file to-title-case.js - * @module to-title-case + * @file string-cases.js + * @module to-lower-case */ + /** + * Lowercase the first letter of a string. + * + * @param {string} string + * String to be lowercased + * + * @return {string} + * The string with a lowercased first letter + */ + var toLowerCase = function toLowerCase(string) { + if (typeof string !== 'string') { + return string; + } + + return string.replace(/./, function (w) { + return w.toLowerCase(); + }); + }; /** * Uppercase the first letter of a string. * @@ -2958,14 +3133,16 @@ * @return {string} * The string with an uppercased first letter */ - function toTitleCase(string) { + + var toTitleCase = function toTitleCase(string) { if (typeof string !== 'string') { return string; } - return string.charAt(0).toUpperCase() + string.slice(1); - } - + return string.replace(/./, function (w) { + return w.toUpperCase(); + }); + }; /** * Compares the TitleCase versions of the two strings for equality. * @@ -2978,29 +3155,37 @@ * @return {boolean} * Whether the TitleCase versions of the strings are equal */ - function titleCaseEquals(str1, str2) { + + var titleCaseEquals = function titleCaseEquals(str1, str2) { return toTitleCase(str1) === toTitleCase(str2); - } + }; /** * @file merge-options.js * @module merge-options */ - /** - * Deep-merge one or more options objects, recursively merging **only** plain - * object properties. + * Merge two objects recursively. * + * Performs a deep merge like + * {@link https://lodash.com/docs/4.17.10#merge|lodash.merge}, but only merges + * plain objects (not arrays, elements, or anything else). + * + * Non-plain object values will be copied directly from the right-most + * argument. + * + * @static * @param {Object[]} sources * One or more objects to merge into a new object. * - * @returns {Object} + * @return {Object} * A new object that is the merged result of all sources. */ + function mergeOptions() { var result = {}; - for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) { + for (var _len = arguments.length, sources = new Array(_len), _key = 0; _key < _len; _key++) { sources[_key] = arguments[_key]; } @@ -3022,7 +3207,6 @@ result[key] = mergeOptions(result[key], value); }); }); - return result; } @@ -3031,7 +3215,6 @@ * * @file component.js */ - /** * Base class for all UI Components. * Components are UI objects which represent both a javascript object and an element @@ -3041,8 +3224,9 @@ * Components can also use methods from {@link EventTarget} */ - var Component = function () { - + var Component = + /*#__PURE__*/ + function () { /** * A callback that is called when a component is ready. Does not have any * paramters and any callback value will be ignored. @@ -3069,9 +3253,6 @@ * Function that gets called when the `Component` is ready. */ function Component(player, options, ready) { - classCallCheck(this, Component); - - // The component might be the player itself and we can't pass `this` to super if (!player && this.play) { this.player_ = player = this; // eslint-disable-line @@ -3079,57 +3260,95 @@ this.player_ = player; } - // Make a copy of prototype.options_ to protect against overriding defaults - this.options_ = mergeOptions({}, this.options_); + this.isDisposed_ = false; // Hold the reference to the parent component via `addChild` method - // Updated options with supplied options - options = this.options_ = mergeOptions(this.options_, options); + this.parentComponent_ = null; // Make a copy of prototype.options_ to protect against overriding defaults - // Get ID from options or options element if one is supplied - this.id_ = options.id || options.el && options.el.id; + this.options_ = mergeOptions({}, this.options_); // Updated options with supplied options + + options = this.options_ = mergeOptions(this.options_, options); // Get ID from options or options element if one is supplied + + this.id_ = options.id || options.el && options.el.id; // If there was no ID from the options, generate one - // If there was no ID from the options, generate one if (!this.id_) { // Don't require the player ID function in the case of mock players var id = player && player.id && player.id() || 'no_player'; - - this.id_ = id + '_component_' + newGUID(); + this.id_ = id + "_component_" + newGUID(); } - this.name_ = options.name || null; + this.name_ = options.name || null; // Create element if one wasn't provided in options - // Create element if one wasn't provided in options if (options.el) { this.el_ = options.el; } else if (options.createEl !== false) { this.el_ = this.createEl(); - } + } // if evented is anything except false, we want to mixin in evented + - // if evented is anything except false, we want to mixin in evented if (options.evented !== false) { // Make this an evented object and use `el_`, if available, as its event bus - evented(this, { eventBusKey: this.el_ ? 'el_' : null }); + evented(this, { + eventBusKey: this.el_ ? 'el_' : null + }); } - stateful(this, this.constructor.defaultState); + stateful(this, this.constructor.defaultState); this.children_ = []; this.childIndex_ = {}; this.childNameIndex_ = {}; + var SetSham; + + if (!window$1.Set) { + SetSham = + /*#__PURE__*/ + function () { + function SetSham() { + this.set_ = {}; + } + + var _proto2 = SetSham.prototype; + + _proto2.has = function has(key) { + return key in this.set_; + }; + + _proto2["delete"] = function _delete(key) { + var has = this.has(key); + delete this.set_[key]; + return has; + }; + + _proto2.add = function add(key) { + this.set_[key] = 1; + return this; + }; + + _proto2.forEach = function forEach(callback, thisArg) { + for (var key in this.set_) { + callback.call(thisArg, key, key, this); + } + }; + + return SetSham; + }(); + } + + this.setTimeoutIds_ = window$1.Set ? new Set() : new SetSham(); + this.setIntervalIds_ = window$1.Set ? new Set() : new SetSham(); + this.rafIds_ = window$1.Set ? new Set() : new SetSham(); + this.clearingTimersOnDispose_ = false; // Add any child components in options - // Add any child components in options if (options.initChildren !== false) { this.initChildren(); } - this.ready(ready); - // Don't want to trigger ready here or it will before init is actually + this.ready(ready); // Don't want to trigger ready here or it will before init is actually // finished for all children that run this constructor if (options.reportTouchActivity !== false) { this.enableTouchActivity(); } } - /** * Dispose of the `Component` and all child components. * @@ -3137,8 +3356,13 @@ */ - Component.prototype.dispose = function dispose() { + var _proto = Component.prototype; + _proto.dispose = function dispose() { + // Bail out if the component has already been disposed. + if (this.isDisposed_) { + return; + } /** * Triggered when a `Component` is disposed. * @@ -3146,24 +3370,30 @@ * @type {EventTarget~Event} * * @property {boolean} [bubbles=false] - * set to false so that the close event does not + * set to false so that the dispose event does not * bubble up */ - this.trigger({ type: 'dispose', bubbles: false }); - // Dispose all children. + + this.trigger({ + type: 'dispose', + bubbles: false + }); + this.isDisposed_ = true; // Dispose all children. + if (this.children_) { for (var i = this.children_.length - 1; i >= 0; i--) { if (this.children_[i].dispose) { this.children_[i].dispose(); } } - } + } // Delete child references + - // Delete child references this.children_ = null; this.childIndex_ = null; this.childNameIndex_ = null; + this.parentComponent_ = null; if (this.el_) { // Remove element from DOM @@ -3171,26 +3401,38 @@ this.el_.parentNode.removeChild(this.el_); } - removeData(this.el_); + if (DomData.has(this.el_)) { + DomData["delete"](this.el_); + } + this.el_ = null; - } + } // remove reference to the player after disposing of the element + - // remove reference to the player after disposing of the element this.player_ = null; - }; + } + /** + * Determine whether or not this component has been disposed. + * + * @return {boolean} + * If the component has been disposed, will be `true`. Otherwise, `false`. + */ + ; + _proto.isDisposed = function isDisposed() { + return Boolean(this.isDisposed_); + } /** * Return the {@link Player} that the `Component` has attached to. * * @return {Player} * The player that this `Component` has attached to. */ + ; - - Component.prototype.player = function player() { + _proto.player = function player() { return this.player_; - }; - + } /** * Deep merge of options objects with new options. * > Note: When both `obj` and `options` contain properties whose values are objects. @@ -3201,34 +3443,28 @@ * * @return {Object} * A new object of `this.options_` and `obj` merged together. - * - * @deprecated since version 5 */ + ; - - Component.prototype.options = function options(obj) { - log$1.warn('this.options() has been deprecated and will be moved to the constructor in 6.0'); - + _proto.options = function options(obj) { if (!obj) { return this.options_; } this.options_ = mergeOptions(this.options_, obj); return this.options_; - }; - + } /** * Get the `Component`s DOM element * * @return {Element} * The DOM element for this `Component`. */ + ; - - Component.prototype.el = function el() { + _proto.el = function el() { return this.el_; - }; - + } /** * Create the `Component`s DOM element. * @@ -3244,12 +3480,11 @@ * @return {Element} * The element that gets created. */ + ; - - Component.prototype.createEl = function createEl$$1(tagName, properties, attributes) { + _proto.createEl = function createEl$1(tagName, properties, attributes) { return createEl(tagName, properties, attributes); - }; - + } /** * Localize a string given the string in english. * @@ -3288,17 +3523,18 @@ * @return {string} * The localized string or if no localization exists the english string. */ + ; - - Component.prototype.localize = function localize(string, tokens) { - var defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : string; + _proto.localize = function localize(string, tokens, defaultValue) { + if (defaultValue === void 0) { + defaultValue = string; + } var code = this.player_.language && this.player_.language(); var languages = this.player_.languages && this.player_.languages(); var language = languages && languages[code]; var primaryCode = code && code.split('-')[0]; var primaryLang = languages && languages[primaryCode]; - var localizedString = defaultValue; if (language && language[string]) { @@ -3321,8 +3557,7 @@ } return localizedString; - }; - + } /** * Return the `Component`s DOM element. This is where children get inserted. * This will usually be the the same as the element returned in {@link Component#el}. @@ -3330,24 +3565,22 @@ * @return {Element} * The content element for this `Component`. */ + ; - - Component.prototype.contentEl = function contentEl() { + _proto.contentEl = function contentEl() { return this.contentEl_ || this.el_; - }; - + } /** * Get this `Component`s ID * * @return {string} * The id of this `Component` */ + ; - - Component.prototype.id = function id() { + _proto.id = function id() { return this.id_; - }; - + } /** * Get the `Component`s name. The name gets used to reference the `Component` * and is set during registration. @@ -3355,24 +3588,22 @@ * @return {string} * The name of this `Component`. */ + ; - - Component.prototype.name = function name() { + _proto.name = function name() { return this.name_; - }; - + } /** * Get an array of all child components * * @return {Array} * The children */ + ; - - Component.prototype.children = function children() { + _proto.children = function children() { return this.children_; - }; - + } /** * Returns the child `Component` with the given `id`. * @@ -3382,12 +3613,11 @@ * @return {Component|undefined} * The child `Component` with the given `id` or undefined. */ + ; - - Component.prototype.getChildById = function getChildById(id) { + _proto.getChildById = function getChildById(id) { return this.childIndex_[id]; - }; - + } /** * Returns the child `Component` with the given `name`. * @@ -3397,18 +3627,15 @@ * @return {Component|undefined} * The child `Component` with the given `name` or undefined. */ + ; - - Component.prototype.getChild = function getChild(name) { + _proto.getChild = function getChild(name) { if (!name) { return; } - name = toTitleCase(name); - return this.childNameIndex_[name]; - }; - + } /** * Add a child `Component` inside the current `Component`. * @@ -3427,74 +3654,82 @@ * The `Component` that gets added as a child. When using a string the * `Component` will get created by this process. */ + ; + _proto.addChild = function addChild(child, options, index) { + if (options === void 0) { + options = {}; + } - Component.prototype.addChild = function addChild(child) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.children_.length; + if (index === void 0) { + index = this.children_.length; + } - var component = void 0; - var componentName = void 0; + var component; + var componentName; // If child is a string, create component with options - // If child is a string, create component with options if (typeof child === 'string') { componentName = toTitleCase(child); + var componentClassName = options.componentClass || componentName; // Set name through options - var componentClassName = options.componentClass || componentName; - - // Set name through options - options.name = componentName; - - // Create a new object & element for this controls set + options.name = componentName; // Create a new object & element for this controls set // If there's no .player_, this is a player + var ComponentClass = Component.getComponent(componentClassName); if (!ComponentClass) { - throw new Error('Component ' + componentClassName + ' does not exist'); - } - - // data stored directly on the videojs object may be + throw new Error("Component " + componentClassName + " does not exist"); + } // data stored directly on the videojs object may be // misidentified as a component to retain // backwards-compatibility with 4.x. check to make sure the // component class can be instantiated. + + if (typeof ComponentClass !== 'function') { return null; } - component = new ComponentClass(this.player_ || this, options); - - // child is a component instance + component = new ComponentClass(this.player_ || this, options); // child is a component instance } else { component = child; } + if (component.parentComponent_) { + component.parentComponent_.removeChild(component); + } + this.children_.splice(index, 0, component); + component.parentComponent_ = this; if (typeof component.id === 'function') { this.childIndex_[component.id()] = component; - } - - // If a name wasn't used to create the component, check if we can use the + } // If a name wasn't used to create the component, check if we can use the // name function of the component + + componentName = componentName || component.name && toTitleCase(component.name()); if (componentName) { this.childNameIndex_[componentName] = component; - } - - // Add the UI object's element to the container div (box) + this.childNameIndex_[toLowerCase(componentName)] = component; + } // Add the UI object's element to the container div (box) // Having an element is not required + + if (typeof component.el === 'function' && component.el()) { - var childNodes = this.contentEl().children; - var refNode = childNodes[index] || null; + // If inserting before a component, insert before that component's element + var refNode = null; + + if (this.children_[index + 1] && this.children_[index + 1].el_) { + refNode = this.children_[index + 1].el_; + } this.contentEl().insertBefore(component.el(), refNode); - } + } // Return so it can stored on parent object if desired. + - // Return so it can stored on parent object if desired. return component; - }; - + } /** * Remove a child `Component` from this `Component`s list of children. Also removes * the child `Component`s element from this `Component`s element. @@ -3502,9 +3737,9 @@ * @param {Component} component * The child `Component` to remove. */ + ; - - Component.prototype.removeChild = function removeChild(component) { + _proto.removeChild = function removeChild(component) { if (typeof component === 'string') { component = this.getChild(component); } @@ -3527,22 +3762,22 @@ return; } + component.parentComponent_ = null; this.childIndex_[component.id()] = null; - this.childNameIndex_[component.name()] = null; - + this.childNameIndex_[toTitleCase(component.name())] = null; + this.childNameIndex_[toLowerCase(component.name())] = null; var compEl = component.el(); if (compEl && compEl.parentNode === this.contentEl()) { this.contentEl().removeChild(component.el()); } - }; - + } /** * Add and initialize default child `Component`s based upon options. */ + ; - - Component.prototype.initChildren = function initChildren() { + _proto.initChildren = function initChildren() { var _this = this; var children = this.options_.children; @@ -3553,45 +3788,43 @@ var handleAdd = function handleAdd(child) { var name = child.name; - var opts = child.opts; - - // Allow options for children to be set at the parent options + var opts = child.opts; // Allow options for children to be set at the parent options // e.g. videojs(id, { controlBar: false }); // instead of videojs(id, { children: { controlBar: false }); + if (parentOptions[name] !== undefined) { opts = parentOptions[name]; - } - - // Allow for disabling default components + } // Allow for disabling default components // e.g. options['children']['posterImage'] = false + + if (opts === false) { return; - } - - // Allow options to be passed as a simple boolean if no configuration + } // Allow options to be passed as a simple boolean if no configuration // is necessary. + + if (opts === true) { opts = {}; - } - - // We also want to pass the original player options + } // We also want to pass the original player options // to each component as well so they don't need to // reach back into the player for options later. - opts.playerOptions = _this.options_.playerOptions; - // Create and add the child component. + + opts.playerOptions = _this.options_.playerOptions; // Create and add the child component. // Add a direct reference to the child by name on the parent instance. // If two of the same component are used, different names should be supplied // for each + var newChild = _this.addChild(name, opts); if (newChild) { _this[name] = newChild; } - }; + }; // Allow for an array of children details to passed in the options - // Allow for an array of children details to passed in the options - var workingChildren = void 0; + + var workingChildren; var Tech = Component.getComponent('Tech'); if (Array.isArray(children)) { @@ -3600,19 +3833,19 @@ workingChildren = Object.keys(children); } - workingChildren - // children that are in this.options_ but also in workingChildren would + workingChildren // children that are in this.options_ but also in workingChildren would // give us extra children we do not want. So, we want to filter them out. .concat(Object.keys(this.options_).filter(function (child) { return !workingChildren.some(function (wchild) { if (typeof wchild === 'string') { return child === wchild; } + return child === wchild.name; }); })).map(function (child) { - var name = void 0; - var opts = void 0; + var name; + var opts; if (typeof child === 'string') { name = child; @@ -3622,18 +3855,19 @@ opts = child; } - return { name: name, opts: opts }; + return { + name: name, + opts: opts + }; }).filter(function (child) { // we have to make sure that child.name isn't in the techOrder since // techs are registerd as Components but can't aren't compatible // See https://github.com/videojs/video.js/issues/2772 var c = Component.getComponent(child.opts.componentClass || toTitleCase(child.name)); - return c && !Tech.isTech(c); }).forEach(handleAdd); } - }; - + } /** * Builds the default DOM class name. Should be overriden by sub-components. * @@ -3642,14 +3876,13 @@ * * @abstract */ + ; - - Component.prototype.buildCSSClass = function buildCSSClass() { + _proto.buildCSSClass = function buildCSSClass() { // Child classes can include a function that does: // return 'CLASS NAME' + this._super(); return ''; - }; - + } /** * Bind a listener to the component's ready state. * Different from event listeners in that if the ready event has already happened @@ -3658,10 +3891,12 @@ * @return {Component} * Returns itself; method can be chained. */ + ; - - Component.prototype.ready = function ready(fn) { - var sync = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + _proto.ready = function ready(fn, sync) { + if (sync === void 0) { + sync = false; + } if (!fn) { return; @@ -3679,42 +3914,39 @@ // Call the function asynchronously by default for consistency this.setTimeout(fn, 1); } - }; - + } /** * Trigger all the ready listeners for this `Component`. * * @fires Component#ready */ + ; + _proto.triggerReady = function triggerReady() { + this.isReady_ = true; // Ensure ready is triggered asynchronously - Component.prototype.triggerReady = function triggerReady() { - this.isReady_ = true; - - // Ensure ready is triggered asynchronously this.setTimeout(function () { - var readyQueue = this.readyQueue_; + var readyQueue = this.readyQueue_; // Reset Ready Queue - // Reset Ready Queue this.readyQueue_ = []; if (readyQueue && readyQueue.length > 0) { readyQueue.forEach(function (fn) { fn.call(this); }, this); - } + } // Allow for using event listeners also - // Allow for using event listeners also /** * Triggered when a `Component` is ready. * * @event Component#ready * @type {EventTarget~Event} */ + + this.trigger('ready'); }, 1); - }; - + } /** * Find a single DOM element matching a `selector`. This can be within the `Component`s * `contentEl()` or another custom context. @@ -3733,12 +3965,11 @@ * * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors) */ + ; - - Component.prototype.$ = function $$$1(selector, context) { + _proto.$ = function $$1(selector, context) { return $(selector, context || this.contentEl()); - }; - + } /** * Finds all DOM element matching a `selector`. This can be within the `Component`s * `contentEl()` or another custom context. @@ -3757,12 +3988,11 @@ * * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors) */ + ; - - Component.prototype.$$ = function $$$$1(selector, context) { + _proto.$$ = function $$$1(selector, context) { return $$(selector, context || this.contentEl()); - }; - + } /** * Check if a component's element has a CSS class name. * @@ -3773,36 +4003,33 @@ * - True if the `Component` has the class. * - False if the `Component` does not have the class` */ + ; - - Component.prototype.hasClass = function hasClass$$1(classToCheck) { + _proto.hasClass = function hasClass$1(classToCheck) { return hasClass(this.el_, classToCheck); - }; - + } /** * Add a CSS class name to the `Component`s element. * * @param {string} classToAdd * CSS class name to add */ + ; - - Component.prototype.addClass = function addClass$$1(classToAdd) { + _proto.addClass = function addClass$1(classToAdd) { addClass(this.el_, classToAdd); - }; - + } /** * Remove a CSS class name from the `Component`s element. * * @param {string} classToRemove * CSS class name to remove */ + ; - - Component.prototype.removeClass = function removeClass$$1(classToRemove) { + _proto.removeClass = function removeClass$1(classToRemove) { removeClass(this.el_, classToRemove); - }; - + } /** * Add or remove a CSS class name from the component's element. * - `classToToggle` gets added when {@link Component#hasClass} would return false. @@ -3814,56 +4041,51 @@ * @param {boolean|Dom~predicate} [predicate] * An {@link Dom~predicate} function or a boolean */ + ; - - Component.prototype.toggleClass = function toggleClass$$1(classToToggle, predicate) { + _proto.toggleClass = function toggleClass$1(classToToggle, predicate) { toggleClass(this.el_, classToToggle, predicate); - }; - + } /** * Show the `Component`s element if it is hidden by removing the * 'vjs-hidden' class name from it. */ + ; - - Component.prototype.show = function show() { + _proto.show = function show() { this.removeClass('vjs-hidden'); - }; - + } /** * Hide the `Component`s element if it is currently showing by adding the * 'vjs-hidden` class name to it. */ + ; - - Component.prototype.hide = function hide() { + _proto.hide = function hide() { this.addClass('vjs-hidden'); - }; - + } /** * Lock a `Component`s element in its visible state by adding the 'vjs-lock-showing' * class name to it. Used during fadeIn/fadeOut. * * @private */ + ; - - Component.prototype.lockShowing = function lockShowing() { + _proto.lockShowing = function lockShowing() { this.addClass('vjs-lock-showing'); - }; - + } /** * Unlock a `Component`s element from its visible state by removing the 'vjs-lock-showing' * class name from it. Used during fadeIn/fadeOut. * * @private */ + ; - - Component.prototype.unlockShowing = function unlockShowing() { + _proto.unlockShowing = function unlockShowing() { this.removeClass('vjs-lock-showing'); - }; - + } /** * Get the value of an attribute on the `Component`s element. * @@ -3879,12 +4101,11 @@ * * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute} */ + ; - - Component.prototype.getAttribute = function getAttribute$$1(attribute) { + _proto.getAttribute = function getAttribute$1(attribute) { return getAttribute(this.el_, attribute); - }; - + } /** * Set the value of an attribute on the `Component`'s element * @@ -3896,12 +4117,11 @@ * * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute} */ + ; - - Component.prototype.setAttribute = function setAttribute$$1(attribute, value) { + _proto.setAttribute = function setAttribute$1(attribute, value) { setAttribute(this.el_, attribute, value); - }; - + } /** * Remove an attribute from the `Component`s element. * @@ -3910,12 +4130,11 @@ * * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute} */ + ; - - Component.prototype.removeAttribute = function removeAttribute$$1(attribute) { + _proto.removeAttribute = function removeAttribute$1(attribute) { removeAttribute(this.el_, attribute); - }; - + } /** * Get or set the width of the component based upon the CSS styles. * See {@link Component#dimension} for more detailed information. @@ -3930,12 +4149,11 @@ * The width when getting, zero if there is no width. Can be a string * postpixed with '%' or 'px'. */ + ; - - Component.prototype.width = function width(num, skipListeners) { + _proto.width = function width(num, skipListeners) { return this.dimension('width', num, skipListeners); - }; - + } /** * Get or set the height of the component based upon the CSS styles. * See {@link Component#dimension} for more detailed information. @@ -3950,12 +4168,11 @@ * The width when getting, zero if there is no width. Can be a string * postpixed with '%' or 'px'. */ + ; - - Component.prototype.height = function height(num, skipListeners) { + _proto.height = function height(num, skipListeners) { return this.dimension('height', num, skipListeners); - }; - + } /** * Set both the width and height of the `Component` element at the same time. * @@ -3965,14 +4182,13 @@ * @param {number|string} height * Height to set the `Component`s element to. */ + ; - - Component.prototype.dimensions = function dimensions(width, height) { + _proto.dimensions = function dimensions(width, height) { // Skip componentresize listeners on width for optimization this.width(width, true); this.height(height); - }; - + } /** * Get or set width or height of the `Component` element. This is the shared code * for the {@link Component#width} and {@link Component#height}. @@ -4001,25 +4217,25 @@ * @return {number} * The dimension when getting or 0 if unset */ + ; - - Component.prototype.dimension = function dimension(widthOrHeight, num, skipListeners) { + _proto.dimension = function dimension(widthOrHeight, num, skipListeners) { if (num !== undefined) { // Set to zero if null or literally NaN (NaN !== NaN) if (num === null || num !== num) { num = 0; - } + } // Check if using css width/height (% or px) and adjust + - // Check if using css width/height (% or px) and adjust if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) { this.el_.style[widthOrHeight] = num; } else if (num === 'auto') { this.el_.style[widthOrHeight] = ''; } else { this.el_.style[widthOrHeight] = num + 'px'; - } + } // skipListeners allows us to avoid triggering the resize event when setting both width and height + - // skipListeners allows us to avoid triggering the resize event when setting both width and height if (!skipListeners) { /** * Triggered when a component is resized. @@ -4031,32 +4247,32 @@ } return; - } - - // Not setting a value, so getting it + } // Not setting a value, so getting it // Make sure element exists + + if (!this.el_) { return 0; - } + } // Get dimension value from style + - // Get dimension value from style var val = this.el_.style[widthOrHeight]; var pxIndex = val.indexOf('px'); if (pxIndex !== -1) { // Return the pixel value with no 'px' return parseInt(val.slice(0, pxIndex), 10); - } - - // No px so using % or no style was set, so falling back to offsetWidth/height + } // No px so using % or no style was set, so falling back to offsetWidth/height // If component has display:none, offset will return 0 // TODO: handle display:none and no dimension style using px - return parseInt(this.el_['offset' + toTitleCase(widthOrHeight)], 10); - }; + + return parseInt(this.el_['offset' + toTitleCase(widthOrHeight)], 10); + } /** - * Get the width or the height of the `Component` elements computed style. Uses - * `window.getComputedStyle`. + * Get the computed width or the height of the component's element. + * + * Uses `window.getComputedStyle`. * * @param {string} widthOrHeight * A string containing 'width' or 'height'. Whichever one you want to get. @@ -4065,36 +4281,28 @@ * The dimension that gets asked for or 0 if nothing was set * for that dimension. */ + ; - - Component.prototype.currentDimension = function currentDimension(widthOrHeight) { + _proto.currentDimension = function currentDimension(widthOrHeight) { var computedWidthOrHeight = 0; if (widthOrHeight !== 'width' && widthOrHeight !== 'height') { throw new Error('currentDimension only accepts width or height value'); } - if (typeof window_1.getComputedStyle === 'function') { - var computedStyle = window_1.getComputedStyle(this.el_); + computedWidthOrHeight = computedStyle(this.el_, widthOrHeight); // remove 'px' from variable and parse as integer - computedWidthOrHeight = computedStyle.getPropertyValue(widthOrHeight) || computedStyle[widthOrHeight]; - } - - // remove 'px' from variable and parse as integer - computedWidthOrHeight = parseFloat(computedWidthOrHeight); - - // if the computed value is still 0, it's possible that the browser is lying + computedWidthOrHeight = parseFloat(computedWidthOrHeight); // if the computed value is still 0, it's possible that the browser is lying // and we want to check the offset values. // This code also runs wherever getComputedStyle doesn't exist. - if (computedWidthOrHeight === 0) { - var rule = 'offset' + toTitleCase(widthOrHeight); + if (computedWidthOrHeight === 0 || isNaN(computedWidthOrHeight)) { + var rule = "offset" + toTitleCase(widthOrHeight); computedWidthOrHeight = this.el_[rule]; } return computedWidthOrHeight; - }; - + } /** * An object that contains width and height values of the `Component`s * computed style. Uses `window.getComputedStyle`. @@ -4109,63 +4317,95 @@ */ /** - * Get an object that contains width and height values of the `Component`s - * computed style. + * Get an object that contains computed width and height values of the + * component's element. + * + * Uses `window.getComputedStyle`. * * @return {Component~DimensionObject} - * The dimensions of the components element + * The computed dimensions of the component's element. */ + ; - - Component.prototype.currentDimensions = function currentDimensions() { + _proto.currentDimensions = function currentDimensions() { return { width: this.currentDimension('width'), height: this.currentDimension('height') }; - }; - + } /** - * Get the width of the `Component`s computed style. Uses `window.getComputedStyle`. + * Get the computed width of the component's element. * - * @return {number} width - * The width of the `Component`s computed style. + * Uses `window.getComputedStyle`. + * + * @return {number} + * The computed width of the component's element. */ + ; - - Component.prototype.currentWidth = function currentWidth() { + _proto.currentWidth = function currentWidth() { return this.currentDimension('width'); - }; - + } /** - * Get the height of the `Component`s computed style. Uses `window.getComputedStyle`. + * Get the computed height of the component's element. * - * @return {number} height - * The height of the `Component`s computed style. + * Uses `window.getComputedStyle`. + * + * @return {number} + * The computed height of the component's element. */ + ; - - Component.prototype.currentHeight = function currentHeight() { + _proto.currentHeight = function currentHeight() { return this.currentDimension('height'); - }; - + } /** * Set the focus to this component */ + ; - - Component.prototype.focus = function focus() { + _proto.focus = function focus() { this.el_.focus(); - }; - + } /** * Remove the focus from this component */ + ; - - Component.prototype.blur = function blur() { + _proto.blur = function blur() { this.el_.blur(); - }; + } + /** + * When this Component receives a `keydown` event which it does not process, + * it passes the event to the Player for handling. + * + * @param {EventTarget~Event} event + * The `keydown` event that caused this function to be called. + */ + ; + _proto.handleKeyDown = function handleKeyDown(event) { + if (this.player_) { + // We only stop propagation here because we want unhandled events to fall + // back to the browser. + event.stopPropagation(); + this.player_.handleKeyDown(event); + } + } + /** + * Many components used to have a `handleKeyPress` method, which was poorly + * named because it listened to a `keydown` event. This method name now + * delegates to `handleKeyDown`. This means anyone calling `handleKeyPress` + * will not see their method calls stop working. + * + * @param {EventTarget~Event} event + * The event that caused this function to be called. + */ + ; + + _proto.handleKeyPress = function handleKeyPress(event) { + this.handleKeyDown(event); + } /** * Emit a 'tap' events when touch event support gets detected. This gets used to * support toggling the controls through a tap on the video. They get enabled @@ -4179,23 +4419,19 @@ * @listens Component#touchcancel * @listens Component#touchend */ + ; - - Component.prototype.emitTapEvents = function emitTapEvents() { + _proto.emitTapEvents = function emitTapEvents() { // Track the start time so we can determine how long the touch lasted var touchStart = 0; - var firstTouch = null; - - // Maximum movement allowed during a touch event to still be considered a tap + var firstTouch = null; // Maximum movement allowed during a touch event to still be considered a tap // Other popular libs use anywhere from 2 (hammer.js) to 15, // so 10 seems like a nice, round number. - var tapMovementThreshold = 10; - // The maximum length a touch can be while still being considered a tap + var tapMovementThreshold = 10; // The maximum length a touch can be while still being considered a tap + var touchTimeThreshold = 200; - - var couldBeTap = void 0; - + var couldBeTap; this.on('touchstart', function (event) { // If more than one finger, don't consider treating this as a click if (event.touches.length === 1) { @@ -4203,14 +4439,13 @@ firstTouch = { pageX: event.touches[0].pageX, pageY: event.touches[0].pageY - }; - // Record start time so we can detect a tap vs. "touch and hold" - touchStart = new Date().getTime(); - // Reset couldBeTap tracking + }; // Record start time so we can detect a tap vs. "touch and hold" + + touchStart = window$1.performance.now(); // Reset couldBeTap tracking + couldBeTap = true; } }); - this.on('touchmove', function (event) { // If more than one finger, don't consider treating this as a click if (event.touches.length > 1) { @@ -4230,22 +4465,20 @@ var noTap = function noTap() { couldBeTap = false; - }; + }; // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s + - // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s this.on('touchleave', noTap); - this.on('touchcancel', noTap); - - // When the touch ends, measure how long it took and trigger the appropriate + this.on('touchcancel', noTap); // When the touch ends, measure how long it took and trigger the appropriate // event + this.on('touchend', function (event) { - firstTouch = null; - // Proceed only if the touchmove/leave/cancel event didn't happen + firstTouch = null; // Proceed only if the touchmove/leave/cancel event didn't happen + if (couldBeTap === true) { // Measure how long the touch lasted - var touchTime = new Date().getTime() - touchStart; + var touchTime = window$1.performance.now() - touchStart; // Make sure the touch was less than the threshold to be considered a tap - // Make sure the touch was less than the threshold to be considered a tap if (touchTime < touchTimeThreshold) { // Don't let browser turn this into a click event.preventDefault(); @@ -4255,15 +4488,14 @@ * @event Component#tap * @type {EventTarget~Event} */ - this.trigger('tap'); - // It may be good to copy the touchend event object and change the + + this.trigger('tap'); // It may be good to copy the touchend event object and change the // type to tap, if the other event properties aren't exact after // Events.fixEvent runs (e.g. event.target) } } }); - }; - + } /** * This function reports user activity whenever touch events happen. This can get * turned off by any sub-components that wants touch events to act another way. @@ -4287,40 +4519,37 @@ * @listens Component#touchend * @listens Component#touchcancel */ + ; - - Component.prototype.enableTouchActivity = function enableTouchActivity() { + _proto.enableTouchActivity = function enableTouchActivity() { // Don't continue if the root player doesn't support reporting user activity if (!this.player() || !this.player().reportUserActivity) { return; - } + } // listener for reporting that the user is active + - // listener for reporting that the user is active var report = bind(this.player(), this.player().reportUserActivity); - - var touchHolding = void 0; - + var touchHolding; this.on('touchstart', function () { - report(); - // For as long as the they are touching the device or have their mouse down, + report(); // For as long as the they are touching the device or have their mouse down, // we consider them active even if they're not moving their finger or mouse. // So we want to continue to update that they are active - this.clearInterval(touchHolding); - // report at the same interval as activityCheck + + this.clearInterval(touchHolding); // report at the same interval as activityCheck + touchHolding = this.setInterval(report, 250); }); var touchEnd = function touchEnd(event) { - report(); - // stop the interval that maintains activity if the touch is holding + report(); // stop the interval that maintains activity if the touch is holding + this.clearInterval(touchHolding); }; this.on('touchmove', report); this.on('touchend', touchEnd); this.on('touchcancel', touchEnd); - }; - + } /** * A callback that has no parameters and is bound into `Component`s context. * @@ -4354,33 +4583,26 @@ * @listens Component#dispose * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout} */ + ; - - Component.prototype.setTimeout = function setTimeout(fn, timeout) { + _proto.setTimeout = function setTimeout(fn, timeout) { var _this2 = this; // declare as variables so they are properly available in timeout function // eslint-disable-next-line - var timeoutId, disposeFn; - + var timeoutId; fn = bind(this, fn); + this.clearTimersOnDispose_(); + timeoutId = window$1.setTimeout(function () { + if (_this2.setTimeoutIds_.has(timeoutId)) { + _this2.setTimeoutIds_["delete"](timeoutId); + } - timeoutId = window_1.setTimeout(function () { - _this2.off('dispose', disposeFn); fn(); }, timeout); - - disposeFn = function disposeFn() { - return _this2.clearTimeout(timeoutId); - }; - - disposeFn.guid = 'vjs-timeout-' + timeoutId; - - this.on('dispose', disposeFn); - + this.setTimeoutIds_.add(timeoutId); return timeoutId; - }; - + } /** * Clears a timeout that gets created via `window.setTimeout` or * {@link Component#setTimeout}. If you set a timeout via {@link Component#setTimeout} @@ -4396,20 +4618,16 @@ * * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearTimeout} */ + ; - - Component.prototype.clearTimeout = function clearTimeout(timeoutId) { - window_1.clearTimeout(timeoutId); - - var disposeFn = function disposeFn() {}; - - disposeFn.guid = 'vjs-timeout-' + timeoutId; - - this.off('dispose', disposeFn); + _proto.clearTimeout = function clearTimeout(timeoutId) { + if (this.setTimeoutIds_.has(timeoutId)) { + this.setTimeoutIds_["delete"](timeoutId); + window$1.clearTimeout(timeoutId); + } return timeoutId; - }; - + } /** * Creates a function that gets run every `x` milliseconds. This function is a wrapper * around `window.setInterval`. There are a few reasons to use this one instead though. @@ -4430,26 +4648,15 @@ * @listens Component#dispose * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval} */ + ; - - Component.prototype.setInterval = function setInterval(fn, interval) { - var _this3 = this; - + _proto.setInterval = function setInterval(fn, interval) { fn = bind(this, fn); - - var intervalId = window_1.setInterval(fn, interval); - - var disposeFn = function disposeFn() { - return _this3.clearInterval(intervalId); - }; - - disposeFn.guid = 'vjs-interval-' + intervalId; - - this.on('dispose', disposeFn); - + this.clearTimersOnDispose_(); + var intervalId = window$1.setInterval(fn, interval); + this.setIntervalIds_.add(intervalId); return intervalId; - }; - + } /** * Clears an interval that gets created via `window.setInterval` or * {@link Component#setInterval}. If you set an inteval via {@link Component#setInterval} @@ -4465,20 +4672,16 @@ * * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval} */ + ; - - Component.prototype.clearInterval = function clearInterval(intervalId) { - window_1.clearInterval(intervalId); - - var disposeFn = function disposeFn() {}; - - disposeFn.guid = 'vjs-interval-' + intervalId; - - this.off('dispose', disposeFn); + _proto.clearInterval = function clearInterval(intervalId) { + if (this.setIntervalIds_.has(intervalId)) { + this.setIntervalIds_["delete"](intervalId); + window$1.clearInterval(intervalId); + } return intervalId; - }; - + } /** * Queues up a callback to be passed to requestAnimationFrame (rAF), but * with a few extra bonuses: @@ -4504,37 +4707,31 @@ * @listens Component#dispose * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame} */ + ; - - Component.prototype.requestAnimationFrame = function requestAnimationFrame(fn) { - var _this4 = this; - - // declare as variables so they are properly available in rAF function - // eslint-disable-next-line - var id, disposeFn; - - if (this.supportsRaf_) { - fn = bind(this, fn); - - id = window_1.requestAnimationFrame(function () { - _this4.off('dispose', disposeFn); - fn(); - }); - - disposeFn = function disposeFn() { - return _this4.cancelAnimationFrame(id); - }; - - disposeFn.guid = 'vjs-raf-' + id; - this.on('dispose', disposeFn); - - return id; - } + _proto.requestAnimationFrame = function requestAnimationFrame(fn) { + var _this3 = this; // Fall back to using a timer. - return this.setTimeout(fn, 1000 / 60); - }; + if (!this.supportsRaf_) { + return this.setTimeout(fn, 1000 / 60); + } + this.clearTimersOnDispose_(); // declare as variables so they are properly available in rAF function + // eslint-disable-next-line + + var id; + fn = bind(this, fn); + id = window$1.requestAnimationFrame(function () { + if (_this3.rafIds_.has(id)) { + _this3.rafIds_["delete"](id); + } + + fn(); + }); + this.rafIds_.add(id); + return id; + } /** * Cancels a queued callback passed to {@link Component#requestAnimationFrame} * (rAF). @@ -4551,25 +4748,51 @@ * * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/window/cancelAnimationFrame} */ + ; - - Component.prototype.cancelAnimationFrame = function cancelAnimationFrame(id) { - if (this.supportsRaf_) { - window_1.cancelAnimationFrame(id); - - var disposeFn = function disposeFn() {}; - - disposeFn.guid = 'vjs-raf-' + id; - - this.off('dispose', disposeFn); - - return id; + _proto.cancelAnimationFrame = function cancelAnimationFrame(id) { + // Fall back to using a timer. + if (!this.supportsRaf_) { + return this.clearTimeout(id); } - // Fall back to using a timer. - return this.clearTimeout(id); - }; + if (this.rafIds_.has(id)) { + this.rafIds_["delete"](id); + window$1.cancelAnimationFrame(id); + } + return id; + } + /** + * A function to setup `requestAnimationFrame`, `setTimeout`, + * and `setInterval`, clearing on dispose. + * + * > Previously each timer added and removed dispose listeners on it's own. + * For better performance it was decided to batch them all, and use `Set`s + * to track outstanding timer ids. + * + * @private + */ + ; + + _proto.clearTimersOnDispose_ = function clearTimersOnDispose_() { + var _this4 = this; + + if (this.clearingTimersOnDispose_) { + return; + } + + this.clearingTimersOnDispose_ = true; + this.one('dispose', function () { + [['rafIds_', 'cancelAnimationFrame'], ['setTimeoutIds_', 'clearTimeout'], ['setIntervalIds_', 'clearInterval']].forEach(function (_ref) { + var idName = _ref[0], + cancelName = _ref[1]; + + _this4[idName].forEach(_this4[cancelName], _this4); + }); + _this4.clearingTimersOnDispose_ = false; + }); + } /** * Register a `Component` with `videojs` given the name and the component. * @@ -4589,21 +4812,20 @@ * @return {Component} * The `Component` that was registered. */ - + ; Component.registerComponent = function registerComponent(name, ComponentToRegister) { if (typeof name !== 'string' || !name) { - throw new Error('Illegal component name, "' + name + '"; must be a non-empty string.'); + throw new Error("Illegal component name, \"" + name + "\"; must be a non-empty string."); } - var Tech = Component.getComponent('Tech'); + var Tech = Component.getComponent('Tech'); // We need to make sure this check is only done if Tech has been registered. - // We need to make sure this check is only done if Tech has been registered. var isTech = Tech && Tech.isTech(ComponentToRegister); var isComp = Component === ComponentToRegister || Component.prototype.isPrototypeOf(ComponentToRegister.prototype); if (isTech || !isComp) { - var reason = void 0; + var reason; if (isTech) { reason = 'techs must be registered using Tech.registerTech()'; @@ -4611,7 +4833,7 @@ reason = 'must be a Component subclass'; } - throw new Error('Illegal component, "' + name + '"; ' + reason + '.'); + throw new Error("Illegal component, \"" + name + "\"; " + reason + "."); } name = toTitleCase(name); @@ -4624,12 +4846,11 @@ if (name === 'Player' && Player && Player.players) { var players = Player.players; - var playerNames = Object.keys(players); - - // If we have players that were disposed, then their name will still be + var playerNames = Object.keys(players); // If we have players that were disposed, then their name will still be // in Players.players. So, we must loop through and verify that the value // for each item is not null. This allows registration of the Player component // after all players have been disposed or before any were created. + if (players && playerNames.length > 0 && playerNames.map(function (pname) { return players[pname]; }).every(Boolean)) { @@ -4638,10 +4859,9 @@ } Component.components_[name] = ComponentToRegister; - + Component.components_[toLowerCase(name)] = ComponentToRegister; return ComponentToRegister; - }; - + } /** * Get a `Component` based on the name it was registered with. * @@ -4656,23 +4876,18 @@ * check the global `videojs` object for a `Component` name and * return that if it exists. */ - + ; Component.getComponent = function getComponent(name) { - if (!name) { + if (!name || !Component.components_) { return; } - name = toTitleCase(name); - - if (Component.components_ && Component.components_[name]) { - return Component.components_[name]; - } + return Component.components_[name]; }; return Component; }(); - /** * Whether or not this component supports `requestAnimationFrame`. * @@ -4683,34 +4898,50 @@ */ - Component.prototype.supportsRaf_ = typeof window_1.requestAnimationFrame === 'function' && typeof window_1.cancelAnimationFrame === 'function'; - + Component.prototype.supportsRaf_ = typeof window$1.requestAnimationFrame === 'function' && typeof window$1.cancelAnimationFrame === 'function'; Component.registerComponent('Component', Component); + function _assertThisInitialized(self) { + if (self === void 0) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return self; + } + + var assertThisInitialized = _assertThisInitialized; + + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; + } + + var inheritsLoose = _inheritsLoose; + /** * @file browser.js * @module browser */ - - var USER_AGENT = window_1.navigator && window_1.navigator.userAgent || ''; + var USER_AGENT = window$1.navigator && window$1.navigator.userAgent || ''; var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT); var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null; - - /* - * Device is an iPhone + /** + * Whether or not this device is an iPod. * + * @static + * @const * @type {Boolean} - * @constant - * @private */ - var IS_IPAD = /iPad/i.test(USER_AGENT); - // The Facebook app's UIWebView identifies as both an iPhone and iPad, so - // to identify iPhones, we need to exclude iPads. - // http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/ - var IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD; var IS_IPOD = /iPod/i.test(USER_AGENT); - var IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD; + /** + * The detected iOS version - or `null`. + * + * @static + * @const + * @type {string|null} + */ var IOS_VERSION = function () { var match = USER_AGENT.match(/OS (\d+)_/i); @@ -4718,10 +4949,26 @@ if (match && match[1]) { return match[1]; } + return null; }(); + /** + * Whether or not this is an Android device. + * + * @static + * @const + * @type {Boolean} + */ var IS_ANDROID = /Android/i.test(USER_AGENT); + /** + * The detected Android version - or `null`. + * + * @static + * @const + * @type {number|string|null} + */ + var ANDROID_VERSION = function () { // This matches Android Major.Minor.Patch versions // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned @@ -4739,22 +4986,73 @@ } else if (major) { return major; } + return null; }(); + /** + * Whether or not this is a native Android browser. + * + * @static + * @const + * @type {Boolean} + */ var IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537; + /** + * Whether or not this is Mozilla Firefox. + * + * @static + * @const + * @type {Boolean} + */ var IS_FIREFOX = /Firefox/i.test(USER_AGENT); + /** + * Whether or not this is Microsoft Edge. + * + * @static + * @const + * @type {Boolean} + */ + var IS_EDGE = /Edge/i.test(USER_AGENT); + /** + * Whether or not this is Google Chrome. + * + * This will also be `true` for Chrome on iOS, which will have different support + * as it is actually Safari under the hood. + * + * @static + * @const + * @type {Boolean} + */ + var IS_CHROME = !IS_EDGE && (/Chrome/i.test(USER_AGENT) || /CriOS/i.test(USER_AGENT)); + /** + * The detected Google Chrome version - or `null`. + * + * @static + * @const + * @type {number|null} + */ + var CHROME_VERSION = function () { var match = USER_AGENT.match(/(Chrome|CriOS)\/(\d+)/); if (match && match[2]) { return parseFloat(match[2]); } + return null; }(); + /** + * The detected Internet Explorer version - or `null`. + * + * @static + * @const + * @type {number|null} + */ + var IE_VERSION = function () { var result = /MSIE\s(\d+)\.\d/.exec(USER_AGENT); var version = result && parseFloat(result[1]); @@ -4766,17 +5064,75 @@ return version; }(); + /** + * Whether or not this is desktop Safari. + * + * @static + * @const + * @type {Boolean} + */ var IS_SAFARI = /Safari/i.test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE; + /** + * Whether or not this is a Windows machine. + * + * @static + * @const + * @type {Boolean} + */ + + var IS_WINDOWS = /Windows/i.test(USER_AGENT); + /** + * Whether or not this device is touch-enabled. + * + * @static + * @const + * @type {Boolean} + */ + + var TOUCH_ENABLED = isReal() && ('ontouchstart' in window$1 || window$1.navigator.maxTouchPoints || window$1.DocumentTouch && window$1.document instanceof window$1.DocumentTouch); + /** + * Whether or not this device is an iPad. + * + * @static + * @const + * @type {Boolean} + */ + + var IS_IPAD = /iPad/i.test(USER_AGENT) || IS_SAFARI && TOUCH_ENABLED && !/iPhone/i.test(USER_AGENT); + /** + * Whether or not this device is an iPhone. + * + * @static + * @const + * @type {Boolean} + */ + // The Facebook app's UIWebView identifies as both an iPhone and iPad, so + // to identify iPhones, we need to exclude iPads. + // http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/ + + var IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD; + /** + * Whether or not this is an iOS device. + * + * @static + * @const + * @type {Boolean} + */ + + var IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD; + /** + * Whether or not this is any flavor of Safari - including iOS. + * + * @static + * @const + * @type {Boolean} + */ + var IS_ANY_SAFARI = (IS_SAFARI || IS_IOS) && !IS_CHROME; - var TOUCH_ENABLED = isReal() && ('ontouchstart' in window_1 || window_1.navigator.maxTouchPoints || window_1.DocumentTouch && window_1.document instanceof window_1.DocumentTouch); - var browser = /*#__PURE__*/Object.freeze({ - IS_IPAD: IS_IPAD, - IS_IPHONE: IS_IPHONE, IS_IPOD: IS_IPOD, - IS_IOS: IS_IOS, IOS_VERSION: IOS_VERSION, IS_ANDROID: IS_ANDROID, ANDROID_VERSION: ANDROID_VERSION, @@ -4787,8 +5143,12 @@ CHROME_VERSION: CHROME_VERSION, IE_VERSION: IE_VERSION, IS_SAFARI: IS_SAFARI, - IS_ANY_SAFARI: IS_ANY_SAFARI, - TOUCH_ENABLED: TOUCH_ENABLED + IS_WINDOWS: IS_WINDOWS, + TOUCH_ENABLED: TOUCH_ENABLED, + IS_IPAD: IS_IPAD, + IS_IPHONE: IS_IPHONE, + IS_IOS: IS_IOS, + IS_ANY_SAFARI: IS_ANY_SAFARI }); /** @@ -4800,29 +5160,30 @@ * Returns the time for the specified index at the start or end * of a TimeRange object. * - * @function time-ranges:indexFunction + * @typedef {Function} TimeRangeIndex * - * @param {number} [index=0] - * The range number to return the time for. + * @param {number} [index=0] + * The range number to return the time for. * - * @return {number} - * The time that offset at the specified index. + * @return {number} + * The time offset at the specified index. * - * @depricated index must be set to a value, in the future this will throw an error. + * @deprecated The index argument must be provided. + * In the future, leaving it out will throw an error. */ /** - * An object that contains ranges of time for various reasons. + * An object that contains ranges of time. * - * @typedef {Object} TimeRange + * @typedef {Object} TimeRange * * @property {number} length - * The number of time ranges represented by this Object + * The number of time ranges represented by this object. * - * @property {time-ranges:indexFunction} start + * @property {module:time-ranges~TimeRangeIndex} start * Returns the time offset at which a specified time range begins. * - * @property {time-ranges:indexFunction} end + * @property {module:time-ranges~TimeRangeIndex} end * Returns the time offset at which a specified time range ends. * * @see https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges @@ -4831,57 +5192,62 @@ /** * Check if any of the time ranges are over the maximum index. * - * @param {string} fnName - * The function name to use for logging + * @private + * @param {string} fnName + * The function name to use for logging * - * @param {number} index - * The index to check + * @param {number} index + * The index to check * - * @param {number} maxIndex - * The maximum possible index + * @param {number} maxIndex + * The maximum possible index * - * @throws {Error} if the timeRanges provided are over the maxIndex + * @throws {Error} if the timeRanges provided are over the maxIndex */ function rangeCheck(fnName, index, maxIndex) { if (typeof index !== 'number' || index < 0 || index > maxIndex) { - throw new Error('Failed to execute \'' + fnName + '\' on \'TimeRanges\': The index provided (' + index + ') is non-numeric or out of bounds (0-' + maxIndex + ').'); + throw new Error("Failed to execute '" + fnName + "' on 'TimeRanges': The index provided (" + index + ") is non-numeric or out of bounds (0-" + maxIndex + ")."); } } - /** * Get the time for the specified index at the start or end * of a TimeRange object. * - * @param {string} fnName - * The function name to use for logging + * @private + * @param {string} fnName + * The function name to use for logging * - * @param {string} valueIndex - * The property that should be used to get the time. should be 'start' or 'end' + * @param {string} valueIndex + * The property that should be used to get the time. should be + * 'start' or 'end' * - * @param {Array} ranges - * An array of time ranges + * @param {Array} ranges + * An array of time ranges * - * @param {Array} [rangeIndex=0] - * The index to start the search at + * @param {Array} [rangeIndex=0] + * The index to start the search at * - * @return {number} - * The time that offset at the specified index. + * @return {number} + * The time that offset at the specified index. * - * - * @depricated rangeIndex must be set to a value, in the future this will throw an error. - * @throws {Error} if rangeIndex is more than the length of ranges + * @deprecated rangeIndex must be set to a value, in the future this will throw an error. + * @throws {Error} if rangeIndex is more than the length of ranges */ + + function getRange(fnName, valueIndex, ranges, rangeIndex) { rangeCheck(fnName, rangeIndex, ranges.length - 1); return ranges[rangeIndex][valueIndex]; } - /** * Create a time range object given ranges of time. * - * @param {Array} [ranges] - * An array of time ranges. + * @private + * @param {Array} [ranges] + * An array of time ranges. */ + + function createTimeRangesObj(ranges) { if (ranges === undefined || ranges.length === 0) { return { @@ -4894,30 +5260,34 @@ } }; } + return { length: ranges.length, start: getRange.bind(null, 'start', 0, ranges), end: getRange.bind(null, 'end', 1, ranges) }; } - /** - * Should create a fake `TimeRange` object which mimics an HTML5 time range instance. + * Create a `TimeRange` object which mimics an + * {@link https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges|HTML5 TimeRanges instance}. * - * @param {number|Array} start - * The start of a single range or an array of ranges + * @param {number|Array[]} start + * The start of a single range (a number) or an array of ranges (an + * array of arrays of two numbers each). * * @param {number} end - * The end of a single range. - * - * @private + * The end of a single range. Cannot be used with the array form of + * the `start` argument. */ + + function createTimeRanges(start, end) { if (Array.isArray(start)) { return createTimeRangesObj(start); } else if (start === undefined || end === undefined) { return createTimeRangesObj(); } + return createTimeRangesObj([[start, end]]); } @@ -4925,7 +5295,6 @@ * @file buffer.js * @module buffer */ - /** * Compute the percentage of the media that has been buffered. * @@ -4938,10 +5307,11 @@ * @return {number} * Percent buffered of the total duration in decimal form. */ + function bufferedPercent(buffered, duration) { var bufferedDuration = 0; - var start = void 0; - var end = void 0; + var start; + var end; if (!duration) { return 0; @@ -4953,9 +5323,8 @@ for (var i = 0; i < buffered.length; i++) { start = buffered.start(i); - end = buffered.end(i); + end = buffered.end(i); // buffered end can be bigger than duration by a very small fraction - // buffered end can be bigger than duration by a very small fraction if (end > duration) { end = duration; } @@ -4971,7 +5340,6 @@ * @module fullscreen-api * @private */ - /** * Store the browser-specific methods for the fullscreen API. * @@ -4979,42 +5347,38 @@ * @see [Specification]{@link https://fullscreen.spec.whatwg.org} * @see [Map Approach From Screenfull.js]{@link https://github.com/sindresorhus/screenfull.js} */ - var FullscreenApi = {}; - // browser API methods - var apiMap = [['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'], - // WebKit - ['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'], - // Old WebKit (Safari 5.1) - ['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'], - // Mozilla - ['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'], - // Microsoft - ['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']]; + var FullscreenApi = { + prefixed: true + }; // browser API methods + var apiMap = [['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror', 'fullscreen'], // WebKit + ['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror', '-webkit-full-screen'], // Mozilla + ['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror', '-moz-full-screen'], // Microsoft + ['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError', '-ms-fullscreen']]; var specApi = apiMap[0]; - var browserApi = void 0; + var browserApi; // determine the supported set of functions - // determine the supported set of functions for (var i = 0; i < apiMap.length; i++) { // check for exitFullscreen function - if (apiMap[i][1] in document_1) { + if (apiMap[i][1] in document) { browserApi = apiMap[i]; break; } - } + } // map the browser API names to the spec API names + - // map the browser API names to the spec API names if (browserApi) { for (var _i = 0; _i < browserApi.length; _i++) { FullscreenApi[specApi[_i]] = browserApi[_i]; } + + FullscreenApi.prefixed = browserApi[0] !== specApi[0]; } /** * @file media-error.js */ - /** * A Custom `MediaError` class which mimics the standard HTML5 `MediaError` class. * @@ -5032,8 +5396,8 @@ * * @class MediaError */ - function MediaError(value) { + function MediaError(value) { // Allow redundant calls to this constructor to avoid having `instanceof` // checks peppered around the code. if (value instanceof MediaError) { @@ -5046,7 +5410,6 @@ // default code is zero, so this is a custom error this.message = value; } else if (isObject(value)) { - // We assign the `code` property manually because native `MediaError` objects // do not expose it as an own/enumerable property of the object. if (typeof value.code === 'number') { @@ -5060,22 +5423,22 @@ this.message = MediaError.defaultMessages[this.code] || ''; } } - /** * The error code that refers two one of the defined `MediaError` types * * @type {Number} */ - MediaError.prototype.code = 0; + + MediaError.prototype.code = 0; /** * An optional message that to show with the error. Message is not part of the HTML5 * video spec but allows for more informative custom errors. * * @type {String} */ - MediaError.prototype.message = ''; + MediaError.prototype.message = ''; /** * An optional status code that can be set by plugins to allow even more detail about * the error. For example a plugin might provide a specific HTTP status code and an @@ -5085,8 +5448,8 @@ * * @type {Array} */ - MediaError.prototype.status = null; + MediaError.prototype.status = null; /** * Errors indexed by the W3C standard. The order **CANNOT CHANGE**! See the * specification listed under {@link MediaError} for more information. @@ -5094,49 +5457,49 @@ * @enum {array} * @readonly * @property {string} 0 - MEDIA_ERR_CUSTOM - * @property {string} 1 - MEDIA_ERR_CUSTOM - * @property {string} 2 - MEDIA_ERR_ABORTED - * @property {string} 3 - MEDIA_ERR_NETWORK + * @property {string} 1 - MEDIA_ERR_ABORTED + * @property {string} 2 - MEDIA_ERR_NETWORK + * @property {string} 3 - MEDIA_ERR_DECODE * @property {string} 4 - MEDIA_ERR_SRC_NOT_SUPPORTED * @property {string} 5 - MEDIA_ERR_ENCRYPTED */ - MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', 'MEDIA_ERR_ABORTED', 'MEDIA_ERR_NETWORK', 'MEDIA_ERR_DECODE', 'MEDIA_ERR_SRC_NOT_SUPPORTED', 'MEDIA_ERR_ENCRYPTED']; + MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', 'MEDIA_ERR_ABORTED', 'MEDIA_ERR_NETWORK', 'MEDIA_ERR_DECODE', 'MEDIA_ERR_SRC_NOT_SUPPORTED', 'MEDIA_ERR_ENCRYPTED']; /** * The default `MediaError` messages based on the {@link MediaError.errorTypes}. * * @type {Array} * @constant */ + MediaError.defaultMessages = { 1: 'You aborted the media playback', 2: 'A network error caused the media download to fail part-way.', 3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.', 4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.', 5: 'The media is encrypted and we do not have the keys to decrypt it.' - }; - - // Add types as properties on MediaError + }; // Add types as properties on MediaError // e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4; + for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) { - MediaError[MediaError.errorTypes[errNum]] = errNum; - // values should be accessible on both the class and instance + MediaError[MediaError.errorTypes[errNum]] = errNum; // values should be accessible on both the class and instance + MediaError.prototype[MediaError.errorTypes[errNum]] = errNum; - } + } // jsdocs for instance/static members added above var tuple = SafeParseTuple; function SafeParseTuple(obj, reviver) { - var json; - var error = null; + var json; + var error = null; - try { - json = JSON.parse(obj, reviver); - } catch (err) { - error = err; - } + try { + json = JSON.parse(obj, reviver); + } catch (err) { + error = err; + } - return [error, json]; + return [error, json]; } /** @@ -5145,13 +5508,12 @@ * @param {Object} value * An object that may or may not be `Promise`-like. * - * @return {Boolean} + * @return {boolean} * Whether or not the object is `Promise`-like. */ function isPromise(value) { return value !== undefined && value !== null && typeof value.then === 'function'; } - /** * Silence a Promise-like object. * @@ -5161,6 +5523,7 @@ * @param {Object} value * An object that may or may not be `Promise`-like. */ + function silencePromise(value) { if (isPromise(value)) { value.then(null, function (e) {}); @@ -5187,7 +5550,6 @@ */ var trackToJson_ = function trackToJson_(track) { var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) { - if (track[prop]) { acc[prop] = track[prop]; } @@ -5203,10 +5565,8 @@ }; }) }); - return ret; }; - /** * Examine a {@link Tech} and return a JSON-compatible javascript array that represents the * state of all {@link TextTrack}s currently configured. The return array is compatible with @@ -5219,10 +5579,10 @@ * A serializable javascript representation of the {@link Tech}s * {@link TextTrackList}. */ + + var textTracksToJson = function textTracksToJson(tech) { - var trackEls = tech.$$('track'); - var trackObjs = Array.prototype.map.call(trackEls, function (t) { return t.track; }); @@ -5232,14 +5592,13 @@ if (trackEl.src) { json.src = trackEl.src; } + return json; }); - return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) { return trackObjs.indexOf(track) === -1; }).map(trackToJson_)); }; - /** * Create a set of remote {@link TextTrack}s on a {@link Tech} based on an array of javascript * object {@link TextTrack} representations. @@ -5251,6 +5610,8 @@ * @param {Tech} tech * The `Tech` to create the `TextTrack`s on. */ + + var jsonToTextTracks = function jsonToTextTracks(json, tech) { json.forEach(function (track) { var addedTrack = tech.addRemoteTextTrack(track).track; @@ -5261,19 +5622,212 @@ }); } }); - return tech.textTracks(); }; - var textTrackConverter = { textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_ }; + var textTrackConverter = { + textTracksToJson: textTracksToJson, + jsonToTextTracks: jsonToTextTracks, + trackToJson_: trackToJson_ + }; - /** - * @file modal-dialog.js - */ + var keycode = createCommonjsModule(function (module, exports) { + // Source: http://jsfiddle.net/vWx8V/ + // http://stackoverflow.com/questions/5603195/full-list-of-javascript-keycodes + + /** + * Conenience method returns corresponding value for given keyName or keyCode. + * + * @param {Mixed} keyCode {Number} or keyName {String} + * @return {Mixed} + * @api public + */ + function keyCode(searchInput) { + // Keyboard Events + if (searchInput && 'object' === typeof searchInput) { + var hasKeyCode = searchInput.which || searchInput.keyCode || searchInput.charCode; + if (hasKeyCode) searchInput = hasKeyCode; + } // Numbers + + + if ('number' === typeof searchInput) return names[searchInput]; // Everything else (cast to string) + + var search = String(searchInput); // check codes + + var foundNamedKey = codes[search.toLowerCase()]; + if (foundNamedKey) return foundNamedKey; // check aliases + + var foundNamedKey = aliases[search.toLowerCase()]; + if (foundNamedKey) return foundNamedKey; // weird character? + + if (search.length === 1) return search.charCodeAt(0); + return undefined; + } + /** + * Compares a keyboard event with a given keyCode or keyName. + * + * @param {Event} event Keyboard event that should be tested + * @param {Mixed} keyCode {Number} or keyName {String} + * @return {Boolean} + * @api public + */ + + + keyCode.isEventKey = function isEventKey(event, nameOrCode) { + if (event && 'object' === typeof event) { + var keyCode = event.which || event.keyCode || event.charCode; + + if (keyCode === null || keyCode === undefined) { + return false; + } + + if (typeof nameOrCode === 'string') { + // check codes + var foundNamedKey = codes[nameOrCode.toLowerCase()]; + + if (foundNamedKey) { + return foundNamedKey === keyCode; + } // check aliases + + + var foundNamedKey = aliases[nameOrCode.toLowerCase()]; + + if (foundNamedKey) { + return foundNamedKey === keyCode; + } + } else if (typeof nameOrCode === 'number') { + return nameOrCode === keyCode; + } + + return false; + } + }; + + exports = module.exports = keyCode; + /** + * Get by name + * + * exports.code['enter'] // => 13 + */ + + var codes = exports.code = exports.codes = { + 'backspace': 8, + 'tab': 9, + 'enter': 13, + 'shift': 16, + 'ctrl': 17, + 'alt': 18, + 'pause/break': 19, + 'caps lock': 20, + 'esc': 27, + 'space': 32, + 'page up': 33, + 'page down': 34, + 'end': 35, + 'home': 36, + 'left': 37, + 'up': 38, + 'right': 39, + 'down': 40, + 'insert': 45, + 'delete': 46, + 'command': 91, + 'left command': 91, + 'right command': 93, + 'numpad *': 106, + 'numpad +': 107, + 'numpad -': 109, + 'numpad .': 110, + 'numpad /': 111, + 'num lock': 144, + 'scroll lock': 145, + 'my computer': 182, + 'my calculator': 183, + ';': 186, + '=': 187, + ',': 188, + '-': 189, + '.': 190, + '/': 191, + '`': 192, + '[': 219, + '\\': 220, + ']': 221, + "'": 222 // Helper aliases + + }; + var aliases = exports.aliases = { + 'windows': 91, + '⇧': 16, + '⌥': 18, + '⌃': 17, + '⌘': 91, + 'ctl': 17, + 'control': 17, + 'option': 18, + 'pause': 19, + 'break': 19, + 'caps': 20, + 'return': 13, + 'escape': 27, + 'spc': 32, + 'spacebar': 32, + 'pgup': 33, + 'pgdn': 34, + 'ins': 45, + 'del': 46, + 'cmd': 91 + /*! + * Programatically add the following + */ + // lower case chars + + }; + + for (i = 97; i < 123; i++) { + codes[String.fromCharCode(i)] = i - 32; + } // numbers + + + for (var i = 48; i < 58; i++) { + codes[i - 48] = i; + } // function keys + + + for (i = 1; i < 13; i++) { + codes['f' + i] = i + 111; + } // numpad keys + + + for (i = 0; i < 10; i++) { + codes['numpad ' + i] = i + 96; + } + /** + * Get by code + * + * exports.name[13] // => 'Enter' + */ + + + var names = exports.names = exports.title = {}; // title for backward compat + // Create reverse mapping + + for (i in codes) { + names[codes[i]] = i; + } // Add aliases + + + for (var alias in aliases) { + codes[alias] = aliases[alias]; + } + }); + var keycode_1 = keycode.code; + var keycode_2 = keycode.codes; + var keycode_3 = keycode.aliases; + var keycode_4 = keycode.names; + var keycode_5 = keycode.title; var MODAL_CLASS_NAME = 'vjs-modal-dialog'; - var ESC = 27; - /** * The `ModalDialog` displays over the video and its controls, which blocks * interaction with the player until it is closed. @@ -5284,8 +5838,10 @@ * @extends Component */ - var ModalDialog = function (_Component) { - inherits(ModalDialog, _Component); + var ModalDialog = + /*#__PURE__*/ + function (_Component) { + inheritsLoose(ModalDialog, _Component); /** * Create an instance of this class. @@ -5310,6 +5866,10 @@ * @param {string} [options.label] * A text label for the modal, primarily for accessibility. * + * @param {boolean} [options.pauseOnOpen=true] + * If `true`, playback will will be paused if playing when + * the modal opens, and resumed when it closes. + * * @param {boolean} [options.temporary=true] * If `true`, the modal can only be opened once; it will be * disposed as soon as it's closed. @@ -5320,35 +5880,35 @@ * still possible. */ function ModalDialog(player, options) { - classCallCheck(this, ModalDialog); - - var _this = possibleConstructorReturn(this, _Component.call(this, player, options)); + var _this; + _this = _Component.call(this, player, options) || this; _this.opened_ = _this.hasBeenOpened_ = _this.hasBeenFilled_ = false; _this.closeable(!_this.options_.uncloseable); - _this.content(_this.options_.content); - // Make sure the contentEl is defined AFTER any children are initialized + _this.content(_this.options_.content); // Make sure the contentEl is defined AFTER any children are initialized // because we only want the contents of the modal in the contentEl // (not the UI elements like the close button). + + _this.contentEl_ = createEl('div', { - className: MODAL_CLASS_NAME + '-content' + className: MODAL_CLASS_NAME + "-content" }, { role: 'document' }); - _this.descEl_ = createEl('p', { - className: MODAL_CLASS_NAME + '-description vjs-control-text', + className: MODAL_CLASS_NAME + "-description vjs-control-text", id: _this.el().getAttribute('aria-describedby') }); - textContent(_this.descEl_, _this.description()); + _this.el_.appendChild(_this.descEl_); + _this.el_.appendChild(_this.contentEl_); + return _this; } - /** * Create the `ModalDialog`'s DOM element * @@ -5357,67 +5917,49 @@ */ - ModalDialog.prototype.createEl = function createEl$$1() { + var _proto = ModalDialog.prototype; + + _proto.createEl = function createEl() { return _Component.prototype.createEl.call(this, 'div', { className: this.buildCSSClass(), tabIndex: -1 }, { - 'aria-describedby': this.id() + '_description', + 'aria-describedby': this.id() + "_description", 'aria-hidden': 'true', 'aria-label': this.label(), 'role': 'dialog' }); }; - ModalDialog.prototype.dispose = function dispose() { + _proto.dispose = function dispose() { this.contentEl_ = null; this.descEl_ = null; this.previouslyActiveEl_ = null; _Component.prototype.dispose.call(this); - }; - + } /** * Builds the default DOM `className`. * * @return {string} * The DOM `className` for this object. */ + ; - - ModalDialog.prototype.buildCSSClass = function buildCSSClass() { - return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this); - }; - - /** - * Handles `keydown` events on the document, looking for ESC, which closes - * the modal. - * - * @param {EventTarget~Event} e - * The keypress that triggered this event. - * - * @listens keydown - */ - - - ModalDialog.prototype.handleKeyPress = function handleKeyPress(e) { - if (e.which === ESC && this.closeable()) { - this.close(); - } - }; - + _proto.buildCSSClass = function buildCSSClass() { + return MODAL_CLASS_NAME + " vjs-hidden " + _Component.prototype.buildCSSClass.call(this); + } /** * Returns the label string for this modal. Primarily used for accessibility. * * @return {string} * the localized or raw label of this modal. */ + ; - - ModalDialog.prototype.label = function label() { + _proto.label = function label() { return this.localize(this.options_.label || 'Modal Window'); - }; - + } /** * Returns the description string for this modal. Primarily used for * accessibility. @@ -5425,77 +5967,69 @@ * @return {string} * The localized or raw description of this modal. */ + ; + _proto.description = function description() { + var desc = this.options_.description || this.localize('This is a modal window.'); // Append a universal closeability message if the modal is closeable. - ModalDialog.prototype.description = function description() { - var desc = this.options_.description || this.localize('This is a modal window.'); - - // Append a universal closeability message if the modal is closeable. if (this.closeable()) { desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.'); } return desc; - }; - + } /** * Opens the modal. * * @fires ModalDialog#beforemodalopen * @fires ModalDialog#modalopen */ + ; - - ModalDialog.prototype.open = function open() { + _proto.open = function open() { if (!this.opened_) { var player = this.player(); - /** * Fired just before a `ModalDialog` is opened. * * @event ModalDialog#beforemodalopen * @type {EventTarget~Event} */ - this.trigger('beforemodalopen'); - this.opened_ = true; - // Fill content if the modal has never opened before and + this.trigger('beforemodalopen'); + this.opened_ = true; // Fill content if the modal has never opened before and // never been filled. + if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) { this.fill(); - } - - // If the player was playing, pause it and take note of its previously + } // If the player was playing, pause it and take note of its previously // playing state. + + this.wasPlaying_ = !player.paused(); if (this.options_.pauseOnOpen && this.wasPlaying_) { player.pause(); } - if (this.closeable()) { - this.on(this.el_.ownerDocument, 'keydown', bind(this, this.handleKeyPress)); - } + this.on('keydown', this.handleKeyDown); // Hide controls and note if they were enabled. - // Hide controls and note if they were enabled. this.hadControls_ = player.controls(); player.controls(false); - this.show(); this.conditionalFocus_(); this.el().setAttribute('aria-hidden', 'false'); - /** * Fired just after a `ModalDialog` is opened. * * @event ModalDialog#modalopen * @type {EventTarget~Event} */ + this.trigger('modalopen'); this.hasBeenOpened_ = true; } - }; - + } /** * If the `ModalDialog` is currently open or closed. * @@ -5505,15 +6039,15 @@ * @return {boolean} * the current open state of the modaldialog */ + ; - - ModalDialog.prototype.opened = function opened(value) { + _proto.opened = function opened(value) { if (typeof value === 'boolean') { this[value ? 'open' : 'close'](); } - return this.opened_; - }; + return this.opened_; + } /** * Closes the modal, does nothing if the `ModalDialog` is * not open. @@ -5521,20 +6055,21 @@ * @fires ModalDialog#beforemodalclose * @fires ModalDialog#modalclose */ + ; - - ModalDialog.prototype.close = function close() { + _proto.close = function close() { if (!this.opened_) { return; } - var player = this.player(); + var player = this.player(); /** * Fired just before a `ModalDialog` is closed. * * @event ModalDialog#beforemodalclose * @type {EventTarget~Event} */ + this.trigger('beforemodalclose'); this.opened_ = false; @@ -5542,9 +6077,7 @@ player.play(); } - if (this.closeable()) { - this.off(this.el_.ownerDocument, 'keydown', bind(this, this.handleKeyPress)); - } + this.off('keydown', this.handleKeyDown); if (this.hadControls_) { player.controls(true); @@ -5552,21 +6085,20 @@ this.hide(); this.el().setAttribute('aria-hidden', 'true'); - /** * Fired just after a `ModalDialog` is closed. * * @event ModalDialog#modalclose * @type {EventTarget~Event} */ + this.trigger('modalclose'); this.conditionalBlur_(); if (this.options_.temporary) { this.dispose(); } - }; - + } /** * Check to see if the `ModalDialog` is closeable via the UI. * @@ -5576,46 +6108,44 @@ * @return {boolean} * Returns the final value of the closable option. */ + ; - - ModalDialog.prototype.closeable = function closeable(value) { + _proto.closeable = function closeable(value) { if (typeof value === 'boolean') { var closeable = this.closeable_ = !!value; - var close = this.getChild('closeButton'); + var close = this.getChild('closeButton'); // If this is being made closeable and has no close button, add one. - // If this is being made closeable and has no close button, add one. if (closeable && !close) { - // The close button should be a child of the modal - not its // content element, so temporarily change the content element. var temp = this.contentEl_; - this.contentEl_ = this.el_; - close = this.addChild('closeButton', { controlText: 'Close Modal Dialog' }); + close = this.addChild('closeButton', { + controlText: 'Close Modal Dialog' + }); this.contentEl_ = temp; this.on(close, 'close', this.close); - } + } // If this is being made uncloseable and has a close button, remove it. + - // If this is being made uncloseable and has a close button, remove it. if (!closeable && close) { this.off(close, 'close', this.close); this.removeChild(close); close.dispose(); } } - return this.closeable_; - }; + return this.closeable_; + } /** * Fill the modal's content element with the modal's "content" option. * The content element will be emptied before this change takes place. */ + ; - - ModalDialog.prototype.fill = function fill() { + _proto.fill = function fill() { this.fillWith(this.content()); - }; - + } /** * Fill the modal's content element with arbitrary content. * The content element will be emptied before this change takes place. @@ -5626,24 +6156,23 @@ * @param {Mixed} [content] * The same rules apply to this as apply to the `content` option. */ + ; - - ModalDialog.prototype.fillWith = function fillWith(content) { + _proto.fillWith = function fillWith(content) { var contentEl = this.contentEl(); var parentEl = contentEl.parentNode; var nextSiblingEl = contentEl.nextSibling; - /** - * Fired just before a `ModalDialog` is filled with content. - * - * @event ModalDialog#beforemodalfill - * @type {EventTarget~Event} - */ - this.trigger('beforemodalfill'); - this.hasBeenFilled_ = true; + * Fired just before a `ModalDialog` is filled with content. + * + * @event ModalDialog#beforemodalfill + * @type {EventTarget~Event} + */ - // Detach the content element from the DOM before performing + this.trigger('beforemodalfill'); + this.hasBeenFilled_ = true; // Detach the content element from the DOM before performing // manipulation to avoid modifying the live DOM multiple times. + parentEl.removeChild(contentEl); this.empty(); insertContent(contentEl, content); @@ -5653,50 +6182,48 @@ * @event ModalDialog#modalfill * @type {EventTarget~Event} */ - this.trigger('modalfill'); - // Re-inject the re-filled content element. + this.trigger('modalfill'); // Re-inject the re-filled content element. + if (nextSiblingEl) { parentEl.insertBefore(contentEl, nextSiblingEl); } else { parentEl.appendChild(contentEl); - } + } // make sure that the close button is last in the dialog DOM + - // make sure that the close button is last in the dialog DOM var closeButton = this.getChild('closeButton'); if (closeButton) { parentEl.appendChild(closeButton.el_); } - }; - + } /** * Empties the content element. This happens anytime the modal is filled. * * @fires ModalDialog#beforemodalempty * @fires ModalDialog#modalempty */ + ; - - ModalDialog.prototype.empty = function empty() { + _proto.empty = function empty() { /** - * Fired just before a `ModalDialog` is emptied. - * - * @event ModalDialog#beforemodalempty - * @type {EventTarget~Event} - */ + * Fired just before a `ModalDialog` is emptied. + * + * @event ModalDialog#beforemodalempty + * @type {EventTarget~Event} + */ this.trigger('beforemodalempty'); emptyEl(this.contentEl()); - /** - * Fired just after a `ModalDialog` is emptied. - * - * @event ModalDialog#modalempty - * @type {EventTarget~Event} - */ - this.trigger('modalempty'); - }; + * Fired just after a `ModalDialog` is emptied. + * + * @event ModalDialog#modalempty + * @type {EventTarget~Event} + */ + this.trigger('modalempty'); + } /** * Gets or sets the modal content, which gets normalized before being * rendered into the DOM. @@ -5712,69 +6239,70 @@ * @return {Mixed} * The current content of the modal dialog */ + ; - - ModalDialog.prototype.content = function content(value) { + _proto.content = function content(value) { if (typeof value !== 'undefined') { this.content_ = value; } - return this.content_; - }; + return this.content_; + } /** * conditionally focus the modal dialog if focus was previously on the player. * * @private */ + ; - - ModalDialog.prototype.conditionalFocus_ = function conditionalFocus_() { - var activeEl = document_1.activeElement; + _proto.conditionalFocus_ = function conditionalFocus_() { + var activeEl = document.activeElement; var playerEl = this.player_.el_; - this.previouslyActiveEl_ = null; if (playerEl.contains(activeEl) || playerEl === activeEl) { this.previouslyActiveEl_ = activeEl; - this.focus(); - - this.on(document_1, 'keydown', this.handleKeyDown); } - }; - + } /** * conditionally blur the element and refocus the last focused element * * @private */ + ; - - ModalDialog.prototype.conditionalBlur_ = function conditionalBlur_() { + _proto.conditionalBlur_ = function conditionalBlur_() { if (this.previouslyActiveEl_) { this.previouslyActiveEl_.focus(); this.previouslyActiveEl_ = null; } - - this.off(document_1, 'keydown', this.handleKeyDown); - }; - + } /** * Keydown handler. Attached when modal is focused. * * @listens keydown */ + ; + + _proto.handleKeyDown = function handleKeyDown(event) { + // Do not allow keydowns to reach out of the modal dialog. + event.stopPropagation(); + + if (keycode.isEventKey(event, 'Escape') && this.closeable()) { + event.preventDefault(); + this.close(); + return; + } // exit early if it isn't a tab key - ModalDialog.prototype.handleKeyDown = function handleKeyDown(event) { - // exit early if it isn't a tab key - if (event.which !== 9) { + if (!keycode.isEventKey(event, 'Tab')) { return; } var focusableEls = this.focusableEls_(); var activeEl = this.el_.querySelector(':focus'); - var focusIndex = void 0; + var focusIndex; for (var i = 0; i < focusableEls.length; i++) { if (activeEl === focusableEls[i]) { @@ -5783,7 +6311,7 @@ } } - if (document_1.activeElement === this.el_) { + if (document.activeElement === this.el_) { focusIndex = 0; } @@ -5794,26 +6322,23 @@ focusableEls[0].focus(); event.preventDefault(); } - }; - + } /** * get all focusable elements * * @private */ + ; - - ModalDialog.prototype.focusableEls_ = function focusableEls_() { + _proto.focusableEls_ = function focusableEls_() { var allChildren = this.el_.querySelectorAll('*'); - return Array.prototype.filter.call(allChildren, function (child) { - return (child instanceof window_1.HTMLAnchorElement || child instanceof window_1.HTMLAreaElement) && child.hasAttribute('href') || (child instanceof window_1.HTMLInputElement || child instanceof window_1.HTMLSelectElement || child instanceof window_1.HTMLTextAreaElement || child instanceof window_1.HTMLButtonElement) && !child.hasAttribute('disabled') || child instanceof window_1.HTMLIFrameElement || child instanceof window_1.HTMLObjectElement || child instanceof window_1.HTMLEmbedElement || child.hasAttribute('tabindex') && child.getAttribute('tabindex') !== -1 || child.hasAttribute('contenteditable'); + return (child instanceof window$1.HTMLAnchorElement || child instanceof window$1.HTMLAreaElement) && child.hasAttribute('href') || (child instanceof window$1.HTMLInputElement || child instanceof window$1.HTMLSelectElement || child instanceof window$1.HTMLTextAreaElement || child instanceof window$1.HTMLButtonElement) && !child.hasAttribute('disabled') || child instanceof window$1.HTMLIFrameElement || child instanceof window$1.HTMLObjectElement || child instanceof window$1.HTMLEmbedElement || child.hasAttribute('tabindex') && child.getAttribute('tabindex') !== -1 || child.hasAttribute('contenteditable'); }); }; return ModalDialog; }(Component); - /** * Default options for `ModalDialog` default options. * @@ -5826,13 +6351,8 @@ pauseOnOpen: true, temporary: true }; - Component.registerComponent('ModalDialog', ModalDialog); - /** - * @file track-list.js - */ - /** * Common functionaliy between {@link TextTrackList}, {@link AudioTrackList}, and * {@link VideoTrackList} @@ -5840,8 +6360,10 @@ * @extends EventTarget */ - var TrackList = function (_EventTarget) { - inherits(TrackList, _EventTarget); + var TrackList = + /*#__PURE__*/ + function (_EventTarget) { + inheritsLoose(TrackList, _EventTarget); /** * Create an instance of this class @@ -5851,22 +6373,24 @@ * * @abstract */ - function TrackList() { - var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; - classCallCheck(this, TrackList); + function TrackList(tracks) { + var _this; - var _this = possibleConstructorReturn(this, _EventTarget.call(this)); + if (tracks === void 0) { + tracks = []; + } + _this = _EventTarget.call(this) || this; _this.tracks_ = []; - /** * @memberof TrackList * @member {number} length * The current number of `Track`s in the this Trackist. * @instance */ - Object.defineProperty(_this, 'length', { - get: function get$$1() { + + Object.defineProperty(assertThisInitialized(_this), 'length', { + get: function get() { return this.tracks_.length; } }); @@ -5874,9 +6398,9 @@ for (var i = 0; i < tracks.length; i++) { _this.addTrack(tracks[i]); } + return _this; } - /** * Add a {@link Track} to the `TrackList` * @@ -5887,18 +6411,20 @@ */ - TrackList.prototype.addTrack = function addTrack(track) { + var _proto = TrackList.prototype; + + _proto.addTrack = function addTrack(track) { var index = this.tracks_.length; if (!('' + index in this)) { Object.defineProperty(this, index, { - get: function get$$1() { + get: function get() { return this.tracks_[index]; } }); - } + } // Do not add duplicate tracks + - // Do not add duplicate tracks if (this.tracks_.indexOf(track) === -1) { this.tracks_.push(track); /** @@ -5909,13 +6435,14 @@ * @property {Track} track * A reference to track that was added. */ + this.trigger({ track: track, - type: 'addtrack' + type: 'addtrack', + target: this }); } - }; - + } /** * Remove a {@link Track} from the `TrackList` * @@ -5924,20 +6451,20 @@ * * @fires TrackList#removetrack */ + ; - - TrackList.prototype.removeTrack = function removeTrack(rtrack) { - var track = void 0; + _proto.removeTrack = function removeTrack(rtrack) { + var track; for (var i = 0, l = this.length; i < l; i++) { if (this[i] === rtrack) { track = this[i]; + if (track.off) { track.off(); } this.tracks_.splice(i, 1); - break; } } @@ -5945,7 +6472,6 @@ if (!track) { return; } - /** * Triggered when a track is removed from track list. * @@ -5954,23 +6480,25 @@ * @property {Track} track * A reference to track that was removed. */ + + this.trigger({ track: track, - type: 'removetrack' + type: 'removetrack', + target: this }); - }; - + } /** * Get a Track from the TrackList by a tracks id * - * @param {String} id - the id of the track to get + * @param {string} id - the id of the track to get * @method getTrackById * @return {Track} * @private */ + ; - - TrackList.prototype.getTrackById = function getTrackById(id) { + _proto.getTrackById = function getTrackById(id) { var result = null; for (var i = 0, l = this.length; i < l; i++) { @@ -5987,7 +6515,6 @@ return TrackList; }(EventTarget); - /** * Triggered when a different track is selected/enabled. * @@ -6007,17 +6534,12 @@ change: 'change', addtrack: 'addtrack', removetrack: 'removetrack' - }; + }; // emulate attribute EventHandler support to allow for feature detection - // emulate attribute EventHandler support to allow for feature detection for (var event in TrackList.prototype.allowedEvents_) { TrackList.prototype['on' + event] = null; } - /** - * @file audio-track-list.js - */ - /** * Anywhere we call this function we diverge from the spec * as we only support one enabled audiotrack at a time @@ -6030,16 +6552,17 @@ * * @private */ + var disableOthers = function disableOthers(list, track) { for (var i = 0; i < list.length; i++) { if (!Object.keys(list[i]).length || track.id === list[i].id) { continue; - } - // another audio track is enabled, disable it + } // another audio track is enabled, disable it + + list[i].enabled = false; } }; - /** * The current list of {@link AudioTrack} for a media file. * @@ -6047,8 +6570,11 @@ * @extends TrackList */ - var AudioTrackList = function (_TrackList) { - inherits(AudioTrackList, _TrackList); + + var AudioTrackList = + /*#__PURE__*/ + function (_TrackList) { + inheritsLoose(AudioTrackList, _TrackList); /** * Create an instance of this class. @@ -6056,9 +6582,12 @@ * @param {AudioTrack[]} [tracks=[]] * A list of `AudioTrack` to instantiate the list with. */ - function AudioTrackList() { - var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; - classCallCheck(this, AudioTrackList); + function AudioTrackList(tracks) { + var _this; + + if (tracks === void 0) { + tracks = []; + } // make sure only 1 track is enabled // sorted from last index to first index @@ -6069,12 +6598,10 @@ } } - var _this = possibleConstructorReturn(this, _TrackList.call(this, tracks)); - + _this = _TrackList.call(this, tracks) || this; _this.changing_ = false; return _this; } - /** * Add an {@link AudioTrack} to the `AudioTrackList`. * @@ -6085,44 +6612,57 @@ */ - AudioTrackList.prototype.addTrack = function addTrack(track) { + var _proto = AudioTrackList.prototype; + + _proto.addTrack = function addTrack(track) { var _this2 = this; if (track.enabled) { disableOthers(this, track); } - _TrackList.prototype.addTrack.call(this, track); - // native tracks don't have this + _TrackList.prototype.addTrack.call(this, track); // native tracks don't have this + + if (!track.addEventListener) { return; } - /** - * @listens AudioTrack#enabledchange - * @fires TrackList#change - */ - track.addEventListener('enabledchange', function () { + track.enabledChange_ = function () { // when we are disabling other tracks (since we don't support // more than one track at a time) we will set changing_ // to true so that we don't trigger additional change events if (_this2.changing_) { return; } + _this2.changing_ = true; disableOthers(_this2, track); _this2.changing_ = false; + _this2.trigger('change'); - }); + }; + /** + * @listens AudioTrack#enabledchange + * @fires TrackList#change + */ + + + track.addEventListener('enabledchange', track.enabledChange_); + }; + + _proto.removeTrack = function removeTrack(rtrack) { + _TrackList.prototype.removeTrack.call(this, rtrack); + + if (rtrack.removeEventListener && rtrack.enabledChange_) { + rtrack.removeEventListener('enabledchange', rtrack.enabledChange_); + rtrack.enabledChange_ = null; + } }; return AudioTrackList; }(TrackList); - /** - * @file video-track-list.js - */ - /** * Un-select all other {@link VideoTrack}s that are selected. * @@ -6134,16 +6674,17 @@ * * @private */ + var disableOthers$1 = function disableOthers(list, track) { for (var i = 0; i < list.length; i++) { if (!Object.keys(list[i]).length || track.id === list[i].id) { continue; - } - // another video track is enabled, disable it + } // another video track is enabled, disable it + + list[i].selected = false; } }; - /** * The current list of {@link VideoTrack} for a video. * @@ -6151,8 +6692,11 @@ * @extends TrackList */ - var VideoTrackList = function (_TrackList) { - inherits(VideoTrackList, _TrackList); + + var VideoTrackList = + /*#__PURE__*/ + function (_TrackList) { + inheritsLoose(VideoTrackList, _TrackList); /** * Create an instance of this class. @@ -6160,9 +6704,12 @@ * @param {VideoTrack[]} [tracks=[]] * A list of `VideoTrack` to instantiate the list with. */ - function VideoTrackList() { - var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; - classCallCheck(this, VideoTrackList); + function VideoTrackList(tracks) { + var _this; + + if (tracks === void 0) { + tracks = []; + } // make sure only 1 track is enabled // sorted from last index to first index @@ -6173,28 +6720,27 @@ } } - var _this = possibleConstructorReturn(this, _TrackList.call(this, tracks)); - + _this = _TrackList.call(this, tracks) || this; _this.changing_ = false; - /** * @member {number} VideoTrackList#selectedIndex * The current index of the selected {@link VideoTrack`}. */ - Object.defineProperty(_this, 'selectedIndex', { - get: function get$$1() { + + Object.defineProperty(assertThisInitialized(_this), 'selectedIndex', { + get: function get() { for (var _i = 0; _i < this.length; _i++) { if (this[_i].selected) { return _i; } } + return -1; }, - set: function set$$1() {} + set: function set() {} }); return _this; } - /** * Add a {@link VideoTrack} to the `VideoTrackList`. * @@ -6205,41 +6751,54 @@ */ - VideoTrackList.prototype.addTrack = function addTrack(track) { + var _proto = VideoTrackList.prototype; + + _proto.addTrack = function addTrack(track) { var _this2 = this; if (track.selected) { disableOthers$1(this, track); } - _TrackList.prototype.addTrack.call(this, track); - // native tracks don't have this + _TrackList.prototype.addTrack.call(this, track); // native tracks don't have this + + if (!track.addEventListener) { return; } + track.selectedChange_ = function () { + if (_this2.changing_) { + return; + } + + _this2.changing_ = true; + disableOthers$1(_this2, track); + _this2.changing_ = false; + + _this2.trigger('change'); + }; /** * @listens VideoTrack#selectedchange * @fires TrackList#change */ - track.addEventListener('selectedchange', function () { - if (_this2.changing_) { - return; - } - _this2.changing_ = true; - disableOthers$1(_this2, track); - _this2.changing_ = false; - _this2.trigger('change'); - }); + + + track.addEventListener('selectedchange', track.selectedChange_); + }; + + _proto.removeTrack = function removeTrack(rtrack) { + _TrackList.prototype.removeTrack.call(this, rtrack); + + if (rtrack.removeEventListener && rtrack.selectedChange_) { + rtrack.removeEventListener('selectedchange', rtrack.selectedChange_); + rtrack.selectedChange_ = null; + } }; return VideoTrackList; }(TrackList); - /** - * @file text-track-list.js - */ - /** * The current list of {@link TextTrack} for a media file. * @@ -6247,14 +6806,17 @@ * @extends TrackList */ - var TextTrackList = function (_TrackList) { - inherits(TextTrackList, _TrackList); + var TextTrackList = + /*#__PURE__*/ + function (_TrackList) { + inheritsLoose(TextTrackList, _TrackList); function TextTrackList() { - classCallCheck(this, TextTrackList); - return possibleConstructorReturn(this, _TrackList.apply(this, arguments)); + return _TrackList.apply(this, arguments) || this; } + var _proto = TextTrackList.prototype; + /** * Add a {@link TextTrack} to the `TextTrackList` * @@ -6263,23 +6825,48 @@ * * @fires TrackList#addtrack */ - TextTrackList.prototype.addTrack = function addTrack(track) { + _proto.addTrack = function addTrack(track) { + var _this = this; + _TrackList.prototype.addTrack.call(this, track); + if (!this.queueChange_) { + this.queueChange_ = function () { + return _this.queueTrigger('change'); + }; + } + + if (!this.triggerSelectedlanguagechange) { + this.triggerSelectedlanguagechange_ = function () { + return _this.trigger('selectedlanguagechange'); + }; + } /** * @listens TextTrack#modechange * @fires TrackList#change */ - track.addEventListener('modechange', bind(this, function () { - this.queueTrigger('change'); - })); + + track.addEventListener('modechange', this.queueChange_); var nonLanguageTextTrackKind = ['metadata', 'chapters']; if (nonLanguageTextTrackKind.indexOf(track.kind) === -1) { - track.addEventListener('modechange', bind(this, function () { - this.trigger('selectedlanguagechange'); - })); + track.addEventListener('modechange', this.triggerSelectedlanguagechange_); + } + }; + + _proto.removeTrack = function removeTrack(rtrack) { + _TrackList.prototype.removeTrack.call(this, rtrack); // manually remove the event handlers we added + + + if (rtrack.removeEventListener) { + if (this.queueChange_) { + rtrack.removeEventListener('modechange', this.queueChange_); + } + + if (this.selectedlanguagechange_) { + rtrack.removeEventListener('modechange', this.triggerSelectedlanguagechange_); + } } }; @@ -6293,28 +6880,30 @@ /** * The current list of {@link HtmlTrackElement}s. */ - var HtmlTrackElementList = function () { - + var HtmlTrackElementList = + /*#__PURE__*/ + function () { /** * Create an instance of this class. * * @param {HtmlTrackElement[]} [tracks=[]] * A list of `HtmlTrackElement` to instantiate the list with. */ - function HtmlTrackElementList() { - var trackElements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; - classCallCheck(this, HtmlTrackElementList); + function HtmlTrackElementList(trackElements) { + if (trackElements === void 0) { + trackElements = []; + } this.trackElements_ = []; - /** * @memberof HtmlTrackElementList * @member {number} length * The current number of `Track`s in the this Trackist. * @instance */ + Object.defineProperty(this, 'length', { - get: function get$$1() { + get: function get() { return this.trackElements_.length; } }); @@ -6323,7 +6912,6 @@ this.addTrackElement_(trackElements[i]); } } - /** * Add an {@link HtmlTrackElement} to the `HtmlTrackElementList` * @@ -6334,23 +6922,24 @@ */ - HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) { + var _proto = HtmlTrackElementList.prototype; + + _proto.addTrackElement_ = function addTrackElement_(trackElement) { var index = this.trackElements_.length; if (!('' + index in this)) { Object.defineProperty(this, index, { - get: function get$$1() { + get: function get() { return this.trackElements_[index]; } }); - } + } // Do not add duplicate elements + - // Do not add duplicate elements if (this.trackElements_.indexOf(trackElement) === -1) { this.trackElements_.push(trackElement); } - }; - + } /** * Get an {@link HtmlTrackElement} from the `HtmlTrackElementList` given an * {@link TextTrack}. @@ -6363,22 +6952,20 @@ * * @private */ + ; - - HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) { - var trackElement_ = void 0; + _proto.getTrackElementByTrack_ = function getTrackElementByTrack_(track) { + var trackElement_; for (var i = 0, length = this.trackElements_.length; i < length; i++) { if (track === this.trackElements_[i].track) { trackElement_ = this.trackElements_[i]; - break; } } return trackElement_; - }; - + } /** * Remove a {@link HtmlTrackElement} from the `HtmlTrackElementList` * @@ -6387,13 +6974,20 @@ * * @private */ + ; - - HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) { + _proto.removeTrackElement_ = function removeTrackElement_(trackElement) { for (var i = 0, length = this.trackElements_.length; i < length; i++) { if (trackElement === this.trackElements_[i]) { - this.trackElements_.splice(i, 1); + if (this.trackElements_[i].track && typeof this.trackElements_[i].track.off === 'function') { + this.trackElements_[i].track.off(); + } + if (typeof this.trackElements_[i].off === 'function') { + this.trackElements_[i].off(); + } + + this.trackElements_.splice(i, 1); break; } } @@ -6429,8 +7023,9 @@ * * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist} */ - var TextTrackCueList = function () { - + var TextTrackCueList = + /*#__PURE__*/ + function () { /** * Create an instance of this class.. * @@ -6438,23 +7033,20 @@ * A list of cues to be initialized with */ function TextTrackCueList(cues) { - classCallCheck(this, TextTrackCueList); - TextTrackCueList.prototype.setCues_.call(this, cues); - /** * @memberof TextTrackCueList * @member {number} length * The current number of `TextTrackCue`s in the TextTrackCueList. * @instance */ + Object.defineProperty(this, 'length', { - get: function get$$1() { + get: function get() { return this.length_; } }); } - /** * A setter for cues in this list. Creates getters * an an index for the cues. @@ -6466,18 +7058,19 @@ */ - TextTrackCueList.prototype.setCues_ = function setCues_(cues) { + var _proto = TextTrackCueList.prototype; + + _proto.setCues_ = function setCues_(cues) { var oldLength = this.length || 0; var i = 0; var l = cues.length; - this.cues_ = cues; this.length_ = cues.length; var defineProp = function defineProp(index) { if (!('' + index in this)) { Object.defineProperty(this, '' + index, { - get: function get$$1() { + get: function get() { return this.cues_[index]; } }); @@ -6491,8 +7084,7 @@ defineProp.call(this, i); } } - }; - + } /** * Get a `TextTrackCue` that is currently in the `TextTrackCueList` by id. * @@ -6502,9 +7094,9 @@ * @return {TextTrackCueList~TextTrackCue|null} * A single cue or null if none was found. */ + ; - - TextTrackCueList.prototype.getCueById = function getCueById(id) { + _proto.getCueById = function getCueById(id) { var result = null; for (var i = 0, l = this.length; i < l; i++) { @@ -6541,7 +7133,6 @@ subtitles: 'subtitles', commentary: 'commentary' }; - /** * All possible `AudioTrackKind`s * @@ -6549,6 +7140,7 @@ * @typedef AudioTrack~Kind * @enum */ + var AudioTrackKind = { 'alternative': 'alternative', 'descriptions': 'descriptions', @@ -6557,7 +7149,6 @@ 'translation': 'translation', 'commentary': 'commentary' }; - /** * All possible `TextTrackKind`s * @@ -6565,6 +7156,7 @@ * @typedef TextTrack~Kind * @enum */ + var TextTrackKind = { subtitles: 'subtitles', captions: 'captions', @@ -6572,7 +7164,6 @@ chapters: 'chapters', metadata: 'metadata' }; - /** * All possible `TextTrackMode`s * @@ -6580,16 +7171,13 @@ * @typedef TextTrack~Mode * @enum */ + var TextTrackMode = { disabled: 'disabled', hidden: 'hidden', showing: 'showing' }; - /** - * @file track.js - */ - /** * A Track class that contains all of the common functionality for {@link AudioTrack}, * {@link VideoTrack}, and {@link TextTrack}. @@ -6601,8 +7189,10 @@ * @abstract */ - var Track = function (_EventTarget) { - inherits(Track, _EventTarget); + var Track = + /*#__PURE__*/ + function (_EventTarget) { + inheritsLoose(Track, _EventTarget); /** * Create an instance of this class. @@ -6624,19 +7214,20 @@ * * @abstract */ - function Track() { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - classCallCheck(this, Track); + function Track(options) { + var _this; - var _this = possibleConstructorReturn(this, _EventTarget.call(this)); + if (options === void 0) { + options = {}; + } + _this = _EventTarget.call(this) || this; var trackProps = { id: options.id || 'vjs_track_' + newGUID(), kind: options.kind || '', label: options.label || '', language: options.language || '' }; - /** * @memberof Track * @member {string} id @@ -6675,17 +7266,18 @@ */ var _loop = function _loop(key) { - Object.defineProperty(_this, key, { - get: function get$$1() { + Object.defineProperty(assertThisInitialized(_this), key, { + get: function get() { return trackProps[key]; }, - set: function set$$1() {} + set: function set() {} }); }; for (var key in trackProps) { _loop(key); } + return _this; } @@ -6696,7 +7288,6 @@ * @file url.js * @module url */ - /** * @typedef {Object} url:URLObject * @@ -6725,46 +7316,45 @@ /** * Resolve and parse the elements of a URL. * - * @param {String} url - * The url to parse + * @function + * @param {String} url + * The url to parse * - * @return {url:URLObject} - * An object of url details + * @return {url:URLObject} + * An object of url details */ + var parseUrl = function parseUrl(url) { - var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host']; + var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host']; // add the url to an anchor and let the browser parse the URL - // add the url to an anchor and let the browser parse the URL - var a = document_1.createElement('a'); - - a.href = url; - - // IE8 (and 9?) Fix + var a = document.createElement('a'); + a.href = url; // IE8 (and 9?) Fix // ie8 doesn't parse the URL correctly until the anchor is actually // added to the body, and an innerHTML is needed to trigger the parsing + var addToBody = a.host === '' && a.protocol !== 'file:'; - var div = void 0; + var div; if (addToBody) { - div = document_1.createElement('div'); - div.innerHTML = ''; - a = div.firstChild; - // prevent the div from affecting layout - div.setAttribute('style', 'display:none; position:absolute;'); - document_1.body.appendChild(div); - } + div = document.createElement('div'); + div.innerHTML = ""; + a = div.firstChild; // prevent the div from affecting layout - // Copy the specific URL properties to a new object + div.setAttribute('style', 'display:none; position:absolute;'); + document.body.appendChild(div); + } // Copy the specific URL properties to a new object // This is also needed for IE8 because the anchor loses its // properties when it's removed from the dom + + var details = {}; for (var i = 0; i < props.length; i++) { details[props[i]] = a[props[i]]; - } - - // IE9 adds the port to the host property unlike everyone else. If + } // IE9 adds the port to the host property unlike everyone else. If // a port identifier is added for standard ports, strip it. + + if (details.protocol === 'http:') { details.host = details.host.replace(/:80$/, ''); } @@ -6774,55 +7364,55 @@ } if (!details.protocol) { - details.protocol = window_1.location.protocol; + details.protocol = window$1.location.protocol; } if (addToBody) { - document_1.body.removeChild(div); + document.body.removeChild(div); } return details; }; - /** - * Get absolute version of relative URL. Used to tell flash correct URL. + * Get absolute version of relative URL. Used to tell Flash the correct URL. * + * @function + * @param {string} url + * URL to make absolute * - * @param {string} url - * URL to make absolute + * @return {string} + * Absolute URL * - * @return {string} - * Absolute URL - * - * @see http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue + * @see http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue */ + var getAbsoluteURL = function getAbsoluteURL(url) { // Check if absolute URL if (!url.match(/^https?:\/\//)) { // Convert to absolute URL. Flash hosted off-site needs an absolute URL. - var div = document_1.createElement('div'); - - div.innerHTML = 'x'; + var div = document.createElement('div'); + div.innerHTML = "x"; url = div.firstChild.href; } return url; }; - /** * Returns the extension of the passed file name. It will return an empty string * if passed an invalid path. * - * @param {string} path - * The fileName path like '/path/to/file.mp4' + * @function + * @param {string} path + * The fileName path like '/path/to/file.mp4' * - * @returns {string} - * The extension in lower case or an empty string if no - * extension could be found. + * @return {string} + * The extension in lower case or an empty string if no + * extension could be found. */ + var getFileExtension = function getFileExtension(path) { if (typeof path === 'string') { - var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i; + var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/; var pathParts = splitPathRe.exec(path); if (pathParts) { @@ -6832,27 +7422,37 @@ return ''; }; - /** * Returns whether the url passed is a cross domain request or not. * - * @param {string} url - * The url to check. + * @function + * @param {string} url + * The url to check. * - * @return {boolean} - * Whether it is a cross domain request or not. + * @param {Object} [winLoc] + * the domain to check the url against, defaults to window.location + * + * @param {string} [winLoc.protocol] + * The window location protocol defaults to window.location.protocol + * + * @param {string} [winLoc.host] + * The window location host defaults to window.location.host + * + * @return {boolean} + * Whether it is a cross domain request or not. */ - var isCrossOrigin = function isCrossOrigin(url) { - var winLoc = window_1.location; - var urlInfo = parseUrl(url); - // IE8 protocol relative urls will return ':' for protocol - var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol; + var isCrossOrigin = function isCrossOrigin(url, winLoc) { + if (winLoc === void 0) { + winLoc = window$1.location; + } - // Check if url is for another domain/origin + var urlInfo = parseUrl(url); // IE8 protocol relative urls will return ':' for protocol + + var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol; // Check if url is for another domain/origin // IE8 doesn't know location.origin, so we won't rely on it here - var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host; + var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host; return crossOrigin; }; @@ -6864,356 +7464,303 @@ }); var isFunction_1 = isFunction; - var toString$1 = Object.prototype.toString; function isFunction(fn) { var string = toString$1.call(fn); - return string === '[object Function]' || typeof fn === 'function' && string !== '[object RegExp]' || typeof window !== 'undefined' && ( - // IE8 and below + return string === '[object Function]' || typeof fn === 'function' && string !== '[object RegExp]' || typeof window !== 'undefined' && ( // IE8 and below fn === window.setTimeout || fn === window.alert || fn === window.confirm || fn === window.prompt); } - var trim_1 = createCommonjsModule(function (module, exports) { - exports = module.exports = trim; + /** + * @license + * slighly modified parse-headers 2.0.2 + * Copyright (c) 2014 David Björklund + * Available under the MIT license + * + */ - function trim(str) { - return str.replace(/^\s*|\s*$/g, ''); - } - - exports.left = function (str) { - return str.replace(/^\s*/, ''); - }; - - exports.right = function (str) { - return str.replace(/\s*$/, ''); - }; - }); - var trim_2 = trim_1.left; - var trim_3 = trim_1.right; - - var forEach_1 = forEach; - - var toString$2 = Object.prototype.toString; - var hasOwnProperty = Object.prototype.hasOwnProperty; - - function forEach(list, iterator, context) { - if (!isFunction_1(iterator)) { - throw new TypeError('iterator must be a function'); - } - - if (arguments.length < 3) { - context = this; - } - - if (toString$2.call(list) === '[object Array]') forEachArray(list, iterator, context);else if (typeof list === 'string') forEachString(list, iterator, context);else forEachObject(list, iterator, context); - } - - function forEachArray(array, iterator, context) { - for (var i = 0, len = array.length; i < len; i++) { - if (hasOwnProperty.call(array, i)) { - iterator.call(context, array[i], i, array); - } - } - } - - function forEachString(string, iterator, context) { - for (var i = 0, len = string.length; i < len; i++) { - // no such thing as a sparse string. - iterator.call(context, string.charAt(i), i, string); - } - } - - function forEachObject(object, iterator, context) { - for (var k in object) { - if (hasOwnProperty.call(object, k)) { - iterator.call(context, object[k], k, object); - } - } - } - - var isArray = function isArray(arg) { - return Object.prototype.toString.call(arg) === '[object Array]'; - }; var parseHeaders = function parseHeaders(headers) { - if (!headers) return {}; - var result = {}; - forEach_1(trim_1(headers).split('\n'), function (row) { - var index = row.indexOf(':'), - key = trim_1(row.slice(0, index)).toLowerCase(), - value = trim_1(row.slice(index + 1)); + if (!headers) { + return result; + } + + headers.trim().split('\n').forEach(function (row) { + var index = row.indexOf(':'); + var key = row.slice(0, index).trim().toLowerCase(); + var value = row.slice(index + 1).trim(); if (typeof result[key] === 'undefined') { result[key] = value; - } else if (isArray(result[key])) { + } else if (Array.isArray(result[key])) { result[key].push(value); } else { result[key] = [result[key], value]; } }); - return result; }; - var immutable = extend; + var xhr = createXHR; // Allow use of default import syntax in TypeScript - var hasOwnProperty$1 = Object.prototype.hasOwnProperty; - - function extend() { - var target = {}; - - for (var i = 0; i < arguments.length; i++) { - var source = arguments[i]; - - for (var key in source) { - if (hasOwnProperty$1.call(source, key)) { - target[key] = source[key]; - } - } - } - - return target; - } - - var xhr = createXHR; - createXHR.XMLHttpRequest = window_1.XMLHttpRequest || noop; - createXHR.XDomainRequest = "withCredentials" in new createXHR.XMLHttpRequest() ? createXHR.XMLHttpRequest : window_1.XDomainRequest; - - forEachArray$1(["get", "put", "post", "patch", "head", "delete"], function (method) { - createXHR[method === "delete" ? "del" : method] = function (uri, options, callback) { - options = initParams(uri, options, callback); - options.method = method.toUpperCase(); - return _createXHR(options); - }; + var default_1 = createXHR; + createXHR.XMLHttpRequest = window$1.XMLHttpRequest || noop; + createXHR.XDomainRequest = "withCredentials" in new createXHR.XMLHttpRequest() ? createXHR.XMLHttpRequest : window$1.XDomainRequest; + forEachArray(["get", "put", "post", "patch", "head", "delete"], function (method) { + createXHR[method === "delete" ? "del" : method] = function (uri, options, callback) { + options = initParams(uri, options, callback); + options.method = method.toUpperCase(); + return _createXHR(options); + }; }); - function forEachArray$1(array, iterator) { - for (var i = 0; i < array.length; i++) { - iterator(array[i]); - } + function forEachArray(array, iterator) { + for (var i = 0; i < array.length; i++) { + iterator(array[i]); + } } function isEmpty(obj) { - for (var i in obj) { - if (obj.hasOwnProperty(i)) return false; - } - return true; + for (var i in obj) { + if (obj.hasOwnProperty(i)) return false; + } + + return true; } function initParams(uri, options, callback) { - var params = uri; + var params = uri; - if (isFunction_1(options)) { - callback = options; - if (typeof uri === "string") { - params = { uri: uri }; - } - } else { - params = immutable(options, { uri: uri }); + if (isFunction_1(options)) { + callback = options; + + if (typeof uri === "string") { + params = { + uri: uri + }; } + } else { + params = _extends_1({}, options, { + uri: uri + }); + } - params.callback = callback; - return params; + params.callback = callback; + return params; } function createXHR(uri, options, callback) { - options = initParams(uri, options, callback); - return _createXHR(options); + options = initParams(uri, options, callback); + return _createXHR(options); } function _createXHR(options) { - if (typeof options.callback === "undefined") { - throw new Error("callback argument missing"); + if (typeof options.callback === "undefined") { + throw new Error("callback argument missing"); + } + + var called = false; + + var callback = function cbOnce(err, response, body) { + if (!called) { + called = true; + options.callback(err, response, body); + } + }; + + function readystatechange() { + if (xhr.readyState === 4) { + setTimeout(loadFunc, 0); + } + } + + function getBody() { + // Chrome with requestType=blob throws errors arround when even testing access to responseText + var body = undefined; + + if (xhr.response) { + body = xhr.response; + } else { + body = xhr.responseText || getXml(xhr); } - var called = false; - var callback = function cbOnce(err, response, body) { - if (!called) { - called = true; - options.callback(err, response, body); - } - }; - - function readystatechange() { - if (xhr.readyState === 4) { - setTimeout(loadFunc, 0); - } + if (isJson) { + try { + body = JSON.parse(body); + } catch (e) {} } - function getBody() { - // Chrome with requestType=blob throws errors arround when even testing access to responseText - var body = undefined; + return body; + } - if (xhr.response) { - body = xhr.response; - } else { - body = xhr.responseText || getXml(xhr); - } + function errorFunc(evt) { + clearTimeout(timeoutTimer); - if (isJson) { - try { - body = JSON.parse(body); - } catch (e) {} - } - - return body; + if (!(evt instanceof Error)) { + evt = new Error("" + (evt || "Unknown XMLHttpRequest Error")); } - function errorFunc(evt) { - clearTimeout(timeoutTimer); - if (!(evt instanceof Error)) { - evt = new Error("" + (evt || "Unknown XMLHttpRequest Error")); - } - evt.statusCode = 0; - return callback(evt, failureResponse); + evt.statusCode = 0; + return callback(evt, failureResponse); + } // will load the data & process the response in a special response object + + + function loadFunc() { + if (aborted) return; + var status; + clearTimeout(timeoutTimer); + + if (options.useXDR && xhr.status === undefined) { + //IE8 CORS GET successful response doesn't have a status field, but body is fine + status = 200; + } else { + status = xhr.status === 1223 ? 204 : xhr.status; } - // will load the data & process the response in a special response object - function loadFunc() { - if (aborted) return; - var status; - clearTimeout(timeoutTimer); - if (options.useXDR && xhr.status === undefined) { - //IE8 CORS GET successful response doesn't have a status field, but body is fine - status = 200; - } else { - status = xhr.status === 1223 ? 204 : xhr.status; - } - var response = failureResponse; - var err = null; + var response = failureResponse; + var err = null; - if (status !== 0) { - response = { - body: getBody(), - statusCode: status, - method: method, - headers: {}, - url: uri, - rawRequest: xhr - }; - if (xhr.getAllResponseHeaders) { - //remember xhr can in fact be XDR for CORS in IE - response.headers = parseHeaders(xhr.getAllResponseHeaders()); - } - } else { - err = new Error("Internal XMLHttpRequest Error"); - } - return callback(err, response, response.body); - } - - var xhr = options.xhr || null; - - if (!xhr) { - if (options.cors || options.useXDR) { - xhr = new createXHR.XDomainRequest(); - } else { - xhr = new createXHR.XMLHttpRequest(); - } - } - - var key; - var aborted; - var uri = xhr.url = options.uri || options.url; - var method = xhr.method = options.method || "GET"; - var body = options.body || options.data; - var headers = xhr.headers = options.headers || {}; - var sync = !!options.sync; - var isJson = false; - var timeoutTimer; - var failureResponse = { - body: undefined, - headers: {}, - statusCode: 0, + if (status !== 0) { + response = { + body: getBody(), + statusCode: status, method: method, + headers: {}, url: uri, rawRequest: xhr - }; + }; - if ("json" in options && options.json !== false) { - isJson = true; - headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json"); //Don't override existing accept header declared by user - if (method !== "GET" && method !== "HEAD") { - headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json"); //Don't override existing accept header declared by user - body = JSON.stringify(options.json === true ? body : options.json); - } + if (xhr.getAllResponseHeaders) { + //remember xhr can in fact be XDR for CORS in IE + response.headers = parseHeaders(xhr.getAllResponseHeaders()); + } + } else { + err = new Error("Internal XMLHttpRequest Error"); } - xhr.onreadystatechange = readystatechange; - xhr.onload = loadFunc; - xhr.onerror = errorFunc; - // IE9 must have onprogress be set to a unique function. - xhr.onprogress = function () { - // IE must die - }; - xhr.onabort = function () { - aborted = true; - }; - xhr.ontimeout = errorFunc; - xhr.open(method, uri, !sync, options.username, options.password); - //has to be after open - if (!sync) { - xhr.withCredentials = !!options.withCredentials; - } - // Cannot set timeout with sync request - // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly - // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent - if (!sync && options.timeout > 0) { - timeoutTimer = setTimeout(function () { - if (aborted) return; - aborted = true; //IE9 may still call readystatechange - xhr.abort("timeout"); - var e = new Error("XMLHttpRequest timeout"); - e.code = "ETIMEDOUT"; - errorFunc(e); - }, options.timeout); - } + return callback(err, response, response.body); + } - if (xhr.setRequestHeader) { - for (key in headers) { - if (headers.hasOwnProperty(key)) { - xhr.setRequestHeader(key, headers[key]); - } - } - } else if (options.headers && !isEmpty(options.headers)) { - throw new Error("Headers cannot be set on an XDomainRequest object"); + var xhr = options.xhr || null; + + if (!xhr) { + if (options.cors || options.useXDR) { + xhr = new createXHR.XDomainRequest(); + } else { + xhr = new createXHR.XMLHttpRequest(); } + } - if ("responseType" in options) { - xhr.responseType = options.responseType; + var key; + var aborted; + var uri = xhr.url = options.uri || options.url; + var method = xhr.method = options.method || "GET"; + var body = options.body || options.data; + var headers = xhr.headers = options.headers || {}; + var sync = !!options.sync; + var isJson = false; + var timeoutTimer; + var failureResponse = { + body: undefined, + headers: {}, + statusCode: 0, + method: method, + url: uri, + rawRequest: xhr + }; + + if ("json" in options && options.json !== false) { + isJson = true; + headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json"); //Don't override existing accept header declared by user + + if (method !== "GET" && method !== "HEAD") { + headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json"); //Don't override existing accept header declared by user + + body = JSON.stringify(options.json === true ? body : options.json); } + } - if ("beforeSend" in options && typeof options.beforeSend === "function") { - options.beforeSend(xhr); + xhr.onreadystatechange = readystatechange; + xhr.onload = loadFunc; + xhr.onerror = errorFunc; // IE9 must have onprogress be set to a unique function. + + xhr.onprogress = function () {// IE must die + }; + + xhr.onabort = function () { + aborted = true; + }; + + xhr.ontimeout = errorFunc; + xhr.open(method, uri, !sync, options.username, options.password); //has to be after open + + if (!sync) { + xhr.withCredentials = !!options.withCredentials; + } // Cannot set timeout with sync request + // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly + // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent + + + if (!sync && options.timeout > 0) { + timeoutTimer = setTimeout(function () { + if (aborted) return; + aborted = true; //IE9 may still call readystatechange + + xhr.abort("timeout"); + var e = new Error("XMLHttpRequest timeout"); + e.code = "ETIMEDOUT"; + errorFunc(e); + }, options.timeout); + } + + if (xhr.setRequestHeader) { + for (key in headers) { + if (headers.hasOwnProperty(key)) { + xhr.setRequestHeader(key, headers[key]); + } } + } else if (options.headers && !isEmpty(options.headers)) { + throw new Error("Headers cannot be set on an XDomainRequest object"); + } - // Microsoft Edge browser sends "undefined" when send is called with undefined value. - // XMLHttpRequest spec says to pass null as body to indicate no body - // See https://github.com/naugtur/xhr/issues/100. - xhr.send(body || null); + if ("responseType" in options) { + xhr.responseType = options.responseType; + } - return xhr; + if ("beforeSend" in options && typeof options.beforeSend === "function") { + options.beforeSend(xhr); + } // Microsoft Edge browser sends "undefined" when send is called with undefined value. + // XMLHttpRequest spec says to pass null as body to indicate no body + // See https://github.com/naugtur/xhr/issues/100. + + + xhr.send(body || null); + return xhr; } function getXml(xhr) { + // xhr.responseXML will throw Exception "InvalidStateError" or "DOMException" + // See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseXML. + try { if (xhr.responseType === "document") { - return xhr.responseXML; - } - var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror"; - if (xhr.responseType === "" && !firefoxBugTakenEffect) { - return xhr.responseXML; + return xhr.responseXML; } - return null; + var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror"; + + if (xhr.responseType === "" && !firefoxBugTakenEffect) { + return xhr.responseXML; + } + } catch (e) {} + + return null; } function noop() {} - - /** - * @file text-track.js - */ + xhr["default"] = default_1; /** * Takes a webvtt file contents and parses it into cues @@ -7226,8 +7773,9 @@ * * @private */ + var parseCues = function parseCues(srcContent, track) { - var parser = new window_1.WebVTT.Parser(window_1, window_1.vttjs, window_1.WebVTT.StringDecoder()); + var parser = new window$1.WebVTT.Parser(window$1, window$1.vttjs, window$1.WebVTT.StringDecoder()); var errors = []; parser.oncue = function (cue) { @@ -7246,21 +7794,23 @@ }; parser.parse(srcContent); + if (errors.length > 0) { - if (window_1.console && window_1.console.groupCollapsed) { - window_1.console.groupCollapsed('Text Track parsing errors for ' + track.src); + if (window$1.console && window$1.console.groupCollapsed) { + window$1.console.groupCollapsed("Text Track parsing errors for " + track.src); } + errors.forEach(function (error) { - return log$1.error(error); + return log.error(error); }); - if (window_1.console && window_1.console.groupEnd) { - window_1.console.groupEnd(); + + if (window$1.console && window$1.console.groupEnd) { + window$1.console.groupEnd(); } } parser.flush(); }; - /** * Load a `TextTrack` from a specified url. * @@ -7272,6 +7822,8 @@ * * @private */ + + var loadTrack = function loadTrack(src, track) { var opts = { uri: src @@ -7284,23 +7836,23 @@ xhr(opts, bind(this, function (err, response, responseBody) { if (err) { - return log$1.error(err, response); + return log.error(err, response); } - track.loaded_ = true; - - // Make sure that vttjs has loaded, otherwise, wait till it finished loading + track.loaded_ = true; // Make sure that vttjs has loaded, otherwise, wait till it finished loading // NOTE: this is only used for the alt/video.novtt.js build - if (typeof window_1.WebVTT !== 'function') { - if (track.tech_) { - var loadHandler = function loadHandler() { - return parseCues(responseBody, track); - }; - track.tech_.on('vttjsloaded', loadHandler); - track.tech_.on('vttjserror', function () { - log$1.error('vttjs failed to load, stopping trying to process ' + track.src); - track.tech_.off('vttjsloaded', loadHandler); + if (typeof window$1.WebVTT !== 'function') { + if (track.tech_) { + // to prevent use before define eslint error, we define loadHandler + // as a let here + track.tech_.any(['vttjsloaded', 'vttjserror'], function (event) { + if (event.type === 'vttjserror') { + log.error("vttjs failed to load, stopping trying to process " + track.src); + return; + } + + return parseCues(responseBody, track); }); } } else { @@ -7308,7 +7860,6 @@ } })); }; - /** * A representation of a single `TextTrack`. * @@ -7316,8 +7867,11 @@ * @extends Track */ - var TextTrack = function (_Track) { - inherits(TextTrack, _Track); + + var TextTrack = + /*#__PURE__*/ + function (_Track) { + inheritsLoose(TextTrack, _Track); /** * Create an instance of this class. @@ -7353,9 +7907,12 @@ * @param {boolean} [options.default] * If this track should default to on or off. */ - function TextTrack() { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - classCallCheck(this, TextTrack); + function TextTrack(options) { + var _this; + + if (options === void 0) { + options = {}; + } if (!options.tech) { throw new Error('A tech was not provided.'); @@ -7366,29 +7923,27 @@ language: options.language || options.srclang || '' }); var mode = TextTrackMode[settings.mode] || 'disabled'; - var default_ = settings.default; + var default_ = settings["default"]; if (settings.kind === 'metadata' || settings.kind === 'chapters') { mode = 'hidden'; } - var _this = possibleConstructorReturn(this, _Track.call(this, settings)); - + _this = _Track.call(this, settings) || this; _this.tech_ = settings.tech; - _this.cues_ = []; _this.activeCues_ = []; - + _this.preload_ = _this.tech_.preloadTextTracks !== false; var cues = new TextTrackCueList(_this.cues_); var activeCues = new TextTrackCueList(_this.activeCues_); var changed = false; - var timeupdateHandler = bind(_this, function () { - + var timeupdateHandler = bind(assertThisInitialized(_this), function () { // Accessing this.activeCues for the side-effects of updating itself - // due to it's nature as a getter function. Do not remove or cues will + // due to its nature as a getter function. Do not remove or cues will // stop updating! // Use the setter to prevent deletion from uglify (pure_getters rule) this.activeCues = this.activeCues; + if (changed) { this.trigger('cuechange'); changed = false; @@ -7401,7 +7956,7 @@ }, true); } - Object.defineProperties(_this, { + Object.defineProperties(assertThisInitialized(_this), { /** * @memberof TextTrack * @member {boolean} default @@ -7411,11 +7966,11 @@ * * @readonly */ - default: { - get: function get$$1() { + "default": { + get: function get() { return default_; }, - set: function set$$1() {} + set: function set() {} }, /** @@ -7428,21 +7983,29 @@ * @fires TextTrack#modechange */ mode: { - get: function get$$1() { + get: function get() { return mode; }, - set: function set$$1(newMode) { + set: function set(newMode) { var _this2 = this; if (!TextTrackMode[newMode]) { return; } - mode = newMode; - if (mode === 'showing') { + mode = newMode; + + if (!this.preload_ && mode !== 'disabled' && this.cues.length === 0) { + // On-demand load. + loadTrack(this.src, this); + } + + if (mode !== 'disabled') { this.tech_.ready(function () { _this2.tech_.on('timeupdate', timeupdateHandler); }, true); + } else { + this.tech_.off('timeupdate', timeupdateHandler); } /** * An event that fires when mode changes on this track. This allows @@ -7453,6 +8016,8 @@ * @event TextTrack#modechange * @type {EventTarget~Event} */ + + this.trigger('modechange'); } }, @@ -7464,14 +8029,14 @@ * @instance */ cues: { - get: function get$$1() { + get: function get() { if (!this.loaded_) { return null; } return cues; }, - set: function set$$1() {} + set: function set() {} }, /** @@ -7481,12 +8046,12 @@ * @instance */ activeCues: { - get: function get$$1() { + get: function get() { if (!this.loaded_) { return null; - } + } // nothing to do + - // nothing to do if (this.cues.length === 0) { return activeCues; } @@ -7518,25 +8083,31 @@ this.activeCues_ = active; activeCues.setCues_(this.activeCues_); - return activeCues; }, - - // /!\ Keep this setter empty (see the timeupdate handler above) - set: function set$$1() {} + set: function set() {} } }); if (settings.src) { _this.src = settings.src; - loadTrack(settings.src, _this); + + if (!_this.preload_) { + // Tracks will load on-demand. + // Act like we're loaded for other purposes. + _this.loaded_ = true; + } + + if (_this.preload_ || default_ || settings.kind !== 'subtitles' && settings.kind !== 'captions') { + loadTrack(_this.src, assertThisInitialized(_this)); + } } else { _this.loaded_ = true; } + return _this; } - /** * Add a cue to the internal list of cues. * @@ -7545,19 +8116,21 @@ */ - TextTrack.prototype.addCue = function addCue(originalCue) { + var _proto = TextTrack.prototype; + + _proto.addCue = function addCue(originalCue) { var cue = originalCue; - if (window_1.vttjs && !(originalCue instanceof window_1.vttjs.VTTCue)) { - cue = new window_1.vttjs.VTTCue(originalCue.startTime, originalCue.endTime, originalCue.text); + if (window$1.vttjs && !(originalCue instanceof window$1.vttjs.VTTCue)) { + cue = new window$1.vttjs.VTTCue(originalCue.startTime, originalCue.endTime, originalCue.text); for (var prop in originalCue) { if (!(prop in cue)) { cue[prop] = originalCue[prop]; } - } + } // make sure that `id` is copied over + - // make sure that `id` is copied over cue.id = originalCue.id; cue.originalCue_ = originalCue; } @@ -7572,17 +8145,16 @@ this.cues_.push(cue); this.cues.setCues_(this.cues_); - }; - + } /** * Remove a cue from our internal list * * @param {TextTrack~Cue} removeCue * The cue to remove from our internal list */ + ; - - TextTrack.prototype.removeCue = function removeCue(_removeCue) { + _proto.removeCue = function removeCue(_removeCue) { var i = this.cues_.length; while (i--) { @@ -7598,7 +8170,6 @@ return TextTrack; }(Track); - /** * cuechange - One or more cues in the track have become active or stopped being active. */ @@ -7616,8 +8187,10 @@ * @extends Track */ - var AudioTrack = function (_Track) { - inherits(AudioTrack, _Track); + var AudioTrack = + /*#__PURE__*/ + function (_Track) { + inheritsLoose(AudioTrack, _Track); /** * Create an instance of this class. @@ -7641,18 +8214,18 @@ * If this track is the one that is currently playing. If this track is part of * an {@link AudioTrackList}, only one {@link AudioTrack} will be enabled. */ - function AudioTrack() { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - classCallCheck(this, AudioTrack); + function AudioTrack(options) { + var _this; + + if (options === void 0) { + options = {}; + } var settings = mergeOptions(options, { kind: AudioTrackKind[options.kind] || '' }); - - var _this = possibleConstructorReturn(this, _Track.call(this, settings)); - + _this = _Track.call(this, settings) || this; var enabled = false; - /** * @memberof AudioTrack * @member {boolean} enabled @@ -7662,17 +8235,18 @@ * * @fires VideoTrack#selectedchange */ - Object.defineProperty(_this, 'enabled', { - get: function get$$1() { + + Object.defineProperty(assertThisInitialized(_this), 'enabled', { + get: function get() { return enabled; }, - set: function set$$1(newEnabled) { + set: function set(newEnabled) { // an invalid or unchanged value if (typeof newEnabled !== 'boolean' || newEnabled === enabled) { return; } - enabled = newEnabled; + enabled = newEnabled; /** * An event that fires when enabled changes on this track. This allows * the AudioTrackList that holds this track to act accordingly. @@ -7683,16 +8257,17 @@ * @event AudioTrack#enabledchange * @type {EventTarget~Event} */ + this.trigger('enabledchange'); } - }); - - // if the user sets this track to selected then + }); // if the user sets this track to selected then // set selected to that true value otherwise // we keep it false + if (settings.enabled) { _this.enabled = settings.enabled; } + _this.loaded_ = true; return _this; } @@ -7707,8 +8282,10 @@ * @extends Track */ - var VideoTrack = function (_Track) { - inherits(VideoTrack, _Track); + var VideoTrack = + /*#__PURE__*/ + function (_Track) { + inheritsLoose(VideoTrack, _Track); /** * Create an instance of this class. @@ -7731,18 +8308,18 @@ * @param {boolean} [options.selected] * If this track is the one that is currently playing. */ - function VideoTrack() { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - classCallCheck(this, VideoTrack); + function VideoTrack(options) { + var _this; + + if (options === void 0) { + options = {}; + } var settings = mergeOptions(options, { kind: VideoTrackKind[options.kind] || '' }); - - var _this = possibleConstructorReturn(this, _Track.call(this, settings)); - + _this = _Track.call(this, settings) || this; var selected = false; - /** * @memberof VideoTrack * @member {boolean} selected @@ -7752,17 +8329,18 @@ * * @fires VideoTrack#selectedchange */ - Object.defineProperty(_this, 'selected', { - get: function get$$1() { + + Object.defineProperty(assertThisInitialized(_this), 'selected', { + get: function get() { return selected; }, - set: function set$$1(newSelected) { + set: function set(newSelected) { // an invalid or unchanged value if (typeof newSelected !== 'boolean' || newSelected === selected) { return; } - selected = newSelected; + selected = newSelected; /** * An event that fires when selected changes on this track. This allows * the VideoTrackList that holds this track to act accordingly. @@ -7773,36 +8351,33 @@ * @event VideoTrack#selectedchange * @type {EventTarget~Event} */ + this.trigger('selectedchange'); } - }); - - // if the user sets this track to selected then + }); // if the user sets this track to selected then // set selected to that true value otherwise // we keep it false + if (settings.selected) { _this.selected = settings.selected; } + return _this; } return VideoTrack; }(Track); - /** - * @file html-track-element.js - */ - /** * @memberof HTMLTrackElement * @typedef {HTMLTrackElement~ReadyState} * @enum {number} */ + var NONE = 0; var LOADING = 1; var LOADED = 2; var ERROR = 3; - /** * A single track represented in the DOM. * @@ -7810,8 +8385,10 @@ * @extends EventTarget */ - var HTMLTrackElement = function (_EventTarget) { - inherits(HTMLTrackElement, _EventTarget); + var HTMLTrackElement = + /*#__PURE__*/ + function (_EventTarget) { + inheritsLoose(HTMLTrackElement, _EventTarget); /** * Create an instance of this class. @@ -7847,24 +8424,22 @@ * @param {boolean} [options.default] * If this track should default to on or off. */ - function HTMLTrackElement() { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - classCallCheck(this, HTMLTrackElement); + function HTMLTrackElement(options) { + var _this; - var _this = possibleConstructorReturn(this, _EventTarget.call(this)); - - var readyState = void 0; + if (options === void 0) { + options = {}; + } + _this = _EventTarget.call(this) || this; + var readyState; var track = new TextTrack(options); - _this.kind = track.kind; _this.src = track.src; _this.srclang = track.language; _this.label = track.label; - _this.default = track.default; - - Object.defineProperties(_this, { - + _this["default"] = track["default"]; + Object.defineProperties(assertThisInitialized(_this), { /** * @memberof HTMLTrackElement * @member {HTMLTrackElement~ReadyState} readyState @@ -7872,7 +8447,7 @@ * @instance */ readyState: { - get: function get$$1() { + get: function get() { return readyState; } }, @@ -7885,24 +8460,23 @@ * */ track: { - get: function get$$1() { + get: function get() { return track; } } }); - readyState = NONE; - /** * @listens TextTrack#loadeddata * @fires HTMLTrackElement#load */ + track.addEventListener('loadeddata', function () { readyState = LOADED; _this.trigger({ type: 'load', - target: _this + target: assertThisInitialized(_this) }); }); return _this; @@ -7914,7 +8488,6 @@ HTMLTrackElement.prototype.allowedEvents_ = { load: 'load' }; - HTMLTrackElement.NONE = NONE; HTMLTrackElement.LOADING = LOADING; HTMLTrackElement.LOADED = LOADED; @@ -7942,12 +8515,10 @@ capitalName: 'Text' } }; - Object.keys(NORMAL).forEach(function (type) { - NORMAL[type].getterName = type + 'Tracks'; - NORMAL[type].privateName = type + 'Tracks_'; + NORMAL[type].getterName = type + "Tracks"; + NORMAL[type].privateName = type + "Tracks_"; }); - var REMOTE = { remoteText: { ListClass: TextTrackList, @@ -7965,7 +8536,7 @@ } }; - var ALL = mergeOptions(NORMAL, REMOTE); + var ALL = _extends_1({}, NORMAL, REMOTE); REMOTE.names = Object.keys(REMOTE); NORMAL.names = Object.keys(NORMAL); @@ -7988,31 +8559,35 @@ */ /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ + var _objCreate = Object.create || function () { function F() {} + return function (o) { if (arguments.length !== 1) { throw new Error('Object.create shim only accepts one parameter.'); } + F.prototype = o; return new F(); }; - }(); - - // Creates a new ParserError object from an errorData object. The errorData + }(); // Creates a new ParserError object from an errorData object. The errorData // object should have default code and message properties. The default message // property can be overriden by passing in a message parameter. // See ParsingError.Errors below for acceptable errors. + + function ParsingError(errorData, message) { this.name = "ParsingError"; this.code = errorData.code; this.message = message || errorData.message; } - ParsingError.prototype = _objCreate(Error.prototype); - ParsingError.prototype.constructor = ParsingError; - // ParsingError metadata for acceptable ParsingErrors. + ParsingError.prototype = _objCreate(Error.prototype); + ParsingError.prototype.constructor = ParsingError; // ParsingError metadata for acceptable ParsingErrors. + ParsingError.Errors = { BadSignature: { code: 0, @@ -8022,16 +8597,15 @@ code: 1, message: "Malformed time stamp." } - }; + }; // Try to parse input as a time stamp. - // Try to parse input as a time stamp. function parseTimeStamp(input) { - function computeSeconds(h, m, s, f) { return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000; } - var m = input.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/); + var m = input.match(/^(\d+):(\d{1,2})(:\d{1,2})?\.(\d{3})/); + if (!m) { return null; } @@ -8047,10 +8621,10 @@ // Timestamp takes the form of [minutes]:[seconds].[milliseconds] return computeSeconds(0, m[1], m[2], m[4]); } - } - - // A settings object holds key/value pairs and will ignore anything but the first + } // A settings object holds key/value pairs and will ignore anything but the first // assignment to a specific key. + + function Settings() { this.values = _objCreate(null); } @@ -8071,6 +8645,7 @@ if (defaultKey) { return this.has(k) ? this.values[k] : dflt[defaultKey]; } + return this.has(k) ? this.values[k] : dflt; }, // Check whether we have a value for a key. @@ -8096,29 +8671,35 @@ // Accept a setting if its a valid percentage. percent: function percent(k, v) { var m; + if (m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/)) { v = parseFloat(v); + if (v >= 0 && v <= 100) { this.set(k, v); return true; } } + return false; } - }; - - // Helper function to parse input into groups separated by 'groupDelim', and + }; // Helper function to parse input into groups separated by 'groupDelim', and // interprete each group as a key/value pair separated by 'keyValueDelim'. + function parseOptions(input, callback, keyValueDelim, groupDelim) { var groups = groupDelim ? input.split(groupDelim) : [input]; + for (var i in groups) { if (typeof groups[i] !== "string") { continue; } + var kv = groups[i].split(keyValueDelim); + if (kv.length !== 2) { continue; } + var k = kv[0]; var v = kv[1]; callback(k, v); @@ -8127,22 +8708,23 @@ function parseCue(input, cue, regionList) { // Remember the original input if we need to throw an error. - var oInput = input; - // 4.1 WebVTT timestamp + var oInput = input; // 4.1 WebVTT timestamp + function consumeTimeStamp() { var ts = parseTimeStamp(input); + if (ts === null) { throw new ParsingError(ParsingError.Errors.BadTimeStamp, "Malformed timestamp: " + oInput); - } - // Remove time stamp from input. + } // Remove time stamp from input. + + input = input.replace(/^[^\sa-zA-Z-]+/, ""); return ts; - } + } // 4.4.2 WebVTT cue settings + - // 4.4.2 WebVTT cue settings function consumeCueSettings(input, cue) { var settings = new Settings(); - parseOptions(input, function (k, v) { switch (k) { case "region": @@ -8153,55 +8735,81 @@ break; } } + break; + case "vertical": settings.alt(k, v, ["rl", "lr"]); break; + case "line": var vals = v.split(","), vals0 = vals[0]; settings.integer(k, vals0); settings.percent(k, vals0) ? settings.set("snapToLines", false) : null; settings.alt(k, vals0, ["auto"]); + if (vals.length === 2) { - settings.alt("lineAlign", vals[1], ["start", "middle", "end"]); + settings.alt("lineAlign", vals[1], ["start", "center", "end"]); } + break; + case "position": vals = v.split(","); settings.percent(k, vals[0]); + if (vals.length === 2) { - settings.alt("positionAlign", vals[1], ["start", "middle", "end"]); + settings.alt("positionAlign", vals[1], ["start", "center", "end"]); } + break; + case "size": settings.percent(k, v); break; + case "align": - settings.alt(k, v, ["start", "middle", "end", "left", "right"]); + settings.alt(k, v, ["start", "center", "end", "left", "right"]); break; } - }, /:/, /\s/); + }, /:/, /\s/); // Apply default values for any missing fields. - // Apply default values for any missing fields. cue.region = settings.get("region", null); cue.vertical = settings.get("vertical", ""); - cue.line = settings.get("line", "auto"); + + try { + cue.line = settings.get("line", "auto"); + } catch (e) {} + cue.lineAlign = settings.get("lineAlign", "start"); cue.snapToLines = settings.get("snapToLines", true); - cue.size = settings.get("size", 100); - cue.align = settings.get("align", "middle"); - cue.position = settings.get("position", { - start: 0, - left: 0, - middle: 50, - end: 100, - right: 100 - }, cue.align); + cue.size = settings.get("size", 100); // Safari still uses the old middle value and won't accept center + + try { + cue.align = settings.get("align", "center"); + } catch (e) { + cue.align = settings.get("align", "middle"); + } + + try { + cue.position = settings.get("position", "auto"); + } catch (e) { + cue.position = settings.get("position", { + start: 0, + left: 0, + center: 50, + middle: 50, + end: 100, + right: 100 + }, cue.align); + } + cue.positionAlign = settings.get("positionAlign", { start: "start", left: "start", - middle: "middle", + center: "center", + middle: "center", end: "end", right: "end" }, cue.align); @@ -8209,34 +8817,29 @@ function skipWhitespace() { input = input.replace(/^\s+/, ""); - } + } // 4.1 WebVTT cue timings. + - // 4.1 WebVTT cue timings. skipWhitespace(); cue.startTime = consumeTimeStamp(); // (1) collect cue start time + skipWhitespace(); + if (input.substr(0, 3) !== "-->") { // (3) next characters must match "-->" throw new ParsingError(ParsingError.Errors.BadTimeStamp, "Malformed time stamp (time stamps must be separated by '-->'): " + oInput); } + input = input.substr(3); skipWhitespace(); cue.endTime = consumeTimeStamp(); // (5) collect cue end time - // 4.1 WebVTT cue settings list. + skipWhitespace(); consumeCueSettings(input, cue); } - var ESCAPE = { - "&": "&", - "<": "<", - ">": ">", - "‎": "\u200E", - "‏": "\u200F", - " ": "\xA0" - }; - + var TEXTAREA_ELEMENT = document.createElement("textarea"); var TAG_NAME = { c: "span", i: "i", @@ -8246,64 +8849,72 @@ rt: "rt", v: "span", lang: "span" - }; + }; // 5.1 default text color + // 5.2 default text background color is equivalent to text color with bg_ prefix + var DEFAULT_COLOR_CLASS = { + white: 'rgba(255,255,255,1)', + lime: 'rgba(0,255,0,1)', + cyan: 'rgba(0,255,255,1)', + red: 'rgba(255,0,0,1)', + yellow: 'rgba(255,255,0,1)', + magenta: 'rgba(255,0,255,1)', + blue: 'rgba(0,0,255,1)', + black: 'rgba(0,0,0,1)' + }; var TAG_ANNOTATION = { v: "title", lang: "lang" }; - var NEEDS_PARENT = { rt: "ruby" - }; + }; // Parse content into a document fragment. - // Parse content into a document fragment. function parseContent(window, input) { function nextToken() { // Check for end-of-string. if (!input) { return null; - } + } // Consume 'n' characters from the input. + - // Consume 'n' characters from the input. function consume(result) { input = input.substr(result.length); return result; } - var m = input.match(/^([^<]*)(<[^>]*>?)?/); - // If there is some text before the next tag, return it, otherwise return + var m = input.match(/^([^<]*)(<[^>]*>?)?/); // If there is some text before the next tag, return it, otherwise return // the tag. + return consume(m[1] ? m[1] : m[2]); } - // Unescape a string 's'. - function unescape1(e) { - return ESCAPE[e]; - } function unescape(s) { - while (m = s.match(/&(amp|lt|gt|lrm|rlm|nbsp);/)) { - s = s.replace(m[0], unescape1); - } + TEXTAREA_ELEMENT.innerHTML = s; + s = TEXTAREA_ELEMENT.textContent; + TEXTAREA_ELEMENT.textContent = ""; return s; } function shouldAdd(current, element) { return !NEEDS_PARENT[element.localName] || NEEDS_PARENT[element.localName] === current.localName; - } + } // Create an element for this tag. + - // Create an element for this tag. function createElement(type, annotation) { var tagName = TAG_NAME[type]; + if (!tagName) { return null; } + var element = window.document.createElement(tagName); - element.localName = tagName; var name = TAG_ANNOTATION[type]; + if (name && annotation) { element[name] = annotation.trim(); } + return element; } @@ -8319,62 +8930,84 @@ if (tagStack.length && tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) { tagStack.pop(); current = current.parentNode; - } - // Otherwise just ignore the end tag. + } // Otherwise just ignore the end tag. + + continue; } + var ts = parseTimeStamp(t.substr(1, t.length - 2)); var node; + if (ts) { // Timestamps are lead nodes as well. node = window.document.createProcessingInstruction("timestamp", ts); current.appendChild(node); continue; } - var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/); - // If we can't parse the tag, skip to the next tag. + + var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/); // If we can't parse the tag, skip to the next tag. + if (!m) { continue; - } - // Try to construct an element, and ignore the tag if we couldn't. + } // Try to construct an element, and ignore the tag if we couldn't. + + node = createElement(m[1], m[3]); + if (!node) { continue; - } - // Determine if the tag should be added based on the context of where it + } // Determine if the tag should be added based on the context of where it // is placed in the cuetext. + + if (!shouldAdd(current, node)) { continue; - } - // Set the class list (as a list of classes, separated by space). + } // Set the class list (as a list of classes, separated by space). + + if (m[2]) { - node.className = m[2].substr(1).replace('.', ' '); - } - // Append the node to the current node, and enter the scope of the new + var classes = m[2].split('.'); + classes.forEach(function (cl) { + var bgColor = /^bg_/.test(cl); // slice out `bg_` if it's a background color + + var colorName = bgColor ? cl.slice(3) : cl; + + if (DEFAULT_COLOR_CLASS.hasOwnProperty(colorName)) { + var propName = bgColor ? 'background-color' : 'color'; + var propValue = DEFAULT_COLOR_CLASS[colorName]; + node.style[propName] = propValue; + } + }); + node.className = classes.join(' '); + } // Append the node to the current node, and enter the scope of the new // node. + + tagStack.push(m[1]); current.appendChild(node); current = node; continue; - } + } // Text nodes are leaf nodes. + - // Text nodes are leaf nodes. current.appendChild(window.document.createTextNode(unescape(t))); } return rootDiv; - } - - // This is a list of all the Unicode characters that have a strong + } // This is a list of all the Unicode characters that have a strong // right-to-left category. What this means is that these characters are // written right-to-left for sure. It was generated by pulling all the strong // right-to-left characters out of the Unicode data table. That table can // found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt + + var strongRTLRanges = [[0x5be, 0x5be], [0x5c0, 0x5c0], [0x5c3, 0x5c3], [0x5c6, 0x5c6], [0x5d0, 0x5ea], [0x5f0, 0x5f4], [0x608, 0x608], [0x60b, 0x60b], [0x60d, 0x60d], [0x61b, 0x61b], [0x61e, 0x64a], [0x66d, 0x66f], [0x671, 0x6d5], [0x6e5, 0x6e6], [0x6ee, 0x6ef], [0x6fa, 0x70d], [0x70f, 0x710], [0x712, 0x72f], [0x74d, 0x7a5], [0x7b1, 0x7b1], [0x7c0, 0x7ea], [0x7f4, 0x7f5], [0x7fa, 0x7fa], [0x800, 0x815], [0x81a, 0x81a], [0x824, 0x824], [0x828, 0x828], [0x830, 0x83e], [0x840, 0x858], [0x85e, 0x85e], [0x8a0, 0x8a0], [0x8a2, 0x8ac], [0x200f, 0x200f], [0xfb1d, 0xfb1d], [0xfb1f, 0xfb28], [0xfb2a, 0xfb36], [0xfb38, 0xfb3c], [0xfb3e, 0xfb3e], [0xfb40, 0xfb41], [0xfb43, 0xfb44], [0xfb46, 0xfbc1], [0xfbd3, 0xfd3d], [0xfd50, 0xfd8f], [0xfd92, 0xfdc7], [0xfdf0, 0xfdfc], [0xfe70, 0xfe74], [0xfe76, 0xfefc], [0x10800, 0x10805], [0x10808, 0x10808], [0x1080a, 0x10835], [0x10837, 0x10838], [0x1083c, 0x1083c], [0x1083f, 0x10855], [0x10857, 0x1085f], [0x10900, 0x1091b], [0x10920, 0x10939], [0x1093f, 0x1093f], [0x10980, 0x109b7], [0x109be, 0x109bf], [0x10a00, 0x10a00], [0x10a10, 0x10a13], [0x10a15, 0x10a17], [0x10a19, 0x10a33], [0x10a40, 0x10a47], [0x10a50, 0x10a58], [0x10a60, 0x10a7f], [0x10b00, 0x10b35], [0x10b40, 0x10b55], [0x10b58, 0x10b72], [0x10b78, 0x10b7f], [0x10c00, 0x10c48], [0x1ee00, 0x1ee03], [0x1ee05, 0x1ee1f], [0x1ee21, 0x1ee22], [0x1ee24, 0x1ee24], [0x1ee27, 0x1ee27], [0x1ee29, 0x1ee32], [0x1ee34, 0x1ee37], [0x1ee39, 0x1ee39], [0x1ee3b, 0x1ee3b], [0x1ee42, 0x1ee42], [0x1ee47, 0x1ee47], [0x1ee49, 0x1ee49], [0x1ee4b, 0x1ee4b], [0x1ee4d, 0x1ee4f], [0x1ee51, 0x1ee52], [0x1ee54, 0x1ee54], [0x1ee57, 0x1ee57], [0x1ee59, 0x1ee59], [0x1ee5b, 0x1ee5b], [0x1ee5d, 0x1ee5d], [0x1ee5f, 0x1ee5f], [0x1ee61, 0x1ee62], [0x1ee64, 0x1ee64], [0x1ee67, 0x1ee6a], [0x1ee6c, 0x1ee72], [0x1ee74, 0x1ee77], [0x1ee79, 0x1ee7c], [0x1ee7e, 0x1ee7e], [0x1ee80, 0x1ee89], [0x1ee8b, 0x1ee9b], [0x1eea1, 0x1eea3], [0x1eea5, 0x1eea9], [0x1eeab, 0x1eebb], [0x10fffd, 0x10fffd]]; function isStrongRTLChar(charCode) { for (var i = 0; i < strongRTLRanges.length; i++) { var currentRange = strongRTLRanges[i]; + if (charCode >= currentRange[0] && charCode <= currentRange[1]) { return true; } @@ -8405,19 +9038,24 @@ var node = nodeStack.pop(), text = node.textContent || node.innerText; + if (text) { // TODO: This should match all unicode type B characters (paragraph // separator characters). See issue #115. var m = text.match(/^.*(\n|\r)/); + if (m) { nodeStack.length = 0; return m[0]; } + return text; } + if (node.tagName === "ruby") { return nextTextNode(nodeStack); } + if (node.childNodes) { pushNodes(nodeStack, node); return nextTextNode(nodeStack); @@ -8425,14 +9063,17 @@ } pushNodes(nodeStack, cueDiv); + while (text = nextTextNode(nodeStack)) { for (var i = 0; i < text.length; i++) { charCode = text.charCodeAt(i); + if (isStrongRTLChar(charCode)) { return "rtl"; } } } + return "ltr"; } @@ -8440,26 +9081,31 @@ if (typeof cue.line === "number" && (cue.snapToLines || cue.line >= 0 && cue.line <= 100)) { return cue.line; } + if (!cue.track || !cue.track.textTrackList || !cue.track.textTrackList.mediaElement) { return -1; } + var track = cue.track, trackList = track.textTrackList, count = 0; + for (var i = 0; i < trackList.length && trackList[i] !== track; i++) { if (trackList[i].mode === "showing") { count++; } } + return ++count * -1; } - function StyleBox() {} - - // Apply styles to a div. If there is no div passed then it defaults to the + function StyleBox() {} // Apply styles to a div. If there is no div passed then it defaults to the // div on 'this'. + + StyleBox.prototype.applyStyles = function (styles, div) { div = div || this.div; + for (var prop in styles) { if (styles.hasOwnProperty(prop)) { div.style[prop] = styles[prop]; @@ -8469,16 +9115,15 @@ StyleBox.prototype.formatStyle = function (val, unit) { return val === 0 ? 0 : val + unit; - }; - - // Constructs the computed display state of the cue (a div). Places the div + }; // Constructs the computed display state of the cue (a div). Places the div // into the overlay which should be a block level element (usually a div). + + function CueStyleBox(window, cue, styleOptions) { StyleBox.call(this); - this.cue = cue; - - // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will + this.cue = cue; // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will // have inline positioning and will function as the cue background box. + this.cueDiv = parseContent(window, cue.text); var styles = { color: "rgba(255, 255, 255, 1)", @@ -8492,12 +9137,10 @@ writingMode: cue.vertical === "" ? "horizontal-tb" : cue.vertical === "lr" ? "vertical-lr" : "vertical-rl", unicodeBidi: "plaintext" }; - - this.applyStyles(styles, this.cueDiv); - - // Create an absolutely positioned div that will be used to position the cue + this.applyStyles(styles, this.cueDiv); // Create an absolutely positioned div that will be used to position the cue // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS - // mirrors of them except "middle" which is "center" in CSS. + // mirrors of them except middle instead of center on Safari. + this.div = window.document.createElement("div"); styles = { direction: determineBidi(this.cueDiv), @@ -8508,35 +9151,35 @@ whiteSpace: "pre-line", position: "absolute" }; - this.applyStyles(styles); - this.div.appendChild(this.cueDiv); - - // Calculate the distance from the reference edge of the viewport to the text + this.div.appendChild(this.cueDiv); // Calculate the distance from the reference edge of the viewport to the text // position of the cue box. The reference edge will be resolved later when // the box orientation styles are applied. + var textPos = 0; + switch (cue.positionAlign) { case "start": textPos = cue.position; break; - case "middle": + + case "center": textPos = cue.position - cue.size / 2; break; + case "end": textPos = cue.position - cue.size; break; - } - - // Horizontal box orientation; textPos is the distance from the left edge of the + } // Horizontal box orientation; textPos is the distance from the left edge of the // area to the left edge of the box and cue.size is the distance extending to // the right from there. + + if (cue.vertical === "") { this.applyStyles({ left: this.formatStyle(textPos, "%"), width: this.formatStyle(cue.size, "%") - }); - // Vertical box orientation; textPos is the distance from the top edge of the + }); // Vertical box orientation; textPos is the distance from the top edge of the // area to the top edge of the box and cue.size is the height extending // downwards from there. } else { @@ -8557,31 +9200,32 @@ }); }; } - CueStyleBox.prototype = _objCreate(StyleBox.prototype); - CueStyleBox.prototype.constructor = CueStyleBox; - // Represents the co-ordinates of an Element in a way that we can easily + CueStyleBox.prototype = _objCreate(StyleBox.prototype); + CueStyleBox.prototype.constructor = CueStyleBox; // Represents the co-ordinates of an Element in a way that we can easily // compute things with such as if it overlaps or intersects with another Element. // Can initialize it with either a StyleBox or another BoxPosition. + function BoxPosition(obj) { // Either a BoxPosition was passed in and we need to copy it, or a StyleBox // was passed in and we need to copy the results of 'getBoundingClientRect' // as the object returned is readonly. All co-ordinate values are in reference // to the viewport origin (top left). var lh, height, width, top; + if (obj.div) { height = obj.div.offsetHeight; width = obj.div.offsetWidth; top = obj.div.offsetTop; - var rects = (rects = obj.div.childNodes) && (rects = rects[0]) && rects.getClientRects && rects.getClientRects(); - obj = obj.div.getBoundingClientRect(); - // In certain cases the outter div will be slightly larger then the sum of + obj = obj.div.getBoundingClientRect(); // In certain cases the outter div will be slightly larger then the sum of // the inner div's lines. This could be due to bold text, etc, on some platforms. // In this case we should get the average line height and use that. This will // result in the desired behaviour. + lh = rects ? Math.max(rects[0] && rects[0].height || 0, obj.height / rects.length) : 0; } + this.left = obj.left; this.right = obj.right; this.top = obj.top || top; @@ -8589,83 +9233,91 @@ this.bottom = obj.bottom || top + (obj.height || height); this.width = obj.width || width; this.lineHeight = lh !== undefined ? lh : obj.lineHeight; - } - - // Move the box along a particular axis. Optionally pass in an amount to move + } // Move the box along a particular axis. Optionally pass in an amount to move // the box. If no amount is passed then the default is the line height of the // box. + + BoxPosition.prototype.move = function (axis, toMove) { toMove = toMove !== undefined ? toMove : this.lineHeight; + switch (axis) { case "+x": this.left += toMove; this.right += toMove; break; + case "-x": this.left -= toMove; this.right -= toMove; break; + case "+y": this.top += toMove; this.bottom += toMove; break; + case "-y": this.top -= toMove; this.bottom -= toMove; break; } - }; + }; // Check if this box overlaps another box, b2. + - // Check if this box overlaps another box, b2. BoxPosition.prototype.overlaps = function (b2) { return this.left < b2.right && this.right > b2.left && this.top < b2.bottom && this.bottom > b2.top; - }; + }; // Check if this box overlaps any other boxes in boxes. + - // Check if this box overlaps any other boxes in boxes. BoxPosition.prototype.overlapsAny = function (boxes) { for (var i = 0; i < boxes.length; i++) { if (this.overlaps(boxes[i])) { return true; } } - return false; - }; - // Check if this box is within another box. + return false; + }; // Check if this box is within another box. + + BoxPosition.prototype.within = function (container) { return this.top >= container.top && this.bottom <= container.bottom && this.left >= container.left && this.right <= container.right; - }; - - // Check if this box is entirely within the container or it is overlapping + }; // Check if this box is entirely within the container or it is overlapping // on the edge opposite of the axis direction passed. For example, if "+x" is // passed and the box is overlapping on the left edge of the container, then // return true. + + BoxPosition.prototype.overlapsOppositeAxis = function (container, axis) { switch (axis) { case "+x": return this.left < container.left; + case "-x": return this.right > container.right; + case "+y": return this.top < container.top; + case "-y": return this.bottom > container.bottom; } - }; - - // Find the percentage of the area that this box is overlapping with another + }; // Find the percentage of the area that this box is overlapping with another // box. + + BoxPosition.prototype.intersectPercentage = function (b2) { var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)), y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)), intersectArea = x * y; return intersectArea / (this.height * this.width); - }; - - // Convert the positions from this box to CSS compatible positions using + }; // Convert the positions from this box to CSS compatible positions using // the reference container's positions. This has to be done because this // box's positions are in reference to the viewport origin, whereas, CSS // values are in referecne to their respective edges. + + BoxPosition.prototype.toCSSCompatValues = function (reference) { return { top: this.top - reference.top, @@ -8675,15 +9327,14 @@ height: this.height, width: this.width }; - }; - - // Get an object that represents the box's position without anything extra. + }; // Get an object that represents the box's position without anything extra. // Can pass a StyleBox, HTMLElement, or another BoxPositon. + + BoxPosition.getSimpleBoxPosition = function (obj) { var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0; var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0; var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0; - obj = obj.div ? obj.div.getBoundingClientRect() : obj.tagName ? obj.getBoundingClientRect() : obj; var ret = { left: obj.left, @@ -8694,13 +9345,12 @@ width: obj.width || width }; return ret; - }; - - // Move a StyleBox to its specified, or next best, position. The containerBox + }; // Move a StyleBox to its specified, or next best, position. The containerBox // is the box that contains the StyleBox, such as a div. boxPositions are // a list of other boxes that the styleBox can't overlap with. - function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) { + + function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) { // Find the best position for a cue box, b, on the video. The axis parameter // is a list of axis, the order of which, it will move the box along. For example: // Passing ["+x", "-x"] will move the box first along the x axis in the positive @@ -8714,42 +9364,48 @@ for (var i = 0; i < axis.length; i++) { while (b.overlapsOppositeAxis(containerBox, axis[i]) || b.within(containerBox) && b.overlapsAny(boxPositions)) { b.move(axis[i]); - } - // We found a spot where we aren't overlapping anything. This is our + } // We found a spot where we aren't overlapping anything. This is our // best position. + + if (b.within(containerBox)) { return b; } - var p = b.intersectPercentage(containerBox); - // If we're outside the container box less then we were on our last try + + var p = b.intersectPercentage(containerBox); // If we're outside the container box less then we were on our last try // then remember this position as the best position. + if (percentage > p) { bestPosition = new BoxPosition(b); percentage = p; - } - // Reset the box position to the specified position. + } // Reset the box position to the specified position. + + b = new BoxPosition(specifiedPosition); } + return bestPosition || specifiedPosition; } var boxPosition = new BoxPosition(styleBox), cue = styleBox.cue, linePos = computeLinePos(cue), - axis = []; + axis = []; // If we have a line number to align the cue to. - // If we have a line number to align the cue to. if (cue.snapToLines) { var size; + switch (cue.vertical) { case "": axis = ["+y", "-y"]; size = "height"; break; + case "rl": axis = ["+x", "-x"]; size = "width"; break; + case "lr": axis = ["-x", "+x"]; size = "width"; @@ -8759,53 +9415,55 @@ var step = boxPosition.lineHeight, position = step * Math.round(linePos), maxPosition = containerBox[size] + step, - initialAxis = axis[0]; - - // If the specified intial position is greater then the max position then + initialAxis = axis[0]; // If the specified intial position is greater then the max position then // clamp the box to the amount of steps it would take for the box to // reach the max position. + if (Math.abs(position) > maxPosition) { position = position < 0 ? -1 : 1; position *= Math.ceil(maxPosition / step) * step; - } - - // If computed line position returns negative then line numbers are + } // If computed line position returns negative then line numbers are // relative to the bottom of the video instead of the top. Therefore, we // need to increase our initial position by the length or width of the // video, depending on the writing direction, and reverse our axis directions. + + if (linePos < 0) { position += cue.vertical === "" ? containerBox.height : containerBox.width; axis = axis.reverse(); - } - - // Move the box to the specified position. This may not be its best + } // Move the box to the specified position. This may not be its best // position. + + boxPosition.move(initialAxis, position); } else { // If we have a percentage line value for the cue. var calculatedPercentage = boxPosition.lineHeight / containerBox.height * 100; switch (cue.lineAlign) { - case "middle": + case "center": linePos -= calculatedPercentage / 2; break; + case "end": linePos -= calculatedPercentage; break; - } + } // Apply initial line position to the cue box. + - // Apply initial line position to the cue box. switch (cue.vertical) { case "": styleBox.applyStyles({ top: styleBox.formatStyle(linePos, "%") }); break; + case "rl": styleBox.applyStyles({ left: styleBox.formatStyle(linePos, "%") }); break; + case "lr": styleBox.applyStyles({ right: styleBox.formatStyle(linePos, "%") @@ -8813,10 +9471,9 @@ break; } - axis = ["+y", "-x", "+x", "-y"]; - - // Get the box position again after we've applied the specified positioning + axis = ["+y", "-x", "+x", "-y"]; // Get the box position again after we've applied the specified positioning // to it. + boxPosition = new BoxPosition(styleBox); } @@ -8824,20 +9481,21 @@ styleBox.move(bestPosition.toCSSCompatValues(containerBox)); } - function WebVTT$1() {} - // Nothing - - + function WebVTT$1() {} // Nothing // Helper to allow strings to be decoded instead of the default binary utf8 data. + + WebVTT$1.StringDecoder = function () { return { decode: function decode(data) { if (!data) { return ""; } + if (typeof data !== "string") { throw new Error("Error - expected string data."); } + return decodeURIComponent(encodeURIComponent(data)); } }; @@ -8847,22 +9505,22 @@ if (!window || !cuetext) { return null; } + return parseContent(window, cuetext); }; var FONT_SIZE_PERCENT = 0.05; var FONT_STYLE = "sans-serif"; - var CUE_BACKGROUND_PADDING = "1.5%"; - - // Runs the processing model over the cues and regions passed to it. + var CUE_BACKGROUND_PADDING = "1.5%"; // Runs the processing model over the cues and regions passed to it. // @param overlay A block level element (usually a div) that the computed cues // and regions will be placed into. + WebVTT$1.processCues = function (window, cues, overlay) { if (!window || !cues || !overlay) { return null; - } + } // Remove all previous children. + - // Remove all previous children. while (overlay.firstChild) { overlay.removeChild(overlay.firstChild); } @@ -8874,25 +9532,26 @@ paddedOverlay.style.top = "0"; paddedOverlay.style.bottom = "0"; paddedOverlay.style.margin = CUE_BACKGROUND_PADDING; - overlay.appendChild(paddedOverlay); - - // Determine if we need to compute the display states of the cues. This could + overlay.appendChild(paddedOverlay); // Determine if we need to compute the display states of the cues. This could // be the case if a cue's state has been changed since the last computation or // if it has not been computed yet. + function shouldCompute(cues) { for (var i = 0; i < cues.length; i++) { if (cues[i].hasBeenReset || !cues[i].displayState) { return true; } } - return false; - } - // We don't need to recompute the cues' display states. Just reuse them. + return false; + } // We don't need to recompute the cues' display states. Just reuse them. + + if (!shouldCompute(cues)) { for (var i = 0; i < cues.length; i++) { paddedOverlay.appendChild(cues[i].displayState); } + return; } @@ -8907,19 +9566,15 @@ var styleBox, cue; for (var i = 0; i < cues.length; i++) { - cue = cues[i]; + cue = cues[i]; // Compute the intial position and styles of the cue div. - // Compute the intial position and styles of the cue div. styleBox = new CueStyleBox(window, cue, styleOptions); - paddedOverlay.appendChild(styleBox.div); + paddedOverlay.appendChild(styleBox.div); // Move the cue div to it's correct line position. - // Move the cue div to it's correct line position. - moveBoxToLinePosition(window, styleBox, containerBox, boxPositions); - - // Remember the computed div so that we don't have to recompute it later + moveBoxToLinePosition(window, styleBox, containerBox, boxPositions); // Remember the computed div so that we don't have to recompute it later // if we don't have too. - cue.displayState = styleBox.div; + cue.displayState = styleBox.div; boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox)); } })(); @@ -8930,6 +9585,7 @@ decoder = vttjs; vttjs = {}; } + if (!vttjs) { vttjs = {}; } @@ -8953,74 +9609,85 @@ } }, parse: function parse(data) { - var self = this; - - // If there is no data then we won't decode it, but will just try to parse + var self = this; // If there is no data then we won't decode it, but will just try to parse // whatever is in buffer already. This may occur in circumstances, for // example when flush() is called. + if (data) { // Try to decode the data that we received. - self.buffer += self.decoder.decode(data, { stream: true }); + self.buffer += self.decoder.decode(data, { + stream: true + }); } function collectNextLine() { var buffer = self.buffer; var pos = 0; + while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') { ++pos; } - var line = buffer.substr(0, pos); - // Advance the buffer early in case we fail below. + + var line = buffer.substr(0, pos); // Advance the buffer early in case we fail below. + if (buffer[pos] === '\r') { ++pos; } + if (buffer[pos] === '\n') { ++pos; } + self.buffer = buffer.substr(pos); return line; - } + } // 3.4 WebVTT region and WebVTT region settings syntax + - // 3.4 WebVTT region and WebVTT region settings syntax function parseRegion(input) { var settings = new Settings(); - parseOptions(input, function (k, v) { switch (k) { case "id": settings.set(k, v); break; + case "width": settings.percent(k, v); break; + case "lines": settings.integer(k, v); break; + case "regionanchor": case "viewportanchor": var xy = v.split(','); + if (xy.length !== 2) { break; - } - // We have to make sure both x and y parse, so use a temporary + } // We have to make sure both x and y parse, so use a temporary // settings object here. + + var anchor = new Settings(); anchor.percent("x", xy[0]); anchor.percent("y", xy[1]); + if (!anchor.has("x") || !anchor.has("y")) { break; } + settings.set(k + "X", anchor.get("x")); settings.set(k + "Y", anchor.get("y")); break; + case "scroll": settings.alt(k, v, ["up"]); break; } - }, /=/, /\s/); - - // Create the region, using default values for any values that were not + }, /=/, /\s/); // Create the region, using default values for any values that were not // specified. + if (settings.has("id")) { var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)(); region.width = settings.get("width", 100); @@ -9029,42 +9696,41 @@ region.regionAnchorY = settings.get("regionanchorY", 100); region.viewportAnchorX = settings.get("viewportanchorX", 0); region.viewportAnchorY = settings.get("viewportanchorY", 100); - region.scroll = settings.get("scroll", ""); - // Register the region. - self.onregion && self.onregion(region); - // Remember the VTTRegion for later in case we parse any VTTCues that + region.scroll = settings.get("scroll", ""); // Register the region. + + self.onregion && self.onregion(region); // Remember the VTTRegion for later in case we parse any VTTCues that // reference it. + self.regionList.push({ id: settings.get("id"), region: region }); } - } - - // draft-pantos-http-live-streaming-20 + } // draft-pantos-http-live-streaming-20 // https://tools.ietf.org/html/draft-pantos-http-live-streaming-20#section-3.5 // 3.5 WebVTT + + function parseTimestampMap(input) { var settings = new Settings(); - parseOptions(input, function (k, v) { switch (k) { case "MPEGT": settings.integer(k + 'S', v); break; + case "LOCA": settings.set(k + 'L', parseTimeStamp(v)); break; } }, /[^\d]:/, /,/); - self.ontimestampmap && self.ontimestampmap({ "MPEGTS": settings.get("MPEGTS"), "LOCAL": settings.get("LOCAL") }); - } + } // 3.2 WebVTT metadata header syntax + - // 3.2 WebVTT metadata header syntax function parseHeader(input) { if (input.match(/X-TIMESTAMP-MAP/)) { // This line contains HLS X-TIMESTAMP-MAP metadata @@ -9085,11 +9751,12 @@ } }, /:/); } - } + } // 5.1 WebVTT file parsing. + - // 5.1 WebVTT file parsing. try { var line; + if (self.state === "INITIAL") { // We can't start parsing until we have the first line. if (!/\r\n|\n/.test(self.buffer)) { @@ -9097,8 +9764,8 @@ } line = collectNextLine(); - var m = line.match(/^WEBVTT([ \t].*)?$/); + if (!m || !m[0]) { throw new ParsingError(ParsingError.Errors.BadSignature); } @@ -9107,6 +9774,7 @@ } var alreadyCollectedLine = false; + while (self.buffer) { // We can't parse a line until we have the full line. if (!/\r\n|\n/.test(self.buffer)) { @@ -9128,51 +9796,69 @@ // An empty line terminates the header and starts the body (cues). self.state = "ID"; } + continue; + case "NOTE": // Ignore NOTE blocks. if (!line) { self.state = "ID"; } + continue; + case "ID": // Check for the start of NOTE blocks. if (/^NOTE($|[ \t])/.test(line)) { self.state = "NOTE"; break; - } - // 19-29 - Allow any number of line terminators, then initialize new cue values. + } // 19-29 - Allow any number of line terminators, then initialize new cue values. + + if (!line) { continue; } - self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, ""); - self.state = "CUE"; - // 30-39 - Check if self line contains an optional identifier or timing data. + + self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, ""); // Safari still uses the old middle value and won't accept center + + try { + self.cue.align = "center"; + } catch (e) { + self.cue.align = "middle"; + } + + self.state = "CUE"; // 30-39 - Check if self line contains an optional identifier or timing data. + if (line.indexOf("-->") === -1) { self.cue.id = line; continue; } + // Process line as start of a cue. + /*falls through*/ + case "CUE": // 40 - Collect cue timings and settings. try { parseCue(line, self.cue, self.regionList); } catch (e) { - self.reportOrThrowError(e); - // In case of an error ignore rest of the cue. + self.reportOrThrowError(e); // In case of an error ignore rest of the cue. + self.cue = null; self.state = "BADCUE"; continue; } + self.state = "CUETEXT"; continue; + case "CUETEXT": - var hasSubstring = line.indexOf("-->") !== -1; - // 34 - If we have an empty line then report the cue. + var hasSubstring = line.indexOf("-->") !== -1; // 34 - If we have an empty line then report the cue. // 35 - If we have the special substring '-->' then report the cue, // but do not collect the line as we need to process the current // one as a new cue. + if (!line || hasSubstring && (alreadyCollectedLine = true)) { // We are done parsing self cue. self.oncue && self.oncue(self.cue); @@ -9180,58 +9866,65 @@ self.state = "ID"; continue; } + if (self.cue.text) { self.cue.text += "\n"; } - self.cue.text += line; + + self.cue.text += line.replace(/\u2028/g, '\n').replace(/u2029/g, '\n'); continue; + case "BADCUE": // BADCUE // 54-62 - Collect and discard the remaining cue. if (!line) { self.state = "ID"; } + continue; } } } catch (e) { - self.reportOrThrowError(e); + self.reportOrThrowError(e); // If we are currently parsing a cue, report what we have. - // If we are currently parsing a cue, report what we have. if (self.state === "CUETEXT" && self.cue && self.oncue) { self.oncue(self.cue); } - self.cue = null; - // Enter BADWEBVTT state if header was not parsed correctly otherwise + + self.cue = null; // Enter BADWEBVTT state if header was not parsed correctly otherwise // another exception occurred so enter BADCUE state. + self.state = self.state === "INITIAL" ? "BADWEBVTT" : "BADCUE"; } + return this; }, flush: function flush() { var self = this; + try { // Finish decoding the stream. - self.buffer += self.decoder.decode(); - // Synthesize the end of the current cue or region. + self.buffer += self.decoder.decode(); // Synthesize the end of the current cue or region. + if (self.cue || self.state === "HEADER") { self.buffer += "\n\n"; self.parse(); - } - // If we've flushed, parsed, and we're still on the INITIAL state then + } // If we've flushed, parsed, and we're still on the INITIAL state then // that means we don't have enough of the stream to parse the first // line. + + if (self.state === "INITIAL") { throw new ParsingError(ParsingError.Errors.BadSignature); } } catch (e) { self.reportOrThrowError(e); } + self.onflush && self.onflush(); return this; } }; - var vtt = WebVTT$1; /** @@ -9249,7 +9942,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - var autoKeyword = "auto"; var directionSetting = { "": 1, @@ -9258,16 +9950,20 @@ }; var alignSetting = { "start": 1, - "middle": 1, + "center": 1, "end": 1, "left": 1, - "right": 1 + "right": 1, + "auto": 1, + "line-left": 1, + "line-right": 1 }; function findDirectionSetting(value) { if (typeof value !== "string") { return false; } + var dir = directionSetting[value.toLowerCase()]; return dir ? value.toLowerCase() : false; } @@ -9276,6 +9972,7 @@ if (typeof value !== "string") { return false; } + var align = alignSetting[value.toLowerCase()]; return align ? value.toLowerCase() : false; } @@ -9285,12 +9982,10 @@ * Shim implementation specific properties. These properties are not in * the spec. */ - // Lets us know when the VTTCue's data has changed in such a way that we need // to recompute its display state. This lets us compute its display state // lazily. this.hasBeenReset = false; - /** * VTTCue and TextTrackCue properties * http://dev.w3.org/html5/webvtt/#vttcue-interface @@ -9306,11 +10001,10 @@ var _snapToLines = true; var _line = "auto"; var _lineAlign = "start"; - var _position = 50; - var _positionAlign = "middle"; - var _size = 50; - var _align = "middle"; - + var _position = "auto"; + var _positionAlign = "auto"; + var _size = 100; + var _align = "center"; Object.defineProperties(this, { "id": { enumerable: true, @@ -9321,7 +10015,6 @@ _id = "" + value; } }, - "pauseOnExit": { enumerable: true, get: function get() { @@ -9331,7 +10024,6 @@ _pauseOnExit = !!value; } }, - "startTime": { enumerable: true, get: function get() { @@ -9341,11 +10033,11 @@ if (typeof value !== "number") { throw new TypeError("Start time must be set to a number."); } + _startTime = value; this.hasBeenReset = true; } }, - "endTime": { enumerable: true, get: function get() { @@ -9355,11 +10047,11 @@ if (typeof value !== "number") { throw new TypeError("End time must be set to a number."); } + _endTime = value; this.hasBeenReset = true; } }, - "text": { enumerable: true, get: function get() { @@ -9370,7 +10062,6 @@ this.hasBeenReset = true; } }, - "region": { enumerable: true, get: function get() { @@ -9381,23 +10072,22 @@ this.hasBeenReset = true; } }, - "vertical": { enumerable: true, get: function get() { return _vertical; }, set: function set(value) { - var setting = findDirectionSetting(value); - // Have to check for false because the setting an be an empty string. + var setting = findDirectionSetting(value); // Have to check for false because the setting an be an empty string. + if (setting === false) { - throw new SyntaxError("An invalid or illegal string was specified."); + throw new SyntaxError("Vertical: an invalid or illegal direction string was specified."); } + _vertical = setting; this.hasBeenReset = true; } }, - "snapToLines": { enumerable: true, get: function get() { @@ -9408,7 +10098,6 @@ this.hasBeenReset = true; } }, - "line": { enumerable: true, get: function get() { @@ -9416,13 +10105,13 @@ }, set: function set(value) { if (typeof value !== "number" && value !== autoKeyword) { - throw new SyntaxError("An invalid number or illegal string was specified."); + throw new SyntaxError("Line: an invalid number or illegal string was specified."); } + _line = value; this.hasBeenReset = true; } }, - "lineAlign": { enumerable: true, get: function get() { @@ -9430,14 +10119,15 @@ }, set: function set(value) { var setting = findAlignSetting(value); + if (!setting) { - throw new SyntaxError("An invalid or illegal string was specified."); + console.warn("lineAlign: an invalid or illegal string was specified."); + } else { + _lineAlign = setting; + this.hasBeenReset = true; } - _lineAlign = setting; - this.hasBeenReset = true; } }, - "position": { enumerable: true, get: function get() { @@ -9447,11 +10137,11 @@ if (value < 0 || value > 100) { throw new Error("Position must be between 0 and 100."); } + _position = value; this.hasBeenReset = true; } }, - "positionAlign": { enumerable: true, get: function get() { @@ -9459,14 +10149,15 @@ }, set: function set(value) { var setting = findAlignSetting(value); + if (!setting) { - throw new SyntaxError("An invalid or illegal string was specified."); + console.warn("positionAlign: an invalid or illegal string was specified."); + } else { + _positionAlign = setting; + this.hasBeenReset = true; } - _positionAlign = setting; - this.hasBeenReset = true; } }, - "size": { enumerable: true, get: function get() { @@ -9476,11 +10167,11 @@ if (value < 0 || value > 100) { throw new Error("Size must be between 0 and 100."); } + _size = value; this.hasBeenReset = true; } }, - "align": { enumerable: true, get: function get() { @@ -9488,27 +10179,28 @@ }, set: function set(value) { var setting = findAlignSetting(value); + if (!setting) { - throw new SyntaxError("An invalid or illegal string was specified."); + throw new SyntaxError("align: an invalid or illegal alignment string was specified."); } + _align = setting; this.hasBeenReset = true; } } }); - /** * Other spec defined properties */ - // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state + this.displayState = undefined; } - /** * VTTCue methods */ + VTTCue.prototype.getCueAsHTML = function () { // Assume WebVTT.convertCueToDOMTree is on the global. return WebVTT.convertCueToDOMTree(window, this.text); @@ -9531,7 +10223,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - var scrollSetting = { "": true, "up": true @@ -9541,15 +10232,16 @@ if (typeof value !== "string") { return false; } + var scroll = scrollSetting[value.toLowerCase()]; return scroll ? value.toLowerCase() : false; } function isValidPercentValue(value) { return typeof value === "number" && value >= 0 && value <= 100; - } + } // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface + - // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface function VTTRegion() { var _width = 100; var _lines = 3; @@ -9558,7 +10250,6 @@ var _viewportAnchorX = 0; var _viewportAnchorY = 100; var _scroll = ""; - Object.defineProperties(this, { "width": { enumerable: true, @@ -9569,6 +10260,7 @@ if (!isValidPercentValue(value)) { throw new Error("Width must be between 0 and 100."); } + _width = value; } }, @@ -9581,6 +10273,7 @@ if (typeof value !== "number") { throw new TypeError("Lines must be set to a number."); } + _lines = value; } }, @@ -9593,6 +10286,7 @@ if (!isValidPercentValue(value)) { throw new Error("RegionAnchorX must be between 0 and 100."); } + _regionAnchorY = value; } }, @@ -9605,6 +10299,7 @@ if (!isValidPercentValue(value)) { throw new Error("RegionAnchorY must be between 0 and 100."); } + _regionAnchorX = value; } }, @@ -9617,6 +10312,7 @@ if (!isValidPercentValue(value)) { throw new Error("ViewportAnchorY must be between 0 and 100."); } + _viewportAnchorY = value; } }, @@ -9629,6 +10325,7 @@ if (!isValidPercentValue(value)) { throw new Error("ViewportAnchorX must be between 0 and 100."); } + _viewportAnchorX = value; } }, @@ -9638,12 +10335,13 @@ return _scroll; }, set: function set(value) { - var setting = findScrollSetting(value); - // Have to check for false as an empty string is a legal value. + var setting = findScrollSetting(value); // Have to check for false as an empty string is a legal value. + if (setting === false) { - throw new SyntaxError("An invalid or illegal string was specified."); + console.warn("Scroll: an invalid or illegal string was specified."); + } else { + _scroll = setting; } - _scroll = setting; } } }); @@ -9667,38 +10365,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - // Default exports for Node. Export the extended versions of VTTCue and // VTTRegion in Node since we likely want the capability to convert back and // forth between JSON. If we don't then it's not that big of a deal since we're // off browser. - - var vttjs = module.exports = { WebVTT: vtt, VTTCue: vttcue, VTTRegion: vttregion }; - - window_1.vttjs = vttjs; - window_1.WebVTT = vttjs.WebVTT; - + window$1.vttjs = vttjs; + window$1.WebVTT = vttjs.WebVTT; var cueShim = vttjs.VTTCue; var regionShim = vttjs.VTTRegion; - var nativeVTTCue = window_1.VTTCue; - var nativeVTTRegion = window_1.VTTRegion; + var nativeVTTCue = window$1.VTTCue; + var nativeVTTRegion = window$1.VTTRegion; vttjs.shim = function () { - window_1.VTTCue = cueShim; - window_1.VTTRegion = regionShim; + window$1.VTTCue = cueShim; + window$1.VTTRegion = regionShim; }; vttjs.restore = function () { - window_1.VTTCue = nativeVTTCue; - window_1.VTTRegion = nativeVTTRegion; + window$1.VTTCue = nativeVTTCue; + window$1.VTTRegion = nativeVTTRegion; }; - if (!window_1.VTTCue) { + if (!window$1.VTTCue) { vttjs.shim(); } }); @@ -9706,10 +10399,6 @@ var browserIndex_2 = browserIndex.VTTCue; var browserIndex_3 = browserIndex.VTTRegion; - /** - * @file tech.js - */ - /** * An Object containing a structure like: `{src: 'url', type: 'mimetype'}` or string * that just contains the src url alone. @@ -9748,28 +10437,28 @@ * @return {TextTrack} * The text track that was created. */ - function createTrackHelper(self, kind, label, language) { - var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; + + function createTrackHelper(self, kind, label, language, options) { + if (options === void 0) { + options = {}; + } var tracks = self.textTracks(); - options.kind = kind; if (label) { options.label = label; } + if (language) { options.language = language; } + options.tech = self; - var track = new ALL.text.TrackClass(options); - tracks.addTrack(track); - return track; } - /** * This is the base class for media playback technology controllers, such as * {@link Flash} and {@link HTML5} @@ -9777,35 +10466,44 @@ * @extends Component */ - var Tech = function (_Component) { - inherits(Tech, _Component); + + var Tech = + /*#__PURE__*/ + function (_Component) { + inheritsLoose(Tech, _Component); /** - * Create an instance of this Tech. - * - * @param {Object} [options] - * The key/value store of player options. - * - * @param {Component~ReadyCallback} ready - * Callback function to call when the `HTML5` Tech is ready. - */ - function Tech() { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var ready = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {}; - classCallCheck(this, Tech); + * Create an instance of this Tech. + * + * @param {Object} [options] + * The key/value store of player options. + * + * @param {Component~ReadyCallback} ready + * Callback function to call when the `HTML5` Tech is ready. + */ + function Tech(options, ready) { + var _this; + + if (options === void 0) { + options = {}; + } + + if (ready === void 0) { + ready = function ready() {}; + } // we don't want the tech to report user activity automatically. // This is done manually in addControlsListeners options.reportTouchActivity = false; - - // keep track of whether the current source has played at all to + _this = _Component.call(this, null, options, ready) || this; // keep track of whether the current source has played at all to // implement a very limited played() - var _this = possibleConstructorReturn(this, _Component.call(this, null, options, ready)); _this.hasStarted_ = false; + _this.on('playing', function () { this.hasStarted_ = true; }); + _this.on('loadstart', function () { this.hasStarted_ = false; }); @@ -9816,21 +10514,20 @@ if (options && options[props.getterName]) { _this[props.privateName] = options[props.getterName]; } - }); + }); // Manually track progress in cases where the browser/flash player doesn't report it. - // Manually track progress in cases where the browser/flash player doesn't report it. if (!_this.featuresProgressEvents) { _this.manualProgressOn(); - } + } // Manually track timeupdates in cases where the browser/flash player doesn't report it. + - // Manually track timeupdates in cases where the browser/flash player doesn't report it. if (!_this.featuresTimeupdateEvents) { _this.manualTimeUpdatesOn(); } ['Text', 'Audio', 'Video'].forEach(function (track) { - if (options['native' + track + 'Tracks'] === false) { - _this['featuresNative' + track + 'Tracks'] = false; + if (options["native" + track + "Tracks"] === false) { + _this["featuresNative" + track + "Tracks"] = false; } }); @@ -9844,11 +10541,12 @@ _this.emulateTextTracks(); } + _this.preloadTextTracks = options.preloadTextTracks !== false; _this.autoRemoteTextTracks_ = new ALL.text.ListClass(); - _this.initTrackListeners(); + _this.initTrackListeners(); // Turn on component tap events only if not using native controls + - // Turn on component tap events only if not using native controls if (!options.nativeControlsForTouch) { _this.emitTapEvents(); } @@ -9856,9 +10554,9 @@ if (_this.constructor) { _this.name_ = _this.constructor.name || 'Unknown Tech'; } + return _this; } - /** * A special function to trigger source set in a way that will allow player * to re-trigger if the player or tech are not ready yet. @@ -9868,7 +10566,9 @@ */ - Tech.prototype.triggerSourceset = function triggerSourceset(src) { + var _proto = Tech.prototype; + + _proto.triggerSourceset = function triggerSourceset(src) { var _this2 = this; if (!this.isReady_) { @@ -9880,7 +10580,6 @@ }, 1); }); } - /** * Fired when the source is set on the tech causing the media element * to reload. @@ -9889,12 +10588,13 @@ * @event Tech#sourceset * @type {EventTarget~Event} */ + + this.trigger({ src: src, type: 'sourceset' }); - }; - + } /* Fallbacks for unsupported event types ================================================================================ */ @@ -9903,30 +10603,25 @@ * * @see {@link Tech#trackProgress} */ + ; - - Tech.prototype.manualProgressOn = function manualProgressOn() { + _proto.manualProgressOn = function manualProgressOn() { this.on('durationchange', this.onDurationChange); + this.manualProgress = true; // Trigger progress watching when a source begins loading - this.manualProgress = true; - - // Trigger progress watching when a source begins loading this.one('ready', this.trackProgress); - }; - + } /** * Turn off the polyfill for `progress` events that was created in * {@link Tech#manualProgressOn} */ + ; - - Tech.prototype.manualProgressOff = function manualProgressOff() { + _proto.manualProgressOff = function manualProgressOff() { this.manualProgress = false; this.stopTrackingProgress(); - this.off('durationchange', this.onDurationChange); - }; - + } /** * This is used to trigger a `progress` event when the buffered percent changes. It * sets an interval function that will be called every 500 milliseconds to check if the @@ -9940,13 +10635,12 @@ * @listens Tech#ready * @fires Tech#progress */ + ; - - Tech.prototype.trackProgress = function trackProgress(event) { + _proto.trackProgress = function trackProgress(event) { this.stopTrackingProgress(); this.progressInterval = this.setInterval(bind(this, function () { // Don't trigger unless buffered amount is greater than last time - var numBufferedPercent = this.bufferedPercent(); if (this.bufferedPercent_ !== numBufferedPercent) { @@ -9965,8 +10659,7 @@ this.stopTrackingProgress(); } }), 500); - }; - + } /** * Update our internal duration on a `durationchange` event by calling * {@link Tech#duration}. @@ -9976,24 +10669,22 @@ * * @listens Tech#durationchange */ + ; - - Tech.prototype.onDurationChange = function onDurationChange(event) { + _proto.onDurationChange = function onDurationChange(event) { this.duration_ = this.duration(); - }; - + } /** * Get and create a `TimeRange` object for buffering. * * @return {TimeRange} * The time range object that was created. */ + ; - - Tech.prototype.buffered = function buffered() { + _proto.buffered = function buffered() { return createTimeRanges(0, 0); - }; - + } /** * Get the percentage of the current video that is currently buffered. * @@ -10002,51 +10693,46 @@ * video that is buffered. * */ + ; - - Tech.prototype.bufferedPercent = function bufferedPercent$$1() { + _proto.bufferedPercent = function bufferedPercent$1() { return bufferedPercent(this.buffered(), this.duration_); - }; - + } /** * Turn off the polyfill for `progress` events that was created in * {@link Tech#manualProgressOn} * Stop manually tracking progress events by clearing the interval that was set in * {@link Tech#trackProgress}. */ + ; - - Tech.prototype.stopTrackingProgress = function stopTrackingProgress() { + _proto.stopTrackingProgress = function stopTrackingProgress() { this.clearInterval(this.progressInterval); - }; - + } /** * Polyfill the `timeupdate` event for browsers that don't support it. * * @see {@link Tech#trackCurrentTime} */ + ; - - Tech.prototype.manualTimeUpdatesOn = function manualTimeUpdatesOn() { + _proto.manualTimeUpdatesOn = function manualTimeUpdatesOn() { this.manualTimeUpdates = true; - this.on('play', this.trackCurrentTime); this.on('pause', this.stopTrackingCurrentTime); - }; - + } /** * Turn off the polyfill for `timeupdate` events that was created in * {@link Tech#manualTimeUpdatesOn} */ + ; - - Tech.prototype.manualTimeUpdatesOff = function manualTimeUpdatesOff() { + _proto.manualTimeUpdatesOff = function manualTimeUpdatesOff() { this.manualTimeUpdates = false; this.stopTrackingCurrentTime(); this.off('play', this.trackCurrentTime); this.off('pause', this.stopTrackingCurrentTime); - }; - + } /** * Sets up an interval function to track current time and trigger `timeupdate` every * 250 milliseconds. @@ -10054,12 +10740,13 @@ * @listens Tech#play * @triggers Tech#timeupdate */ + ; - - Tech.prototype.trackCurrentTime = function trackCurrentTime() { + _proto.trackCurrentTime = function trackCurrentTime() { if (this.currentTimeInterval) { this.stopTrackingCurrentTime(); } + this.currentTimeInterval = this.setInterval(function () { /** * Triggered at an interval of 250ms to indicated that time is passing in the video. @@ -10067,42 +10754,43 @@ * @event Tech#timeupdate * @type {EventTarget~Event} */ - this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); - - // 42 = 24 fps // 250 is what Webkit uses // FF uses 15 + this.trigger({ + type: 'timeupdate', + target: this, + manuallyTriggered: true + }); // 42 = 24 fps // 250 is what Webkit uses // FF uses 15 }, 250); - }; - + } /** * Stop the interval function created in {@link Tech#trackCurrentTime} so that the * `timeupdate` event is no longer triggered. * * @listens {Tech#pause} */ + ; - - Tech.prototype.stopTrackingCurrentTime = function stopTrackingCurrentTime() { - this.clearInterval(this.currentTimeInterval); - - // #1002 - if the video ends right before the next timeupdate would happen, + _proto.stopTrackingCurrentTime = function stopTrackingCurrentTime() { + this.clearInterval(this.currentTimeInterval); // #1002 - if the video ends right before the next timeupdate would happen, // the progress bar won't make it all the way to the end - this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); - }; + this.trigger({ + type: 'timeupdate', + target: this, + manuallyTriggered: true + }); + } /** * Turn off all event polyfills, clear the `Tech`s {@link AudioTrackList}, * {@link VideoTrackList}, and {@link TextTrackList}, and dispose of this Tech. * * @fires Component#dispose */ + ; - - Tech.prototype.dispose = function dispose() { - + _proto.dispose = function dispose() { // clear out all tracks because we can't reuse them between techs - this.clearTracks(NORMAL.names); + this.clearTracks(NORMAL.names); // Turn off any manual progress or timeupdate tracking - // Turn off any manual progress or timeupdate tracking if (this.manualProgress) { this.manualProgressOff(); } @@ -10112,8 +10800,7 @@ } _Component.prototype.dispose.call(this); - }; - + } /** * Clear out a single `TrackList` or an array of `TrackLists` given their names. * @@ -10124,15 +10811,15 @@ * TrackList names to clear, valid names are `video`, `audio`, and * `text`. */ + ; - - Tech.prototype.clearTracks = function clearTracks(types) { + _proto.clearTracks = function clearTracks(types) { var _this3 = this; - types = [].concat(types); - // clear out all tracks because we can't reuse them between techs + types = [].concat(types); // clear out all tracks because we can't reuse them between techs + types.forEach(function (type) { - var list = _this3[type + 'Tracks']() || []; + var list = _this3[type + "Tracks"]() || []; var i = list.length; while (i--) { @@ -10141,37 +10828,34 @@ if (type === 'text') { _this3.removeRemoteTextTrack(track); } + list.removeTrack(track); } }); - }; - + } /** * Remove any TextTracks added via addRemoteTextTrack that are * flagged for automatic garbage collection */ + ; - - Tech.prototype.cleanupAutoTextTracks = function cleanupAutoTextTracks() { + _proto.cleanupAutoTextTracks = function cleanupAutoTextTracks() { var list = this.autoRemoteTextTracks_ || []; var i = list.length; while (i--) { var track = list[i]; - this.removeRemoteTextTrack(track); } - }; - + } /** * Reset the tech, which will removes all sources and reset the internal readyState. * * @abstract */ + ; - - Tech.prototype.reset = function reset() {}; - + _proto.reset = function reset() {} /** * Get or set an error on the Tech. * @@ -10181,16 +10865,16 @@ * @return {MediaError|null} * The current error object on the tech, or null if there isn't one. */ + ; - - Tech.prototype.error = function error(err) { + _proto.error = function error(err) { if (err !== undefined) { this.error_ = new MediaError(err); this.trigger('error'); } - return this.error_; - }; + return this.error_; + } /** * Returns the `TimeRange`s that have been played through for the current source. * @@ -10201,24 +10885,24 @@ * - A single time range if this video has played * - An empty set of ranges if not. */ + ; - - Tech.prototype.played = function played() { + _proto.played = function played() { if (this.hasStarted_) { return createTimeRanges(0, 0); } - return createTimeRanges(); - }; + return createTimeRanges(); + } /** * Causes a manual time update to occur if {@link Tech#manualTimeUpdatesOn} was * previously called. * * @fires Tech#timeupdate */ + ; - - Tech.prototype.setCurrentTime = function setCurrentTime() { + _proto.setCurrentTime = function setCurrentTime() { // improve the accuracy of manual timeupdates if (this.manualTimeUpdates) { /** @@ -10227,10 +10911,13 @@ * @event Tech#timeupdate * @type {EventTarget~Event} */ - this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); + this.trigger({ + type: 'timeupdate', + target: this, + manuallyTriggered: true + }); } - }; - + } /** * Turn on listeners for {@link VideoTrackList}, {@link {AudioTrackList}, and * {@link TextTrackList} events. @@ -10241,35 +10928,36 @@ * @fires Tech#videotrackchange * @fires Tech#texttrackchange */ + ; - - Tech.prototype.initTrackListeners = function initTrackListeners() { + _proto.initTrackListeners = function initTrackListeners() { var _this4 = this; /** - * Triggered when tracks are added or removed on the Tech {@link AudioTrackList} - * - * @event Tech#audiotrackchange - * @type {EventTarget~Event} - */ + * Triggered when tracks are added or removed on the Tech {@link AudioTrackList} + * + * @event Tech#audiotrackchange + * @type {EventTarget~Event} + */ /** - * Triggered when tracks are added or removed on the Tech {@link VideoTrackList} - * - * @event Tech#videotrackchange - * @type {EventTarget~Event} - */ + * Triggered when tracks are added or removed on the Tech {@link VideoTrackList} + * + * @event Tech#videotrackchange + * @type {EventTarget~Event} + */ /** - * Triggered when tracks are added or removed on the Tech {@link TextTrackList} - * - * @event Tech#texttrackchange - * @type {EventTarget~Event} - */ + * Triggered when tracks are added or removed on the Tech {@link TextTrackList} + * + * @event Tech#texttrackchange + * @type {EventTarget~Event} + */ NORMAL.names.forEach(function (name) { var props = NORMAL[name]; + var trackListChanges = function trackListChanges() { - _this4.trigger(name + 'trackchange'); + _this4.trigger(name + "trackchange"); }; var tracks = _this4[props.getterName](); @@ -10282,41 +10970,39 @@ tracks.removeEventListener('addtrack', trackListChanges); }); }); - }; - + } /** * Emulate TextTracks using vtt.js if necessary * * @fires Tech#vttjsloaded * @fires Tech#vttjserror */ + ; - - Tech.prototype.addWebVttScript_ = function addWebVttScript_() { + _proto.addWebVttScript_ = function addWebVttScript_() { var _this5 = this; - if (window_1.WebVTT) { + if (window$1.WebVTT) { return; - } - - // Initially, Tech.el_ is a child of a dummy-div wait until the Component system + } // Initially, Tech.el_ is a child of a dummy-div wait until the Component system // signals that the Tech is ready at which point Tech.el_ is part of the DOM // before inserting the WebVTT script - if (document_1.body.contains(this.el())) { + + if (document.body.contains(this.el())) { // load via require if available and vtt.js script location was not passed in // as an option. novtt builds will turn the above require call into an empty object // which will cause this if check to always fail. if (!this.options_['vtt.js'] && isPlain(browserIndex) && Object.keys(browserIndex).length > 0) { this.trigger('vttjsloaded'); return; - } - - // load vtt.js via the script location option or the cdn of no location was + } // load vtt.js via the script location option or the cdn of no location was // passed in - var script = document_1.createElement('script'); + + var script = document.createElement('script'); script.src = this.options_['vtt.js'] || 'https://vjs.zencdn.net/vttjs/0.14.1/vtt.min.js'; + script.onload = function () { /** * Fired when vtt.js is loaded. @@ -10326,6 +11012,7 @@ */ _this5.trigger('vttjsloaded'); }; + script.onerror = function () { /** * Fired when vtt.js was not loaded due to an error @@ -10335,40 +11022,41 @@ */ _this5.trigger('vttjserror'); }; + this.on('dispose', function () { script.onload = null; script.onerror = null; - }); - // but have not loaded yet and we set it to true before the inject so that + }); // but have not loaded yet and we set it to true before the inject so that // we don't overwrite the injected window.WebVTT if it loads right away - window_1.WebVTT = true; + + window$1.WebVTT = true; this.el().parentNode.appendChild(script); } else { this.ready(this.addWebVttScript_); } - }; - + } /** * Emulate texttracks * */ + ; - - Tech.prototype.emulateTextTracks = function emulateTextTracks() { + _proto.emulateTextTracks = function emulateTextTracks() { var _this6 = this; var tracks = this.textTracks(); var remoteTracks = this.remoteTextTracks(); + var handleAddTrack = function handleAddTrack(e) { return tracks.addTrack(e.track); }; + var handleRemoveTrack = function handleRemoveTrack(e) { return tracks.removeTrack(e.track); }; remoteTracks.on('addtrack', handleAddTrack); remoteTracks.on('removetrack', handleRemoveTrack); - this.addWebVttScript_(); var updateDisplay = function updateDisplay() { @@ -10380,8 +11068,8 @@ for (var i = 0; i < tracks.length; i++) { var track = tracks[i]; - track.removeEventListener('cuechange', updateDisplay); + if (track.mode === 'showing') { track.addEventListener('cuechange', updateDisplay); } @@ -10392,7 +11080,6 @@ tracks.addEventListener('change', textTracksChanges); tracks.addEventListener('addtrack', textTracksChanges); tracks.addEventListener('removetrack', textTracksChanges); - this.on('dispose', function () { remoteTracks.off('addtrack', handleAddTrack); remoteTracks.off('removetrack', handleRemoveTrack); @@ -10402,12 +11089,10 @@ for (var i = 0; i < tracks.length; i++) { var track = tracks[i]; - track.removeEventListener('cuechange', updateDisplay); } }); - }; - + } /** * Create and returns a remote {@link TextTrack} object. * @@ -10423,16 +11108,15 @@ * @return {TextTrack} * The TextTrack that gets created. */ + ; - - Tech.prototype.addTextTrack = function addTextTrack(kind, label, language) { + _proto.addTextTrack = function addTextTrack(kind, label, language) { if (!kind) { throw new Error('TextTrack kind is required but was not provided'); } return createTrackHelper(this, kind, label, language); - }; - + } /** * Create an emulated TextTrack for use by addRemoteTextTrack * @@ -10454,16 +11138,14 @@ * @return {HTMLTrackElement} * The track element that gets created. */ + ; - - Tech.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) { + _proto.createRemoteTextTrack = function createRemoteTextTrack(options) { var track = mergeOptions(options, { tech: this }); - return new REMOTE.remoteTextEl.TrackClass(track); - }; - + } /** * Creates a remote text track object and returns an html track element. * @@ -10484,23 +11166,24 @@ * to "manualCleanup=false" in the future. The manualCleanup parameter will * also be removed. */ + ; - - Tech.prototype.addRemoteTextTrack = function addRemoteTextTrack() { + _proto.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) { var _this7 = this; - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var manualCleanup = arguments[1]; + if (options === void 0) { + options = {}; + } var htmlTrackElement = this.createRemoteTextTrack(options); if (manualCleanup !== true && manualCleanup !== false) { // deprecation warning - log$1.warn('Calling addRemoteTextTrack without explicitly setting the "manualCleanup" parameter to `true` is deprecated and default to `false` in future version of video.js'); + log.warn('Calling addRemoteTextTrack without explicitly setting the "manualCleanup" parameter to `true` is deprecated and default to `false` in future version of video.js'); manualCleanup = true; - } + } // store HTMLTrackElement and TextTrack to remote list + - // store HTMLTrackElement and TextTrack to remote list this.remoteTextTrackEls().addTrackElement_(htmlTrackElement); this.remoteTextTracks().addTrack(htmlTrackElement.track); @@ -10512,25 +11195,22 @@ } return htmlTrackElement; - }; - + } /** * Remove a remote text track from the remote `TextTrackList`. * * @param {TextTrack} track * `TextTrack` to remove from the `TextTrackList` */ + ; + _proto.removeRemoteTextTrack = function removeRemoteTextTrack(track) { + var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track); // remove HTMLTrackElement and TextTrack from remote list - Tech.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) { - var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track); - - // remove HTMLTrackElement and TextTrack from remote list this.remoteTextTrackEls().removeTrackElement_(trackElement); this.remoteTextTracks().removeTrack(track); this.autoRemoteTextTracks_.removeTrack(track); - }; - + } /** * Gets available media playback quality metrics as specified by the W3C's Media * Playback Quality API. @@ -10542,63 +11222,80 @@ * * @abstract */ + ; - - Tech.prototype.getVideoPlaybackQuality = function getVideoPlaybackQuality() { + _proto.getVideoPlaybackQuality = function getVideoPlaybackQuality() { return {}; - }; + } + /** + * Attempt to create a floating video window always on top of other windows + * so that users may continue consuming media while they interact with other + * content sites, or applications on their device. + * + * @see [Spec]{@link https://wicg.github.io/picture-in-picture} + * + * @return {Promise|undefined} + * A promise with a Picture-in-Picture window if the browser supports + * Promises (or one was passed in as an option). It returns undefined + * otherwise. + * + * @abstract + */ + ; + _proto.requestPictureInPicture = function requestPictureInPicture() { + var PromiseClass = this.options_.Promise || window$1.Promise; + + if (PromiseClass) { + return PromiseClass.reject(); + } + } /** * A method to set a poster from a `Tech`. * * @abstract */ + ; - - Tech.prototype.setPoster = function setPoster() {}; - + _proto.setPoster = function setPoster() {} /** * A method to check for the presence of the 'playsinline'