@@ -343,12 +343,12 @@ exports.valObjectMeta = {
343343 return false ;
344344 }
345345 for ( var j = 0 ; j < v [ i ] . length ; j ++ ) {
346- if ( ! exports . validate ( v [ i ] [ j ] , arrayItems ? items [ i ] [ j ] : items ) ) {
346+ if ( ! validate ( v [ i ] [ j ] , arrayItems ? items [ i ] [ j ] : items ) ) {
347347 return false ;
348348 }
349349 }
350350 }
351- else if ( ! exports . validate ( v [ i ] , arrayItems ? items [ i ] : items ) ) return false ;
351+ else if ( ! validate ( v [ i ] , arrayItems ? items [ i ] : items ) ) return false ;
352352 }
353353
354354 return true ;
@@ -369,10 +369,17 @@ exports.valObjectMeta = {
369369 * as a convenience, returns the value it finally set
370370 */
371371exports . coerce = function ( containerIn , containerOut , attributes , attribute , dflt ) {
372- var opts = nestedProperty ( attributes , attribute ) . get ( ) ,
373- propIn = nestedProperty ( containerIn , attribute ) ,
374- propOut = nestedProperty ( containerOut , attribute ) ,
375- v = propIn . get ( ) ;
372+ var opts = nestedProperty ( attributes , attribute ) . get ( ) ;
373+ var propIn = nestedProperty ( containerIn , attribute ) ;
374+ var propOut = nestedProperty ( containerOut , attribute ) ;
375+ var v = propIn . get ( ) ;
376+
377+ var template = containerOut . _template ;
378+ if ( v === undefined && template ) {
379+ v = nestedProperty ( template , attribute ) . get ( ) ;
380+ // already used the template value, so short-circuit the second check
381+ template = 0 ;
382+ }
376383
377384 if ( dflt === undefined ) dflt = opts . dflt ;
378385
@@ -387,9 +394,18 @@ exports.coerce = function(containerIn, containerOut, attributes, attribute, dflt
387394 return v ;
388395 }
389396
390- exports . valObjectMeta [ opts . valType ] . coerceFunction ( v , propOut , dflt , opts ) ;
397+ var coerceFunction = exports . valObjectMeta [ opts . valType ] . coerceFunction ;
398+ coerceFunction ( v , propOut , dflt , opts ) ;
391399
392- return propOut . get ( ) ;
400+ var out = propOut . get ( ) ;
401+ // in case v was provided but invalid, try the template again so it still
402+ // overrides the regular default
403+ if ( template && out === dflt && ! validate ( v , opts ) ) {
404+ v = nestedProperty ( template , attribute ) . get ( ) ;
405+ coerceFunction ( v , propOut , dflt , opts ) ;
406+ out = propOut . get ( ) ;
407+ }
408+ return out ;
393409} ;
394410
395411/**
@@ -486,7 +502,7 @@ exports.coerceSelectionMarkerOpacity = function(traceOut, coerce) {
486502 coerce ( 'unselected.marker.opacity' , usmoDflt ) ;
487503} ;
488504
489- exports . validate = function ( value , opts ) {
505+ function validate ( value , opts ) {
490506 var valObjectDef = exports . valObjectMeta [ opts . valType ] ;
491507
492508 if ( opts . arrayOk && isArrayOrTypedArray ( value ) ) return true ;
@@ -503,4 +519,5 @@ exports.validate = function(value, opts) {
503519
504520 valObjectDef . coerceFunction ( value , propMock , failed , opts ) ;
505521 return out !== failed ;
506- } ;
522+ }
523+ exports . validate = validate ;
0 commit comments