var roundingPrecisionFrom = require('./rounding-precision').roundingPrecisionFrom; var override = require('../utils/override'); var OptimizationLevel = { Zero: '0', One: '1', Two: '2' }; var DEFAULTS = {}; DEFAULTS[OptimizationLevel.Zero] = {}; DEFAULTS[OptimizationLevel.One] = { cleanupCharsets: true, normalizeUrls: true, optimizeBackground: true, optimizeBorderRadius: true, optimizeFilter: true, optimizeFont: true, optimizeFontWeight: true, optimizeOutline: true, removeNegativePaddings: true, removeQuotes: true, removeWhitespace: true, replaceMultipleZeros: true, replaceTimeUnits: true, replaceZeroUnits: true, roundingPrecision: roundingPrecisionFrom(undefined), selectorsSortingMethod: 'standard', specialComments: 'all', tidyAtRules: true, tidyBlockScopes: true, tidySelectors: true, transform: noop }; DEFAULTS[OptimizationLevel.Two] = { mergeAdjacentRules: true, mergeIntoShorthands: true, mergeMedia: true, mergeNonAdjacentRules: true, mergeSemantically: false, overrideProperties: true, reduceNonAdjacentRules: true, removeDuplicateFontRules: true, removeDuplicateMediaBlocks: true, removeDuplicateRules: true, restructureRules: false }; var ALL_KEYWORD_1 = '*'; var ALL_KEYWORD_2 = 'all'; var FALSE_KEYWORD_1 = 'false'; var FALSE_KEYWORD_2 = 'off'; var TRUE_KEYWORD_1 = 'true'; var TRUE_KEYWORD_2 = 'on'; var OPTION_SEPARATOR = ';'; var OPTION_VALUE_SEPARATOR = ':'; function noop() {} function optimizationLevelFrom(source) { var level = override(DEFAULTS, {}); var Zero = OptimizationLevel.Zero; var One = OptimizationLevel.One; var Two = OptimizationLevel.Two; if (undefined === source) { delete level[Two]; return level; } if (typeof source == 'string') { source = parseInt(source); } if (typeof source == 'number' && source === parseInt(Two)) { return level; } if (typeof source == 'number' && source === parseInt(One)) { delete level[Two]; return level; } if (typeof source == 'number' && source === parseInt(Zero)) { delete level[Two]; delete level[One]; return level; } if (typeof source == 'object') { source = covertValuesToHashes(source); } if (One in source && 'roundingPrecision' in source[One]) { source[One].roundingPrecision = roundingPrecisionFrom(source[One].roundingPrecision); } if (Zero in source || One in source || Two in source) { level[Zero] = override(level[Zero], source[Zero]); } if (One in source && ALL_KEYWORD_1 in source[One]) { level[One] = override(level[One], defaults(One, normalizeValue(source[One][ALL_KEYWORD_1]))); delete source[One][ALL_KEYWORD_1]; } if (One in source && ALL_KEYWORD_2 in source[One]) { level[One] = override(level[One], defaults(One, normalizeValue(source[One][ALL_KEYWORD_2]))); delete source[One][ALL_KEYWORD_2]; } if (One in source || Two in source) { level[One] = override(level[One], source[One]); } else { delete level[One]; } if (Two in source && ALL_KEYWORD_1 in source[Two]) { level[Two] = override(level[Two], defaults(Two, normalizeValue(source[Two][ALL_KEYWORD_1]))); delete source[Two][ALL_KEYWORD_1]; } if (Two in source && ALL_KEYWORD_2 in source[Two]) { level[Two] = override(level[Two], defaults(Two, normalizeValue(source[Two][ALL_KEYWORD_2]))); delete source[Two][ALL_KEYWORD_2]; } if (Two in source) { level[Two] = override(level[Two], source[Two]); } else { delete level[Two]; } return level; } function defaults(level, value) { var options = override(DEFAULTS[level], {}); var key; for (key in options) { if (typeof options[key] == 'boolean') { options[key] = value; } } return options; } function normalizeValue(value) { switch (value) { case FALSE_KEYWORD_1: case FALSE_KEYWORD_2: return false; case TRUE_KEYWORD_1: case TRUE_KEYWORD_2: return true; default: return value; } } function covertValuesToHashes(source) { var clonedSource = override(source, {}); var level; var i; for (i = 0; i <= 2; i++) { level = '' + i; if (level in clonedSource && (clonedSource[level] === undefined || clonedSource[level] === false)) { delete clonedSource[level]; } if (level in clonedSource && clonedSource[level] === true) { clonedSource[level] = {}; } if (level in clonedSource && typeof clonedSource[level] == 'string') { clonedSource[level] = covertToHash(clonedSource[level], level); } } return clonedSource; } function covertToHash(asString, level) { return asString .split(OPTION_SEPARATOR) .reduce(function (accumulator, directive) { var parts = directive.split(OPTION_VALUE_SEPARATOR); var name = parts[0]; var value = parts[1]; var normalizedValue = normalizeValue(value); if (ALL_KEYWORD_1 == name || ALL_KEYWORD_2 == name) { accumulator = override(accumulator, defaults(level, normalizedValue)); } else { accumulator[name] = normalizedValue; } return accumulator; }, {}); } module.exports = { OptimizationLevel: OptimizationLevel, optimizationLevelFrom: optimizationLevelFrom, };