You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							529 lines
						
					
					
						
							11 KiB
						
					
					
				
			
		
		
	
	
							529 lines
						
					
					
						
							11 KiB
						
					
					
				var functionNoVendorRegexStr = '[A-Z]+(\\-|[A-Z]|[0-9])+\\(.*?\\)'; | 
						|
var functionVendorRegexStr = '\\-(\\-|[A-Z]|[0-9])+\\(.*?\\)'; | 
						|
var variableRegexStr = 'var\\(\\-\\-[^\\)]+\\)'; | 
						|
var functionAnyRegexStr = '(' + variableRegexStr + '|' + functionNoVendorRegexStr + '|' + functionVendorRegexStr + ')'; | 
						|
 | 
						|
var calcRegex = new RegExp('^(\\-moz\\-|\\-webkit\\-)?calc\\([^\\)]+\\)$', 'i'); | 
						|
var decimalRegex = /[0-9]/; | 
						|
var functionAnyRegex = new RegExp('^' + functionAnyRegexStr + '$', 'i'); | 
						|
var hslColorRegex = /^hsl\(\s{0,31}[\-\.]?\d+\s{0,31},\s{0,31}\.?\d+%\s{0,31},\s{0,31}\.?\d+%\s{0,31}\)|hsla\(\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}\)$/i; | 
						|
var identifierRegex = /^(\-[a-z0-9_][a-z0-9\-_]*|[a-z][a-z0-9\-_]*)$/i; | 
						|
var namedEntityRegex = /^[a-z]+$/i; | 
						|
var prefixRegex = /^-([a-z0-9]|-)*$/i; | 
						|
var rgbColorRegex = /^rgb\(\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}\)|rgba\(\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}\)$/i; | 
						|
var timingFunctionRegex = /^(cubic\-bezier|steps)\([^\)]+\)$/; | 
						|
var validTimeUnits = ['ms', 's']; | 
						|
var urlRegex = /^url\([\s\S]+\)$/i; | 
						|
var variableRegex = new RegExp('^' + variableRegexStr + '$', 'i'); | 
						|
 | 
						|
var eightValueColorRegex = /^#[0-9a-f]{8}$/i; | 
						|
var fourValueColorRegex = /^#[0-9a-f]{4}$/i; | 
						|
var sixValueColorRegex = /^#[0-9a-f]{6}$/i; | 
						|
var threeValueColorRegex = /^#[0-9a-f]{3}$/i; | 
						|
 | 
						|
var DECIMAL_DOT = '.'; | 
						|
var MINUS_SIGN = '-'; | 
						|
var PLUS_SIGN = '+'; | 
						|
 | 
						|
var Keywords = { | 
						|
  '^': [ | 
						|
    'inherit', | 
						|
    'initial', | 
						|
    'unset' | 
						|
  ], | 
						|
  '*-style': [ | 
						|
    'auto', | 
						|
    'dashed', | 
						|
    'dotted', | 
						|
    'double', | 
						|
    'groove', | 
						|
    'hidden', | 
						|
    'inset', | 
						|
    'none', | 
						|
    'outset', | 
						|
    'ridge', | 
						|
    'solid' | 
						|
  ], | 
						|
  '*-timing-function': [ | 
						|
    'ease', | 
						|
    'ease-in', | 
						|
    'ease-in-out', | 
						|
    'ease-out', | 
						|
    'linear', | 
						|
    'step-end', | 
						|
    'step-start' | 
						|
  ], | 
						|
  'animation-direction': [ | 
						|
    'alternate', | 
						|
    'alternate-reverse', | 
						|
    'normal', | 
						|
    'reverse' | 
						|
  ], | 
						|
  'animation-fill-mode': [ | 
						|
    'backwards', | 
						|
    'both', | 
						|
    'forwards', | 
						|
    'none' | 
						|
  ], | 
						|
  'animation-iteration-count': [ | 
						|
    'infinite' | 
						|
  ], | 
						|
  'animation-name': [ | 
						|
    'none' | 
						|
  ], | 
						|
  'animation-play-state': [ | 
						|
    'paused', | 
						|
    'running' | 
						|
  ], | 
						|
  'background-attachment': [ | 
						|
    'fixed', | 
						|
    'inherit', | 
						|
    'local', | 
						|
    'scroll' | 
						|
  ], | 
						|
  'background-clip': [ | 
						|
    'border-box', | 
						|
    'content-box', | 
						|
    'inherit', | 
						|
    'padding-box', | 
						|
    'text' | 
						|
  ], | 
						|
  'background-origin': [ | 
						|
    'border-box', | 
						|
    'content-box', | 
						|
    'inherit', | 
						|
    'padding-box' | 
						|
  ], | 
						|
  'background-position': [ | 
						|
    'bottom', | 
						|
    'center', | 
						|
    'left', | 
						|
    'right', | 
						|
    'top' | 
						|
  ], | 
						|
  'background-repeat': [ | 
						|
    'no-repeat', | 
						|
    'inherit', | 
						|
    'repeat', | 
						|
    'repeat-x', | 
						|
    'repeat-y', | 
						|
    'round', | 
						|
    'space' | 
						|
  ], | 
						|
  'background-size': [ | 
						|
    'auto', | 
						|
    'cover', | 
						|
    'contain' | 
						|
  ], | 
						|
  'border-collapse': [ | 
						|
    'collapse', | 
						|
    'inherit', | 
						|
    'separate' | 
						|
  ], | 
						|
  'bottom': [ | 
						|
    'auto' | 
						|
  ], | 
						|
  'clear': [ | 
						|
    'both', | 
						|
    'left', | 
						|
    'none', | 
						|
    'right' | 
						|
  ], | 
						|
  'color': [ | 
						|
    'transparent' | 
						|
  ], | 
						|
  'cursor': [ | 
						|
    'all-scroll', | 
						|
    'auto', | 
						|
    'col-resize', | 
						|
    'crosshair', | 
						|
    'default', | 
						|
    'e-resize', | 
						|
    'help', | 
						|
    'move', | 
						|
    'n-resize', | 
						|
    'ne-resize', | 
						|
    'no-drop', | 
						|
    'not-allowed', | 
						|
    'nw-resize', | 
						|
    'pointer', | 
						|
    'progress', | 
						|
    'row-resize', | 
						|
    's-resize', | 
						|
    'se-resize', | 
						|
    'sw-resize', | 
						|
    'text', | 
						|
    'vertical-text', | 
						|
    'w-resize', | 
						|
    'wait' | 
						|
  ], | 
						|
  'display': [ | 
						|
    'block', | 
						|
    'inline', | 
						|
    'inline-block', | 
						|
    'inline-table', | 
						|
    'list-item', | 
						|
    'none', | 
						|
    'table', | 
						|
    'table-caption', | 
						|
    'table-cell', | 
						|
    'table-column', | 
						|
    'table-column-group', | 
						|
    'table-footer-group', | 
						|
    'table-header-group', | 
						|
    'table-row', | 
						|
    'table-row-group' | 
						|
  ], | 
						|
  'float': [ | 
						|
    'left', | 
						|
    'none', | 
						|
    'right' | 
						|
  ], | 
						|
  'left': [ | 
						|
    'auto' | 
						|
  ], | 
						|
  'font': [ | 
						|
    'caption', | 
						|
    'icon', | 
						|
    'menu', | 
						|
    'message-box', | 
						|
    'small-caption', | 
						|
    'status-bar', | 
						|
    'unset' | 
						|
  ], | 
						|
  'font-size': [ | 
						|
    'large', | 
						|
    'larger', | 
						|
    'medium', | 
						|
    'small', | 
						|
    'smaller', | 
						|
    'x-large', | 
						|
    'x-small', | 
						|
    'xx-large', | 
						|
    'xx-small' | 
						|
  ], | 
						|
  'font-stretch': [ | 
						|
    'condensed', | 
						|
    'expanded', | 
						|
    'extra-condensed', | 
						|
    'extra-expanded', | 
						|
    'normal', | 
						|
    'semi-condensed', | 
						|
    'semi-expanded', | 
						|
    'ultra-condensed', | 
						|
    'ultra-expanded' | 
						|
  ], | 
						|
  'font-style': [ | 
						|
    'italic', | 
						|
    'normal', | 
						|
    'oblique' | 
						|
  ], | 
						|
  'font-variant': [ | 
						|
    'normal', | 
						|
    'small-caps' | 
						|
  ], | 
						|
  'font-weight': [ | 
						|
    '100', | 
						|
    '200', | 
						|
    '300', | 
						|
    '400', | 
						|
    '500', | 
						|
    '600', | 
						|
    '700', | 
						|
    '800', | 
						|
    '900', | 
						|
    'bold', | 
						|
    'bolder', | 
						|
    'lighter', | 
						|
    'normal' | 
						|
  ], | 
						|
  'line-height': [ | 
						|
    'normal' | 
						|
  ], | 
						|
  'list-style-position': [ | 
						|
    'inside', | 
						|
    'outside' | 
						|
  ], | 
						|
  'list-style-type': [ | 
						|
    'armenian', | 
						|
    'circle', | 
						|
    'decimal', | 
						|
    'decimal-leading-zero', | 
						|
    'disc', | 
						|
    'decimal|disc', // this is the default value of list-style-type, see comment in compactable.js | 
						|
    'georgian', | 
						|
    'lower-alpha', | 
						|
    'lower-greek', | 
						|
    'lower-latin', | 
						|
    'lower-roman', | 
						|
    'none', | 
						|
    'square', | 
						|
    'upper-alpha', | 
						|
    'upper-latin', | 
						|
    'upper-roman' | 
						|
  ], | 
						|
  'overflow': [ | 
						|
    'auto', | 
						|
    'hidden', | 
						|
    'scroll', | 
						|
    'visible' | 
						|
  ], | 
						|
  'position': [ | 
						|
    'absolute', | 
						|
    'fixed', | 
						|
    'relative', | 
						|
    'static' | 
						|
  ], | 
						|
  'right': [ | 
						|
    'auto' | 
						|
  ], | 
						|
  'text-align': [ | 
						|
    'center', | 
						|
    'justify', | 
						|
    'left', | 
						|
    'left|right', // this is the default value of list-style-type, see comment in compactable.js | 
						|
    'right' | 
						|
  ], | 
						|
  'text-decoration': [ | 
						|
    'line-through', | 
						|
    'none', | 
						|
    'overline', | 
						|
    'underline' | 
						|
  ], | 
						|
  'text-overflow': [ | 
						|
    'clip', | 
						|
    'ellipsis' | 
						|
  ], | 
						|
  'top': [ | 
						|
    'auto' | 
						|
  ], | 
						|
  'vertical-align': [ | 
						|
    'baseline', | 
						|
    'bottom', | 
						|
    'middle', | 
						|
    'sub', | 
						|
    'super', | 
						|
    'text-bottom', | 
						|
    'text-top', | 
						|
    'top' | 
						|
  ], | 
						|
  'visibility': [ | 
						|
    'collapse', | 
						|
    'hidden', | 
						|
    'visible' | 
						|
  ], | 
						|
  'white-space': [ | 
						|
    'normal', | 
						|
    'nowrap', | 
						|
    'pre' | 
						|
  ], | 
						|
  'width': [ | 
						|
    'inherit', | 
						|
    'initial', | 
						|
    'medium', | 
						|
    'thick', | 
						|
    'thin' | 
						|
  ] | 
						|
}; | 
						|
 | 
						|
var Units = [ | 
						|
  '%', | 
						|
  'ch', | 
						|
  'cm', | 
						|
  'em', | 
						|
  'ex', | 
						|
  'in', | 
						|
  'mm', | 
						|
  'pc', | 
						|
  'pt', | 
						|
  'px', | 
						|
  'rem', | 
						|
  'vh', | 
						|
  'vm', | 
						|
  'vmax', | 
						|
  'vmin', | 
						|
  'vw' | 
						|
]; | 
						|
 | 
						|
function isColor(value) { | 
						|
  return value != 'auto' && | 
						|
    ( | 
						|
      isKeyword('color')(value) || | 
						|
      isHexColor(value) || | 
						|
      isColorFunction(value) || | 
						|
      isNamedEntity(value) | 
						|
    ); | 
						|
} | 
						|
 | 
						|
function isColorFunction(value) { | 
						|
  return isRgbColor(value) || isHslColor(value); | 
						|
} | 
						|
 | 
						|
function isDynamicUnit(value) { | 
						|
  return calcRegex.test(value); | 
						|
} | 
						|
 | 
						|
function isFunction(value) { | 
						|
  return functionAnyRegex.test(value); | 
						|
} | 
						|
 | 
						|
function isHexColor(value) { | 
						|
  return threeValueColorRegex.test(value) || fourValueColorRegex.test(value) || sixValueColorRegex.test(value) || eightValueColorRegex.test(value); | 
						|
} | 
						|
 | 
						|
function isHslColor(value) { | 
						|
  return hslColorRegex.test(value); | 
						|
} | 
						|
 | 
						|
function isIdentifier(value) { | 
						|
  return identifierRegex.test(value); | 
						|
} | 
						|
 | 
						|
function isImage(value) { | 
						|
  return value == 'none' || value == 'inherit' || isUrl(value); | 
						|
} | 
						|
 | 
						|
function isKeyword(propertyName) { | 
						|
  return function(value) { | 
						|
    return Keywords[propertyName].indexOf(value) > -1; | 
						|
  }; | 
						|
} | 
						|
 | 
						|
function isNamedEntity(value) { | 
						|
  return namedEntityRegex.test(value); | 
						|
} | 
						|
 | 
						|
function isNumber(value) { | 
						|
  return scanForNumber(value) == value.length; | 
						|
} | 
						|
 | 
						|
function isRgbColor(value) { | 
						|
  return rgbColorRegex.test(value); | 
						|
} | 
						|
 | 
						|
function isPrefixed(value) { | 
						|
  return prefixRegex.test(value); | 
						|
} | 
						|
 | 
						|
function isPositiveNumber(value) { | 
						|
  return isNumber(value) && | 
						|
    parseFloat(value) >= 0; | 
						|
} | 
						|
 | 
						|
function isVariable(value) { | 
						|
  return variableRegex.test(value); | 
						|
} | 
						|
 | 
						|
function isTime(value) { | 
						|
  var numberUpTo = scanForNumber(value); | 
						|
 | 
						|
  return numberUpTo == value.length && parseInt(value) === 0 || | 
						|
    numberUpTo > -1 && validTimeUnits.indexOf(value.slice(numberUpTo + 1)) > -1; | 
						|
} | 
						|
 | 
						|
function isTimingFunction() { | 
						|
  var isTimingFunctionKeyword = isKeyword('*-timing-function'); | 
						|
 | 
						|
  return function (value) { | 
						|
    return isTimingFunctionKeyword(value) || timingFunctionRegex.test(value); | 
						|
  }; | 
						|
} | 
						|
 | 
						|
function isUnit(validUnits, value) { | 
						|
  var numberUpTo = scanForNumber(value); | 
						|
 | 
						|
  return numberUpTo == value.length && parseInt(value) === 0 || | 
						|
    numberUpTo > -1 && validUnits.indexOf(value.slice(numberUpTo + 1)) > -1 || | 
						|
    value == 'auto' || | 
						|
    value == 'inherit'; | 
						|
} | 
						|
 | 
						|
function isUrl(value) { | 
						|
  return urlRegex.test(value); | 
						|
} | 
						|
 | 
						|
function isZIndex(value) { | 
						|
  return value == 'auto' || | 
						|
    isNumber(value) || | 
						|
    isKeyword('^')(value); | 
						|
} | 
						|
 | 
						|
function scanForNumber(value) { | 
						|
  var hasDot = false; | 
						|
  var hasSign = false; | 
						|
  var character; | 
						|
  var i, l; | 
						|
 | 
						|
  for (i = 0, l = value.length; i < l; i++) { | 
						|
    character = value[i]; | 
						|
 | 
						|
    if (i === 0 && (character == PLUS_SIGN || character == MINUS_SIGN)) { | 
						|
      hasSign = true; | 
						|
    } else if (i > 0 && hasSign && (character == PLUS_SIGN || character == MINUS_SIGN)) { | 
						|
      return i - 1; | 
						|
    } else if (character == DECIMAL_DOT && !hasDot) { | 
						|
      hasDot = true; | 
						|
    } else if (character == DECIMAL_DOT && hasDot) { | 
						|
      return i - 1; | 
						|
    } else if (decimalRegex.test(character)) { | 
						|
      continue; | 
						|
    } else { | 
						|
      return i - 1; | 
						|
    } | 
						|
  } | 
						|
 | 
						|
  return i; | 
						|
} | 
						|
 | 
						|
function validator(compatibility) { | 
						|
  var validUnits = Units.slice(0).filter(function (value) { | 
						|
    return !(value in compatibility.units) || compatibility.units[value] === true; | 
						|
  }); | 
						|
 | 
						|
  return { | 
						|
    colorOpacity: compatibility.colors.opacity, | 
						|
    isAnimationDirectionKeyword: isKeyword('animation-direction'), | 
						|
    isAnimationFillModeKeyword: isKeyword('animation-fill-mode'), | 
						|
    isAnimationIterationCountKeyword: isKeyword('animation-iteration-count'), | 
						|
    isAnimationNameKeyword: isKeyword('animation-name'), | 
						|
    isAnimationPlayStateKeyword: isKeyword('animation-play-state'), | 
						|
    isTimingFunction: isTimingFunction(), | 
						|
    isBackgroundAttachmentKeyword: isKeyword('background-attachment'), | 
						|
    isBackgroundClipKeyword: isKeyword('background-clip'), | 
						|
    isBackgroundOriginKeyword: isKeyword('background-origin'), | 
						|
    isBackgroundPositionKeyword: isKeyword('background-position'), | 
						|
    isBackgroundRepeatKeyword: isKeyword('background-repeat'), | 
						|
    isBackgroundSizeKeyword: isKeyword('background-size'), | 
						|
    isColor: isColor, | 
						|
    isColorFunction: isColorFunction, | 
						|
    isDynamicUnit: isDynamicUnit, | 
						|
    isFontKeyword: isKeyword('font'), | 
						|
    isFontSizeKeyword: isKeyword('font-size'), | 
						|
    isFontStretchKeyword: isKeyword('font-stretch'), | 
						|
    isFontStyleKeyword: isKeyword('font-style'), | 
						|
    isFontVariantKeyword: isKeyword('font-variant'), | 
						|
    isFontWeightKeyword: isKeyword('font-weight'), | 
						|
    isFunction: isFunction, | 
						|
    isGlobal: isKeyword('^'), | 
						|
    isHslColor: isHslColor, | 
						|
    isIdentifier: isIdentifier, | 
						|
    isImage: isImage, | 
						|
    isKeyword: isKeyword, | 
						|
    isLineHeightKeyword: isKeyword('line-height'), | 
						|
    isListStylePositionKeyword: isKeyword('list-style-position'), | 
						|
    isListStyleTypeKeyword: isKeyword('list-style-type'), | 
						|
    isNumber: isNumber, | 
						|
    isPrefixed: isPrefixed, | 
						|
    isPositiveNumber: isPositiveNumber, | 
						|
    isRgbColor: isRgbColor, | 
						|
    isStyleKeyword: isKeyword('*-style'), | 
						|
    isTime: isTime, | 
						|
    isUnit: isUnit.bind(null, validUnits), | 
						|
    isUrl: isUrl, | 
						|
    isVariable: isVariable, | 
						|
    isWidth: isKeyword('width'), | 
						|
    isZIndex: isZIndex | 
						|
  }; | 
						|
} | 
						|
 | 
						|
module.exports = validator;
 | 
						|
 |