From d4825a7564e6b17b97d51238a5f51fc9ce965bc7 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowicz Date: Sat, 14 Jan 2017 22:35:28 +0100 Subject: [PATCH] Refactors validator into a set of functions. Why: * There's no need to keep it as an object, since configuration can also be passed in. --- lib/clean.js | 4 +- .../{level-2/compacting => }/validator.js | 220 ++++++++++-------- test/optimizer/level-2/break-up-test.js | 5 +- .../compacting/longhand-overriding-test.js | 5 +- .../level-2/compacting/optimize-test.js | 5 +- .../compacting/override-compacting-test.js | 5 +- .../compacting/shorthand-compacting-test.js | 5 +- test/optimizer/level-2/restore-test.js | 5 +- .../optimizer/restore-from-optimizing-test.js | 12 +- 9 files changed, 145 insertions(+), 121 deletions(-) rename lib/optimizer/{level-2/compacting => }/validator.js (50%) diff --git a/lib/clean.js b/lib/clean.js index 850f1ddb..d9a1006e 100644 --- a/lib/clean.js +++ b/lib/clean.js @@ -15,7 +15,7 @@ var optimizationLevelFrom = require('./options/optimization-level').optimization var level0Optimize = require('./optimizer/level-0/optimize'); var level1Optimize = require('./optimizer/level-1/optimize'); var level2Optimize = require('./optimizer/level-2/optimize'); -var Validator = require('./optimizer/level-2/compacting/validator'); +var validator = require('./optimizer/validator'); var inputSourceMapTracker = require('./reader/input-source-map-tracker'); var readSources = require('./reader/read-sources'); @@ -89,7 +89,7 @@ CleanCSS.prototype.minify = function (input, callback) { options: this.options, source: null, sourcesContent: {}, - validator: new Validator(this.options.compatibility), + validator: validator(this.options.compatibility), warnings: [] }; diff --git a/lib/optimizer/level-2/compacting/validator.js b/lib/optimizer/validator.js similarity index 50% rename from lib/optimizer/level-2/compacting/validator.js rename to lib/optimizer/validator.js index c3fa0544..4321a71a 100644 --- a/lib/optimizer/level-2/compacting/validator.js +++ b/lib/optimizer/validator.js @@ -30,103 +30,91 @@ var styleKeywords = ['auto', 'inherit', 'hidden', 'none', 'dotted', 'dashed', 's var listStyleTypeKeywords = ['armenian', 'circle', 'cjk-ideographic', 'decimal', 'decimal-leading-zero', 'disc', 'georgian', 'hebrew', 'hiragana', 'hiragana-iroha', 'inherit', 'katakana', 'katakana-iroha', 'lower-alpha', 'lower-greek', 'lower-latin', 'lower-roman', 'none', 'square', 'upper-alpha', 'upper-latin', 'upper-roman']; var listStylePositionKeywords = ['inside', 'outside', 'inherit']; -function Validator(compatibility) { - var validUnits = allUnits.slice(0).filter(function (value) { - return !(value in compatibility.units) || compatibility.units[value] === true; - }); - - var compatibleCssUnitRegexStr = '(\\-?\\.?\\d+\\.?\\d*(' + validUnits.join('|') + '|)|auto|inherit)'; - this.compatibleCssUnitRegex = new RegExp('^' + compatibleCssUnitRegexStr + '$', 'i'); - this.compatibleCssUnitAnyRegex = new RegExp('^(none|' + widthKeywords.join('|') + '|' + compatibleCssUnitRegexStr + '|' + cssVariableRegexStr + '|' + cssFunctionNoVendorRegexStr + '|' + cssFunctionVendorRegexStr + ')$', 'i'); - - this.colorOpacity = compatibility.colors.opacity; -} - -Validator.prototype.isValidHexColor = function (s) { +function isValidHexColor(s) { return (s.length === 4 || s.length === 7) && s[0] === '#'; -}; +} -Validator.prototype.isValidRgbaColor = function (s) { +function isValidRgbaColor(s) { s = s.split(' ').join(''); return s.length > 0 && s.indexOf('rgba(') === 0 && s.indexOf(')') === s.length - 1; -}; +} -Validator.prototype.isValidHslaColor = function (s) { +function isValidHslaColor(s) { s = s.split(' ').join(''); return s.length > 0 && s.indexOf('hsla(') === 0 && s.indexOf(')') === s.length - 1; -}; +} -Validator.prototype.isValidNamedColor = function (s) { +function isValidNamedColor(s) { // We don't really check if it's a valid color value, but allow any letters in it return s !== 'auto' && (s === 'transparent' || s === 'inherit' || /^[a-zA-Z]+$/.test(s)); -}; +} -Validator.prototype.isValidVariable = function (s) { +function isValidVariable(s) { return cssVariableRegex.test(s); -}; - -Validator.prototype.isValidColor = function (s) { - return this.isValidNamedColor(s) || - this.isValidColorValue(s) || - this.isValidVariable(s) || - this.isValidVendorPrefixedValue(s); -}; - -Validator.prototype.isValidColorValue = function (s) { - return this.isValidHexColor(s) || - this.isValidRgbaColor(s) || - this.isValidHslaColor(s); -}; - -Validator.prototype.isValidUrl = function (s) { +} + +function isValidColor(s) { + return isValidNamedColor(s) || + isValidColorValue(s) || + isValidVariable(s) || + isValidVendorPrefixedValue(s); +} + +function isValidColorValue(s) { + return isValidHexColor(s) || + isValidRgbaColor(s) || + isValidHslaColor(s); +} + +function isValidUrl(s) { return urlRegex.test(s); -}; +} -Validator.prototype.isValidUnit = function (s) { +function isValidUnit(s) { return cssUnitAnyRegex.test(s); -}; +} -Validator.prototype.isValidUnitWithoutFunction = function (s) { +function isValidUnitWithoutFunction(s) { return cssUnitRegex.test(s); -}; +} -Validator.prototype.isValidAndCompatibleUnit = function (s) { - return this.compatibleCssUnitAnyRegex.test(s); -}; +function isValidAndCompatibleUnit(compatibleCssUnitAnyRegex, s) { + return compatibleCssUnitAnyRegex.test(s); +} -Validator.prototype.isValidAndCompatibleUnitWithoutFunction = function (s) { - return this.compatibleCssUnitRegex.test(s); -}; +function isValidAndCompatibleUnitWithoutFunction(compatibleCssUnitRegex, s) { + return compatibleCssUnitRegex.test(s); +} -Validator.prototype.isValidFunctionWithoutVendorPrefix = function (s) { +function isValidFunctionWithoutVendorPrefix(s) { return !urlRegex.test(s) && cssFunctionNoVendorRegex.test(s); -}; +} -Validator.prototype.isValidFunctionWithVendorPrefix = function (s) { +function isValidFunctionWithVendorPrefix(s) { return !urlRegex.test(s) && cssFunctionVendorRegex.test(s); -}; +} -Validator.prototype.isValidFunction = function (s) { +function isValidFunction(s) { return !urlRegex.test(s) && cssFunctionAnyRegex.test(s); -}; +} -Validator.prototype.isValidBackgroundRepeat = function (s) { - return backgroundRepeatKeywords.indexOf(s) >= 0 || this.isValidVariable(s); -}; +function isValidBackgroundRepeat(s) { + return backgroundRepeatKeywords.indexOf(s) >= 0 || isValidVariable(s); +} -Validator.prototype.isValidBackgroundAttachment = function (s) { - return backgroundAttachmentKeywords.indexOf(s) >= 0 || this.isValidVariable(s); -}; +function isValidBackgroundAttachment(s) { + return backgroundAttachmentKeywords.indexOf(s) >= 0 || isValidVariable(s); +} -Validator.prototype.isValidBackgroundBox = function (s) { - return backgroundBoxKeywords.indexOf(s) >= 0 || this.isValidVariable(s); -}; +function isValidBackgroundBox(s) { + return backgroundBoxKeywords.indexOf(s) >= 0 || isValidVariable(s); +} -Validator.prototype.isValidBackgroundPositionPart = function (s) { - return backgroundPositionKeywords.indexOf(s) >= 0 || cssUnitOrCalcRegex.test(s) || this.isValidVariable(s); -}; +function isValidBackgroundPositionPart(s) { + return backgroundPositionKeywords.indexOf(s) >= 0 || cssUnitOrCalcRegex.test(s) || isValidVariable(s); +} -Validator.prototype.isValidBackgroundPosition = function (s) { +function isValidBackgroundPosition(s) { if (s === 'inherit') return true; @@ -134,55 +122,99 @@ Validator.prototype.isValidBackgroundPosition = function (s) { for (var i = 0, l = parts.length; i < l; i++) { if (parts[i] === '') continue; - if (this.isValidBackgroundPositionPart(parts[i]) || this.isValidVariable(parts[i])) + if (isValidBackgroundPositionPart(parts[i]) || isValidVariable(parts[i])) continue; return false; } return true; -}; +} -Validator.prototype.isValidBackgroundSizePart = function (s) { - return backgroundSizeKeywords.indexOf(s) >= 0 || cssUnitRegex.test(s) || this.isValidVariable(s); -}; +function isValidBackgroundSizePart(s) { + return backgroundSizeKeywords.indexOf(s) >= 0 || cssUnitRegex.test(s) || isValidVariable(s); +} -Validator.prototype.isValidListStyleType = function (s) { - return listStyleTypeKeywords.indexOf(s) >= 0 || this.isValidVariable(s); -}; +function isValidListStyleType(s) { + return listStyleTypeKeywords.indexOf(s) >= 0 || isValidVariable(s); +} -Validator.prototype.isValidListStylePosition = function (s) { - return listStylePositionKeywords.indexOf(s) >= 0 || this.isValidVariable(s); -}; +function isValidListStylePosition(s) { + return listStylePositionKeywords.indexOf(s) >= 0 || isValidVariable(s); +} -Validator.prototype.isValidStyle = function (s) { - return this.isValidStyleKeyword(s) || this.isValidVariable(s); -}; +function isValidStyle(s) { + return isValidStyleKeyword(s) || isValidVariable(s); +} -Validator.prototype.isValidStyleKeyword = function (s) { +function isValidStyleKeyword(s) { return styleKeywords.indexOf(s) >= 0; -}; +} -Validator.prototype.isValidWidth = function (s) { - return this.isValidUnit(s) || this.isValidWidthKeyword(s) || this.isValidVariable(s); -}; +function isValidWidth(s) { + return isValidUnit(s) || isValidWidthKeyword(s) || isValidVariable(s); +} -Validator.prototype.isValidWidthKeyword = function (s) { +function isValidWidthKeyword(s) { return widthKeywords.indexOf(s) >= 0; -}; +} -Validator.prototype.isValidVendorPrefixedValue = function (s) { +function isValidVendorPrefixedValue(s) { return /^-([A-Za-z0-9]|-)*$/gi.test(s); -}; +} -Validator.prototype.areSameFunction = function (a, b) { - if (!this.isValidFunction(a) || !this.isValidFunction(b)) +function areSameFunction(a, b) { + if (!isValidFunction(a) || !isValidFunction(b)) return false; var f1name = a.substring(0, a.indexOf('(')); var f2name = b.substring(0, b.indexOf('(')); return f1name === f2name; -}; +} + +function validator(compatibility) { + var validUnits = allUnits.slice(0).filter(function (value) { + return !(value in compatibility.units) || compatibility.units[value] === true; + }); + + var compatibleCssUnitRegexStr = '(\\-?\\.?\\d+\\.?\\d*(' + validUnits.join('|') + '|)|auto|inherit)'; + var compatibleCssUnitRegex = new RegExp('^' + compatibleCssUnitRegexStr + '$', 'i'); + var compatibleCssUnitAnyRegex = new RegExp('^(none|' + widthKeywords.join('|') + '|' + compatibleCssUnitRegexStr + '|' + cssVariableRegexStr + '|' + cssFunctionNoVendorRegexStr + '|' + cssFunctionVendorRegexStr + ')$', 'i'); + var colorOpacity = compatibility.colors.opacity; + + return { + colorOpacity: colorOpacity, + isValidHexColor: isValidHexColor, + isValidRgbaColor: isValidRgbaColor, + isValidHslaColor: isValidHslaColor, + isValidNamedColor: isValidNamedColor, + isValidVariable: isValidVariable, + isValidColor: isValidColor, + isValidColorValue: isValidColorValue, + isValidUrl: isValidUrl, + isValidUnit: isValidUnit, + isValidUnitWithoutFunction: isValidUnitWithoutFunction, + isValidAndCompatibleUnit: isValidAndCompatibleUnit.bind(null, compatibleCssUnitAnyRegex), + isValidAndCompatibleUnitWithoutFunction: isValidAndCompatibleUnitWithoutFunction.bind(null, compatibleCssUnitRegex), + isValidFunctionWithoutVendorPrefix: isValidFunctionWithoutVendorPrefix, + isValidFunctionWithVendorPrefix: isValidFunctionWithVendorPrefix, + isValidFunction: isValidFunction, + isValidBackgroundRepeat: isValidBackgroundRepeat, + isValidBackgroundAttachment: isValidBackgroundAttachment, + isValidBackgroundBox: isValidBackgroundBox, + isValidBackgroundPositionPart: isValidBackgroundPositionPart, + isValidBackgroundPosition: isValidBackgroundPosition, + isValidBackgroundSizePart: isValidBackgroundSizePart, + isValidListStyleType: isValidListStyleType, + isValidListStylePosition: isValidListStylePosition, + isValidStyle: isValidStyle, + isValidStyleKeyword: isValidStyleKeyword, + isValidWidth: isValidWidth, + isValidWidthKeyword: isValidWidthKeyword, + isValidVendorPrefixedValue: isValidVendorPrefixedValue, + areSameFunction: areSameFunction + }; +} -module.exports = Validator; +module.exports = validator; diff --git a/test/optimizer/level-2/break-up-test.js b/test/optimizer/level-2/break-up-test.js index 885aef6d..d573e85f 100644 --- a/test/optimizer/level-2/break-up-test.js +++ b/test/optimizer/level-2/break-up-test.js @@ -3,15 +3,14 @@ var vows = require('vows'); var wrapForOptimizing = require('../../../lib/optimizer/wrap-for-optimizing').all; var populateComponents = require('../../../lib/optimizer/level-2/compacting/populate-components'); -var Validator = require('../../../lib/optimizer/level-2/compacting/validator'); +var validator = require('../../../lib/optimizer/validator'); var compatibility = require('../../../lib/utils/compatibility'); var breakUp = require('../../../lib/optimizer/level-2/break-up'); function _breakUp(properties) { - var validator = new Validator(compatibility()); var wrapped = wrapForOptimizing(properties); - populateComponents(wrapped, validator, []); + populateComponents(wrapped, validator(compatibility()), []); return wrapped[0].components; } diff --git a/test/optimizer/level-2/compacting/longhand-overriding-test.js b/test/optimizer/level-2/compacting/longhand-overriding-test.js index dc093847..e1c0eceb 100644 --- a/test/optimizer/level-2/compacting/longhand-overriding-test.js +++ b/test/optimizer/level-2/compacting/longhand-overriding-test.js @@ -6,7 +6,7 @@ var optimize = require('../../../../lib/optimizer/level-2/compacting/optimize'); var tokenize = require('../../../../lib/tokenizer/tokenize'); var inputSourceMapTracker = require('../../../../lib/reader/input-source-map-tracker'); var compatibility = require('../../../../lib/utils/compatibility'); -var Validator = require('../../../../lib/optimizer/level-2/compacting/validator'); +var validator = require('../../../../lib/optimizer/validator'); function _optimize(source) { var tokens = tokenize(source, { @@ -28,8 +28,7 @@ function _optimize(source) { } } }; - var validator = new Validator(compat); - optimize(tokens[0][1], tokens[0][2], false, true, { options: options, validator: validator }); + optimize(tokens[0][1], tokens[0][2], false, true, { options: options, validator: validator(compat) }); return tokens[0][2]; } diff --git a/test/optimizer/level-2/compacting/optimize-test.js b/test/optimizer/level-2/compacting/optimize-test.js index 62d07358..a3f5b6b6 100644 --- a/test/optimizer/level-2/compacting/optimize-test.js +++ b/test/optimizer/level-2/compacting/optimize-test.js @@ -6,7 +6,7 @@ var optimize = require('../../../../lib/optimizer/level-2/compacting/optimize'); var tokenize = require('../../../../lib/tokenizer/tokenize'); var inputSourceMapTracker = require('../../../../lib/reader/input-source-map-tracker'); var compatibility = require('../../../../lib/utils/compatibility'); -var Validator = require('../../../../lib/optimizer/level-2/compacting/validator'); +var validator = require('../../../../lib/optimizer/validator'); function _optimize(source, mergeAdjacent, aggressiveMerging, compatibilityOptions) { var compat = compatibility(compatibilityOptions); @@ -22,14 +22,13 @@ function _optimize(source, mergeAdjacent, aggressiveMerging, compatibilityOption } } }; - var validator = new Validator(compat); var tokens = tokenize(source, { inputSourceMapTracker: inputSourceMapTracker(), options: {}, warnings: [] }); - optimize(tokens[0][1], tokens[0][2], mergeAdjacent, true, { options: options, validator: validator }); + optimize(tokens[0][1], tokens[0][2], mergeAdjacent, true, { options: options, validator: validator(compat) }); return tokens[0][2]; } diff --git a/test/optimizer/level-2/compacting/override-compacting-test.js b/test/optimizer/level-2/compacting/override-compacting-test.js index e93bed44..6f288e39 100644 --- a/test/optimizer/level-2/compacting/override-compacting-test.js +++ b/test/optimizer/level-2/compacting/override-compacting-test.js @@ -6,7 +6,7 @@ var optimize = require('../../../../lib/optimizer/level-2/compacting/optimize'); var tokenize = require('../../../../lib/tokenizer/tokenize'); var inputSourceMapTracker = require('../../../../lib/reader/input-source-map-tracker'); var compatibility = require('../../../../lib/utils/compatibility'); -var Validator = require('../../../../lib/optimizer/level-2/compacting/validator'); +var validator = require('../../../../lib/optimizer/validator'); function _optimize(source, compat, aggressiveMerging) { var tokens = tokenize(source, { @@ -16,7 +16,6 @@ function _optimize(source, compat, aggressiveMerging) { }); compat = compatibility(compat); - var validator = new Validator(compat); var options = { aggressiveMerging: undefined === aggressiveMerging ? true : aggressiveMerging, compatibility: compat, @@ -26,7 +25,7 @@ function _optimize(source, compat, aggressiveMerging) { } } }; - optimize(tokens[0][1], tokens[0][2], false, true, { options: options, validator: validator }); + optimize(tokens[0][1], tokens[0][2], false, true, { options: options, validator: validator(compat) }); return tokens[0][2]; } diff --git a/test/optimizer/level-2/compacting/shorthand-compacting-test.js b/test/optimizer/level-2/compacting/shorthand-compacting-test.js index f0cfad83..33ed033b 100644 --- a/test/optimizer/level-2/compacting/shorthand-compacting-test.js +++ b/test/optimizer/level-2/compacting/shorthand-compacting-test.js @@ -6,7 +6,7 @@ var optimize = require('../../../../lib/optimizer/level-2/compacting/optimize'); var tokenize = require('../../../../lib/tokenizer/tokenize'); var inputSourceMapTracker = require('../../../../lib/reader/input-source-map-tracker'); var compatibility = require('../../../../lib/utils/compatibility'); -var Validator = require('../../../../lib/optimizer/level-2/compacting/validator'); +var validator = require('../../../../lib/optimizer/validator'); function _optimize(source) { var tokens = tokenize(source, { @@ -16,7 +16,6 @@ function _optimize(source) { }); var compat = compatibility(compat); - var validator = new Validator(compat); var options = { aggressiveMerging: true, compatibility: compat, @@ -26,7 +25,7 @@ function _optimize(source) { } } }; - optimize(tokens[0][1], tokens[0][2], false, true, { options: options, validator: validator }); + optimize(tokens[0][1], tokens[0][2], false, true, { options: options, validator: validator(compat) }); return tokens[0][2]; } diff --git a/test/optimizer/level-2/restore-test.js b/test/optimizer/level-2/restore-test.js index c21f0c54..b57463d6 100644 --- a/test/optimizer/level-2/restore-test.js +++ b/test/optimizer/level-2/restore-test.js @@ -4,15 +4,14 @@ var assert = require('assert'); var wrapForOptimizing = require('../../../lib/optimizer/wrap-for-optimizing').single; var compactable = require('../../../lib/optimizer/level-2/compactable'); var compatibility = require('../../../lib/utils/compatibility'); -var Validator = require('../../../lib/optimizer/level-2/compacting/validator'); +var validator = require('../../../lib/optimizer/validator'); var restore = require('../../../lib/optimizer/level-2/restore'); function _breakUp(property) { - var validator = new Validator(compatibility()); var descriptor = compactable[property[1][1]]; var _property = wrapForOptimizing(property); - _property.components = descriptor.breakUp(_property, compactable, validator); + _property.components = descriptor.breakUp(_property, compactable, validator(compatibility())); _property.multiplex = _property.components[0].multiplex; return _property; } diff --git a/test/optimizer/restore-from-optimizing-test.js b/test/optimizer/restore-from-optimizing-test.js index 0fe15189..97d18142 100644 --- a/test/optimizer/restore-from-optimizing-test.js +++ b/test/optimizer/restore-from-optimizing-test.js @@ -8,12 +8,10 @@ var shallowClone = require('../../lib/optimizer/level-2/clone').shallow; var restoreWithComponents = require('../../lib/optimizer/level-2/restore-with-components'); var populateComponents = require('../../lib/optimizer/level-2/compacting/populate-components'); -var Validator = require('../../lib/optimizer/level-2/compacting/validator'); +var validator = require('../../lib/optimizer/validator'); var compatibility = require('../../lib/utils/compatibility'); -var validator = new Validator(compatibility()); - vows.describe(restoreFromOptimizing) .addBatch({ 'without descriptor': { @@ -80,7 +78,7 @@ vows.describe(restoreFromOptimizing) ] ]; var wrapped = wrapForOptimizing(properties); - populateComponents(wrapped, validator); + populateComponents(wrapped, validator(compatibility())); restoreFromOptimizing(wrapped); return properties; @@ -109,7 +107,7 @@ vows.describe(restoreFromOptimizing) ] ]; var wrapped = wrapForOptimizing(properties); - populateComponents(wrapped, validator); + populateComponents(wrapped, validator(compatibility())); wrapped[0].dirty = true; @@ -164,7 +162,7 @@ vows.describe(restoreFromOptimizing) ] ]; var wrapped = wrapForOptimizing(properties); - populateComponents(wrapped, validator); + populateComponents(wrapped, validator(compatibility())); wrapped[0].value = []; wrapped[0].dirty = true; @@ -192,7 +190,7 @@ vows.describe(restoreFromOptimizing) ] ]; var wrapped = wrapForOptimizing(properties); - populateComponents(wrapped, validator); + populateComponents(wrapped, validator(compatibility())); var cloned = shallowClone(wrapped[0]); cloned.components = wrapped[0].components; -- 2.34.1