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.
218 lines
5.4 KiB
218 lines
5.4 KiB
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 |
|
};
|
|
|