@@ -5,18 +5,23 @@ var functionAnyRegexStr = '(' + variableRegexStr + '|' + functionNoVendorRegexSt
5
5
6
6
var animationTimingFunctionRegex = / ^ ( c u b i c \- b e z i e r | s t e p s ) \( [ ^ \) ] + \) $ / ;
7
7
var calcRegex = new RegExp ( '^(\\-moz\\-|\\-webkit\\-)?calc\\([^\\)]+\\)$' , 'i' ) ;
8
+ var decimalRegex = / [ 0 - 9 ] / ;
8
9
var functionAnyRegex = new RegExp ( '^' + functionAnyRegexStr + '$' , 'i' ) ;
9
- var hslColorRegex = / ^ h s l \( \s * [ \- \. \d ] + \s * , \s * [ \. \d ] + % \s * , \s * [ \. \d ] + % \s * \) | h s l a \( \s * [ \- \. \d ] + \s * , \s * [ \. \d ] + % \s * , \s * [ \. \d ] + % \s * , \s * [ \. \d ] + \s * \) $ / ;
10
+ var hslColorRegex = / ^ h s l \( \s { 0 , 31 } [ \- \. ] ? \d + \s { 0 , 31 } , \s { 0 , 31 } \. ? \d + % \s { 0 , 31 } , \s { 0 , 31 } \. ? \d + % \s { 0 , 31 } \) | h s l a \( \s { 0 , 31 } [ \- \. ] ? \d + \s { 0 , 31 } , \s { 0 , 31 } \. ? \d + % \s { 0 , 31 } , \s { 0 , 31 } \. ? \d + % \s { 0 , 31 } , \s { 0 , 31 } \. ? \d + \s { 0 , 31 } \) $ / ;
10
11
var identifierRegex = / ^ ( \- [ a - z 0 - 9 _ ] [ a - z 0 - 9 \- _ ] * | [ a - z ] [ a - z 0 - 9 \- _ ] * ) $ / i;
11
12
var longHexColorRegex = / ^ # [ 0 - 9 a - f ] { 6 } $ / i;
12
13
var namedEntityRegex = / ^ [ a - z ] + $ / i;
13
14
var prefixRegex = / ^ - ( [ a - z 0 - 9 ] | - ) * $ / i;
14
- var rgbColorRegex = / ^ r g b \( \s * [ \d ] { 1 , 3 } \s * , \s * [ \d ] { 1 , 3 } \s * , \s * [ \d ] { 1 , 3 } \s * \) | r g b a \( \s * [ \d ] { 1 , 3 } \s * , \s * [ \d ] { 1 , 3 } \s * , \s * [ \d ] { 1 , 3 } \s * , \s * [ \. \d ] + \s * \) $ / ;
15
+ var rgbColorRegex = / ^ r g b \( \s { 0 , 31 } [ \d ] { 1 , 3 } \s { 0 , 31 } , \s { 0 , 31 } [ \d ] { 1 , 3 } \s { 0 , 31 } , \s { 0 , 31 } [ \d ] { 1 , 3 } \s { 0 , 31 } \) | r g b a \( \s { 0 , 31 } [ \d ] { 1 , 3 } \s { 0 , 31 } , \s { 0 , 31 } [ \d ] { 1 , 3 } \s { 0 , 31 } , \s { 0 , 31 } [ \d ] { 1 , 3 } \s { 0 , 31 } , \s { 0 , 31 } [ \. \d ] + \s { 0 , 31 } \) $ / ;
15
16
var shortHexColorRegex = / ^ # [ 0 - 9 a - f ] { 3 } $ / i;
16
- var timeRegex = new RegExp ( '^(\\-?\\+?\\.?\\d+\\.?\\d*(s|ms))$' ) ;
17
+ var validTimeUnits = [ 'ms' , 's' ] ;
17
18
var urlRegex = / ^ u r l \( [ \s \S ] + \) $ / i;
18
19
var variableRegex = new RegExp ( '^' + variableRegexStr + '$' , 'i' ) ;
19
20
21
+ var DECIMAL_DOT = '.' ;
22
+ var MINUS_SIGN = '-' ;
23
+ var PLUS_SIGN = '+' ;
24
+
20
25
var Keywords = {
21
26
'^' : [
22
27
'inherit' ,
@@ -394,7 +399,7 @@ function isNamedEntity(value) {
394
399
}
395
400
396
401
function isNumber ( value ) {
397
- return value . length > 0 && ( '' + parseFloat ( value ) ) === value ;
402
+ return scanForNumber ( value ) == value . length ;
398
403
}
399
404
400
405
function isRgbColor ( value ) {
@@ -415,11 +420,19 @@ function isVariable(value) {
415
420
}
416
421
417
422
function isTime ( value ) {
418
- return timeRegex . test ( value ) ;
423
+ var numberUpTo = scanForNumber ( value ) ;
424
+
425
+ return numberUpTo == value . length && parseInt ( value ) === 0 ||
426
+ numberUpTo > - 1 && validTimeUnits . indexOf ( value . slice ( numberUpTo + 1 ) ) > - 1 ;
419
427
}
420
428
421
- function isUnit ( compatibleCssUnitRegex , value ) {
422
- return compatibleCssUnitRegex . test ( value ) ;
429
+ function isUnit ( validUnits , value ) {
430
+ var numberUpTo = scanForNumber ( value ) ;
431
+
432
+ return numberUpTo == value . length && parseInt ( value ) === 0 ||
433
+ numberUpTo > - 1 && validUnits . indexOf ( value . slice ( numberUpTo + 1 ) ) > - 1 ||
434
+ value == 'auto' ||
435
+ value == 'inherit' ;
423
436
}
424
437
425
438
function isUrl ( value ) {
@@ -432,13 +445,38 @@ function isZIndex(value) {
432
445
isKeyword ( '^' ) ( value ) ;
433
446
}
434
447
448
+ function scanForNumber ( value ) {
449
+ var hasDot = false ;
450
+ var hasSign = false ;
451
+ var character ;
452
+ var i , l ;
453
+
454
+ for ( i = 0 , l = value . length ; i < l ; i ++ ) {
455
+ character = value [ i ] ;
456
+
457
+ if ( i === 0 && ( character == PLUS_SIGN || character == MINUS_SIGN ) ) {
458
+ hasSign = true ;
459
+ } else if ( i > 0 && hasSign && ( character == PLUS_SIGN || character == MINUS_SIGN ) ) {
460
+ return i - 1 ;
461
+ } else if ( character == DECIMAL_DOT && ! hasDot ) {
462
+ hasDot = true ;
463
+ } else if ( character == DECIMAL_DOT && hasDot ) {
464
+ return i - 1 ;
465
+ } else if ( decimalRegex . test ( character ) ) {
466
+ continue ;
467
+ } else {
468
+ return i - 1 ;
469
+ }
470
+ }
471
+
472
+ return i ;
473
+ }
474
+
435
475
function validator ( compatibility ) {
436
476
var validUnits = Units . slice ( 0 ) . filter ( function ( value ) {
437
477
return ! ( value in compatibility . units ) || compatibility . units [ value ] === true ;
438
478
} ) ;
439
479
440
- var compatibleCssUnitRegex = new RegExp ( '^(\\-?\\.?\\d+\\.?\\d*(' + validUnits . join ( '|' ) + '|)|auto|inherit)$' , 'i' ) ;
441
-
442
480
return {
443
481
colorOpacity : compatibility . colors . opacity ,
444
482
isAnimationDirectionKeyword : isKeyword ( 'animation-direction' ) ,
@@ -471,12 +509,13 @@ function validator(compatibility) {
471
509
isLineHeightKeyword : isKeyword ( 'line-height' ) ,
472
510
isListStylePositionKeyword : isKeyword ( 'list-style-position' ) ,
473
511
isListStyleTypeKeyword : isKeyword ( 'list-style-type' ) ,
512
+ isNumber : isNumber ,
474
513
isPrefixed : isPrefixed ,
475
514
isPositiveNumber : isPositiveNumber ,
476
515
isRgbColor : isRgbColor ,
477
516
isStyleKeyword : isKeyword ( '*-style' ) ,
478
517
isTime : isTime ,
479
- isUnit : isUnit . bind ( null , compatibleCssUnitRegex ) ,
518
+ isUnit : isUnit . bind ( null , validUnits ) ,
480
519
isUrl : isUrl ,
481
520
isVariable : isVariable ,
482
521
isWidth : isKeyword ( 'width' ) ,
0 commit comments