@@ -99,16 +99,14 @@ exports.valObjects = {
99
99
// TODO 'values shouldn't be in there (edge case: 'dash' in Scatter)
100
100
otherOpts : [ 'dflt' , 'noBlank' , 'strict' , 'arrayOk' , 'values' ] ,
101
101
coerceFunction : function ( v , propOut , dflt , opts ) {
102
- if ( opts . strict === true && typeof v !== 'string' ) {
103
- propOut . set ( dflt ) ;
104
- return ;
105
- }
102
+ if ( typeof v !== 'string' ) {
103
+ var okToCoerce = ( typeof v === 'number' ) ;
106
104
107
- var s = String ( v ) ;
108
- if ( v === undefined || ( opts . noBlank === true && ! s ) ) {
109
- propOut . set ( dflt ) ;
105
+ if ( opts . strict === true || ! okToCoerce ) propOut . set ( dflt ) ;
106
+ else propOut . set ( String ( v ) ) ;
110
107
}
111
- else propOut . set ( s ) ;
108
+ else if ( opts . noBlank && ! v ) propOut . set ( dflt ) ;
109
+ else propOut . set ( v ) ;
112
110
}
113
111
} ,
114
112
color : {
@@ -162,11 +160,11 @@ exports.valObjects = {
162
160
subplotid : {
163
161
description : [
164
162
'An id string of a subplot type (given by dflt), optionally' ,
165
- 'followed by an integer >1. e.g. if dflt=\'geo\', we can have' ,
163
+ 'followed by an integer >1. e.g. if dflt=\'geo\', we can have' ,
166
164
'\'geo\', \'geo2\', \'geo3\', ...'
167
165
] . join ( ' ' ) ,
168
- requiredOpts : [ ] ,
169
- otherOpts : [ 'dflt' ] ,
166
+ requiredOpts : [ 'dflt' ] ,
167
+ otherOpts : [ ] ,
170
168
coerceFunction : function ( v , propOut , dflt ) {
171
169
var dlen = dflt . length ;
172
170
if ( typeof v === 'string' && v . substr ( 0 , dlen ) === dflt &&
@@ -175,6 +173,18 @@ exports.valObjects = {
175
173
return ;
176
174
}
177
175
propOut . set ( dflt ) ;
176
+ } ,
177
+ validateFunction : function ( v , opts ) {
178
+ var dflt = opts . dflt ,
179
+ dlen = dflt . length ;
180
+
181
+ if ( v === dflt ) return true ;
182
+ if ( typeof v !== 'string' ) return false ;
183
+ if ( v . substr ( 0 , dlen ) === dflt && idRegex . test ( v . substr ( dlen ) ) ) {
184
+ return true ;
185
+ }
186
+
187
+ return false ;
178
188
}
179
189
} ,
180
190
flaglist : {
@@ -239,6 +249,22 @@ exports.valObjects = {
239
249
}
240
250
241
251
propOut . set ( vOut ) ;
252
+ } ,
253
+ validateFunction : function ( v , opts ) {
254
+ if ( ! Array . isArray ( v ) ) return false ;
255
+
256
+ var items = opts . items ;
257
+
258
+ if ( v . length !== items . length ) return false ;
259
+
260
+ // valid when all items are valid
261
+ for ( var i = 0 ; i < items . length ; i ++ ) {
262
+ var isItemValid = exports . validate ( v [ i ] , opts . items [ i ] ) ;
263
+
264
+ if ( ! isItemValid ) return false ;
265
+ }
266
+
267
+ return true ;
242
268
}
243
269
}
244
270
} ;
@@ -309,3 +335,22 @@ exports.coerceFont = function(coerce, attr, dfltObj) {
309
335
310
336
return out ;
311
337
} ;
338
+
339
+ exports . validate = function ( value , opts ) {
340
+ var valObject = exports . valObjects [ opts . valType ] ;
341
+
342
+ if ( opts . arrayOk && Array . isArray ( value ) ) return true ;
343
+
344
+ if ( valObject . validateFunction ) {
345
+ return valObject . validateFunction ( value , opts ) ;
346
+ }
347
+
348
+ var failed = { } ,
349
+ out = failed ,
350
+ propMock = { set : function ( v ) { out = v ; } } ;
351
+
352
+ // 'failed' just something mutable that won't be === anything else
353
+
354
+ valObject . coerceFunction ( value , propMock , failed , opts ) ;
355
+ return out !== failed ;
356
+ } ;
0 commit comments