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
JavaScript
/**
* @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