1
0
mirror of https://github.com/videojs/video.js.git synced 2025-04-15 11:56:32 +02:00

Array traversing for children opts - closes #1070

This commit is contained in:
Gregory Waxman 2014-03-18 15:49:59 -04:00
parent 80d7b5014a
commit 204bb84ecb
4 changed files with 116 additions and 38 deletions

View File

@ -447,7 +447,13 @@ vjs.Component.prototype.initChildren = function(){
var self = this; var self = this;
// Loop through components and add them to the player // Loop through components and add them to the player
vjs.obj.each(options['children'], function(name, opts){ vjs.each(options['children'], function(name, opts){
//Support for a simpler setup, children with no options
if (typeof name == 'number') {
name = opts;
opts = {};
}
// Allow for disabling default components // Allow for disabling default components
// e.g. vjs.options['children']['posterImage'] = false // e.g. vjs.options['children']['posterImage'] = false
if (opts === false) return; if (opts === false) return;

View File

@ -24,11 +24,11 @@ vjs.createEl = function(tagName, properties){
// browsers handle the attribute just fine. The W3C allows for aria-* attributes to be used in pre-HTML5 docs. // browsers handle the attribute just fine. The W3C allows for aria-* attributes to be used in pre-HTML5 docs.
// http://www.w3.org/TR/wai-aria-primer/#ariahtml. Using setAttribute gets around this problem. // http://www.w3.org/TR/wai-aria-primer/#ariahtml. Using setAttribute gets around this problem.
if (propName.indexOf('aria-') !== -1 || propName=='role') { if (propName.indexOf('aria-') !== -1 || propName=='role') {
el.setAttribute(propName, properties[propName]); el.setAttribute(propName, properties[propName]);
} else { } else {
el[propName] = properties[propName]; el[propName] = properties[propName];
} }
} }
} }
return el; return el;
@ -44,6 +44,18 @@ vjs.capitalize = function(string){
return string.charAt(0).toUpperCase() + string.slice(1); return string.charAt(0).toUpperCase() + string.slice(1);
}; };
vjs.each = function (arrLike, fn, context) {
if (vjs.obj.isPlain(arrLike)) vjs.obj.each(arrLike, fn, context);
else {
for (var i = 0, len = arrLike.length; i < len; ++i) {
var val = arrLike[i];
if (vjs.obj.isPlain(val)) vjs.obj.each(val, fn, context);
else fn.call(context || this, i, val);
}
}
};
/** /**
* Object functions container * Object functions container
* @type {Object} * @type {Object}
@ -60,7 +72,7 @@ vjs.obj = {};
* @param {Object} obj Object to use as prototype * @param {Object} obj Object to use as prototype
* @private * @private
*/ */
vjs.obj.create = Object.create || function(obj){ vjs.obj.create = Object.create || function(obj){
//Create a new function called 'F' which is just an empty object. //Create a new function called 'F' which is just an empty object.
function F() {} function F() {}
@ -155,9 +167,9 @@ vjs.obj.copy = function(obj){
*/ */
vjs.obj.isPlain = function(obj){ vjs.obj.isPlain = function(obj){
return !!obj return !!obj
&& typeof obj === 'object' && typeof obj === 'object'
&& obj.toString() === '[object Object]' && obj.toString() === '[object Object]'
&& obj.constructor === Object; && obj.constructor === Object;
}; };
/** /**
@ -354,8 +366,8 @@ vjs.ANDROID_VERSION = (function() {
// This matches Android Major.Minor.Patch versions // This matches Android Major.Minor.Patch versions
// ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned
var match = vjs.USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i), var match = vjs.USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i),
major, major,
minor; minor;
if (!match) { if (!match) {
return null; return null;
@ -669,32 +681,32 @@ vjs.log = function(){
// Offset Left // Offset Left
// getBoundingClientRect technique from John Resig http://ejohn.org/blog/getboundingclientrect-is-awesome/ // getBoundingClientRect technique from John Resig http://ejohn.org/blog/getboundingclientrect-is-awesome/
vjs.findPosition = function(el) { vjs.findPosition = function(el) {
var box, docEl, body, clientLeft, scrollLeft, left, clientTop, scrollTop, top; var box, docEl, body, clientLeft, scrollLeft, left, clientTop, scrollTop, top;
if (el.getBoundingClientRect && el.parentNode) { if (el.getBoundingClientRect && el.parentNode) {
box = el.getBoundingClientRect(); box = el.getBoundingClientRect();
} }
if (!box) {
return {
left: 0,
top: 0
};
}
docEl = document.documentElement;
body = document.body;
clientLeft = docEl.clientLeft || body.clientLeft || 0;
scrollLeft = window.pageXOffset || body.scrollLeft;
left = box.left + scrollLeft - clientLeft;
clientTop = docEl.clientTop || body.clientTop || 0;
scrollTop = window.pageYOffset || body.scrollTop;
top = box.top + scrollTop - clientTop;
if (!box) {
return { return {
left: left, left: 0,
top: top top: 0
}; };
}
docEl = document.documentElement;
body = document.body;
clientLeft = docEl.clientLeft || body.clientLeft || 0;
scrollLeft = window.pageXOffset || body.scrollLeft;
left = box.left + scrollLeft - clientLeft;
clientTop = docEl.clientTop || body.clientTop || 0;
scrollTop = window.pageYOffset || body.scrollTop;
top = box.top + scrollTop - clientTop;
return {
left: left,
top: top
};
}; };

View File

@ -26,7 +26,7 @@ test('should add a child component', function(){
ok(comp.getChildById(child.id()) === child); ok(comp.getChildById(child.id()) === child);
}); });
test('should init child coponents from options', function(){ test('should init child components from options', function(){
var comp = new vjs.Component(getFakePlayer(), { var comp = new vjs.Component(getFakePlayer(), {
children: { children: {
'component': true 'component': true
@ -37,6 +37,32 @@ test('should init child coponents from options', function(){
ok(comp.el().childNodes.length === 1); ok(comp.el().childNodes.length === 1);
}); });
test('should init child components from simple children array', function(){
var comp = new vjs.Component(getFakePlayer(), {
children: [
'component',
'component',
'component'
]
});
ok(comp.children().length === 3);
ok(comp.el().childNodes.length === 3);
});
test('should init child components from children array of objects', function(){
var comp = new vjs.Component(getFakePlayer(), {
children: [
{'component':{}},
{'component':{}},
{'component':{}}
]
});
ok(comp.children().length === 3);
ok(comp.el().childNodes.length === 3);
});
test('should do a deep merge of child options', function(){ test('should do a deep merge of child options', function(){
// Create a default option for component // Create a default option for component
vjs.Component.prototype.options_ = { vjs.Component.prototype.options_ = {

View File

@ -22,13 +22,47 @@ test('should loop through each property on an object', function(){
}; };
// Add 3 to each value // Add 3 to each value
vjs.obj.each(asdf, function(key, value){ vjs.each(asdf, function(key, value){
asdf[key] = value + 3; asdf[key] = value + 3;
}); });
deepEqual(asdf,{a:4,b:5,'c':6}); deepEqual(asdf,{a:4,b:5,'c':6});
}); });
test('should loop through simple array', function(){
var asdf = [
'a',
'b',
'c'
];
var newArr = [];
vjs.each(asdf, function(key, value){
newArr[key] = value;
ok(typeof key == 'number', 'Key is not a number, the array index');
ok(typeof value == 'string', 'Value is not a string');
});
deepEqual(asdf,newArr);
});
test('should loop through an array of objects', function(){
var asdf = [
{ a: {} },
{ b: {} },
{ 'c': {} }
];
var newObj = {};
vjs.each(asdf, function(key, value){
newObj[key] = value;
ok(typeof key == 'string', 'Key is not a string');
ok(vjs.obj.isPlain(value), 'Value is not an object');
});
deepEqual(newObj, { a: {}, b: {}, 'c': {}});
});
test('should copy an object', function(){ test('should copy an object', function(){
var asdf = { var asdf = {
a: 1, a: 1,