123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527 |
- var functionNoVendorRegexStr = '[A-Z]+(\\-|[A-Z]|[0-9])+\\(.*?\\)';
- var functionVendorRegexStr = '\\-(\\-|[A-Z]|[0-9])+\\(.*?\\)';
- var variableRegexStr = 'var\\(\\-\\-[^\\)]+\\)';
- var functionAnyRegexStr = '(' + variableRegexStr + '|' + functionNoVendorRegexStr + '|' + functionVendorRegexStr + ')';
-
- var animationTimingFunctionRegex = /^(cubic\-bezier|steps)\([^\)]+\)$/;
- 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}\)$/;
- var identifierRegex = /^(\-[a-z0-9_][a-z0-9\-_]*|[a-z][a-z0-9\-_]*)$/i;
- var longHexColorRegex = /^#[0-9a-f]{6}$/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}\)$/;
- var shortHexColorRegex = /^#[0-9a-f]{3}$/i;
- var validTimeUnits = ['ms', 's'];
- var urlRegex = /^url\([\s\S]+\)$/i;
- var variableRegex = new RegExp('^' + variableRegexStr + '$', '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'
- ],
- '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'
- ],
- 'animation-timing-function': [
- 'ease',
- 'ease-in',
- 'ease-in-out',
- 'ease-out',
- 'linear',
- 'step-end',
- 'step-start'
- ],
- '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 isAnimationTimingFunction() {
- var isTimingFunctionKeyword = isKeyword('animation-timing-function');
-
- return function (value) {
- return isTimingFunctionKeyword(value) || animationTimingFunctionRegex.test(value);
- };
- }
-
- 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 shortHexColorRegex.test(value) || longHexColorRegex.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 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'),
- isAnimationTimingFunction: isAnimationTimingFunction(),
- 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;
|