UNPKG

45.2 kBJavaScriptView Raw
1/*! @name @brightcove/react-player-loader @version 1.4.2 @license Apache-2.0 */
2import React from 'react';
3import document from 'global/document';
4import window from 'global/window';
5
6function _extends() {
7 _extends = Object.assign || function (target) {
8 for (var i = 1; i < arguments.length; i++) {
9 var source = arguments[i];
10
11 for (var key in source) {
12 if (Object.prototype.hasOwnProperty.call(source, key)) {
13 target[key] = source[key];
14 }
15 }
16 }
17
18 return target;
19 };
20
21 return _extends.apply(this, arguments);
22}
23
24function _inheritsLoose(subClass, superClass) {
25 subClass.prototype = Object.create(superClass.prototype);
26 subClass.prototype.constructor = subClass;
27 subClass.__proto__ = superClass;
28}
29
30function _assertThisInitialized(self) {
31 if (self === void 0) {
32 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
33 }
34
35 return self;
36}
37
38/*! @name @brightcove/player-loader @version 1.8.0 @license Apache-2.0 */
39
40function _extends$1() {
41 _extends$1 = Object.assign || function (target) {
42 for (var i = 1; i < arguments.length; i++) {
43 var source = arguments[i];
44
45 for (var key in source) {
46 if (Object.prototype.hasOwnProperty.call(source, key)) {
47 target[key] = source[key];
48 }
49 }
50 }
51
52 return target;
53 };
54
55 return _extends$1.apply(this, arguments);
56}
57
58var version = "1.8.0";
59
60/*! @name @brightcove/player-url @version 1.2.0 @license Apache-2.0 */
61var version$1 = "1.2.0";
62
63var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
64 return typeof obj;
65} : function (obj) {
66 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
67};
68
69// The parameters that may include JSON.
70var JSON_ALLOWED_PARAMS = ['catalogSearch', 'catalogSequence'];
71
72// The parameters that may be set as query string parameters for iframes.
73var IFRAME_ALLOWED_QUERY_PARAMS = ['adConfigId', 'applicationId', 'catalogSearch', 'catalogSequence', 'playlistId', 'playlistVideoId', 'videoId'];
74
75/**
76 * Gets the value of a parameter and encodes it as a string.
77 *
78 * For certain keys, JSON is allowed and will be encoded.
79 *
80 * @private
81 * @param {Object} params
82 * A parameters object. See README for details.
83 *
84 * @param {string} key
85 * The key in the params object.
86 *
87 * @return {string|undefined}
88 * The encoded value - or `undefined` if none.
89 */
90var getQueryParamValue = function getQueryParamValue(params, key) {
91
92 if (!params || params[key] === undefined) {
93 return;
94 }
95
96 // If it's not a string, such as with a catalog search or sequence, we
97 // try to encode it as JSON.
98 if (typeof params[key] !== 'string' && JSON_ALLOWED_PARAMS.indexOf(key) !== -1) {
99 try {
100 return encodeURIComponent(JSON.stringify(params[key]));
101 } catch (x) {
102
103 // If it's not a string and we can't encode as JSON, it's ignored entirely.
104 return;
105 }
106 }
107
108 return encodeURIComponent(String(params[key]).trim()) || undefined;
109};
110
111/**
112 * In some cases, we need to add query string parameters to an iframe URL.
113 *
114 * @private
115 * @param {Object} params
116 * An object of query parameters.
117 *
118 * @return {string}
119 * A query string starting with `?`. If no valid parameters are given,
120 * returns an empty string.
121 */
122var getQueryString = function getQueryString(params) {
123 return Object.keys(params).filter(function (k) {
124 return IFRAME_ALLOWED_QUERY_PARAMS.indexOf(k) !== -1;
125 }).reduce(function (qs, k) {
126 var value = getQueryParamValue(params, k);
127
128 if (value !== undefined) {
129 qs += qs ? '&' : '?';
130 qs += encodeURIComponent(k) + '=' + value;
131 }
132
133 return qs;
134 }, '');
135};
136
137/**
138 * Generate a URL to a Brightcove Player.
139 *
140 * @param {Object} params
141 * A set of parameters describing the player URL to create.
142 *
143 * @param {string} params.accountId
144 * A Brightcove account ID.
145 *
146 * @param {string} [params.playerId="default"]
147 * A Brightcove player ID.
148 *
149 * @param {string} [params.embedId="default"]
150 * A Brightcove player embed ID.
151 *
152 * @param {boolean} [params.iframe=false]
153 * Whether to return a URL for an HTML document to be embedded in
154 * an iframe.
155 *
156 * @param {boolean} [params.minified=true]
157 * When the `iframe` argument is `false`, this can be used to control
158 * whether the minified or unminified JavaScript URL is returned.
159 *
160 * @param {string} [params.base="https://players.brightcove.net"]
161 * A base CDN protocol and hostname. Mainly used for testing.
162 *
163 * @return {string}
164 * A URL to a Brightcove Player.
165 */
166var brightcovePlayerUrl = function brightcovePlayerUrl(_ref) {
167 var accountId = _ref.accountId,
168 _ref$base = _ref.base,
169 base = _ref$base === undefined ? 'https://players.brightcove.net' : _ref$base,
170 _ref$playerId = _ref.playerId,
171 playerId = _ref$playerId === undefined ? 'default' : _ref$playerId,
172 _ref$embedId = _ref.embedId,
173 embedId = _ref$embedId === undefined ? 'default' : _ref$embedId,
174 _ref$iframe = _ref.iframe,
175 iframe = _ref$iframe === undefined ? false : _ref$iframe,
176 _ref$minified = _ref.minified,
177 minified = _ref$minified === undefined ? true : _ref$minified,
178 _ref$queryParams = _ref.queryParams,
179 queryParams = _ref$queryParams === undefined ? null : _ref$queryParams;
180
181 var ext = '';
182
183 if (iframe) {
184 ext += 'html';
185 } else {
186 if (minified) {
187 ext += 'min.';
188 }
189 ext += 'js';
190 }
191
192 if (base.charAt(base.length - 1) === '/') {
193 base = base.substring(0, base.length - 1);
194 }
195
196 var qs = '';
197
198 if (iframe && queryParams && (typeof queryParams === 'undefined' ? 'undefined' : _typeof(queryParams)) === 'object') {
199 qs = getQueryString(queryParams);
200 }
201
202 accountId = encodeURIComponent(accountId);
203 playerId = encodeURIComponent(playerId);
204 embedId = encodeURIComponent(embedId);
205
206 return base + '/' + accountId + '/' + playerId + '_' + embedId + '/index.' + ext + qs;
207};
208
209/**
210 * The version of this module.
211 *
212 * @type {string}
213 */
214brightcovePlayerUrl.VERSION = version$1;
215
216var DEFAULTS = {
217 embedId: 'default',
218 embedType: 'in-page',
219 playerId: 'default',
220 Promise: window.Promise,
221 refNodeInsert: 'append'
222};
223var DEFAULT_ASPECT_RATIO = '16:9';
224var DEFAULT_IFRAME_HORIZONTAL_PLAYLIST = false;
225var DEFAULT_MAX_WIDTH = '100%';
226var EMBED_TAG_NAME_VIDEO = 'video';
227var EMBED_TAG_NAME_VIDEOJS = 'video-js';
228var EMBED_TYPE_IN_PAGE = 'in-page';
229var EMBED_TYPE_IFRAME = 'iframe';
230var REF_NODE_INSERT_APPEND = 'append';
231var REF_NODE_INSERT_PREPEND = 'prepend';
232var REF_NODE_INSERT_BEFORE = 'before';
233var REF_NODE_INSERT_AFTER = 'after';
234var REF_NODE_INSERT_REPLACE = 'replace';
235var JSON_ALLOWED_ATTRS = ['catalogSearch', 'catalogSequence'];
236
237var BASE_URL = 'https://players.brightcove.net/';
238/**
239 * Gets the URL to a player on CDN.
240 *
241 * @private
242 * @param {Object} params
243 * A parameters object. See README for details.
244 *
245 * @return {string}
246 * A URL.
247 */
248
249var getUrl = function getUrl(params) {
250 if (params.playerUrl) {
251 return params.playerUrl;
252 }
253
254 var accountId = params.accountId,
255 playerId = params.playerId,
256 embedId = params.embedId,
257 embedOptions = params.embedOptions;
258 var iframe = params.embedType === EMBED_TYPE_IFRAME;
259 return brightcovePlayerUrl({
260 accountId: accountId,
261 playerId: playerId,
262 embedId: embedId,
263 iframe: iframe,
264 base: BASE_URL,
265 // The unminified embed option is the exact reverse of the minified option
266 // here.
267 minified: embedOptions ? !embedOptions.unminified : true,
268 // Pass the entire params object as query params. This is safe because
269 // @brightcove/player-url only accepts a whitelist of parameters. Anything
270 // else will be ignored.
271 queryParams: params
272 });
273};
274/**
275 * Function used to get the base URL - primarily for testing.
276 *
277 * @private
278 * @return {string}
279 * The current base URL.
280 */
281
282
283var getBaseUrl = function getBaseUrl() {
284 return BASE_URL;
285};
286/**
287 * Function used to set the base URL - primarily for testing.
288 *
289 * @private
290 * @param {string} baseUrl
291 * A new base URL (instead of Brightcove CDN).
292 */
293
294
295var setBaseUrl = function setBaseUrl(baseUrl) {
296 BASE_URL = baseUrl;
297};
298
299var urls = {
300 getUrl: getUrl,
301 getBaseUrl: getBaseUrl,
302 setBaseUrl: setBaseUrl
303};
304
305/**
306 * Is this value an element?
307 *
308 * @param {Element} el
309 * A maybe element.
310 *
311 * @return {boolean}
312 * Whether or not the value is a element.
313 */
314
315var isEl = function isEl(el) {
316 return Boolean(el && el.nodeType === 1);
317};
318/**
319 * Is this value an element with a parent node?
320 *
321 * @param {Element} el
322 * A maybe element.
323 *
324 * @return {boolean}
325 * Whether or not the value is a element with a parent node.
326 */
327
328
329var isElInDom = function isElInDom(el) {
330 return Boolean(isEl(el) && el.parentNode);
331};
332/**
333 * Creates an iframe embed code.
334 *
335 * @private
336 * @param {Object} params
337 * A parameters object. See README for details.
338 *
339 * @return {Element}
340 * The DOM element that will ultimately be passed to the `bc()` function.
341 */
342
343
344var createIframeEmbed = function createIframeEmbed(params) {
345 var el = document.createElement('iframe');
346 el.setAttribute('allow', 'autoplay;encrypted-media;fullscreen');
347 el.setAttribute('allowfullscreen', 'allowfullscreen');
348 el.src = urls.getUrl(params);
349 return el;
350};
351/**
352 * Creates an in-page embed code.
353 *
354 * @private
355 * @param {Object} params
356 * A parameters object. See README for details.
357 *
358 * @return {Element}
359 * The DOM element that will ultimately be passed to the `bc()` function.
360 */
361
362
363var createInPageEmbed = function createInPageEmbed(params) {
364 var embedOptions = params.embedOptions; // We DO NOT include the data-account, data-player, or data-embed attributes
365 // here because we will be manually initializing the player.
366
367 var paramsToAttrs = {
368 adConfigId: 'data-ad-config-id',
369 applicationId: 'data-application-id',
370 catalogSearch: 'data-catalog-search',
371 catalogSequence: 'data-catalog-sequence',
372 deliveryConfigId: 'data-delivery-config-id',
373 playlistId: 'data-playlist-id',
374 playlistVideoId: 'data-playlist-video-id',
375 poster: 'poster',
376 videoId: 'data-video-id'
377 };
378 var tagName = embedOptions && embedOptions.tagName || EMBED_TAG_NAME_VIDEOJS;
379 var el = document.createElement(tagName);
380 Object.keys(paramsToAttrs).filter(function (key) {
381 return params[key];
382 }).forEach(function (key) {
383 var value; // If it's not a string, such as with a catalog search or sequence, we
384 // try to encode it as JSON.
385
386 if (typeof params[key] !== 'string' && JSON_ALLOWED_ATTRS.indexOf(key) !== -1) {
387 try {
388 value = JSON.stringify(params[key]); // If it fails, don't set anything.
389 } catch (x) {
390 return;
391 }
392 } else {
393 value = String(params[key]).trim();
394 }
395
396 el.setAttribute(paramsToAttrs[key], value);
397 });
398 el.setAttribute('controls', 'controls');
399 el.classList.add('video-js');
400 return el;
401};
402/**
403 * Wraps an element in responsive intrinsic ratio elements.
404 *
405 * @private
406 * @param {string} embedType
407 * The type of the embed.
408 *
409 * @param {Object} embedOptions
410 * Embed options from the params.
411 *
412 * @param {Element} el
413 * The DOM element.
414 *
415 * @return {Element}
416 * A new element (if needed).
417 */
418
419
420var wrapResponsive = function wrapResponsive(embedType, embedOptions, el) {
421 if (!embedOptions.responsive) {
422 return el;
423 }
424
425 el.style.position = 'absolute';
426 el.style.top = '0px';
427 el.style.right = '0px';
428 el.style.bottom = '0px';
429 el.style.left = '0px';
430 el.style.width = '100%';
431 el.style.height = '100%';
432
433 var responsive = _extends$1({
434 aspectRatio: DEFAULT_ASPECT_RATIO,
435 iframeHorizontalPlaylist: DEFAULT_IFRAME_HORIZONTAL_PLAYLIST,
436 maxWidth: DEFAULT_MAX_WIDTH
437 }, embedOptions.responsive); // This value is validate at a higher level, so we can trust that it's in the
438 // correct format.
439
440
441 var aspectRatio = responsive.aspectRatio.split(':').map(Number);
442 var inner = document.createElement('div');
443 var paddingTop = aspectRatio[1] / aspectRatio[0] * 100; // For iframes with a horizontal playlist, the playlist takes up 20% of the
444 // vertical space (if shown); so, adjust the vertical size of the embed to
445 // avoid black bars.
446
447 if (embedType === EMBED_TYPE_IFRAME && responsive.iframeHorizontalPlaylist) {
448 paddingTop *= 1.25;
449 }
450
451 inner.style.paddingTop = paddingTop + '%';
452 inner.appendChild(el);
453 var outer = document.createElement('div');
454 outer.style.position = 'relative';
455 outer.style.display = 'block';
456 outer.style.maxWidth = responsive.maxWidth;
457 outer.appendChild(inner);
458 return outer;
459};
460/**
461 * Wraps an element in a Picture-in-Picture plugin container.
462 *
463 * @private
464 * @param {Object} embedOptions
465 * Embed options from the params.
466 *
467 * @param {Element} el
468 * The DOM element.
469 *
470 * @return {Element}
471 * A new element (if needed).
472 */
473
474
475var wrapPip = function wrapPip(embedOptions, el) {
476 if (!embedOptions.pip) {
477 return el;
478 }
479
480 var pip = document.createElement('div');
481 pip.classList.add('vjs-pip-container');
482 pip.appendChild(el);
483 return pip;
484};
485/**
486 * Wraps a bare embed element with necessary parent elements, depending on
487 * embed options given in params.
488 *
489 * @private
490 * @param {string} embedType
491 * The type of the embed.
492 *
493 * @param {Object} embedOptions
494 * Embed options from the params.
495 *
496 * @param {Element} embed
497 * The embed DOM element.
498 *
499 * @return {Element}
500 * A new element (if needed) or the embed itself.
501 */
502
503
504var wrapEmbed = function wrapEmbed(embedType, embedOptions, embed) {
505 if (!embedOptions) {
506 return embed;
507 }
508
509 return wrapPip(embedOptions, wrapResponsive(embedType, embedOptions, embed));
510};
511/**
512 * Inserts a previously-created embed element into the page based on params.
513 *
514 * @private
515 * @param {Object} params
516 * A parameters object. See README for details.
517 *
518 * @param {Element} embed
519 * The embed DOM element.
520 *
521 * @return {Element}
522 * The embed DOM element.
523 */
524
525
526var insertEmbed = function insertEmbed(params, embed) {
527 var refNode = params.refNode,
528 refNodeInsert = params.refNodeInsert;
529 var refNodeParent = refNode.parentNode; // Wrap the embed, if needed, in container elements to support various
530 // plugins.
531
532 var wrapped = wrapEmbed(params.embedType, params.embedOptions, embed); // Decide where to insert the wrapped embed.
533
534 if (refNodeInsert === REF_NODE_INSERT_BEFORE) {
535 refNodeParent.insertBefore(wrapped, refNode);
536 } else if (refNodeInsert === REF_NODE_INSERT_AFTER) {
537 refNodeParent.insertBefore(wrapped, refNode.nextElementSibling || null);
538 } else if (refNodeInsert === REF_NODE_INSERT_REPLACE) {
539 refNodeParent.replaceChild(wrapped, refNode);
540 } else if (refNodeInsert === REF_NODE_INSERT_PREPEND) {
541 refNode.insertBefore(wrapped, refNode.firstChild || null); // Append is the default.
542 } else {
543 refNode.appendChild(wrapped);
544 } // If the playlist embed option is provided, we need to add a playlist element
545 // immediately after the embed. This has to happen after the embed is inserted
546 // into the DOM (above).
547
548
549 if (params.embedOptions && params.embedOptions.playlist) {
550 var playlistTagName = params.embedOptions.playlist.legacy ? 'ul' : 'div';
551 var playlist = document.createElement(playlistTagName);
552 playlist.classList.add('vjs-playlist');
553 embed.parentNode.insertBefore(playlist, embed.nextElementSibling || null);
554 } // Clean up internal reference to the refNode to avoid potential memory
555 // leaks in case the params get persisted somewhere. We won't need it beyond
556 // this point.
557
558
559 params.refNode = null; // Return the original embed element that can be passed to `bc()`.
560
561 return embed;
562};
563/**
564 * Handles `onEmbedCreated` callback invocation.
565 *
566 * @private
567 * @param {Object} params
568 * A parameters object. See README for details.
569 *
570 * @param {Element} embed
571 * The embed DOM element.
572 *
573 * @return {Element}
574 * A possibly-new DOM element.
575 */
576
577
578var onEmbedCreated = function onEmbedCreated(params, embed) {
579 if (typeof params.onEmbedCreated !== 'function') {
580 return embed;
581 }
582
583 var result = params.onEmbedCreated(embed);
584
585 if (isEl(result)) {
586 return result;
587 }
588
589 return embed;
590};
591/**
592 * Creates an embed code of the appropriate type, runs any customizations
593 * necessary, and inserts it into the DOM.
594 *
595 * @param {Object} params
596 * A parameters object. See README for details.
597 *
598 * @return {Element}
599 * The DOM element that will ultimately be passed to the `bc()`
600 * function. Even when customized or wrapped, the return value will be
601 * the target element.
602 */
603
604
605var createEmbed = function createEmbed(params) {
606 var embed = params.embedType === EMBED_TYPE_IFRAME ? createIframeEmbed(params) : createInPageEmbed(params);
607 return insertEmbed(params, onEmbedCreated(params, embed));
608};
609
610//
611// The keys follow the format "accountId_playerId_embedId" where accountId is
612// optional and defaults to "*". This happens when we detect pre-existing
613// player globals.
614
615var actualCache = new window.Map();
616/**
617 * Get the cache key given some properties.
618 *
619 * @private
620 * @param {Object} props
621 * Properties describing the player record to cache.
622 *
623 * @param {string} props.playerId
624 * A player ID.
625 *
626 * @param {string} props.embedId
627 * An embed ID.
628 *
629 * @param {string} [props.accountId="*"]
630 * An optional account ID. This is optional because when we search for
631 * pre-existing players to avoid downloads, we will not necessarily
632 * know the account ID.
633 *
634 * @return {string}
635 * A key to be used in the script cache.
636 */
637
638var key = function key(_ref) {
639 var accountId = _ref.accountId,
640 playerId = _ref.playerId,
641 embedId = _ref.embedId;
642 return (accountId || '*') + "_" + playerId + "_" + embedId;
643};
644/**
645 * Add an entry to the script cache.
646 *
647 * @private
648 * @param {Object} props
649 * Properties describing the player record to cache.
650 *
651 * @param {string} props.playerId
652 * A player ID.
653 *
654 * @param {string} props.embedId
655 * An embed ID.
656 *
657 * @param {string} [props.accountId="*"]
658 * An optional account ID. This is optional because when we search for
659 * pre-existing players to avoid downloads, we will not necessarily
660 * know the account ID. If not given, we assume that no script was
661 * downloaded for this player.
662 */
663
664
665var store = function store(props) {
666 actualCache.set(key(props), props.accountId ? urls.getUrl(props) : '');
667};
668/**
669 * Checks if the script cache has an entry.
670 *
671 * @private
672 * @param {Object} props
673 * Properties describing the player record to cache.
674 *
675 * @param {string} props.playerId
676 * A player ID.
677 *
678 * @param {string} props.embedId
679 * An embed ID.
680 *
681 * @param {string} [props.accountId="*"]
682 * An optional account ID. This is optional because when we search for
683 * pre-existing players to avoid downloads, we will not necessarily
684 * know the account ID.
685 *
686 * @return {boolean}
687 * Will be `true` if there is a matching cache entry.
688 */
689
690
691var has = function has(props) {
692 return actualCache.has(key(props));
693};
694/**
695 * Gets a cache entry.
696 *
697 * @private
698 * @param {Object} props
699 * Properties describing the player record to cache.
700 *
701 * @param {string} props.playerId
702 * A player ID.
703 *
704 * @param {string} props.embedId
705 * An embed ID.
706 *
707 * @param {string} [props.accountId="*"]
708 * An optional account ID. This is optional because when we search for
709 * pre-existing players to avoid downloads, we will not necessarily
710 * know the account ID.
711 *
712 * @return {string}
713 * A cache entry - a URL or empty string.
714 *
715 */
716
717
718var get = function get(props) {
719 return actualCache.get(key(props));
720};
721/**
722 * Clears the cache.
723 */
724
725
726var clear = function clear() {
727 actualCache.clear();
728};
729/**
730 * Iterates over the cache.
731 *
732 * @param {Function} fn
733 * A callback function that will be called with a value and a key
734 * for each item in the cache.
735 */
736
737
738var forEach = function forEach(fn) {
739 actualCache.forEach(fn);
740};
741
742var playerScriptCache = {
743 clear: clear,
744 forEach: forEach,
745 get: get,
746 has: has,
747 key: key,
748 store: store
749};
750
751var REGEX_PLAYER_EMBED = /^([A-Za-z0-9]+)_([A-Za-z0-9]+)$/;
752/**
753 * Gets an array of current per-player/per-embed `bc` globals that are
754 * attached to the `bc` global (e.g. `bc.abc123xyz_default`).
755 *
756 * If `bc` is not defined, returns an empty array.
757 *
758 * @private
759 * @return {string[]}
760 * An array of keys.
761 */
762
763var getBcGlobalKeys = function getBcGlobalKeys() {
764 return window.bc ? Object.keys(window.bc).filter(function (k) {
765 return REGEX_PLAYER_EMBED.test(k);
766 }) : [];
767};
768/**
769 * Gets known global object keys that Brightcove Players may create.
770 *
771 * @private
772 * @return {string[]}
773 * An array of global variables that were added during testing.
774 */
775
776
777var getGlobalKeys = function getGlobalKeys() {
778 return Object.keys(window).filter(function (k) {
779 return /^videojs/i.test(k) || /^(bc)$/.test(k);
780 });
781};
782/**
783 * Dispose all players from a copy of Video.js.
784 *
785 * @param {Function} videojs
786 * A copy of Video.js.
787 */
788
789
790var disposeAll = function disposeAll(videojs) {
791 if (!videojs) {
792 return;
793 }
794
795 Object.keys(videojs.players).forEach(function (k) {
796 var p = videojs.players[k];
797
798 if (p) {
799 p.dispose();
800 }
801 });
802};
803/**
804 * Resets environment state.
805 *
806 * This will dispose ALL Video.js players on the page and remove ALL `bc` and
807 * `videojs` globals it finds.
808 */
809
810
811var reset = function reset() {
812 // Remove all script elements from the DOM.
813 playerScriptCache.forEach(function (value, key) {
814 // If no script URL is associated, skip it.
815 if (!value) {
816 return;
817 } // Find all script elements and remove them.
818
819
820 Array.prototype.slice.call(document.querySelectorAll("script[src=\"" + value + "\"]")).forEach(function (el) {
821 return el.parentNode.removeChild(el);
822 });
823 }); // Clear the internal cache that have been downloaded.
824
825 playerScriptCache.clear(); // Dispose any remaining players from the `videojs` global.
826
827 disposeAll(window.videojs); // There may be other `videojs` instances lurking in the bowels of the
828 // `bc` global. This should eliminate any of those.
829
830 getBcGlobalKeys().forEach(function (k) {
831 return disposeAll(window.bc[k].videojs);
832 }); // Delete any global object keys that were created.
833
834 getGlobalKeys().forEach(function (k) {
835 delete window[k];
836 });
837};
838/**
839 * At runtime, populate the cache with pre-detected players. This allows
840 * people who have bundled their player or included a script tag before this
841 * runs to not have to re-download players.
842 */
843
844
845var detectPlayers = function detectPlayers() {
846 getBcGlobalKeys().forEach(function (k) {
847 var matches = k.match(REGEX_PLAYER_EMBED);
848 var props = {
849 playerId: matches[1],
850 embedId: matches[2]
851 };
852
853 if (!playerScriptCache.has(props)) {
854 playerScriptCache.store(props);
855 }
856 });
857};
858
859var env = {
860 detectPlayers: detectPlayers,
861 reset: reset
862};
863
864env.detectPlayers();
865/**
866 * Is this value a function?
867 *
868 * @private
869 * @param {Function} fn
870 * A maybe function.
871 *
872 * @return {boolean}
873 * Whether or not the value is a function.
874 */
875
876var isFn = function isFn(fn) {
877 return typeof fn === 'function';
878};
879/**
880 * Checks whether an embedType parameter is valid.
881 *
882 * @private
883 * @param {string} embedType
884 * The value to test.
885 *
886 * @return {boolean}
887 * Whether the value is valid.
888 */
889
890
891var isValidEmbedType = function isValidEmbedType(embedType) {
892 return embedType === EMBED_TYPE_IN_PAGE || embedType === EMBED_TYPE_IFRAME;
893};
894/**
895 * Checks whether an embedOptions.tagName parameter is valid.
896 *
897 * @private
898 * @param {string} tagName
899 * The value to test.
900 *
901 * @return {boolean}
902 * Whether the value is valid.
903 */
904
905
906var isValidTagName = function isValidTagName(tagName) {
907 return tagName === EMBED_TAG_NAME_VIDEOJS || tagName === EMBED_TAG_NAME_VIDEO;
908};
909/**
910 * Checks whether a refNodeInsert parameter is valid.
911 *
912 * @private
913 * @param {string} refNodeInsert
914 * The value to test.
915 *
916 * @return {boolean}
917 * Whether the value is valid.
918 */
919
920
921var isValidRootInsert = function isValidRootInsert(refNodeInsert) {
922 return refNodeInsert === REF_NODE_INSERT_APPEND || refNodeInsert === REF_NODE_INSERT_PREPEND || refNodeInsert === REF_NODE_INSERT_BEFORE || refNodeInsert === REF_NODE_INSERT_AFTER || refNodeInsert === REF_NODE_INSERT_REPLACE;
923};
924/**
925 * Checks parameters and throws an error on validation problems.
926 *
927 * @private
928 * @param {Object} params
929 * A parameters object. See README for details.
930 *
931 * @throws {Error} If accountId is missing.
932 * @throws {Error} If refNode is missing or invalid.
933 * @throws {Error} If embedType is missing or invalid.
934 * @throws {Error} If attempting to use an iframe embed with options.
935 * @throws {Error} If attempting to use embedOptions.responsiveIframe with a
936 * non-iframe embed.
937 * @throws {Error} If refNodeInsert is missing or invalid.
938 */
939
940
941var checkParams = function checkParams(params) {
942 var accountId = params.accountId,
943 embedOptions = params.embedOptions,
944 embedType = params.embedType,
945 options = params.options,
946 refNode = params.refNode,
947 refNodeInsert = params.refNodeInsert;
948
949 if (!accountId) {
950 throw new Error('accountId is required');
951 } else if (!isElInDom(refNode)) {
952 throw new Error('refNode must resolve to a node attached to the DOM');
953 } else if (!isValidEmbedType(embedType)) {
954 throw new Error('embedType is missing or invalid');
955 } else if (embedType === EMBED_TYPE_IFRAME && options) {
956 throw new Error('cannot use options with an iframe embed');
957 } else if (embedOptions && embedOptions.tagName !== undefined && !isValidTagName(embedOptions.tagName)) {
958 throw new Error("embedOptions.tagName is invalid (value: \"" + embedOptions.tagName + "\")");
959 } else if (embedOptions && embedOptions.responsive && embedOptions.responsive.aspectRatio && !/^\d+\:\d+$/.test(embedOptions.responsive.aspectRatio)) {
960 throw new Error("embedOptions.responsive.aspectRatio must be in the \"n:n\" format (value: \"" + embedOptions.responsive.aspectRatio + "\")");
961 } else if (!isValidRootInsert(refNodeInsert)) {
962 throw new Error('refNodeInsert is missing or invalid');
963 }
964};
965/**
966 * Normalizes a `refNode` param to an element - or `null`.
967 *
968 * @private
969 * @param {Element|string} refNode
970 * The value of a `refNode` param.
971 *
972 * @return {Element|null}
973 * A DOM element or `null` if the `refNode` was given as a string and
974 * did not match an element.
975 */
976
977
978var resolveRefNode = function resolveRefNode(refNode) {
979 if (isElInDom(refNode)) {
980 return refNode;
981 }
982
983 if (typeof refNode === 'string') {
984 return document.querySelector(refNode);
985 }
986
987 return null;
988};
989/**
990 * Initializes a player and returns it.
991 *
992 * @private
993 * @param {Object} params
994 * A parameters object. See README for details.
995 *
996 * @param {Element} embed
997 * An element that will be passed to the `bc()` function.
998 *
999 * @param {Function} resolve
1000 * A function to call if a player is successfully initialized.
1001 *
1002 * @param {Function} reject
1003 * A function to call if a player fails to be initialized.
1004 *
1005 * @return {Object}
1006 * A success object whose `ref` is a player.
1007 */
1008
1009
1010var initPlayer = function initPlayer(params, embed, resolve, reject) {
1011 var embedId = params.embedId,
1012 playerId = params.playerId;
1013 var bc = window.bc[playerId + "_" + embedId] || window.bc;
1014
1015 if (!bc) {
1016 return reject(new Error("missing bc function for " + playerId));
1017 }
1018
1019 playerScriptCache.store(params);
1020 var player;
1021
1022 try {
1023 player = bc(embed, params.options); // Add a PLAYER_LOADER property to bcinfo to indicate this player was
1024 // loaded via that mechanism.
1025
1026 if (player.bcinfo) {
1027 player.bcinfo.PLAYER_LOADER = true;
1028 }
1029 } catch (x) {
1030 var message = 'Could not initialize the Brightcove Player.'; // Update the rejection message based on known conditions that can cause it.
1031
1032 if (params.embedOptions.tagName === EMBED_TAG_NAME_VIDEOJS) {
1033 message += ' You are attempting to embed using a "video-js" element.' + ' Please ensure that your Player is v6.11.0 or newer in order to' + ' support this embed type. Alternatively, pass `"video"` for' + ' `embedOptions.tagName`.';
1034 }
1035
1036 return reject(new Error(message));
1037 }
1038
1039 resolve({
1040 type: EMBED_TYPE_IN_PAGE,
1041 ref: player
1042 });
1043};
1044/**
1045 * Loads a player from CDN and embeds it.
1046 *
1047 * @private
1048 * @param {Object} params
1049 * A parameters object. See README for details.
1050 *
1051 * @param {Function} resolve
1052 * A function to call if a player is successfully initialized.
1053 *
1054 * @param {Function} reject
1055 * A function to call if a player fails to be initialized.
1056 */
1057
1058
1059var loadPlayer = function loadPlayer(params, resolve, reject) {
1060 params.refNode = resolveRefNode(params.refNode);
1061 checkParams(params);
1062 var refNode = params.refNode,
1063 refNodeInsert = params.refNodeInsert; // Store a reference to the refNode parent. When we use the replace method,
1064 // we'll need it as the location to store the script element.
1065
1066 var refNodeParent = refNode.parentNode;
1067 var embed = createEmbed(params); // If this is an iframe, all we need to do is create the embed code and
1068 // inject it. Because there is no reliable way to hook into an iframe from
1069 // the parent page, we simply resolve immediately upon creating the embed.
1070
1071 if (params.embedType === EMBED_TYPE_IFRAME) {
1072 resolve({
1073 type: EMBED_TYPE_IFRAME,
1074 ref: embed
1075 });
1076 return;
1077 } // If we've already downloaded this script or detected a matching global, we
1078 // should have the proper `bc` global and can bypass the script creation
1079 // process.
1080
1081
1082 if (playerScriptCache.has(params)) {
1083 return initPlayer(params, embed, resolve, reject);
1084 }
1085
1086 var script = document.createElement('script');
1087
1088 script.onload = function () {
1089 return initPlayer(params, embed, resolve, reject);
1090 };
1091
1092 script.onerror = function () {
1093 reject(new Error('player script could not be downloaded'));
1094 };
1095
1096 script.async = true;
1097 script.charset = 'utf-8';
1098 script.src = urls.getUrl(params);
1099
1100 if (refNodeInsert === REF_NODE_INSERT_REPLACE) {
1101 refNodeParent.appendChild(script);
1102 } else {
1103 refNode.appendChild(script);
1104 }
1105};
1106/**
1107 * A function for asynchronously loading a Brightcove Player into a web page.
1108 *
1109 * @param {Object} parameters
1110 * A parameters object. See README for details.
1111 *
1112 * @return {Promise|undefined}
1113 * A Promise, if possible.
1114 */
1115
1116
1117var brightcovePlayerLoader = function brightcovePlayerLoader(parameters) {
1118 var params = _extends$1({}, DEFAULTS, parameters);
1119
1120 var Promise = params.Promise,
1121 onSuccess = params.onSuccess,
1122 onFailure = params.onFailure; // When Promise is not available or any success/failure callback is given,
1123 // do not attempt to use Promises.
1124
1125 if (!isFn(Promise) || isFn(onSuccess) || isFn(onFailure)) {
1126 return loadPlayer(params, isFn(onSuccess) ? onSuccess : function () {}, isFn(onFailure) ? onFailure : function (err) {
1127 throw err;
1128 });
1129 } // Promises are supported, use 'em.
1130
1131
1132 return new Promise(function (resolve, reject) {
1133 return loadPlayer(params, resolve, reject);
1134 });
1135};
1136/**
1137 * Expose a non-writable, non-configurable property on the
1138 * `brightcovePlayerLoader` function.
1139 *
1140 * @private
1141 * @param {string} key
1142 * The property key.
1143 *
1144 * @param {string|Function} value
1145 * The value.
1146 */
1147
1148
1149var expose = function expose(key, value) {
1150 Object.defineProperty(brightcovePlayerLoader, key, {
1151 configurable: false,
1152 enumerable: true,
1153 value: value,
1154 writable: false
1155 });
1156};
1157/**
1158 * Get the base URL for players. By default, this will be the Brightcove CDN.
1159 *
1160 * @return {string}
1161 * The current base URL.
1162 */
1163
1164
1165expose('getBaseUrl', function () {
1166 return urls.getBaseUrl();
1167});
1168/**
1169 * Set the base URL for players. By default, this will be the Brightcove CDN,
1170 * but can be overridden with this function.
1171 *
1172 * @param {string} baseUrl
1173 * A new base URL (instead of Brightcove CDN).
1174 */
1175
1176expose('setBaseUrl', function (baseUrl) {
1177 urls.setBaseUrl(baseUrl);
1178});
1179/**
1180 * Get the URL for a player.
1181 */
1182
1183expose('getUrl', function (options) {
1184 return urls.getUrl(options);
1185});
1186/**
1187 * Completely resets global state.
1188 *
1189 * This will dispose ALL Video.js players on the page and remove ALL `bc` and
1190 * `videojs` globals it finds.
1191 */
1192
1193expose('reset', function () {
1194 return env.reset();
1195}); // Define some read-only constants on the exported function.
1196
1197[['EMBED_TAG_NAME_VIDEO', EMBED_TAG_NAME_VIDEO], ['EMBED_TAG_NAME_VIDEOJS', EMBED_TAG_NAME_VIDEOJS], ['EMBED_TYPE_IN_PAGE', EMBED_TYPE_IN_PAGE], ['EMBED_TYPE_IFRAME', EMBED_TYPE_IFRAME], ['REF_NODE_INSERT_APPEND', REF_NODE_INSERT_APPEND], ['REF_NODE_INSERT_PREPEND', REF_NODE_INSERT_PREPEND], ['REF_NODE_INSERT_BEFORE', REF_NODE_INSERT_BEFORE], ['REF_NODE_INSERT_AFTER', REF_NODE_INSERT_AFTER], ['REF_NODE_INSERT_REPLACE', REF_NODE_INSERT_REPLACE], ['VERSION', version]].forEach(function (arr) {
1198 expose(arr[0], arr[1]);
1199});
1200
1201/**
1202 * These prop changes can be handled by an internal player state change rather
1203 * than a full dispose/recreate.
1204 *
1205 * @private
1206 * @type {Object}
1207 */
1208
1209var UPDATEABLE_PROPS = ['catalogSearch', 'catalogSequence', 'playlistId', 'playlistVideoId', 'videoId'];
1210
1211var logError = function logError(err) {
1212 /* eslint-disable no-console */
1213 if (err && console && console.error) {
1214 console.error(err);
1215 }
1216 /* eslint-enable no-console */
1217
1218};
1219/**
1220 * The official React component for the Brightcove Player!
1221 *
1222 * This uses `@brightcove/player-loader` to load a player into a React
1223 * component based on the given props.
1224 */
1225
1226
1227var ReactPlayerLoader =
1228/*#__PURE__*/
1229function (_React$Component) {
1230 _inheritsLoose(ReactPlayerLoader, _React$Component);
1231
1232 /**
1233 * Create a new Brightcove player.
1234 *
1235 * @param {Object} props
1236 * Most options will be passed along to player-loader, except for
1237 * options that are listed. See README.md for more detail.
1238 *
1239 * @param {string} [props.baseUrl]
1240 * The base URL to use when requesting a player
1241 *
1242 * @param {Object} [props.attrs]
1243 * Used to set attributes on the component element that contains the
1244 * embedded Brightcove Player.
1245 *
1246 * @param {boolean} [props.manualReloadFromPropChanges]
1247 * Used to specify if reloading the player after prop changes will be handled manually.
1248 *
1249 */
1250 function ReactPlayerLoader(props) {
1251 var _this;
1252
1253 _this = _React$Component.call(this, props) || this;
1254 _this.refNode = null;
1255
1256 _this.setRefNode = function (ref) {
1257 _this.refNode = ref;
1258 };
1259
1260 _this.loadPlayer = _this.loadPlayer.bind(_assertThisInitialized(_this));
1261 return _this;
1262 }
1263 /**
1264 * Loads a new player based on the current props.
1265 */
1266
1267
1268 var _proto = ReactPlayerLoader.prototype;
1269
1270 _proto.loadPlayer = function loadPlayer() {
1271 var _this2 = this;
1272
1273 // If there is any player currently loaded, dispose it before fetching a
1274 // new one.
1275 this.disposePlayer(); // We need to provide our own callbacks below, so we cache these
1276 // user-provided callbacks for use later.
1277
1278 var userSuccess = this.props.onSuccess;
1279 var userFailure = this.props.onFailure;
1280
1281 var options = _extends({}, this.props, {
1282 refNode: this.refNode,
1283 refNodeInsert: 'append',
1284 onSuccess: function onSuccess(_ref) {
1285 var ref = _ref.ref,
1286 type = _ref.type;
1287
1288 // If the component is not mounted when the callback fires, dispose
1289 // the player and bail out.
1290 if (!_this2.isMounted_) {
1291 _this2.disposePlayer(ref);
1292
1293 return;
1294 } // Store a player reference on the component.
1295
1296
1297 _this2.player = ref; // Null out the player reference when the player is disposed from
1298 // outside the component.
1299
1300 if (type === 'in-page') {
1301 ref.one('dispose', function () {
1302 _this2.player = null;
1303 });
1304 } // Add a REACT_PLAYER_LOADER property to bcinfo to indicate this player
1305 // was loaded via that mechanism.
1306
1307
1308 if (ref.bcinfo) {
1309 ref.bcinfo.REACT_PLAYER_LOADER = true;
1310 } // Call a user-provided onSuccess callback.
1311
1312
1313 if (typeof userSuccess === 'function') {
1314 userSuccess({
1315 ref: ref,
1316 type: type
1317 });
1318 }
1319 },
1320 onFailure: function onFailure(error) {
1321 // Ignore errors when not mounted.
1322 if (!_this2.isMounted_) {
1323 return;
1324 } // Call a user-provided onFailure callback.
1325
1326
1327 if (typeof userFailure === 'function') {
1328 userFailure(error);
1329 return;
1330 } // Fall back to throwing an error;
1331
1332
1333 throw new Error(error);
1334 }
1335 }); // Delete props that are not meant to be passed to player-loader.
1336
1337
1338 delete options.attrs;
1339 delete options.baseUrl;
1340 delete options.manualReloadFromPropChanges; // If a base URL is provided, it should only apply to this player load.
1341 // This means we need to back up the original base URL and restore it
1342 // _after_ we call player loader.
1343
1344 var originalBaseUrl = brightcovePlayerLoader.getBaseUrl();
1345
1346 if (this.props.baseUrl) {
1347 brightcovePlayerLoader.setBaseUrl(this.props.baseUrl);
1348 }
1349
1350 brightcovePlayerLoader(options);
1351 brightcovePlayerLoader.setBaseUrl(originalBaseUrl);
1352 }
1353 /**
1354 * Disposes the current player, if there is one.
1355 */
1356 ;
1357
1358 _proto.disposePlayer = function disposePlayer() {
1359 // Nothing to dispose.
1360 if (!this.player) {
1361 return;
1362 } // Dispose an in-page player.
1363
1364
1365 if (this.player.dispose) {
1366 this.player.dispose(); // Dispose an iframe player.
1367 } else if (this.player.parentNode) {
1368 this.player.parentNode.removeChild(this.player);
1369 } // Null out the player reference.
1370
1371
1372 this.player = null;
1373 }
1374 /**
1375 * Find the index of the `playlistVideoId` prop within the player's playlist.
1376 *
1377 * @param {Object[]} playlist
1378 * An array of playlist item objects.
1379 *
1380 * @return {number}
1381 * The index of the `playlistVideoId` or `-1` if the player has been
1382 * disposed, is not using the playlist plugin, or if not found.
1383 */
1384 ;
1385
1386 _proto.findPlaylistVideoIdIndex_ = function findPlaylistVideoIdIndex_(playlist) {
1387 var playlistVideoId = this.props.playlistVideoId;
1388
1389 if (Array.isArray(playlist) && playlistVideoId) {
1390 for (var i = 0; i < playlist.length; i++) {
1391 var _playlist$i = playlist[i],
1392 id = _playlist$i.id,
1393 referenceId = _playlist$i.referenceId;
1394
1395 if (id === playlistVideoId || "ref:" + referenceId === playlistVideoId) {
1396 return i;
1397 }
1398 }
1399 }
1400
1401 return -1;
1402 }
1403 /**
1404 * Create a Playback API callback function for the component's player.
1405 *
1406 * @private
1407 * @param {string} requestType
1408 * The Playback API request type (e.g. "video" or "playlist").
1409 *
1410 * @param {Object} changes
1411 * An object. The keys of this object are the props that changed.
1412 *
1413 * @return {Function}
1414 * A callback for the Playback API request.
1415 */
1416 ;
1417
1418 _proto.createPlaybackAPICallback_ = function createPlaybackAPICallback_(requestType, changes) {
1419 var _this3 = this;
1420
1421 return function (err, data) {
1422 if (err) {
1423 logError(err);
1424 return;
1425 } // If the playlistVideoId changed and this is a playlist request, we
1426 // need to search through the playlist items to find the correct
1427 // starting index.
1428
1429
1430 if (requestType === 'playlist' && changes.playlistVideoId) {
1431 var i = _this3.findPlaylistVideoIdIndex_(data);
1432
1433 if (i > -1) {
1434 data.startingIndex = i;
1435 }
1436 }
1437
1438 _this3.player.catalog.load(data);
1439 };
1440 }
1441 /**
1442 * Update the player based on changes to certain props that do not require
1443 * a full player dispose/recreate.
1444 *
1445 * @param {Object} changes
1446 * An object. The keys of this object are the props that changed.
1447 */
1448 ;
1449
1450 _proto.updatePlayer = function updatePlayer(changes) {
1451 // No player exists, player is disposed, or not using the catalog
1452 if (!this.player || !this.player.el || !this.player.el()) {
1453 return;
1454 } // If the player is using the catalog plugin, we _may_ populate this
1455 // variable with an object.
1456
1457
1458 var catalogParams;
1459
1460 if (this.player.usingPlugin('catalog')) {
1461 // There is a new catalog sequence request. This takes precedence over
1462 // other catalog updates because it is a different call.
1463 if (changes.catalogSequence && this.props.catalogSequence) {
1464 var callback = this.createPlaybackAPICallback_('sequence', changes);
1465 this.player.catalog.getLazySequence(this.props.catalogSequence, callback, this.props.adConfigId);
1466 return;
1467 }
1468
1469 if (changes.videoId && this.props.videoId) {
1470 catalogParams = {
1471 type: 'video',
1472 id: this.props.videoId
1473 };
1474 } else if (changes.playlistId && this.props.playlistId) {
1475 catalogParams = {
1476 type: 'playlist',
1477 id: this.props.playlistId
1478 };
1479 } else if (changes.catalogSearch && this.props.catalogSearch) {
1480 catalogParams = {
1481 type: 'search',
1482 q: this.props.catalogSearch
1483 };
1484 }
1485 } // If `catalogParams` is `undefined` here, that means the player either
1486 // does not have the catalog plugin or no valid catalog request can be made.
1487
1488
1489 if (catalogParams) {
1490 if (this.props.adConfigId) {
1491 catalogParams.adConfigId = this.props.adConfigId;
1492 }
1493
1494 if (this.props.deliveryConfigId) {
1495 catalogParams.deliveryConfigId = this.props.deliveryConfigId;
1496 } // We use the callback style here to make tests simpler in IE11 (no need
1497 // for a Promise polyfill).
1498
1499
1500 var _callback = this.createPlaybackAPICallback_(catalogParams.type, changes);
1501
1502 this.player.catalog.get(catalogParams, _callback); // If no catalog request is being made, we may still need to update the
1503 // playlist selected video.
1504 } else if (changes.playlistVideoId && this.props.playlistVideoId && this.player.usingPlugin('playlist')) {
1505 var i = this.findPlaylistVideoIdIndex_(this.player.playlist());
1506
1507 if (i > -1) {
1508 this.player.playlist.currentItem(i);
1509 }
1510 }
1511 }
1512 /**
1513 * Called just after the component has mounted.
1514 */
1515 ;
1516
1517 _proto.componentDidMount = function componentDidMount() {
1518 this.isMounted_ = true;
1519 this.loadPlayer();
1520 }
1521 /**
1522 * Called when the component props are updated.
1523 *
1524 * Some prop changes may trigger special behavior (see `propChangeHandlers`),
1525 * but if ANY prop is changed that is NOT handled, the player will be
1526 * disposed/recreated entirely.
1527 *
1528 * @param {Object} prevProps
1529 * The previous props state before change.
1530 */
1531 ;
1532
1533 _proto.componentDidUpdate = function componentDidUpdate(prevProps) {
1534 var _this4 = this;
1535
1536 // Calculate the prop changes.
1537 var changes = Object.keys(prevProps).reduce(function (acc, key) {
1538 var previous = prevProps[key];
1539 var current = _this4.props[key]; // Do not compare functions
1540
1541 if (typeof current === 'function') {
1542 return acc;
1543 }
1544
1545 if (typeof current === 'object' && current !== null) {
1546 if (JSON.stringify(current) !== JSON.stringify(previous)) {
1547 acc[key] = true;
1548 }
1549
1550 return acc;
1551 }
1552
1553 if (current !== previous) {
1554 acc[key] = true;
1555 }
1556
1557 return acc;
1558 }, {});
1559
1560 if (!this.props.manualReloadFromPropChanges) {
1561 // Dispose and recreate the player if any changed keys cannot be handled.
1562 if (Object.keys(changes).some(function (k) {
1563 return UPDATEABLE_PROPS.indexOf(k) === -1;
1564 })) {
1565 this.loadPlayer();
1566 return;
1567 }
1568 }
1569
1570 this.updatePlayer(changes);
1571 }
1572 /**
1573 * Called just before a component unmounts. Disposes the player.
1574 */
1575 ;
1576
1577 _proto.componentWillUnmount = function componentWillUnmount() {
1578 this.isMounted_ = false;
1579 this.disposePlayer();
1580 }
1581 /**
1582 * Renders the component.
1583 *
1584 * @return {ReactElement}
1585 * The react element to render.
1586 */
1587 ;
1588
1589 _proto.render = function render() {
1590 var props = _extends({
1591 className: 'brightcove-react-player-loader'
1592 }, this.props.attrs, {
1593 ref: this.setRefNode
1594 });
1595
1596 return React.createElement('div', props);
1597 };
1598
1599 return ReactPlayerLoader;
1600}(React.Component);
1601
1602export default ReactPlayerLoader;