From 204bb84ecbf0d1ae10b2d69ed2a3488e41adf1e2 Mon Sep 17 00:00:00 2001 From: Gregory Waxman Date: Tue, 18 Mar 2014 15:49:59 -0400 Subject: [PATCH] Array traversing for children opts - closes #1070 --- src/js/component.js | 8 ++++- src/js/lib.js | 82 ++++++++++++++++++++++++------------------ test/unit/component.js | 28 ++++++++++++++- test/unit/lib.js | 36 ++++++++++++++++++- 4 files changed, 116 insertions(+), 38 deletions(-) diff --git a/src/js/component.js b/src/js/component.js index 82dde8fb2..366481a5c 100644 --- a/src/js/component.js +++ b/src/js/component.js @@ -447,7 +447,13 @@ vjs.Component.prototype.initChildren = function(){ var self = this; // 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 // e.g. vjs.options['children']['posterImage'] = false if (opts === false) return; diff --git a/src/js/lib.js b/src/js/lib.js index 51667ef72..e879c7b6b 100644 --- a/src/js/lib.js +++ b/src/js/lib.js @@ -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. // http://www.w3.org/TR/wai-aria-primer/#ariahtml. Using setAttribute gets around this problem. - if (propName.indexOf('aria-') !== -1 || propName=='role') { - el.setAttribute(propName, properties[propName]); - } else { - el[propName] = properties[propName]; - } + if (propName.indexOf('aria-') !== -1 || propName=='role') { + el.setAttribute(propName, properties[propName]); + } else { + el[propName] = properties[propName]; + } } } return el; @@ -44,6 +44,18 @@ vjs.capitalize = function(string){ 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 * @type {Object} @@ -60,7 +72,7 @@ vjs.obj = {}; * @param {Object} obj Object to use as prototype * @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. function F() {} @@ -155,9 +167,9 @@ vjs.obj.copy = function(obj){ */ vjs.obj.isPlain = function(obj){ return !!obj - && typeof obj === 'object' - && obj.toString() === '[object Object]' - && obj.constructor === Object; + && typeof obj === 'object' + && obj.toString() === '[object Object]' + && obj.constructor === Object; }; /** @@ -354,8 +366,8 @@ vjs.ANDROID_VERSION = (function() { // 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 var match = vjs.USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i), - major, - minor; + major, + minor; if (!match) { return null; @@ -669,32 +681,32 @@ vjs.log = function(){ // Offset Left // getBoundingClientRect technique from John Resig http://ejohn.org/blog/getboundingclientrect-is-awesome/ 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) { - 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 (el.getBoundingClientRect && el.parentNode) { + box = el.getBoundingClientRect(); + } + if (!box) { return { - left: left, - top: top + 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; + + return { + left: left, + top: top + }; }; diff --git a/test/unit/component.js b/test/unit/component.js index fd31df56e..0eec962c2 100644 --- a/test/unit/component.js +++ b/test/unit/component.js @@ -26,7 +26,7 @@ test('should add a child component', function(){ 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(), { children: { 'component': true @@ -37,6 +37,32 @@ test('should init child coponents from options', function(){ 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(){ // Create a default option for component vjs.Component.prototype.options_ = { diff --git a/test/unit/lib.js b/test/unit/lib.js index 3862efeb4..9f43dd0d4 100644 --- a/test/unit/lib.js +++ b/test/unit/lib.js @@ -22,13 +22,47 @@ test('should loop through each property on an object', function(){ }; // Add 3 to each value - vjs.obj.each(asdf, function(key, value){ + vjs.each(asdf, function(key, value){ asdf[key] = value + 3; }); 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(){ var asdf = { a: 1,