@@ -307,20 +307,45 @@ exports.validateTemplate = function(figureIn, template) {
307307 var fullLayout = figure . _fullLayout ;
308308 var fullData = figure . _fullData ;
309309
310+ var layoutPaths = { } ;
311+ function crawlLayoutForContainers ( obj , paths ) {
312+ for ( var key in obj ) {
313+ if ( key . charAt ( 0 ) !== '_' && isPlainObject ( obj [ key ] ) ) {
314+ var baseKey = getBaseKey ( key ) ;
315+ var nextPaths = [ ] ;
316+ var i ;
317+ for ( i = 0 ; i < paths . length ; i ++ ) {
318+ nextPaths . push ( getNextPath ( obj , key , paths [ i ] ) ) ;
319+ if ( baseKey !== key ) nextPaths . push ( getNextPath ( obj , baseKey , paths [ i ] ) ) ;
320+ }
321+ for ( i = 0 ; i < nextPaths . length ; i ++ ) {
322+ layoutPaths [ nextPaths [ i ] ] = 1 ;
323+ }
324+ crawlLayoutForContainers ( obj [ key ] , nextPaths ) ;
325+ }
326+ }
327+ }
328+
329+ function crawlLayoutTemplateForContainers ( obj , path ) {
330+ for ( var key in obj ) {
331+ if ( key . indexOf ( 'defaults' ) === - 1 && isPlainObject ( obj [ key ] ) ) {
332+ var nextPath = getNextPath ( obj , key , path ) ;
333+ if ( layoutPaths [ nextPath ] ) {
334+ crawlLayoutTemplateForContainers ( obj [ key ] , nextPath ) ;
335+ }
336+ else {
337+ errorList . push ( { code : 'unused' , path : nextPath } ) ;
338+ }
339+ }
340+ }
341+ }
342+
310343 if ( ! isPlainObject ( layoutTemplate ) ) {
311344 errorList . push ( { code : 'layout' } ) ;
312345 }
313346 else {
314- // TODO: any need to look deeper than the first level of layout?
315- // I don't think so, that gets all the subplot types which should be
316- // sufficient.
317- for ( var key in layoutTemplate ) {
318- if ( key . indexOf ( 'defaults' ) === - 1 && isPlainObject ( layoutTemplate [ key ] ) &&
319- ! hasMatchingKey ( fullLayout , key )
320- ) {
321- errorList . push ( { code : 'unused' , path : 'layout.' + key } ) ;
322- }
323- }
347+ crawlLayoutForContainers ( fullLayout , [ 'layout' ] ) ;
348+ crawlLayoutTemplateForContainers ( layoutTemplate , 'layout' ) ;
324349 }
325350
326351 if ( ! isPlainObject ( dataTemplate ) ) {
0 commit comments