Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the ability to set options for child components directly on the parent options #1599

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 30 additions & 15 deletions src/js/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -354,17 +354,17 @@ vjs.Component.prototype.getChild = function(name){
* @suppress {accessControls|checkRegExp|checkTypes|checkVars|const|constantProperty|deprecated|duplicate|es5Strict|fileoverviewTags|globalThis|invalidCasts|missingProperties|nonStandardJsDocs|strictModuleDepCheck|undefinedNames|undefinedVars|unknownDefines|uselessCode|visibility}
*/
vjs.Component.prototype.addChild = function(child, options){
var component, componentClass, componentName, componentId;
var component, componentClass, componentName;

// If string, create new component with options
// If child is a string, create new component with options
if (typeof child === 'string') {

componentName = child;

// Make sure options is at least an empty object to protect against errors
options = options || {};

// Assume name of set is a lowercased name of the UI Class (PlayButton, etc.)
// If no componentClass in options, assume componentClass is the name lowercased
// (e.g. playButton)
componentClass = options['componentClass'] || vjs.capitalize(componentName);

// Set name through options
Expand Down Expand Up @@ -473,36 +473,51 @@ vjs.Component.prototype.removeChild = function(component){
*
*/
vjs.Component.prototype.initChildren = function(){
var parent, children, child, name, opts;
var parent, parentOptions, children, child, name, opts, handleAdd;

parent = this;
children = this.options()['children'];
parentOptions = parent.options();
children = parentOptions['children'];

if (children) {
handleAdd = function(name, opts){
// Allow options for children to be set at the parent options
// e.g. videojs(id, { controlBar: false });
// instead of videojs(id, { children: { controlBar: false });
if (parentOptions[name]) {
opts = parentOptions[name];
}

// Allow for disabling default components
// e.g. vjs.options['children']['posterImage'] = false
if (opts === false) return;

// Create and add the child component.
// Add a direct reference to the child by name on the parent instance.
// If two of the same component are used, different names should be supplied
// for each
parent[name] = parent.addChild(name, opts);
};

// Allow for an array of children details to passed in the options
if (vjs.obj.isArray(children)) {
for (var i = 0; i < children.length; i++) {
child = children[i];

if (typeof child == 'string') {
// ['myComponent']
name = child;
opts = {};
} else {
// [{ name: 'myComponent', otherOption: true }]
name = child.name;
opts = child;
}

parent[name] = parent.addChild(name, opts);
handleAdd(name, opts);
}
} else {
vjs.obj.each(children, function(name, opts){
// Allow for disabling default components
// e.g. vjs.options['children']['posterImage'] = false
if (opts === false) return;

// Set property name on player. Could cause conflicts with other prop names, but it's worth making refs easy.
parent[name] = parent.addChild(name, opts);
});
vjs.obj.each(children, handleAdd);
}
}
};
Expand Down
30 changes: 30 additions & 0 deletions test/unit/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,36 @@ test('should do a deep merge of child options', function(){
vjs.Component.prototype.options_ = null;
});

test('should allows setting child options at the parent options level', function(){
var parent;

parent = new vjs.Component(getFakePlayer(), {
'children': [
'component'
],
// parent-level option for child
'component': {
'foo': true
}
});

equal(parent.children()[0].options()['foo'], true, 'child options set when children array is used');

parent = new vjs.Component(getFakePlayer(), {
'children': {
'component': {
'foo': false
}
},
// parent-level option for child
'component': {
'foo': true
}
});

equal(parent.children()[0].options()['foo'], true, 'child options set when children object is used');
});

test('should dispose of component and children', function(){
var comp = new vjs.Component(getFakePlayer());

Expand Down