UNPKG

fulan-editor

Version:

An open source react editor based on draft-Js and ant design, good support HTML, markdown and Draft Raw format.

1,347 lines (1,057 loc) 1.1 MB
/** * @license * Video.js 5.13.2 <http://videojs.com/> * Copyright Brightcove, Inc. <https://www.brightcove.com/> * Available under Apache License Version 2.0 * <https://github.com/videojs/video.js/blob/master/LICENSE> * * Includes vtt.js <https://github.com/mozilla/vtt.js> * Available under Apache License Version 2.0 * <https://github.com/mozilla/vtt.js/blob/master/LICENSE> */ (function (f) { if (typeof exports === "object" && typeof module !== "undefined") { module.exports = f() } else if (typeof define === "function" && define.amd) { define([], f) } else { var g; if (typeof window !== "undefined") { g = window } else if (typeof global !== "undefined") { g = global } else if (typeof self !== "undefined") { g = self } else { g = this } g.videojs = f() } })(function () { var define, module, exports; return (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { var a = typeof require == "function" && require; if (!u && a)return a(o, !0); if (i)return i(o, !0); var f = new Error("Cannot find module '" + o + "'"); throw f.code = "MODULE_NOT_FOUND", f } var l = n[o] = {exports: {}}; t[o][0].call(l.exports, function (e) { var n = t[o][1][e]; return s(n ? n : e) }, l, l.exports, e, t, n, r) } return n[o].exports } var i = typeof require == "function" && require; for (var o = 0; o < r.length; o++)s(r[o]); return s })({ 1: [function (_dereq_, module, exports) { 'use strict'; exports.__esModule = true; var _button = _dereq_(2); var _button2 = _interopRequireDefault(_button); var _component = _dereq_(5); var _component2 = _interopRequireDefault(_component); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : {'default': obj}; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(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; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } 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; } /** * @file big-play-button.js */ /** * Initial play button. Shows before the video has played. The hiding of the * big play button is done via CSS and player states. * * @param {Object} player Main Player * @param {Object=} options Object of option names and values * @extends Button * @class BigPlayButton */ var BigPlayButton = function (_Button) { _inherits(BigPlayButton, _Button); function BigPlayButton() { _classCallCheck(this, BigPlayButton); return _possibleConstructorReturn(this, _Button.apply(this, arguments)); } /** * Allow sub components to stack CSS class names * * @return {String} The constructed class name * @method buildCSSClass */ BigPlayButton.prototype.buildCSSClass = function buildCSSClass() { return 'vjs-big-play-button'; }; /** * Handles click for play * * @method handleClick */ BigPlayButton.prototype.handleClick = function handleClick() { this.player_.play(); }; return BigPlayButton; }(_button2['default']); BigPlayButton.prototype.controlText_ = 'Play Video'; _component2['default'].registerComponent('BigPlayButton', BigPlayButton); exports['default'] = BigPlayButton; }, {"2": 2, "5": 5}], 2: [function (_dereq_, module, exports) { 'use strict'; exports.__esModule = true; var _clickableComponent = _dereq_(3); var _clickableComponent2 = _interopRequireDefault(_clickableComponent); var _component = _dereq_(5); var _component2 = _interopRequireDefault(_component); var _log = _dereq_(86); var _log2 = _interopRequireDefault(_log); var _object = _dereq_(138); var _object2 = _interopRequireDefault(_object); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : {'default': obj}; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(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; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } 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; } /** * @file button.js */ /** * Base class for all buttons * * @param {Object} player Main Player * @param {Object=} options Object of option names and values * @extends ClickableComponent * @class Button */ var Button = function (_ClickableComponent) { _inherits(Button, _ClickableComponent); function Button() { _classCallCheck(this, Button); return _possibleConstructorReturn(this, _ClickableComponent.apply(this, arguments)); } /** * Create the component's DOM element * * @param {String=} type Element's node type. e.g. 'div' * @param {Object=} props An object of properties that should be set on the element * @param {Object=} attributes An object of attributes that should be set on the element * @return {Element} * @method createEl */ Button.prototype.createEl = function createEl() { var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'button'; var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; props = (0, _object2['default'])({ className: this.buildCSSClass() }, props); if (tag !== 'button') { _log2['default'].warn('Creating a Button with an HTML element of ' + tag + ' is deprecated; use ClickableComponent instead.'); // Add properties for clickable element which is not a native HTML button props = (0, _object2['default'])({ tabIndex: 0 }, props); // Add ARIA attributes for clickable element which is not a native HTML button attributes = (0, _object2['default'])({ role: 'button' }, attributes); } // Add attributes for button element attributes = (0, _object2['default'])({ // Necessary since the default button type is "submit" 'type': 'button', // let the screen reader user know that the text of the button may change 'aria-live': 'polite' }, attributes); var el = _component2['default'].prototype.createEl.call(this, tag, props, attributes); this.createControlTextEl(el); return el; }; /** * Adds a child component inside this button * * @param {String|Component} child The class name or instance of a child to add * @param {Object=} options Options, including options to be passed to children of the child. * @return {Component} The child component (created by this process if a string was used) * @deprecated * @method addChild */ Button.prototype.addChild = function addChild(child) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var className = this.constructor.name; _log2['default'].warn('Adding an actionable (user controllable) child to a Button (' + className + ') is not supported; use a ClickableComponent instead.'); // Avoid the error message generated by ClickableComponent's addChild method return _component2['default'].prototype.addChild.call(this, child, options); }; /** * Enable the button element * * @return {Component} * @method enable */ Button.prototype.enable = function enable() { _ClickableComponent.prototype.enable.call(this); this.el_.removeAttribute('disabled'); }; /** * Disable the button element * * @return {Component} * @method disable */ Button.prototype.disable = function disable() { _ClickableComponent.prototype.disable.call(this); this.el_.setAttribute('disabled', 'disabled'); }; /** * Handle KeyPress (document level) - Extend with specific functionality for button * * @method handleKeyPress */ Button.prototype.handleKeyPress = function handleKeyPress(event) { // Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button. if (event.which === 32 || event.which === 13) { return; } // Pass keypress handling up for unsupported keys _ClickableComponent.prototype.handleKeyPress.call(this, event); }; return Button; }(_clickableComponent2['default']); _component2['default'].registerComponent('Button', Button); exports['default'] = Button; }, {"138": 138, "3": 3, "5": 5, "86": 86}], 3: [function (_dereq_, module, exports) { 'use strict'; exports.__esModule = true; var _component = _dereq_(5); var _component2 = _interopRequireDefault(_component); var _dom = _dereq_(81); var Dom = _interopRequireWildcard(_dom); var _events = _dereq_(82); var Events = _interopRequireWildcard(_events); var _fn = _dereq_(83); var Fn = _interopRequireWildcard(_fn); var _log = _dereq_(86); var _log2 = _interopRequireDefault(_log); var _document = _dereq_(94); var _document2 = _interopRequireDefault(_document); var _object = _dereq_(138); var _object2 = _interopRequireDefault(_object); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : {'default': obj}; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(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; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } 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; } /** * @file button.js */ /** * Clickable Component which is clickable or keyboard actionable, but is not a native HTML button * * @param {Object} player Main Player * @param {Object=} options Object of option names and values * @extends Component * @class ClickableComponent */ var ClickableComponent = function (_Component) { _inherits(ClickableComponent, _Component); function ClickableComponent(player, options) { _classCallCheck(this, ClickableComponent); var _this = _possibleConstructorReturn(this, _Component.call(this, player, options)); _this.emitTapEvents(); _this.enable(); return _this; } /** * Create the component's DOM element * * @param {String=} type Element's node type. e.g. 'div' * @param {Object=} props An object of properties that should be set on the element * @param {Object=} attributes An object of attributes that should be set on the element * @return {Element} * @method createEl */ ClickableComponent.prototype.createEl = function createEl() { var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div'; var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; props = (0, _object2['default'])({ className: this.buildCSSClass(), tabIndex: 0 }, props); if (tag === 'button') { _log2['default'].error('Creating a ClickableComponent with an HTML element of ' + tag + ' is not supported; use a Button instead.'); } // Add ARIA attributes for clickable element which is not a native HTML button attributes = (0, _object2['default'])({ 'role': 'button', // let the screen reader user know that the text of the element may change 'aria-live': 'polite' }, attributes); this.tabIndex_ = props.tabIndex; var el = _Component.prototype.createEl.call(this, tag, props, attributes); this.createControlTextEl(el); return el; }; /** * create control text * * @param {Element} el Parent element for the control text * @return {Element} * @method controlText */ ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) { this.controlTextEl_ = Dom.createEl('span', { className: 'vjs-control-text' }); if (el) { el.appendChild(this.controlTextEl_); } this.controlText(this.controlText_, el); return this.controlTextEl_; }; /** * Controls text - both request and localize * * @param {String} text Text for element * @param {Element=} el Element to set the title on * @return {String} * @method controlText */ ClickableComponent.prototype.controlText = function controlText(text) { var el = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.el(); if (!text) { return this.controlText_ || 'Need Text'; } var localizedText = this.localize(text); this.controlText_ = text; this.controlTextEl_.innerHTML = localizedText; el.setAttribute('title', localizedText); return this; }; /** * Allows sub components to stack CSS class names * * @return {String} * @method buildCSSClass */ ClickableComponent.prototype.buildCSSClass = function buildCSSClass() { return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this); }; /** * Enable the component element * * @return {Component} * @method enable */ ClickableComponent.prototype.enable = function enable() { this.removeClass('vjs-disabled'); this.el_.setAttribute('aria-disabled', 'false'); if (typeof this.tabIndex_ !== 'undefined') { this.el_.setAttribute('tabIndex', this.tabIndex_); } this.on('tap', this.handleClick); this.on('click', this.handleClick); this.on('focus', this.handleFocus); this.on('blur', this.handleBlur); return this; }; /** * Disable the component element * * @return {Component} * @method disable */ ClickableComponent.prototype.disable = function disable() { this.addClass('vjs-disabled'); this.el_.setAttribute('aria-disabled', 'true'); if (typeof this.tabIndex_ !== 'undefined') { this.el_.removeAttribute('tabIndex'); } this.off('tap', this.handleClick); this.off('click', this.handleClick); this.off('focus', this.handleFocus); this.off('blur', this.handleBlur); return this; }; /** * Handle Click - Override with specific functionality for component * * @method handleClick */ ClickableComponent.prototype.handleClick = function handleClick() { }; /** * Handle Focus - Add keyboard functionality to element * * @method handleFocus */ ClickableComponent.prototype.handleFocus = function handleFocus() { Events.on(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress)); }; /** * Handle KeyPress (document level) - Trigger click when Space or Enter key is pressed * * @method handleKeyPress */ ClickableComponent.prototype.handleKeyPress = function handleKeyPress(event) { // Support Space (32) or Enter (13) key operation to fire a click event if (event.which === 32 || event.which === 13) { event.preventDefault(); this.handleClick(event); } else if (_Component.prototype.handleKeyPress) { // Pass keypress handling up for unsupported keys _Component.prototype.handleKeyPress.call(this, event); } }; /** * Handle Blur - Remove keyboard triggers * * @method handleBlur */ ClickableComponent.prototype.handleBlur = function handleBlur() { Events.off(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress)); }; return ClickableComponent; }(_component2['default']); _component2['default'].registerComponent('ClickableComponent', ClickableComponent); exports['default'] = ClickableComponent; }, {"138": 138, "5": 5, "81": 81, "82": 82, "83": 83, "86": 86, "94": 94}], 4: [function (_dereq_, module, exports) { 'use strict'; exports.__esModule = true; var _button = _dereq_(2); var _button2 = _interopRequireDefault(_button); var _component = _dereq_(5); var _component2 = _interopRequireDefault(_component); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : {'default': obj}; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(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; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } 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; } /** * The `CloseButton` component is a button which fires a "close" event * when it is activated. * * @extends Button * @class CloseButton */ var CloseButton = function (_Button) { _inherits(CloseButton, _Button); function CloseButton(player, options) { _classCallCheck(this, CloseButton); var _this = _possibleConstructorReturn(this, _Button.call(this, player, options)); _this.controlText(options && options.controlText || _this.localize('Close')); return _this; } CloseButton.prototype.buildCSSClass = function buildCSSClass() { return 'vjs-close-button ' + _Button.prototype.buildCSSClass.call(this); }; CloseButton.prototype.handleClick = function handleClick() { this.trigger({type: 'close', bubbles: false}); }; return CloseButton; }(_button2['default']); _component2['default'].registerComponent('CloseButton', CloseButton); exports['default'] = CloseButton; }, {"2": 2, "5": 5}], 5: [function (_dereq_, module, exports) { 'use strict'; exports.__esModule = true; var _window = _dereq_(95); var _window2 = _interopRequireDefault(_window); var _dom = _dereq_(81); var Dom = _interopRequireWildcard(_dom); var _fn = _dereq_(83); var Fn = _interopRequireWildcard(_fn); var _guid = _dereq_(85); var Guid = _interopRequireWildcard(_guid); var _events = _dereq_(82); var Events = _interopRequireWildcard(_events); var _log = _dereq_(86); var _log2 = _interopRequireDefault(_log); var _toTitleCase = _dereq_(91); var _toTitleCase2 = _interopRequireDefault(_toTitleCase); var _mergeOptions = _dereq_(87); var _mergeOptions2 = _interopRequireDefault(_mergeOptions); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : {'default': obj}; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * @file component.js * * Player Component - Base class for all UI objects */ /** * Base UI Component class * Components are embeddable UI objects that are represented by both a * javascript object and an element in the DOM. They can be children of other * components, and can have many children themselves. * ```js * // adding a button to the player * var button = player.addChild('button'); * button.el(); // -> button element * ``` * ```html * <div class="video-js"> * <div class="vjs-button">Button</div> * </div> * ``` * Components are also event targets. * ```js * button.on('click', function() { * console.log('Button Clicked!'); * }); * button.trigger('customevent'); * ``` * * @param {Object} player Main Player * @param {Object=} options Object of option names and values * @param {Function=} ready Ready callback function * @class Component */ var Component = function () { 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 } else { this.player_ = player; } // Make a copy of prototype.options_ to protect against overriding defaults this.options_ = (0, _mergeOptions2['default'])({}, this.options_); // Updated options with supplied options options = this.options_ = (0, _mergeOptions2['default'])(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 (!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_' + Guid.newGUID(); } this.name_ = options.name || null; // 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(); } this.children_ = []; this.childIndex_ = {}; this.childNameIndex_ = {}; // 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 // finished for all children that run this constructor if (options.reportTouchActivity !== false) { this.enableTouchActivity(); } } /** * Dispose of the component and all child components * * @method dispose */ Component.prototype.dispose = function dispose() { this.trigger({type: 'dispose', bubbles: false}); // 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 this.children_ = null; this.childIndex_ = null; this.childNameIndex_ = null; // Remove all event listeners. this.off(); // Remove element from DOM if (this.el_.parentNode) { this.el_.parentNode.removeChild(this.el_); } Dom.removeElData(this.el_); this.el_ = null; }; /** * Return the component's player * * @return {Player} * @method player */ Component.prototype.player = function player() { return this.player_; }; /** * Deep merge of options objects * Whenever a property is an object on both options objects * the two properties will be merged using mergeOptions. * * ```js * Parent.prototype.options_ = { * optionSet: { * 'childOne': { 'foo': 'bar', 'asdf': 'fdsa' }, * 'childTwo': {}, * 'childThree': {} * } * } * newOptions = { * optionSet: { * 'childOne': { 'foo': 'baz', 'abc': '123' } * 'childTwo': null, * 'childFour': {} * } * } * * this.options(newOptions); * ``` * RESULT * ```js * { * optionSet: { * 'childOne': { 'foo': 'baz', 'asdf': 'fdsa', 'abc': '123' }, * 'childTwo': null, // Disabled. Won't be initialized. * 'childThree': {}, * 'childFour': {} * } * } * ``` * * @param {Object} obj Object of new option values * @return {Object} A NEW object of this.options_ and obj merged * @method options */ Component.prototype.options = function options(obj) { _log2['default'].warn('this.options() has been deprecated and will be moved to the constructor in 6.0'); if (!obj) { return this.options_; } this.options_ = (0, _mergeOptions2['default'])(this.options_, obj); return this.options_; }; /** * Get the component's DOM element * ```js * var domEl = myComponent.el(); * ``` * * @return {Element} * @method el */ Component.prototype.el = function el() { return this.el_; }; /** * Create the component's DOM element * * @param {String=} tagName Element's node type. e.g. 'div' * @param {Object=} properties An object of properties that should be set * @param {Object=} attributes An object of attributes that should be set * @return {Element} * @method createEl */ Component.prototype.createEl = function createEl(tagName, properties, attributes) { return Dom.createEl(tagName, properties, attributes); }; Component.prototype.localize = function localize(string) { var code = this.player_.language && this.player_.language(); var languages = this.player_.languages && this.player_.languages(); if (!code || !languages) { return string; } var language = languages[code]; if (language && language[string]) { return language[string]; } var primaryCode = code.split('-')[0]; var primaryLang = languages[primaryCode]; if (primaryLang && primaryLang[string]) { return primaryLang[string]; } return string; }; /** * Return the component's DOM element where children are inserted. * Will either be the same as el() or a new element defined in createEl(). * * @return {Element} * @method contentEl */ Component.prototype.contentEl = function contentEl() { return this.contentEl_ || this.el_; }; /** * Get the component's ID * ```js * var id = myComponent.id(); * ``` * * @return {String} * @method id */ Component.prototype.id = function id() { return this.id_; }; /** * Get the component's name. The name is often used to reference the component. * ```js * var name = myComponent.name(); * ``` * * @return {String} * @method name */ Component.prototype.name = function name() { return this.name_; }; /** * Get an array of all child components * ```js * var kids = myComponent.children(); * ``` * * @return {Array} The children * @method children */ Component.prototype.children = function children() { return this.children_; }; /** * Returns a child component with the provided ID * * @return {Component} * @method getChildById */ Component.prototype.getChildById = function getChildById(id) { return this.childIndex_[id]; }; /** * Returns a child component with the provided name * * @return {Component} * @method getChild */ Component.prototype.getChild = function getChild(name) { if (!name) { return; } name = (0, _toTitleCase2['default'])(name); return this.childNameIndex_[name]; }; /** * Adds a child component inside this component * ```js * myComponent.el(); * // -> <div class='my-component'></div> * myComponent.children(); * // [empty array] * * var myButton = myComponent.addChild('MyButton'); * // -> <div class='my-component'><div class="my-button">myButton<div></div> * // -> myButton === myComponent.children()[0]; * ``` * Pass in options for child constructors and options for children of the child * ```js * var myButton = myComponent.addChild('MyButton', { * text: 'Press Me', * buttonChildExample: { * buttonChildOption: true * } * }); * ``` * * @param {String|Component} child The class name or instance of a child to add * @param {Object=} options Options, including options to be passed to children of the child. * @param {Number} index into our children array to attempt to add the child * @return {Component} The child component (created by this process if a string was used) * @method addChild */ 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; var component = void 0; var componentName = void 0; // If child is a string, create component with options if (typeof child === 'string') { componentName = (0, _toTitleCase2['default'])(child); // Options can also be specified as a boolean, so convert to an empty object if false. if (!options) { options = {}; } // Same as above, but true is deprecated so show a warning. if (options === true) { _log2['default'].warn('Initializing a child component with `true` is deprecated. Children should be defined in an array when possible, but if necessary use an object instead of `true`.'); options = {}; } var componentClassName = options.componentClass || componentName; // Set name through options 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 // 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 } else { component = child; } this.children_.splice(index, 0, component); 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 // name function of the component componentName = componentName || component.name && component.name(); if (componentName) { this.childNameIndex_[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; this.contentEl().insertBefore(component.el(), refNode); } // Return so it can stored on parent object if desired. return component; }; /** * Remove a child component from this component's list of children, and the * child component's element from this component's element * * @param {Component} component Component to remove * @method removeChild */ Component.prototype.removeChild = function removeChild(component) { if (typeof component === 'string') { component = this.getChild(component); } if (!component || !this.children_) { return; } var childFound = false; for (var i = this.children_.length - 1; i >= 0; i--) { if (this.children_[i] === component) { childFound = true; this.children_.splice(i, 1); break; } } if (!childFound) { return; } this.childIndex_[component.id()] = null; this.childNameIndex_[component.name()] = null; var compEl = component.el(); if (compEl && compEl.parentNode === this.contentEl()) { this.contentEl().removeChild(component.el()); } }; /** * Add and initialize default child components from options * ```js * // when an instance of MyComponent is created, all children in options * // will be added to the instance by their name strings and options * MyComponent.prototype.options_ = { * children: [ * 'myChildComponent' * ], * myChildComponent: { * myChildOption: true * } * }; * * // Or when creating the component * var myComp = new MyComponent(player, { * children: [ * 'myChildComponent' * ], * myChildComponent: { * myChildOption: true * } * }); * ``` * The children option can also be an array of * child options objects (that also include a 'name' key). * This can be used if you have two child components of the * same type that need different options. * ```js * var myComp = new MyComponent(player, { * children: [ * 'button', * { * name: 'button', * someOtherOption: true * }, * { * name: 'button', * someOtherOption: false * } * ] * }); * ``` * * @method initChildren */ Component.prototype.initChildren = function initChildren() { var _this = this; var children = this.options_.children; if (children) { (function () { // `this` is `parent` var parentOptions = _this.options_; var handleAdd = function handleAdd(child) { var name = child.name; var opts = child.opts; // Allow options for children to be set at the parent options // e.g. videojs