Spaces:
Running
Running
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, | |
optimizeFontWeight: true, | |
optimizeOutline: true, | |
removeEmpty: 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, | |
variableValueOptimizers: [] | |
}; | |
DEFAULTS[OptimizationLevel.Two] = { | |
mergeAdjacentRules: true, | |
mergeIntoShorthands: true, | |
mergeMedia: true, | |
mergeNonAdjacentRules: true, | |
mergeSemantically: false, | |
overrideProperties: true, | |
removeEmpty: true, | |
reduceNonAdjacentRules: true, | |
removeDuplicateFontRules: true, | |
removeDuplicateMediaBlocks: true, | |
removeDuplicateRules: true, | |
removeUnusedAtRules: false, | |
restructureRules: false, | |
skipProperties: [] | |
}; | |
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 LIST_VALUE_SEPARATOR = ','; | |
var OPTION_SEPARATOR = ';'; | |
var OPTION_VALUE_SEPARATOR = ':'; | |
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 (Two in source && 'skipProperties' in source[Two] && typeof (source[Two].skipProperties) == 'string') { | |
source[Two].skipProperties = source[Two].skipProperties.split(LIST_VALUE_SEPARATOR); | |
} | |
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 | |
}; | |