@@ -22,6 +22,9 @@ exports.TYPES = {
22
22
UNIDENT : 0x8000 ,
23
23
} ;
24
24
25
+ // CSS global values
26
+ exports . GLOBAL_VALUES = Object . freeze ( [ 'initial' , 'inherit' , 'unset' , 'revert' , 'revert-layer' ] ) ;
27
+
25
28
// regular expressions
26
29
var DIGIT = '(?:0|[1-9]\\d*)' ;
27
30
var NUMBER = `[+-]?(?:${ DIGIT } (?:\\.\\d*)?|\\.\\d+)(?:e-?${ DIGIT } )?` ;
@@ -37,6 +40,7 @@ var calcRegEx =
37
40
38
41
// This will return one of the above types based on the passed in string
39
42
exports . valueType = function valueType ( val ) {
43
+ // see https://webidl.spec.whatwg.org/#LegacyNullToEmptyString
40
44
if ( val === '' || val === null ) {
41
45
return exports . TYPES . NULL_OR_EMPTY_STR ;
42
46
}
@@ -53,7 +57,7 @@ exports.valueType = function valueType(val) {
53
57
return exports . TYPES . CALC ;
54
58
}
55
59
if ( unitRegEx . test ( val ) ) {
56
- const [ , , unit ] = unitRegEx . exec ( val ) ;
60
+ var [ , , unit ] = unitRegEx . exec ( val ) ;
57
61
if ( ! unit ) {
58
62
return exports . TYPES . NUMBER ;
59
63
}
@@ -162,7 +166,7 @@ exports.parseLength = function parseLength(val) {
162
166
format : 'specifiedValue' ,
163
167
} ) ;
164
168
case exports . TYPES . LENGTH : {
165
- const [ , numVal , unit ] = unitRegEx . exec ( val ) ;
169
+ var [ , numVal , unit ] = unitRegEx . exec ( val ) ;
166
170
return `${ parseFloat ( numVal ) } ${ unit } ` ;
167
171
}
168
172
default :
@@ -186,9 +190,10 @@ exports.parsePercent = function parsePercent(val) {
186
190
return cssCalc ( val , {
187
191
format : 'specifiedValue' ,
188
192
} ) ;
189
- case exports . TYPES . PERCENT :
190
- const [ , numVal , unit ] = unitRegEx . exec ( val ) ;
193
+ case exports . TYPES . PERCENT : {
194
+ var [ , numVal , unit ] = unitRegEx . exec ( val ) ;
191
195
return `${ parseFloat ( numVal ) } ${ unit } ` ;
196
+ }
192
197
default :
193
198
if ( varContainedRegEx . test ( val ) ) {
194
199
return val ;
@@ -212,9 +217,10 @@ exports.parseMeasurement = function parseMeasurement(val) {
212
217
format : 'specifiedValue' ,
213
218
} ) ;
214
219
case exports . TYPES . LENGTH :
215
- case exports . TYPES . PERCENT :
216
- const [ , numVal , unit ] = unitRegEx . exec ( val ) ;
220
+ case exports . TYPES . PERCENT : {
221
+ var [ , numVal , unit ] = unitRegEx . exec ( val ) ;
217
222
return `${ parseFloat ( numVal ) } ${ unit } ` ;
223
+ }
218
224
default :
219
225
if ( varContainedRegEx . test ( val ) ) {
220
226
return val ;
@@ -236,7 +242,7 @@ exports.parseInheritingMeasurement = function parseInheritingMeasurement(val) {
236
242
exports . parseUrl = function parseUrl ( val ) {
237
243
var type = exports . valueType ( val ) ;
238
244
if ( type === exports . TYPES . NULL_OR_EMPTY_STR ) {
239
- return val ;
245
+ return '' ;
240
246
}
241
247
var res = urlRegEx . exec ( val ) ;
242
248
// does it match the regex?
@@ -293,10 +299,11 @@ exports.parseUrl = function parseUrl(val) {
293
299
return 'url("' + urlstr + '")' ;
294
300
} ;
295
301
302
+ // NOTE: seems not in use?
296
303
exports . parseString = function parseString ( val ) {
297
304
var type = exports . valueType ( val ) ;
298
305
if ( type === exports . TYPES . NULL_OR_EMPTY_STR ) {
299
- return val ;
306
+ return '' ;
300
307
}
301
308
if ( type !== exports . TYPES . STRING ) {
302
309
return undefined ;
@@ -320,14 +327,38 @@ exports.parseString = function parseString(val) {
320
327
return val ;
321
328
} ;
322
329
323
- exports . parseColor = function parseColor ( val ) {
330
+ exports . parseKeyword = function parseKeyword ( val , validKeywords = [ ] ) {
324
331
var type = exports . valueType ( val ) ;
325
- if ( type === exports . TYPES . NULL_OR_EMPTY_STR || type === exports . TYPES . VAR ) {
332
+ if ( type === exports . TYPES . NULL_OR_EMPTY_STR ) {
333
+ return '' ;
334
+ }
335
+ if ( type === exports . TYPES . VAR ) {
336
+ return val ;
337
+ }
338
+ if ( type !== exports . TYPES . KEYWORD ) {
339
+ return undefined ;
340
+ }
341
+ val = val . toString ( ) . toLowerCase ( ) ;
342
+ if ( validKeywords . includes ( val ) || exports . GLOBAL_VALUES . includes ( val ) ) {
326
343
return val ;
327
344
}
345
+ return undefined ;
346
+ } ;
347
+
348
+ exports . parseColor = function parseColor ( val ) {
349
+ var type = exports . valueType ( val ) ;
350
+ if ( type === exports . TYPES . NULL_OR_EMPTY_STR ) {
351
+ return '' ;
352
+ }
328
353
if ( type === exports . TYPES . UNDEFINED ) {
329
354
return undefined ;
330
355
}
356
+ if ( type === exports . TYPES . VAR ) {
357
+ return val ;
358
+ }
359
+ if ( type === exports . TYPES . KEYWORD ) {
360
+ return exports . parseKeyword ( val ) ;
361
+ }
331
362
if ( / ^ [ a - z ] + $ / i. test ( val ) && type === exports . TYPES . COLOR ) {
332
363
return val ;
333
364
}
@@ -346,7 +377,7 @@ exports.parseColor = function parseColor(val) {
346
377
exports . parseAngle = function parseAngle ( val ) {
347
378
var type = exports . valueType ( val ) ;
348
379
if ( type === exports . TYPES . NULL_OR_EMPTY_STR ) {
349
- return val ;
380
+ return '' ;
350
381
}
351
382
if ( type !== exports . TYPES . ANGLE ) {
352
383
return undefined ;
@@ -368,34 +399,19 @@ exports.parseAngle = function parseAngle(val) {
368
399
return flt + 'deg' ;
369
400
} ;
370
401
371
- exports . parseKeyword = function parseKeyword ( val , validKeywords ) {
402
+ exports . parseImage = function parseImage ( val ) {
372
403
var type = exports . valueType ( val ) ;
373
404
if ( type === exports . TYPES . NULL_OR_EMPTY_STR ) {
374
- return val ;
405
+ return '' ;
375
406
}
376
- if ( type !== exports . TYPES . KEYWORD ) {
407
+ if ( type === exports . TYPES . UNDEFINED ) {
377
408
return undefined ;
378
409
}
379
- val = val . toString ( ) . toLowerCase ( ) ;
380
- var i ;
381
- for ( i = 0 ; i < validKeywords . length ; i ++ ) {
382
- if ( validKeywords [ i ] . toLowerCase ( ) === val ) {
383
- return validKeywords [ i ] ;
384
- }
385
- }
386
- return undefined ;
387
- } ;
388
-
389
- exports . parseImage = function parseImage ( val ) {
390
- if ( / ^ (?: n o n e | i n h e r i t ) $ / i. test ( val ) ) {
391
- return val . toLowerCase ( ) ;
392
- }
393
- var type = exports . valueType ( val ) ;
394
- if ( type === exports . TYPES . NULL_OR_EMPTY_STR || type === exports . TYPES . VAR ) {
410
+ if ( type === exports . TYPES . VAR ) {
395
411
return val ;
396
412
}
397
- if ( type === exports . TYPES . UNDEFINED ) {
398
- return undefined ;
413
+ if ( type === exports . TYPES . KEYWORD ) {
414
+ return exports . parseKeyword ( val , [ 'none' ] ) ;
399
415
}
400
416
var values = splitValue ( val , {
401
417
delimiter : ',' ,
@@ -445,11 +461,11 @@ exports.dashedToCamelCase = function (dashed) {
445
461
return camel ;
446
462
} ;
447
463
448
- var isSpace = / \s / ;
449
- var openingDeliminators = [ '"' , "'" , '(' ] ;
450
- var closingDeliminators = [ '"' , "'" , ')' ] ;
451
464
// this splits on whitespace, but keeps quoted and parened parts together
452
465
var getParts = function ( str ) {
466
+ var isSpace = / \s / ;
467
+ var openingDeliminators = [ '"' , "'" , '(' ] ;
468
+ var closingDeliminators = [ '"' , "'" , ')' ] ;
453
469
var deliminatorStack = [ ] ;
454
470
var length = str . length ;
455
471
var i ;
@@ -489,6 +505,8 @@ var getParts = function (str) {
489
505
return parts ;
490
506
} ;
491
507
508
+ // FIXME: need additional argument which indicates syntax
509
+ // and/or use Map() for shorthandFor to ensure order of the longhand properties
492
510
/*
493
511
* this either returns undefined meaning that it isn't valid
494
512
* or returns an object where the keys are dashed short
@@ -504,19 +522,19 @@ exports.shorthandParser = function parse(v, shorthandFor) {
504
522
} ) ;
505
523
return obj ;
506
524
}
507
-
525
+ if ( type === exports . TYPES . UNDEFINED ) {
526
+ return undefined ;
527
+ }
508
528
if ( typeof v === 'number' ) {
509
529
v = v . toString ( ) ;
510
530
}
511
-
512
531
if ( typeof v !== 'string' ) {
513
532
return undefined ;
514
533
}
515
-
516
534
if ( v . toLowerCase ( ) === 'inherit' ) {
517
535
return { } ;
518
536
}
519
- var parts = getParts ( v ) ;
537
+ var parts = splitValue ( v ) ;
520
538
var valid = true ;
521
539
parts . forEach ( function ( part , i ) {
522
540
var partValid = false ;
@@ -526,7 +544,9 @@ exports.shorthandParser = function parse(v, shorthandFor) {
526
544
obj [ property ] = part ;
527
545
}
528
546
} ) ;
529
- valid = valid && partValid ;
547
+ if ( valid ) {
548
+ valid = partValid ;
549
+ }
530
550
} ) ;
531
551
if ( ! valid ) {
532
552
return undefined ;
@@ -536,11 +556,16 @@ exports.shorthandParser = function parse(v, shorthandFor) {
536
556
537
557
exports . shorthandSetter = function ( property , shorthandFor ) {
538
558
return function ( v ) {
559
+ if ( v === undefined ) {
560
+ return ;
561
+ }
562
+ if ( v === null ) {
563
+ v = '' ;
564
+ }
539
565
var obj = exports . shorthandParser ( v , shorthandFor ) ;
540
566
if ( obj === undefined ) {
541
567
return ;
542
568
}
543
- //console.log('shorthandSetter for:', property, 'obj:', obj);
544
569
Object . keys ( obj ) . forEach ( function ( subprop ) {
545
570
// in case subprop is an implicit property, this will clear
546
571
// *its* subpropertiesX
@@ -698,12 +723,12 @@ exports.subImplicitSetter = function (prefix, part, isValid, parser) {
698
723
} ;
699
724
} ;
700
725
701
- var camelToDashed = / [ A - Z ] / g;
702
- var firstSegment = / ^ \( [ ^ - ] \) - / ;
703
- var vendorPrefixes = [ 'o' , 'moz' , 'ms' , 'webkit' ] ;
704
726
exports . camelToDashed = function ( camelCase ) {
727
+ var upperCase = / [ A - Z ] / g;
728
+ var firstSegment = / ^ \( [ ^ - ] \) - / ;
729
+ var vendorPrefixes = [ 'o' , 'moz' , 'ms' , 'webkit' ] ;
705
730
var match ;
706
- var dashed = camelCase . replace ( camelToDashed , '-$&' ) . toLowerCase ( ) ;
731
+ var dashed = camelCase . replace ( upperCase , '-$&' ) . toLowerCase ( ) ;
707
732
match = dashed . match ( firstSegment ) ;
708
733
if ( match && vendorPrefixes . indexOf ( match [ 1 ] ) !== - 1 ) {
709
734
dashed = '-' + dashed ;
0 commit comments