From de98e0b232509d5f40c135d540a70e415272ff85 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 3 May 2017 15:35:00 +0200 Subject: node_modules --- node_modules/clean-css/lib/optimizer/hack.js | 8 + .../clean-css/lib/optimizer/level-0/optimize.js | 6 + .../clean-css/lib/optimizer/level-1/optimize.js | 734 +++++++++++++++++++ .../clean-css/lib/optimizer/level-1/shorten-hex.js | 189 +++++ .../clean-css/lib/optimizer/level-1/shorten-hsl.js | 61 ++ .../clean-css/lib/optimizer/level-1/shorten-rgb.js | 10 + .../lib/optimizer/level-1/sort-selectors.js | 25 + .../lib/optimizer/level-1/tidy-at-rule.js | 9 + .../clean-css/lib/optimizer/level-1/tidy-block.js | 23 + .../clean-css/lib/optimizer/level-1/tidy-rules.js | 213 ++++++ .../clean-css/lib/optimizer/level-2/break-up.js | 362 ++++++++++ .../lib/optimizer/level-2/can-override.js | 180 +++++ .../clean-css/lib/optimizer/level-2/clone.js | 33 + .../clean-css/lib/optimizer/level-2/compactable.js | 787 +++++++++++++++++++++ .../lib/optimizer/level-2/extract-properties.js | 73 ++ .../optimizer/level-2/invalid-property-error.js | 10 + .../lib/optimizer/level-2/is-mergeable.js | 236 ++++++ .../lib/optimizer/level-2/merge-adjacent.js | 49 ++ .../lib/optimizer/level-2/merge-media-queries.js | 103 +++ .../level-2/merge-non-adjacent-by-body.js | 79 +++ .../level-2/merge-non-adjacent-by-selector.js | 78 ++ .../clean-css/lib/optimizer/level-2/optimize.js | 124 ++++ .../level-2/properties/every-values-pair.js | 28 + .../level-2/properties/find-component-in.js | 40 ++ .../optimizer/level-2/properties/has-inherit.js | 10 + .../level-2/properties/is-component-of.js | 22 + .../level-2/properties/merge-into-shorthands.js | 157 ++++ .../lib/optimizer/level-2/properties/optimize.js | 39 + .../level-2/properties/override-properties.js | 441 ++++++++++++ .../overrides-non-component-shorthand.js | 9 + .../level-2/properties/populate-components.js | 42 ++ .../optimizer/level-2/properties/understandable.js | 15 + .../level-2/properties/vendor-prefixes.js | 23 + .../lib/optimizer/level-2/reduce-non-adjacent.js | 178 +++++ .../level-2/remove-duplicate-font-at-rules.js | 30 + .../level-2/remove-duplicate-media-queries.js | 30 + .../lib/optimizer/level-2/remove-duplicates.js | 43 ++ .../clean-css/lib/optimizer/level-2/reorderable.js | 93 +++ .../optimizer/level-2/restore-with-components.js | 13 + .../clean-css/lib/optimizer/level-2/restore.js | 233 ++++++ .../clean-css/lib/optimizer/level-2/restructure.js | 388 ++++++++++ .../lib/optimizer/level-2/rules-overlap.js | 32 + .../lib/optimizer/level-2/specificities-overlap.js | 34 + .../clean-css/lib/optimizer/level-2/specificity.js | 77 ++ .../lib/optimizer/level-2/tidy-rule-duplicates.js | 21 + .../clean-css/lib/optimizer/remove-unused.js | 11 + .../lib/optimizer/restore-from-optimizing.js | 69 ++ node_modules/clean-css/lib/optimizer/validator.js | 470 ++++++++++++ .../clean-css/lib/optimizer/wrap-for-optimizing.js | 187 +++++ 49 files changed, 6127 insertions(+) create mode 100644 node_modules/clean-css/lib/optimizer/hack.js create mode 100644 node_modules/clean-css/lib/optimizer/level-0/optimize.js create mode 100644 node_modules/clean-css/lib/optimizer/level-1/optimize.js create mode 100644 node_modules/clean-css/lib/optimizer/level-1/shorten-hex.js create mode 100644 node_modules/clean-css/lib/optimizer/level-1/shorten-hsl.js create mode 100644 node_modules/clean-css/lib/optimizer/level-1/shorten-rgb.js create mode 100644 node_modules/clean-css/lib/optimizer/level-1/sort-selectors.js create mode 100644 node_modules/clean-css/lib/optimizer/level-1/tidy-at-rule.js create mode 100644 node_modules/clean-css/lib/optimizer/level-1/tidy-block.js create mode 100644 node_modules/clean-css/lib/optimizer/level-1/tidy-rules.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/break-up.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/can-override.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/clone.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/compactable.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/extract-properties.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/invalid-property-error.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/is-mergeable.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/merge-adjacent.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/merge-media-queries.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/merge-non-adjacent-by-body.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/merge-non-adjacent-by-selector.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/optimize.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/properties/every-values-pair.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/properties/find-component-in.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/properties/has-inherit.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/properties/is-component-of.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/properties/merge-into-shorthands.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/properties/optimize.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/properties/override-properties.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/properties/overrides-non-component-shorthand.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/properties/populate-components.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/properties/understandable.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/properties/vendor-prefixes.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/reduce-non-adjacent.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/remove-duplicate-font-at-rules.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/remove-duplicate-media-queries.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/remove-duplicates.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/reorderable.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/restore-with-components.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/restore.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/restructure.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/rules-overlap.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/specificities-overlap.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/specificity.js create mode 100644 node_modules/clean-css/lib/optimizer/level-2/tidy-rule-duplicates.js create mode 100644 node_modules/clean-css/lib/optimizer/remove-unused.js create mode 100644 node_modules/clean-css/lib/optimizer/restore-from-optimizing.js create mode 100644 node_modules/clean-css/lib/optimizer/validator.js create mode 100644 node_modules/clean-css/lib/optimizer/wrap-for-optimizing.js (limited to 'node_modules/clean-css/lib/optimizer') diff --git a/node_modules/clean-css/lib/optimizer/hack.js b/node_modules/clean-css/lib/optimizer/hack.js new file mode 100644 index 000000000..812b5d5ec --- /dev/null +++ b/node_modules/clean-css/lib/optimizer/hack.js @@ -0,0 +1,8 @@ +var Hack = { + ASTERISK: 'asterisk', + BANG: 'bang', + BACKSLASH: 'backslash', + UNDERSCORE: 'underscore' +}; + +module.exports = Hack; diff --git a/node_modules/clean-css/lib/optimizer/level-0/optimize.js b/node_modules/clean-css/lib/optimizer/level-0/optimize.js new file mode 100644 index 000000000..2a56f89c6 --- /dev/null +++ b/node_modules/clean-css/lib/optimizer/level-0/optimize.js @@ -0,0 +1,6 @@ +function level0Optimize(tokens) { + // noop as level 0 means no optimizations! + return tokens; +} + +module.exports = level0Optimize; diff --git a/node_modules/clean-css/lib/optimizer/level-1/optimize.js b/node_modules/clean-css/lib/optimizer/level-1/optimize.js new file mode 100644 index 000000000..e7a9bbb47 --- /dev/null +++ b/node_modules/clean-css/lib/optimizer/level-1/optimize.js @@ -0,0 +1,734 @@ +var shortenHex = require('./shorten-hex'); +var shortenHsl = require('./shorten-hsl'); +var shortenRgb = require('./shorten-rgb'); +var sortSelectors = require('./sort-selectors'); +var tidyRules = require('./tidy-rules'); +var tidyBlock = require('./tidy-block'); +var tidyAtRule = require('./tidy-at-rule'); + +var Hack = require('../hack'); +var removeUnused = require('../remove-unused'); +var restoreFromOptimizing = require('../restore-from-optimizing'); +var wrapForOptimizing = require('../wrap-for-optimizing').all; + +var OptimizationLevel = require('../../options/optimization-level').OptimizationLevel; + +var Token = require('../../tokenizer/token'); +var Marker = require('../../tokenizer/marker'); + +var formatPosition = require('../../utils/format-position'); +var split = require('../../utils/split'); + +var IgnoreProperty = 'ignore-property'; + +var CHARSET_TOKEN = '@charset'; +var CHARSET_REGEXP = new RegExp('^' + CHARSET_TOKEN, 'i'); + +var DEFAULT_ROUNDING_PRECISION = require('../../options/rounding-precision').DEFAULT; + +var FONT_NUMERAL_WEIGHTS = ['100', '200', '300', '400', '500', '600', '700', '800', '900']; +var FONT_NAME_WEIGHTS = ['normal', 'bold', 'bolder', 'lighter']; +var FONT_NAME_WEIGHTS_WITHOUT_NORMAL = ['bold', 'bolder', 'lighter']; + +var WHOLE_PIXEL_VALUE = /(?:^|\s|\()(-?\d+)px/; +var TIME_VALUE = /^(\-?[\d\.]+)(m?s)$/; + +var PROPERTY_NAME_PATTERN = /^(?:\-chrome\-|\-[\w\-]+\w|\w[\w\-]+\w|\-\-\S+)$/; +var IMPORT_PREFIX_PATTERN = /^@import/i; +var QUOTED_PATTERN = /^('.*'|".*")$/; +var QUOTED_BUT_SAFE_PATTERN = /^['"][a-zA-Z][a-zA-Z\d\-_]+['"]$/; +var URL_PREFIX_PATTERN = /^url\(/i; +var VARIABLE_NAME_PATTERN = /^--\S+$/; + +function isNegative(value) { + return value && value[1][0] == '-' && parseFloat(value[1]) < 0; +} + +function isQuoted(value) { + return QUOTED_PATTERN.test(value); +} + +function isUrl(value) { + return URL_PREFIX_PATTERN.test(value); +} + +function normalizeUrl(value) { + return value + .replace(URL_PREFIX_PATTERN, 'url(') + .replace(/\\?\n|\\?\r\n/g, ''); +} + +function optimizeBackground(property) { + var values = property.value; + + if (values.length == 1 && values[0][1] == 'none') { + values[0][1] = '0 0'; + } + + if (values.length == 1 && values[0][1] == 'transparent') { + values[0][1] = '0 0'; + } +} + +function optimizeBorderRadius(property) { + var values = property.value; + var spliceAt; + + if (values.length == 3 && values[1][1] == '/' && values[0][1] == values[2][1]) { + spliceAt = 1; + } else if (values.length == 5 && values[2][1] == '/' && values[0][1] == values[3][1] && values[1][1] == values[4][1]) { + spliceAt = 2; + } else if (values.length == 7 && values[3][1] == '/' && values[0][1] == values[4][1] && values[1][1] == values[5][1] && values[2][1] == values[6][1]) { + spliceAt = 3; + } else if (values.length == 9 && values[4][1] == '/' && values[0][1] == values[5][1] && values[1][1] == values[6][1] && values[2][1] == values[7][1] && values[3][1] == values[8][1]) { + spliceAt = 4; + } + + if (spliceAt) { + property.value.splice(spliceAt); + property.dirty = true; + } +} + +function optimizeColors(name, value, compatibility) { + if (value.indexOf('#') === -1 && value.indexOf('rgb') == -1 && value.indexOf('hsl') == -1) { + return shortenHex(value); + } + + value = value + .replace(/rgb\((\-?\d+),(\-?\d+),(\-?\d+)\)/g, function (match, red, green, blue) { + return shortenRgb(red, green, blue); + }) + .replace(/hsl\((-?\d+),(-?\d+)%?,(-?\d+)%?\)/g, function (match, hue, saturation, lightness) { + return shortenHsl(hue, saturation, lightness); + }) + .replace(/(^|[^='"])#([0-9a-f]{6})/gi, function (match, prefix, color) { + if (color[0] == color[1] && color[2] == color[3] && color[4] == color[5]) { + return (prefix + '#' + color[0] + color[2] + color[4]).toLowerCase(); + } else { + return (prefix + '#' + color).toLowerCase(); + } + }) + .replace(/(^|[^='"])#([0-9a-f]{3})/gi, function (match, prefix, color) { + return prefix + '#' + color.toLowerCase(); + }) + .replace(/(rgb|rgba|hsl|hsla)\(([^\)]+)\)/g, function (match, colorFunction, colorDef) { + var tokens = colorDef.split(','); + var applies = (colorFunction == 'hsl' && tokens.length == 3) || + (colorFunction == 'hsla' && tokens.length == 4) || + (colorFunction == 'rgb' && tokens.length == 3 && colorDef.indexOf('%') > 0) || + (colorFunction == 'rgba' && tokens.length == 4 && colorDef.indexOf('%') > 0); + + if (!applies) { + return match; + } + + if (tokens[1].indexOf('%') == -1) { + tokens[1] += '%'; + } + + if (tokens[2].indexOf('%') == -1) { + tokens[2] += '%'; + } + + return colorFunction + '(' + tokens.join(',') + ')'; + }); + + if (compatibility.colors.opacity && name.indexOf('background') == -1) { + value = value.replace(/(?:rgba|hsla)\(0,0%?,0%?,0\)/g, function (match) { + if (split(value, ',').pop().indexOf('gradient(') > -1) { + return match; + } + + return 'transparent'; + }); + } + + return shortenHex(value); +} + +function optimizeFilter(property) { + if (property.value.length == 1) { + property.value[0][1] = property.value[0][1].replace(/progid:DXImageTransform\.Microsoft\.(Alpha|Chroma)(\W)/, function (match, filter, suffix) { + return filter.toLowerCase() + suffix; + }); + } + + property.value[0][1] = property.value[0][1] + .replace(/,(\S)/g, ', $1') + .replace(/ ?= ?/g, '='); +} + +function optimizeFont(property, options) { + var values = property.value; + var hasNumeral = FONT_NUMERAL_WEIGHTS.indexOf(values[0][1]) > -1 || + values[1] && FONT_NUMERAL_WEIGHTS.indexOf(values[1][1]) > -1 || + values[2] && FONT_NUMERAL_WEIGHTS.indexOf(values[2][1]) > -1; + var canOptimizeFontWeight = options.level[OptimizationLevel.One].optimizeFontWeight; + var normalCount = 0; + var toOptimize; + + if (!canOptimizeFontWeight) { + return; + } + + if (hasNumeral) { + return; + } + + if (values[1] && values[1][1] == '/') { + return; + } + + if (values[0][1] == 'normal') { + normalCount++; + } + + if (values[1] && values[1][1] == 'normal') { + normalCount++; + } + + if (values[2] && values[2][1] == 'normal') { + normalCount++; + } + + if (normalCount > 1) { + return; + } + + if (FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(values[0][1]) > -1) { + toOptimize = 0; + } else if (values[1] && FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(values[1][1]) > -1) { + toOptimize = 1; + } else if (values[2] && FONT_NAME_WEIGHTS_WITHOUT_NORMAL.indexOf(values[2][1]) > -1) { + toOptimize = 2; + } else if (FONT_NAME_WEIGHTS.indexOf(values[0][1]) > -1) { + toOptimize = 0; + } else if (values[1] && FONT_NAME_WEIGHTS.indexOf(values[1][1]) > -1) { + toOptimize = 1; + } else if (values[2] && FONT_NAME_WEIGHTS.indexOf(values[2][1]) > -1) { + toOptimize = 2; + } + + if (toOptimize !== undefined && canOptimizeFontWeight) { + optimizeFontWeight(property, toOptimize); + property.dirty = true; + } +} + +function optimizeFontWeight(property, atIndex) { + var value = property.value[atIndex][1]; + + if (value == 'normal') { + value = '400'; + } else if (value == 'bold') { + value = '700'; + } + + property.value[atIndex][1] = value; +} + +function optimizeMultipleZeros(property) { + var values = property.value; + var spliceAt; + + if (values.length == 4 && values[0][1] === '0' && values[1][1] === '0' && values[2][1] === '0' && values[3][1] === '0') { + if (property.name.indexOf('box-shadow') > -1) { + spliceAt = 2; + } else { + spliceAt = 1; + } + } + + if (spliceAt) { + property.value.splice(spliceAt); + property.dirty = true; + } +} + +function optimizeOutline(property) { + var values = property.value; + + if (values.length == 1 && values[0][1] == 'none') { + values[0][1] = '0'; + } +} + +function optimizePixelLengths(_, value, compatibility) { + if (!WHOLE_PIXEL_VALUE.test(value)) { + return value; + } + + return value.replace(WHOLE_PIXEL_VALUE, function (match, val) { + var newValue; + var intVal = parseInt(val); + + if (intVal === 0) { + return match; + } + + if (compatibility.properties.shorterLengthUnits && compatibility.units.pt && intVal * 3 % 4 === 0) { + newValue = intVal * 3 / 4 + 'pt'; + } + + if (compatibility.properties.shorterLengthUnits && compatibility.units.pc && intVal % 16 === 0) { + newValue = intVal / 16 + 'pc'; + } + + if (compatibility.properties.shorterLengthUnits && compatibility.units.in && intVal % 96 === 0) { + newValue = intVal / 96 + 'in'; + } + + if (newValue) { + newValue = match.substring(0, match.indexOf(val)) + newValue; + } + + return newValue && newValue.length < match.length ? newValue : match; + }); +} + +function optimizePrecision(_, value, precisionOptions) { + if (!precisionOptions.enabled || value.indexOf('.') === -1) { + return value; + } + + return value + .replace(precisionOptions.decimalPointMatcher, '$1$2$3') + .replace(precisionOptions.zeroMatcher, function (match, integerPart, fractionPart, unit) { + var multiplier = precisionOptions.units[unit].multiplier; + var parsedInteger = parseInt(integerPart); + var integer = isNaN(parsedInteger) ? 0 : parsedInteger; + var fraction = parseFloat(fractionPart); + + return Math.round((integer + fraction) * multiplier) / multiplier + unit; + }); +} + +function optimizeTimeUnits(_, value) { + if (!TIME_VALUE.test(value)) + return value; + + return value.replace(TIME_VALUE, function (match, val, unit) { + var newValue; + + if (unit == 'ms') { + newValue = parseInt(val) / 1000 + 's'; + } else if (unit == 's') { + newValue = parseFloat(val) * 1000 + 'ms'; + } + + return newValue.length < match.length ? newValue : match; + }); +} + +function optimizeUnits(name, value, unitsRegexp) { + if (/^(?:\-moz\-calc|\-webkit\-calc|calc|rgb|hsl|rgba|hsla)\(/.test(value)) { + return value; + } + + if (name == 'flex' || name == '-ms-flex' || name == '-webkit-flex' || name == 'flex-basis' || name == '-webkit-flex-basis') { + return value; + } + + if (value.indexOf('%') > 0 && (name == 'height' || name == 'max-height')) { + return value; + } + + return value + .replace(unitsRegexp, '$1' + '0' + '$2') + .replace(unitsRegexp, '$1' + '0' + '$2'); +} + +function optimizeWhitespace(name, value) { + if (name.indexOf('filter') > -1 || value.indexOf(' ') == -1 || value.indexOf('expression') === 0) { + return value; + } + + if (value.indexOf(Marker.SINGLE_QUOTE) > -1 || value.indexOf(Marker.DOUBLE_QUOTE) > -1) { + return value; + } + + value = value.replace(/\s+/g, ' '); + + if (value.indexOf('calc') > -1) { + value = value.replace(/\) ?\/ ?/g, ')/ '); + } + + return value + .replace(/(\(;?)\s+/g, '$1') + .replace(/\s+(;?\))/g, '$1') + .replace(/, /g, ','); +} + +function optimizeZeroDegUnit(_, value) { + if (value.indexOf('0deg') == -1) { + return value; + } + + return value.replace(/\(0deg\)/g, '(0)'); +} + +function optimizeZeroUnits(name, value) { + if (value.indexOf('0') == -1) { + return value; + } + + if (value.indexOf('-') > -1) { + value = value + .replace(/([^\w\d\-]|^)\-0([^\.]|$)/g, '$10$2') + .replace(/([^\w\d\-]|^)\-0([^\.]|$)/g, '$10$2'); + } + + return value + .replace(/(^|\s)0+([1-9])/g, '$1$2') + .replace(/(^|\D)\.0+(\D|$)/g, '$10$2') + .replace(/(^|\D)\.0+(\D|$)/g, '$10$2') + .replace(/\.([1-9]*)0+(\D|$)/g, function (match, nonZeroPart, suffix) { + return (nonZeroPart.length > 0 ? '.' : '') + nonZeroPart + suffix; + }) + .replace(/(^|\D)0\.(\d)/g, '$1.$2'); +} + +function removeQuotes(name, value) { + if (name == 'content' || name.indexOf('font-feature-settings') > -1 || name.indexOf('grid-') > -1) { + return value; + } + + return QUOTED_BUT_SAFE_PATTERN.test(value) ? + value.substring(1, value.length - 1) : + value; +} + +function removeUrlQuotes(value) { + return /^url\(['"].+['"]\)$/.test(value) && !/^url\(['"].*[\*\s\(\)'"].*['"]\)$/.test(value) && !/^url\(['"]data:[^;]+;charset/.test(value) ? + value.replace(/["']/g, '') : + value; +} + +function transformValue(propertyName, propertyValue, transformCallback) { + var transformedValue = transformCallback(propertyName, propertyValue); + + if (transformedValue === undefined) { + return propertyValue; + } else if (transformedValue === false) { + return IgnoreProperty; + } else { + return transformedValue; + } +} + +// + +function optimizeBody(properties, context) { + var options = context.options; + var levelOptions = options.level[OptimizationLevel.One]; + var property, name, type, value; + var valueIsUrl; + var propertyToken; + var _properties = wrapForOptimizing(properties, true); + + propertyLoop: + for (var i = 0, l = _properties.length; i < l; i++) { + property = _properties[i]; + name = property.name; + + if (!PROPERTY_NAME_PATTERN.test(name)) { + propertyToken = property.all[property.position]; + context.warnings.push('Invalid property name \'' + name + '\' at ' + formatPosition(propertyToken[1][2][0]) + '. Ignoring.'); + property.unused = true; + } + + if (property.value.length === 0) { + propertyToken = property.all[property.position]; + context.warnings.push('Empty property \'' + name + '\' at ' + formatPosition(propertyToken[1][2][0]) + '. Ignoring.'); + property.unused = true; + } + + if (property.hack && ( + (property.hack[0] == Hack.ASTERISK || property.hack[0] == Hack.UNDERSCORE) && !options.compatibility.properties.iePrefixHack || + property.hack[0] == Hack.BACKSLASH && !options.compatibility.properties.ieSuffixHack || + property.hack[0] == Hack.BANG && !options.compatibility.properties.ieBangHack)) { + property.unused = true; + } + + if (levelOptions.removeNegativePaddings && name.indexOf('padding') === 0 && (isNegative(property.value[0]) || isNegative(property.value[1]) || isNegative(property.value[2]) || isNegative(property.value[3]))) { + property.unused = true; + } + + if (!options.compatibility.properties.ieFilters && isLegacyFilter(property)) { + property.unused = true; + } + + if (property.unused) { + continue; + } + + if (property.block) { + optimizeBody(property.value[0][1], context); + continue; + } + + if (VARIABLE_NAME_PATTERN.test(name)) { + continue; + } + + for (var j = 0, m = property.value.length; j < m; j++) { + type = property.value[j][0]; + value = property.value[j][1]; + valueIsUrl = isUrl(value); + + if (type == Token.PROPERTY_BLOCK) { + property.unused = true; + context.warnings.push('Invalid value token at ' + formatPosition(value[0][1][2][0]) + '. Ignoring.'); + break; + } + + if (valueIsUrl && !context.validator.isValidUrl(value)) { + property.unused = true; + context.warnings.push('Broken URL \'' + value + '\' at ' + formatPosition(property.value[j][2][0]) + '. Ignoring.'); + break; + } + + if (valueIsUrl) { + value = levelOptions.normalizeUrls ? + normalizeUrl(value) : + value; + value = !options.compatibility.properties.urlQuotes ? + removeUrlQuotes(value) : + value; + } else if (isQuoted(value)) { + value = levelOptions.removeQuotes ? + removeQuotes(name, value) : + value; + } else { + value = levelOptions.removeWhitespace ? + optimizeWhitespace(name, value) : + value; + value = optimizePrecision(name, value, options.precision); + value = optimizePixelLengths(name, value, options.compatibility); + value = levelOptions.replaceTimeUnits ? + optimizeTimeUnits(name, value) : + value; + value = levelOptions.replaceZeroUnits ? + optimizeZeroUnits(name, value) : + value; + + if (options.compatibility.properties.zeroUnits) { + value = optimizeZeroDegUnit(name, value); + value = optimizeUnits(name, value, options.unitsRegexp); + } + + if (options.compatibility.properties.colors) { + value = optimizeColors(name, value, options.compatibility); + } + } + + value = transformValue(name, value, levelOptions.transform); + + if (value === IgnoreProperty) { + property.unused = true; + continue propertyLoop; + } + + property.value[j][1] = value; + } + + if (levelOptions.replaceMultipleZeros) { + optimizeMultipleZeros(property); + } + + if (name == 'background' && levelOptions.optimizeBackground) { + optimizeBackground(property); + } else if (name.indexOf('border') === 0 && name.indexOf('radius') > 0 && levelOptions.optimizeBorderRadius) { + optimizeBorderRadius(property); + } else if (name == 'filter'&& levelOptions.optimizeFilter && options.compatibility.properties.ieFilters) { + optimizeFilter(property); + } else if (name == 'font' && levelOptions.optimizeFont) { + optimizeFont(property, options); + } else if (name == 'font-weight' && levelOptions.optimizeFontWeight) { + optimizeFontWeight(property, 0); + } else if (name == 'outline' && levelOptions.optimizeOutline) { + optimizeOutline(property); + } + } + + restoreFromOptimizing(_properties); + removeUnused(_properties); + + if (_properties.length != properties.length) { + removeComments(properties, options); + } +} + +function removeComments(tokens, options) { + var token; + var i; + + for (i = 0; i < tokens.length; i++) { + token = tokens[i]; + + if (token[0] != Token.COMMENT) { + continue; + } + + optimizeComment(token, options); + + if (token[1].length === 0) { + tokens.splice(i, 1); + i--; + } + } +} + +function optimizeComment(token, options) { + if (token[1][2] == Marker.EXCLAMATION && (options.level[OptimizationLevel.One].specialComments == 'all' || options.commentsKept < options.level[OptimizationLevel.One].specialComments)) { + options.commentsKept++; + return; + } + + token[1] = []; +} + +function cleanupCharsets(tokens) { + var hasCharset = false; + + for (var i = 0, l = tokens.length; i < l; i++) { + var token = tokens[i]; + + if (token[0] != Token.AT_RULE) + continue; + + if (!CHARSET_REGEXP.test(token[1])) + continue; + + if (hasCharset || token[1].indexOf(CHARSET_TOKEN) == -1) { + tokens.splice(i, 1); + i--; + l--; + } else { + hasCharset = true; + tokens.splice(i, 1); + tokens.unshift([Token.AT_RULE, token[1].replace(CHARSET_REGEXP, CHARSET_TOKEN)]); + } + } +} + +function buildUnitRegexp(options) { + var units = ['px', 'em', 'ex', 'cm', 'mm', 'in', 'pt', 'pc', '%']; + var otherUnits = ['ch', 'rem', 'vh', 'vm', 'vmax', 'vmin', 'vw']; + + otherUnits.forEach(function (unit) { + if (options.compatibility.units[unit]) { + units.push(unit); + } + }); + + return new RegExp('(^|\\s|\\(|,)0(?:' + units.join('|') + ')(\\W|$)', 'g'); +} + +function buildPrecisionOptions(roundingPrecision) { + var precisionOptions = { + matcher: null, + units: {}, + }; + var optimizable = []; + var unit; + var value; + + for (unit in roundingPrecision) { + value = roundingPrecision[unit]; + + if (value != DEFAULT_ROUNDING_PRECISION) { + precisionOptions.units[unit] = {}; + precisionOptions.units[unit].value = value; + precisionOptions.units[unit].multiplier = Math.pow(10, value); + + optimizable.push(unit); + } + } + + if (optimizable.length > 0) { + precisionOptions.enabled = true; + precisionOptions.decimalPointMatcher = new RegExp('(\\d)\\.($|' + optimizable.join('|') + ')($|\W)', 'g'); + precisionOptions.zeroMatcher = new RegExp('(\\d*)(\\.\\d+)(' + optimizable.join('|') + ')', 'g'); + } + + return precisionOptions; +} + +function isImport(token) { + return IMPORT_PREFIX_PATTERN.test(token[1]); +} + +function isLegacyFilter(property) { + var value; + + if (property.name == 'filter' || property.name == '-ms-filter') { + value = property.value[0][1]; + + return value.indexOf('progid') > -1 || + value.indexOf('alpha') === 0 || + value.indexOf('chroma') === 0; + } else { + return false; + } +} + +function level1Optimize(tokens, context) { + var options = context.options; + var levelOptions = options.level[OptimizationLevel.One]; + var ie7Hack = options.compatibility.selectors.ie7Hack; + var adjacentSpace = options.compatibility.selectors.adjacentSpace; + var spaceAfterClosingBrace = options.compatibility.properties.spaceAfterClosingBrace; + var format = options.format; + var mayHaveCharset = false; + var afterRules = false; + + options.unitsRegexp = options.unitsRegexp || buildUnitRegexp(options); + options.precision = options.precision || buildPrecisionOptions(levelOptions.roundingPrecision); + options.commentsKept = options.commentsKept || 0; + + for (var i = 0, l = tokens.length; i < l; i++) { + var token = tokens[i]; + + switch (token[0]) { + case Token.AT_RULE: + token[1] = isImport(token) && afterRules ? '' : token[1]; + token[1] = levelOptions.tidyAtRules ? tidyAtRule(token[1]) : token[1]; + mayHaveCharset = true; + break; + case Token.AT_RULE_BLOCK: + optimizeBody(token[2], context); + afterRules = true; + break; + case Token.NESTED_BLOCK: + token[1] = levelOptions.tidyBlockScopes ? tidyBlock(token[1], spaceAfterClosingBrace) : token[1]; + level1Optimize(token[2], context); + afterRules = true; + break; + case Token.COMMENT: + optimizeComment(token, options); + break; + case Token.RULE: + token[1] = levelOptions.tidySelectors ? tidyRules(token[1], !ie7Hack, adjacentSpace, format, context.warnings) : token[1]; + token[1] = token[1].length > 1 ? sortSelectors(token[1], levelOptions.selectorsSortingMethod) : token[1]; + optimizeBody(token[2], context); + afterRules = true; + break; + } + + if (token[1].length === 0 || (token[2] && token[2].length === 0)) { + tokens.splice(i, 1); + i--; + l--; + } + } + + if (levelOptions.cleanupCharsets && mayHaveCharset) { + cleanupCharsets(tokens); + } + + return tokens; +} + +module.exports = level1Optimize; diff --git a/node_modules/clean-css/lib/optimizer/level-1/shorten-hex.js b/node_modules/clean-css/lib/optimizer/level-1/shorten-hex.js new file mode 100644 index 000000000..3deea381c --- /dev/null +++ b/node_modules/clean-css/lib/optimizer/level-1/shorten-hex.js @@ -0,0 +1,189 @@ +var COLORS = { + aliceblue: '#f0f8ff', + antiquewhite: '#faebd7', + aqua: '#0ff', + aquamarine: '#7fffd4', + azure: '#f0ffff', + beige: '#f5f5dc', + bisque: '#ffe4c4', + black: '#000', + blanchedalmond: '#ffebcd', + blue: '#00f', + blueviolet: '#8a2be2', + brown: '#a52a2a', + burlywood: '#deb887', + cadetblue: '#5f9ea0', + chartreuse: '#7fff00', + chocolate: '#d2691e', + coral: '#ff7f50', + cornflowerblue: '#6495ed', + cornsilk: '#fff8dc', + crimson: '#dc143c', + cyan: '#0ff', + darkblue: '#00008b', + darkcyan: '#008b8b', + darkgoldenrod: '#b8860b', + darkgray: '#a9a9a9', + darkgreen: '#006400', + darkgrey: '#a9a9a9', + darkkhaki: '#bdb76b', + darkmagenta: '#8b008b', + darkolivegreen: '#556b2f', + darkorange: '#ff8c00', + darkorchid: '#9932cc', + darkred: '#8b0000', + darksalmon: '#e9967a', + darkseagreen: '#8fbc8f', + darkslateblue: '#483d8b', + darkslategray: '#2f4f4f', + darkslategrey: '#2f4f4f', + darkturquoise: '#00ced1', + darkviolet: '#9400d3', + deeppink: '#ff1493', + deepskyblue: '#00bfff', + dimgray: '#696969', + dimgrey: '#696969', + dodgerblue: '#1e90ff', + firebrick: '#b22222', + floralwhite: '#fffaf0', + forestgreen: '#228b22', + fuchsia: '#f0f', + gainsboro: '#dcdcdc', + ghostwhite: '#f8f8ff', + gold: '#ffd700', + goldenrod: '#daa520', + gray: '#808080', + green: '#008000', + greenyellow: '#adff2f', + grey: '#808080', + honeydew: '#f0fff0', + hotpink: '#ff69b4', + indianred: '#cd5c5c', + indigo: '#4b0082', + ivory: '#fffff0', + khaki: '#f0e68c', + lavender: '#e6e6fa', + lavenderblush: '#fff0f5', + lawngreen: '#7cfc00', + lemonchiffon: '#fffacd', + lightblue: '#add8e6', + lightcoral: '#f08080', + lightcyan: '#e0ffff', + lightgoldenrodyellow: '#fafad2', + lightgray: '#d3d3d3', + lightgreen: '#90ee90', + lightgrey: '#d3d3d3', + lightpink: '#ffb6c1', + lightsalmon: '#ffa07a', + lightseagreen: '#20b2aa', + lightskyblue: '#87cefa', + lightslategray: '#778899', + lightslategrey: '#778899', + lightsteelblue: '#b0c4de', + lightyellow: '#ffffe0', + lime: '#0f0', + limegreen: '#32cd32', + linen: '#faf0e6', + magenta: '#ff00ff', + maroon: '#800000', + mediumaquamarine: '#66cdaa', + mediumblue: '#0000cd', + mediumorchid: '#ba55d3', + mediumpurple: '#9370db', + mediumseagreen: '#3cb371', + mediumslateblue: '#7b68ee', + mediumspringgreen: '#00fa9a', + mediumturquoise: '#48d1cc', + mediumvioletred: '#c71585', + midnightblue: '#191970', + mintcream: '#f5fffa', + mistyrose: '#ffe4e1', + moccasin: '#ffe4b5', + navajowhite: '#ffdead', + navy: '#000080', + oldlace: '#fdf5e6', + olive: '#808000', + olivedrab: '#6b8e23', + orange: '#ffa500', + orangered: '#ff4500', + orchid: '#da70d6', + palegoldenrod: '#eee8aa', + palegreen: '#98fb98', + paleturquoise: '#afeeee', + palevioletred: '#db7093', + papayawhip: '#ffefd5', + peachpuff: '#ffdab9', + peru: '#cd853f', + pink: '#ffc0cb', + plum: '#dda0dd', + powderblue: '#b0e0e6', + purple: '#800080', + rebeccapurple: '#663399', + red: '#f00', + rosybrown: '#bc8f8f', + royalblue: '#4169e1', + saddlebrown: '#8b4513', + salmon: '#fa8072', + sandybrown: '#f4a460', + seagreen: '#2e8b57', + seashell: '#fff5ee', + sienna: '#a0522d', + silver: '#c0c0c0', + skyblue: '#87ceeb', + slateblue: '#6a5acd', + slategray: '#708090', + slategrey: '#708090', + snow: '#fffafa', + springgreen: '#00ff7f', + steelblue: '#4682b4', + tan: '#d2b48c', + teal: '#008080', + thistle: '#d8bfd8', + tomato: '#ff6347', + turquoise: '#40e0d0', + violet: '#ee82ee', + wheat: '#f5deb3', + white: '#fff', + whitesmoke: '#f5f5f5', + yellow: '#ff0', + yellowgreen: '#9acd32' +}; + +var toHex = {}; +var toName = {}; + +for (var name in COLORS) { + var hex = COLORS[name]; + + if (name.length < hex.length) { + toName[hex] = name; + } else { + toHex[name] = hex; + } +} + +var toHexPattern = new RegExp('(^| |,|\\))(' + Object.keys(toHex).join('|') + ')( |,|\\)|$)', 'ig'); +var toNamePattern = new RegExp('(' + Object.keys(toName).join('|') + ')([^a-f0-9]|$)', 'ig'); + +function hexConverter(match, prefix, colorValue, suffix) { + return prefix + toHex[colorValue.toLowerCase()] + suffix; +} + +function nameConverter(match, colorValue, suffix) { + return toName[colorValue.toLowerCase()] + suffix; +} + +function shortenHex(value) { + var hasHex = value.indexOf('#') > -1; + var shortened = value.replace(toHexPattern, hexConverter); + + if (shortened != value) { + shortened = shortened.replace(toHexPattern, hexConverter); + } + + return hasHex ? + shortened.replace(toNamePattern, nameConverter) : + shortened; +} + +module.exports = shortenHex; diff --git a/node_modules/clean-css/lib/optimizer/level-1/shorten-hsl.js b/node_modules/clean-css/lib/optimizer/level-1/shorten-hsl.js new file mode 100644 index 000000000..fe98dfd39 --- /dev/null +++ b/node_modules/clean-css/lib/optimizer/level-1/shorten-hsl.js @@ -0,0 +1,61 @@ +// HSL to RGB converter. Both methods adapted from: +// http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript + +function hslToRgb(h, s, l) { + var r, g, b; + + // normalize hue orientation b/w 0 and 360 degrees + h = h % 360; + if (h < 0) + h += 360; + h = ~~h / 360; + + if (s < 0) + s = 0; + else if (s > 100) + s = 100; + s = ~~s / 100; + + if (l < 0) + l = 0; + else if (l > 100) + l = 100; + l = ~~l / 100; + + if (s === 0) { + r = g = b = l; // achromatic + } else { + var q = l < 0.5 ? + l * (1 + s) : + l + s - l * s; + var p = 2 * l - q; + r = hueToRgb(p, q, h + 1/3); + g = hueToRgb(p, q, h); + b = hueToRgb(p, q, h - 1/3); + } + + return [~~(r * 255), ~~(g * 255), ~~(b * 255)]; +} + +function hueToRgb(p, q, t) { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1/6) return p + (q - p) * 6 * t; + if (t < 1/2) return q; + if (t < 2/3) return p + (q - p) * (2/3 - t) * 6; + return p; +} + +function shortenHsl(hue, saturation, lightness) { + var asRgb = hslToRgb(hue, saturation, lightness); + var redAsHex = asRgb[0].toString(16); + var greenAsHex = asRgb[1].toString(16); + var blueAsHex = asRgb[2].toString(16); + + return '#' + + ((redAsHex.length == 1 ? '0' : '') + redAsHex) + + ((greenAsHex.length == 1 ? '0' : '') + greenAsHex) + + ((blueAsHex.length == 1 ? '0' : '') + blueAsHex); +} + +module.exports = shortenHsl; diff --git a/node_modules/clean-css/lib/optimizer/level-1/shorten-rgb.js b/node_modules/clean-css/lib/optimizer/level-1/shorten-rgb.js new file mode 100644 index 000000000..3c0a5fa31 --- /dev/null +++ b/node_modules/clean-css/lib/optimizer/level-1/shorten-rgb.js @@ -0,0 +1,10 @@ +function shortenRgb(red, green, blue) { + var normalizedRed = Math.max(0, Math.min(parseInt(red), 255)); + var normalizedGreen = Math.max(0, Math.min(parseInt(green), 255)); + var normalizedBlue = Math.max(0, Math.min(parseInt(blue), 255)); + + // Credit: Asen http://jsbin.com/UPUmaGOc/2/edit?js,console + return '#' + ('00000' + (normalizedRed << 16 | normalizedGreen << 8 | normalizedBlue).toString(16)).slice(-6); +} + +module.exports = shortenRgb; diff --git a/node_modules/clean-css/lib/optimizer/level-1/sort-selectors.js b/node_modules/clean-css/lib/optimizer/level-1/sort-selectors.js new file mode 100644 index 000000000..2f179e6ef --- /dev/null +++ b/node_modules/clean-css/lib/optimizer/level-1/sort-selectors.js @@ -0,0 +1,25 @@ +var naturalCompare = require('../../utils/natural-compare'); + +function naturalSorter(scope1, scope2) { + return naturalCompare(scope1[1], scope2[1]); +} + +function standardSorter(scope1, scope2) { + return scope1[1] > scope2[1] ? 1 : -1; +} + +function sortSelectors(selectors, method) { + var sorter; + + switch (method) { + case 'natural': + sorter = naturalSorter; + break; + case 'standard': + sorter = standardSorter; + } + + return selectors.sort(sorter); +} + +module.exports = sortSelectors; diff --git a/node_modules/clean-css/lib/optimizer/level-1/tidy-at-rule.js b/node_modules/clean-css/lib/optimizer/level-1/tidy-at-rule.js new file mode 100644 index 000000000..a7b149fb5 --- /dev/null +++ b/node_modules/clean-css/lib/optimizer/level-1/tidy-at-rule.js @@ -0,0 +1,9 @@ +function tidyAtRule(value) { + return value + .replace(/\s+/g, ' ') + .replace(/url\(\s+/g, 'url(') + .replace(/\s+\)/g, ')') + .trim(); +} + +module.exports = tidyAtRule; diff --git a/node_modules/clean-css/lib/optimizer/level-1/tidy-block.js b/node_modules/clean-css/lib/optimizer/level-1/tidy-block.js new file mode 100644 index 000000000..8322aeca7 --- /dev/null +++ b/node_modules/clean-css/lib/optimizer/level-1/tidy-block.js @@ -0,0 +1,23 @@ +var SUPPORTED_COMPACT_BLOCK_MATCHER = /^@media\W/; + +function tidyBlock(values, spaceAfterClosingBrace) { + var withoutSpaceAfterClosingBrace; + var i; + + for (i = values.length - 1; i >= 0; i--) { + withoutSpaceAfterClosingBrace = !spaceAfterClosingBrace && SUPPORTED_COMPACT_BLOCK_MATCHER.test(values[i][1]); + + values[i][1] = values[i][1] + .replace(/\n|\r\n/g, ' ') + .replace(/\s+/g, ' ') + .replace(/(,|:|\() /g, '$1') + .replace(/ \)/g, ')') + .replace(/'([a-zA-Z][a-zA-Z\d\-_]+)'/, '$1') + .replace(/"([a-zA-Z][a-zA-Z\d\-_]+)"/, '$1') + .replace(withoutSpaceAfterClosingBrace ? /\) /g : null, ')'); + } + + return values; +} + +module.exports = tidyBlock; diff --git a/node_modules/clean-css/lib/optimizer/level-1/tidy-rules.js b/node_modules/clean-css/lib/optimizer/level-1/tidy-rules.js new file mode 100644 index 000000000..b47ed6b79 --- /dev/null +++ b/node_modules/clean-css/lib/optimizer/level-1/tidy-rules.js @@ -0,0 +1,213 @@ +var Spaces = require('../../options/format').Spaces; +var Marker = require('../../tokenizer/marker'); +var formatPosition = require('../../utils/format-position'); + +var CASE_ATTRIBUTE_PATTERN = /[\s"'][iI]\s*\]/; +var CASE_RESTORE_PATTERN = /([\d\w])([iI])\]/g; +var DOUBLE_QUOTE_CASE_PATTERN = /="([a-zA-Z][a-zA-Z\d\-_]+)"([iI])/g; +var DOUBLE_QUOTE_PATTERN = /="([a-zA-Z][a-zA-Z\d\-_]+)"(\s|\])/g; +var HTML_COMMENT_PATTERN = /^(?:(?:)\s*)+/; +var SINGLE_QUOTE_CASE_PATTERN = /='([a-zA-Z][a-zA-Z\d\-_]+)'([iI])/g; +var SINGLE_QUOTE_PATTERN = /='([a-zA-Z][a-zA-Z\d\-_]+)'(\s|\])/g; +var RELATION_PATTERN = /[>\+~]/; +var WHITESPACE_PATTERN = /\s/; + +var ASTERISK_PLUS_HTML_HACK = '*+html '; +var ASTERISK_FIRST_CHILD_PLUS_HTML_HACK = '*:first-child+html '; +var LESS_THAN = '<'; + +function hasInvalidCharacters(value) { + var isEscaped; + var isInvalid = false; + var character; + var isQuote = false; + var i, l; + + for (i = 0, l = value.length; i < l; i++) { + character = value[i]; + + if (isEscaped) { + // continue as always + } else if (character == Marker.SINGLE_QUOTE || character == Marker.DOUBLE_QUOTE) { + isQuote = !isQuote; + } else if (!isQuote && (character == Marker.CLOSE_CURLY_BRACKET || character == Marker.EXCLAMATION || character == LESS_THAN || character == Marker.SEMICOLON)) { + isInvalid = true; + break; + } else if (!isQuote && i === 0 && RELATION_PATTERN.test(character)) { + isInvalid = true; + break; + } + + isEscaped = character == Marker.BACK_SLASH; + } + + return isInvalid; +} + +function removeWhitespace(value, format) { + var stripped = []; + var character; + var isNewLineNix; + var isNewLineWin; + var isEscaped; + var wasEscaped; + var isQuoted; + var isSingleQuoted; + var isDoubleQuoted; + var isAttribute; + var isRelation; + var isWhitespace; + var roundBracketLevel = 0; + var wasRelation = false; + var wasWhitespace = false; + var withCaseAttribute = CASE_ATTRIBUTE_PATTERN.test(value); + var spaceAroundRelation = format && format.spaces[Spaces.AroundSelectorRelation]; + var i, l; + + for (i = 0, l = value.length; i < l; i++) { + character = value[i]; + + isNewLineNix = character == Marker.NEW_LINE_NIX; + isNewLineWin = character == Marker.NEW_LINE_NIX && value[i - 1] == Marker.NEW_LINE_WIN; + isQuoted = isSingleQuoted || isDoubleQuoted; + isRelation = !isEscaped && roundBracketLevel === 0 && RELATION_PATTERN.test(character); + isWhitespace = WHITESPACE_PATTERN.test(character); + + if (wasEscaped && isQuoted && isNewLineWin) { + // swallow escaped new windows lines in comments + stripped.pop(); + stripped.pop(); + } else if (isEscaped && isQuoted && isNewLineNix) { + // swallow escaped new *nix lines in comments + stripped.pop(); + } else if (isEscaped) { + stripped.push(character); + } else if (character == Marker.OPEN_SQUARE_BRACKET && !isQuoted) { + stripped.push(character); + isAttribute = true; + } else if (character == Marker.CLOSE_SQUARE_BRACKET && !isQuoted) { + stripped.push(character); + isAttribute = false; + } else if (character == Marker.OPEN_ROUND_BRACKET && !isQuoted) { + stripped.push(character); + roundBracketLevel++; + } else if (character == Marker.CLOSE_ROUND_BRACKET && !isQuoted) { + stripped.push(character); + roundBracketLevel--; + } else if (character == Marker.SINGLE_QUOTE && !isQuoted) { + stripped.push(character); + isSingleQuoted = true; + } else if (character == Marker.DOUBLE_QUOTE && !isQuoted) { + stripped.push(character); + isDoubleQuoted = true; + } else if (character == Marker.SINGLE_QUOTE && isQuoted) { + stripped.push(character); + isSingleQuoted = false; + } else if (character == Marker.DOUBLE_QUOTE && isQuoted) { + stripped.push(character); + isDoubleQuoted = false; + } else if (isWhitespace && wasRelation && !spaceAroundRelation) { + continue; + } else if (!isWhitespace && wasRelation && spaceAroundRelation) { + stripped.push(Marker.SPACE); + stripped.push(character); + } else if (isWhitespace && (isAttribute || roundBracketLevel > 0) && !isQuoted) { + // skip space + } else if (isWhitespace && wasWhitespace && !isQuoted) { + // skip extra space + } else if ((isNewLineWin || isNewLineNix) && (isAttribute || roundBracketLevel > 0) && isQuoted) { + // skip newline + } else if (isRelation && wasWhitespace && !spaceAroundRelation) { + stripped.pop(); + stripped.push(character); + } else if (isRelation && !wasWhitespace && spaceAroundRelation) { + stripped.push(Marker.SPACE); + stripped.push(character); + } else if (isWhitespace) { + stripped.push(Marker.SPACE); + } else { + stripped.push(character); + } + + wasEscaped = isEscaped; + isEscaped = character == Marker.BACK_SLASH; + wasRelation = isRelation; + wasWhitespace = isWhitespace; + } + + return withCaseAttribute ? + stripped.join('').replace(CASE_RESTORE_PATTERN, '$1 $2]') : + stripped.join(''); +} + +function removeQuotes(value) { + if (value.indexOf('\'') == -1 && value.indexOf('"') == -1) { + return value; + } + + return value + .replace(SINGLE_QUOTE_CASE_PATTERN, '=$1 $2') + .replace(SINGLE_QUOTE_PATTERN, '=$1$2') + .replace(DOUBLE_QUOTE_CASE_PATTERN, '=$1 $2') + .replace(DOUBLE_QUOTE_PATTERN, '=$1$2'); +} + +function tidyRules(rules, removeUnsupported, adjacentSpace, format, warnings) { + var list = []; + var repeated = []; + + function removeHTMLComment(rule, match) { + warnings.push('HTML comment \'' + match + '\' at ' + formatPosition(rule[2][0]) + '. Removing.'); + return ''; + } + + for (var i = 0, l = rules.length; i < l; i++) { + var rule = rules[i]; + var reduced = rule[1]; + + reduced = reduced.replace(HTML_COMMENT_PATTERN, removeHTMLComment.bind(null, rule)); + + if (hasInvalidCharacters(reduced)) { + warnings.push('Invalid selector \'' + rule[1] + '\' at ' + formatPosition(rule[2][0]) + '. Ignoring.'); + continue; + } + + reduced = removeWhitespace(reduced, format); + reduced = removeQuotes(reduced); + + if (adjacentSpace && reduced.indexOf('nav') > 0) { + reduced = reduced.replace(/\+nav(\S|$)/, '+ nav$1'); + } + + if (removeUnsupported && reduced.indexOf(ASTERISK_PLUS_HTML_HACK) > -1) { + continue; + } + + if (removeUnsupported && reduced.indexOf(ASTERISK_FIRST_CHILD_PLUS_HTML_HACK) > -1) { + continue; + } + + if (reduced.indexOf('*') > -1) { + reduced = reduced + .replace(/\*([:#\.\[])/g, '$1') + .replace(/^(\:first\-child)?\+html/, '*$1+html'); + } + + if (repeated.indexOf(reduced) > -1) { + continue; + } + + rule[1] = reduced; + repeated.push(reduced); + list.push(rule); + } + + if (list.length == 1 && list[0][1].length === 0) { + warnings.push('Empty selector \'' + list[0][1] + '\' at ' + formatPosition(list[0][2][0]) + '. Ignoring.'); + list = []; + } + + return list; +} + +module.exports = tidyRules; diff --git a/node_modules/clean-css/lib/optimizer/level-2/break-up.js b/node_modules/clean-css/lib/optimizer/level-2/break-up.js new file mode 100644 index 000000000..9e44d5a1f --- /dev/null +++ b/node_modules/clean-css/lib/optimizer/level-2/break-up.js @@ -0,0 +1,362 @@ +var InvalidPropertyError = require('./invalid-property-error'); + +var wrapSingle = require('../wrap-for-optimizing').single; + +var Token = require('../../tokenizer/token'); + +var formatPosition = require('../../utils/format-position'); + +var MULTIPLEX_SEPARATOR = ','; + +function _colorFilter(validator) { + return function (value) { + return value[1] == 'invert' || validator.isValidColor(value[1]) || validator.isValidVendorPrefixedValue(value[1]); + }; +} + +function _styleFilter(validator) { + return function (value) { + return value[1] != 'inherit' && validator.isValidStyle(value[1]) && !validator.isValidColorValue(value[1]); + }; +} + +function _wrapDefault(name, property, compactable) { + var descriptor = compactable[name]; + if (descriptor.doubleValues && descriptor.defaultValue.length == 2) { + return wrapSingle([ + Token.PROPERTY, + [Token.PROPERTY_NAME, name], + [Token.PROPERTY_VALUE, descriptor.defaultValue[0]], + [Token.PROPERTY_VALUE, descriptor.defaultValue[1]] + ]); + } else if (descriptor.doubleValues && descriptor.defaultValue.length == 1) { + return wrapSingle([ + Token.PROPERTY, + [Token.PROPERTY_NAME, name], + [Token.PROPERTY_VALUE, descriptor.defaultValue[0]] + ]); + } else { + return wrapSingle([ + Token.PROPERTY, + [Token.PROPERTY_NAME, name], + [Token.PROPERTY_VALUE, descriptor.defaultValue] + ]); + } +} + +function _widthFilter(validator) { + return function (value) { + return value[1] != 'inherit' && validator.isValidWidth(value[1]) && !validator.isValidStyle(value[1]) && !validator.isValidColorValue(value[1]); + }; +} + +function background(property, compactable, validator) { + var image = _wrapDefault('background-image', property, compactable); + var position = _wrapDefault('background-position', property, compactable); + var size = _wrapDefault('background-size', property, compactable); + var repeat = _wrapDefault('background-repeat', property, compactable); + var attachment = _wrapDefault('background-attachment', property, compactable); + var origin = _wrapDefault('background-origin', property, compactable); + var clip = _wrapDefault('background-clip', property, compactable); + var color = _wrapDefault('background-color', property, compactable); + var components = [image, position, size, repeat, attachment, origin, clip, color]; + var values = property.value; + + var positionSet = false; + var clipSet = false; + var originSet = false; + var repeatSet = false; + + var anyValueSet = false; + + if (property.value.length == 1 && property.value[0][1] == 'inherit') { + // NOTE: 'inherit' is not a valid value for background-attachment + color.value = image.value = repeat.value = position.value = size.value = origin.value = clip.value = property.value; + return components; + } + + if (property.value.length == 1 && property.value[0][1] == '0 0') { + return components; + } + + for (var i = values.length - 1; i >= 0; i--) { + var value = values[i]; + + if (validator.isValidBackgroundAttachment(value[1])) { + attachment.value = [value]; + anyValueSet = true; + } else if (validator.isValidBackgroundClip(value[1]) || validator.isValidBackgroundOrigin(value[1])) { + if (clipSet) { + origin.value = [value]; + originSet = true; + } else { + clip.value = [value]; + clipSet = true; + } + anyValueSet = true; + } else if (validator.isValidBackgroundRepeat(value[1])) { + if (repeatSet) { + repeat.value.unshift(value); + } else { + repeat.value = [value]; + repeatSet = true; + } + anyValueSet = true; + } else if (validator.isValidBackgroundPositionPart(value[1]) || validator.isValidBackgroundSizePart(value[1])) { + if (i > 0) { + var previousValue = values[i - 1]; + + if (previousValue[1] == '/') { + size.value = [value]; + } else if (i > 1 && values[i - 2][1] == '/') { + size.value = [previousValue, value]; + i -= 2; + } else { + if (!positionSet) + position.value = []; + + position.value.unshift(value); + positionSet = true; + } + } else { + if (!positionSet) + position.value = []; + + position.value.unshift(value); + positionSet = true; + } + anyValueSet = true; + } else if ((color.value[0][1] == compactable[color.name].defaultValue || color.value[0][1] == 'none') && (validator.isValidColor(value[1]) || validator.isValidVendorPrefixedValue(value[1]))) { + color.value = [value]; + anyValueSet = true; + } else if (validator.isValidUrl(value[1]) || validator.isValidFunction(value[1])) { + image.value = [value]; + anyValueSet = true; + } + } + + if (clipSet && !originSet) + origin.value = clip.value.slice(0); + + if (!anyValueSet) { + throw new InvalidPropertyError('Invalid background value at ' + formatPosition(values[0][2][0]) + '. Ignoring.'); + } + + return components; +} + +function borderRadius(property, compactable) { + var values = property.value; + var splitAt = -1; + + for (var i = 0, l = values.length; i < l; i++) { + if (values[i][1] == '/') { + splitAt = i; + break; + } + } + + if (splitAt === 0 || splitAt === values.length - 1) { + throw new InvalidPropertyError('Invalid border-radius value at ' + formatPosition(values[0][2][0]) + '. Ignoring.'); + } + + var target = _wrapDefault(property.name, property, compactable); + target.value = splitAt > -1 ? + values.slice(0, splitAt) : + values.slice(0); + target.components = fourValues(target, compactable); + + var remainder = _wrapDefault(property.name, property, compactable); + remainder.value = splitAt > -1 ? + values.slice(splitAt + 1) : + values.slice(0); + remainder.components = fourValues(remainder, compactable); + + for (var j = 0; j < 4; j++) { + target.components[j].multiplex = true; + target.components[j].value = target.components[j].value.concat(remainder.components[j].value); + } + + return target.components; +} + +function fourValues(property, compactable) { + var componentNames = compactable[property.name].components; + var components = []; + var value = property.value; + + if (value.length < 1) + return []; + + if (value.length < 2) + value[1] = value[0].slice(0); + if (value.length < 3) + value[2] = value[0].slice(0); + if (value.length < 4) + value[3] = value[1].slice(0); + + for (var i = componentNames.length - 1; i >= 0; i--) { + var component = wrapSingle([ + Token.PROPERTY, + [Token.PROPERTY_NAME, componentNames[i]] + ]); + component.value = [value[i]]; + components.unshift(component); + } + + return components; +} + +function multiplex(splitWith) { + return function (property, compactable, validator) { + var splitsAt = []; + var values = property.value; + var i, j, l, m; + + // find split commas + for (i = 0, l = values.length; i < l; i++) { + if (values[i][1] == ',') + splitsAt.push(i); + } + + if (splitsAt.length === 0) + return splitWith(property, compactable, validator); + + var splitComponents = []; + + // split over commas, and into components + for (i = 0, l = splitsAt.length; i <= l; i++) { + var from = i === 0 ? 0 : splitsAt[i - 1] + 1; + var to = i < l ? splitsAt[i] : values.length; + + var _property = _wrapDefault(property.name, property, compactable); + _property.value = values.slice(from, to); + + splitComponents.push(splitWith(_property, compactable, validator)); + } + + var components = splitComponents[0]; + + // group component values from each split + for (i = 0, l = components.length; i < l; i++) { + components[i].multiplex = true; + + for (j = 1, m = splitComponents.length; j < m; j++) { + components[i].value.push([Token.PROPERTY_VALUE, MULTIPLEX_SEPARATOR]); + Array.prototype.push.apply(components[i].value, splitComponents[j][i].value); + } + } + + return components; + }; +} + +function listStyle(property, compactable, validator) { + var type = _wrapDefault('list-style-type', property, compactable); + var position = _wrapDefault('list-style-position', property, compactable); + var image = _wrapDefault('list-style-image', property, compactable); + var components = [type, position, image]; + + if (property.value.length == 1 && property.value[0][1] == 'inherit') { + type.value = position.value = image.value = [property.value[0]]; + return components; + } + + var values = property.value.slice(0); + var total = values.length; + var index = 0; + + // `image` first... + for (index = 0, total = values.length; index < total; index++) { + if (validator.isValidUrl(values[index][1]) || values[index][1] == '0') { + image.value = [values[index]]; + values.splice(index, 1); + break; + } + } + + // ... then `type`... + for (index = 0, total = values.length; index < total; index++) { + if (validator.isValidListStyleType(values[index][1])) { + type.value = [values[index]]; + values.splice(index, 1); + break; + } + } + + // ... and what's left is a `position` + if (values.length > 0 && validator.isValidListStylePosition(values[0][1])) + position.value = [values[0]]; + + return components; +} + +function widthStyleColor(property, compactable, validator) { + var descriptor = compactable[property.name]; + var components = [ + _wrapDefault(descriptor.components[0], property, compactable), + _wrapDefault(descriptor.components[1], property, compactable), + _wrapDefault(descriptor.components[2], property, compactable) + ]; + var color, style, width; + + for (var i = 0; i < 3; i++) { + var component = components[i]; + + if (component.name.indexOf('color') > 0) + color = component; + else if (component.name.indexOf('style') > 0) + style = component; + else + width = component; + } + + if ((property.value.length == 1 && property.value[0][1] == 'inherit') || + (property.value.length == 3 && property.value[0][1] == 'inherit' && property.value[1][1] == 'inherit' && property.value[2][1] == 'inherit')) { + color.value = style.value = width.value = [property.value[0]]; + return components; + } + + var values = property.value.slice(0); + var match, matches; + + // NOTE: usually users don't follow the required order of parts in this shorthand, + // so we'll try to parse it caring as little about order as possible + + if (values.length > 0) { + matches = values.filter(_widthFilter(validator)); + match = matches.length > 1 && (matches[0][1] == 'none' || matches[0][1] == 'auto') ? matches[1] : matches[0]; + if (match) { + width.value = [match]; + values.splice(values.indexOf(match), 1); + } + } + + if (values.length > 0) { + match = values.filter(_styleFilter(validator))[0]; + if (match) { + style.value = [match]; + values.splice(values.indexOf(match), 1); + } + } + + if (values.length > 0) { + match = values.filter(_colorFilter(validator))[0]; + if (match) { + color.value = [match]; + values.splice(values.indexOf(match), 1); + } + } + + return components; +} + +module.exports = { + background: background, + border: widthStyleColor, + borderRadius: borderRadius, + fourValues: fourValues, + listStyle: listStyle, + multiplex: multiplex, + outline: widthStyleColor +}; diff --git a/node_modules/clean-css/lib/optimizer/level-2/can-override.js b/node_modules/clean-css/lib/optimizer/level-2/can-override.js new file mode 100644 index 000000000..2617234ca --- /dev/null +++ b/node_modules/clean-css/lib/optimizer/level-2/can-override.js @@ -0,0 +1,180 @@ +var understandable = require('./properties/understandable'); + +function backgroundPosition(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !validator.isValidKeywordValue('background-position', value2, true)) { + return false; + } else if (validator.isValidVariable(value1) && validator.isValidVariable(value2)) { + return true; + } else if (validator.isValidKeywordValue('background-position', value2, true)) { + return true; + } + + return unit(validator, value1, value2); +} + +function backgroundSize(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !validator.isValidKeywordValue('background-size', value2, true)) { + return false; + } else if (validator.isValidVariable(value1) && validator.isValidVariable(value2)) { + return true; + } else if (validator.isValidKeywordValue('background-size', value2, true)) { + return true; + } + + return unit(validator, value1, value2); +} + +function color(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !validator.isValidColor(value2)) { + return false; + } else if (validator.isValidVariable(value1) && validator.isValidVariable(value2)) { + return true; + } else if (!validator.colorOpacity && (validator.isValidRgbaColor(value1) || validator.isValidHslaColor(value1))) { + return false; + } else if (!validator.colorOpacity && (validator.isValidRgbaColor(value2) || validator.isValidHslaColor(value2))) { + return false; + } else if (validator.isValidColor(value1) && validator.isValidColor(value2)) { + return true; + } + + return sameFunctionOrValue(validator, value1, value2); +} + +function components(overrideCheckers) { + return function (validator, value1, value2, position) { + return overrideCheckers[position](validator, value1, value2); + }; +} + +function image(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !validator.isValidImage(value2)) { + return false; + } else if (validator.isValidVariable(value1) && validator.isValidVariable(value2)) { + return true; + } else if (validator.isValidImage(value2)) { + return true; + } else if (validator.isValidImage(value1)) { + return false; + } + + return sameFunctionOrValue(validator, value1, value2); +} + +function keyword(propertyName) { + return function(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !validator.isValidKeywordValue(propertyName, value2)) { + return false; + } else if (validator.isValidVariable(value1) && validator.isValidVariable(value2)) { + return true; + } + + return validator.isValidKeywordValue(propertyName, value2, false); + }; +} + +function keywordWithGlobal(propertyName) { + return function(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !validator.isValidKeywordValue(propertyName, value2, true)) { + return false; + } else if (validator.isValidVariable(value1) && validator.isValidVariable(value2)) { + return true; + } + + return validator.isValidKeywordValue(propertyName, value2, true); + }; +} + +function sameFunctionOrValue(validator, value1, value2) { + return validator.areSameFunction(value1, value2) ? + true : + value1 === value2; +} + +function textShadow(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !validator.isValidTextShadow(value2)) { + return false; + } else if (validator.isValidVariable(value1) && validator.isValidVariable(value2)) { + return true; + } + + return validator.isValidTextShadow(value2); +} + +function unit(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !validator.isValidUnitWithoutFunction(value2)) { + return false; + } else if (validator.isValidVariable(value1) && validator.isValidVariable(value2)) { + return true; + } else if (validator.isValidUnitWithoutFunction(value1) && !validator.isValidUnitWithoutFunction(value2)) { + return false; + } else if (validator.isValidUnitWithoutFunction(value2)) { + return true; + } else if (validator.isValidUnitWithoutFunction(value1)) { + return false; + } else if (validator.isValidFunctionWithoutVendorPrefix(value1) && validator.isValidFunctionWithoutVendorPrefix(value2)) { + return true; + } + + return sameFunctionOrValue(validator, value1, value2); +} + +function unitOrKeywordWithGlobal(propertyName) { + var byKeyword = keywordWithGlobal(propertyName); + + return function(validator, value1, value2) { + return unit(validator, value1, value2) || byKeyword(validator, value1, value2); + }; +} + +function zIndex(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !validator.isValidZIndex(value2)) { + return false; + } else if (validator.isValidVariable(value1) && validator.isValidVariable(value2)) { + return true; + } + + return validator.isValidZIndex(value2); +} + +module.exports = { + generic: { + color: color, + components: components, + image: image, + unit: unit + }, + property: { + backgroundAttachment: keyword('background-attachment'), + backgroundClip: keywordWithGlobal('background-clip'), + backgroundOrigin: keyword('background-origin'), + backgroundPosition: backgroundPosition, + backgroundRepeat: keyword('background-repeat'), + backgroundSize: backgroundSize, + bottom: unitOrKeywordWithGlobal('bottom'), + borderCollapse: keyword('border-collapse'), + borderStyle: keywordWithGlobal('*-style'), + clear: keywordWithGlobal('clear'), + cursor: keywordWithGlobal('cursor'), + display: keywordWithGlobal('display'), + float: keywordWithGlobal('float'), + fontStyle: keywordWithGlobal('font-style'), + left: unitOrKeywordWithGlobal('left'), + fontWeight: keywordWithGlobal('font-weight'), + listStyleType: keywordWithGlobal('list-style-type'), + listStylePosition: keywordWithGlobal('list-style-position'), + outlineStyle: keywordWithGlobal('*-style'), + overflow: keywordWithGlobal('overflow'), + position: keywordWithGlobal('position'), + right: unitOrKeywordWithGlobal('right'), + textAlign: keywordWithGlobal('text-align'), + textDecoration: keywordWithGlobal('text-decoration'), + textOverflow: keywordWithGlobal('text-overflow'), + textShadow: textShadow, + top: unitOrKeywordWithGlobal('top'), + transform: sameFunctionOrValue, + verticalAlign: unitOrKeywordWithGlobal('vertical-align'), + visibility: keywordWithGlobal('visibility'), + whiteSpace: keywordWithGlobal('white-space'), + zIndex: zIndex + } +}; diff --git a/node_modules/clean-css/lib/optimizer/level-2/clone.js b/node_modules/clean-css/lib/optimizer/level-2/clone.js new file mode 100644 index 000000000..3830095e9 --- /dev/null +++ b/node_modules/clean-css/lib/optimizer/level-2/clone.js @@ -0,0 +1,33 @@ +var wrapSingle = require('../wrap-for-optimizing').single; + +var Token = require('../../tokenizer/token'); + +function deep(property) { + var cloned = shallow(property); + for (var i = property.components.length - 1; i >= 0; i--) { + var component = shallow(property.components[i]); + component.value = property.components[i].value.slice(0); + cloned.components.unshift(component); + } + + cloned.dirty = true; + cloned.value = property.value.slice(0); + + return cloned; +} + +function shallow(property) { + var cloned = wrapSingle([ + Token.PROPERTY, + [Token.PROPERTY_NAME, property.name] + ]); + cloned.important = property.important; + cloned.hack = property.hack; + cloned.unused = false; + return cloned; +} + +module.exports = { + deep: deep, + shallow: shallow +}; diff --git a/node_modules/clean-css/lib/optimizer/level-2/compactable.js b/node_modules/clean-css/lib/optimizer/level-2/compactable.js new file mode 100644 index 000000000..9cf334d44 --- /dev/null +++ b/node_modules/clean-css/lib/optimizer/level-2/compactable.js @@ -0,0 +1,787 @@ +// Contains the interpretation of CSS properties, as used by the property optimizer + +var breakUp = require('./break-up'); +var canOverride = require('./can-override'); +var restore = require('./restore'); + +var override = require('../../utils/override'); + +// Properties to process +// Extend this object in order to add support for more properties in the optimizer. +// +// Each key in this object represents a CSS property and should be an object. +// Such an object contains properties that describe how the represented CSS property should be handled. +// Possible options: +// +// * components: array (Only specify for shorthand properties.) +// Contains the names of the granular properties this shorthand compacts. +// +// * canOverride: function +// Returns whether two tokens of this property can be merged with each other. +// This property has no meaning for shorthands. +// +// * defaultValue: string +// Specifies the default value of the property according to the CSS standard. +// For shorthand, this is used when every component is set to its default value, therefore it should be the shortest possible default value of all the components. +// +// * shortestValue: string +// Specifies the shortest possible value the property can possibly have. +// (Falls back to defaultValue if unspecified.) +// +// * breakUp: function (Only specify for shorthand properties.) +// Breaks the shorthand up to its components. +// +// * restore: function (Only specify for shorthand properties.) +// Puts the shorthand together from its components. +// +var compactable = { + 'background': { + canOverride: canOverride.generic.components([ + canOverride.generic.image, + canOverride.property.backgroundPosition, + canOverride.property.backgroundSize, + canOverride.property.backgroundRepeat, + canOverride.property.backgroundAttachment, + canOverride.property.backgroundOrigin, + canOverride.property.backgroundClip, + canOverride.generic.color + ]), + components: [ + 'background-image', + 'background-position', + 'background-size', + 'background-repeat', + 'background-attachment', + 'background-origin', + 'background-clip', + 'background-color' + ], + breakUp: breakUp.multiplex(breakUp.background), + defaultValue: '0 0', + restore: restore.multiplex(restore.background), + shortestValue: '0', + shorthand: true + }, + 'background-attachment': { + canOverride: canOverride.property.backgroundAttachment, + componentOf: [ + 'background' + ], + defaultValue: 'scroll' + }, + 'background-clip': { + canOverride: canOverride.property.backgroundClip, + componentOf: [ + 'background' + ], + defaultValue: 'border-box', + shortestValue: 'border-box' + }, + 'background-color': { + canOverride: canOverride.generic.color, + componentOf: [ + 'background' + ], + defaultValue: 'transparent', + multiplexLastOnly: true, + nonMergeableValue: 'none', + shortestValue: 'red' + }, + 'background-image': { + canOverride: canOverride.generic.image, + componentOf: [ + 'background' + ], + defaultValue: 'none' + }, + 'background-origin': { + canOverride: canOverride.property.backgroundOrigin, + componentOf: [ + 'background' + ], + defaultValue: 'padding-box', + shortestValue: 'border-box' + }, + 'background-position': { + canOverride: canOverride.property.backgroundPosition, + componentOf: [ + 'background' + ], + defaultValue: ['0', '0'], + doubleValues: true, + shortestValue: '0' + }, + 'background-repeat': { + canOverride: canOverride.property.backgroundRepeat, + componentOf: [ + 'background' + ], + defaultValue: ['repeat'], + doubleValues: true + }, + 'background-size': { + canOverride: canOverride.property.backgroundSize, + componentOf: [ + 'background' + ], + defaultValue: ['auto'], + doubleValues: true, + shortestValue: '0 0' + }, + 'bottom': { + canOverride: canOverride.property.bottom, + defaultValue: 'auto' + }, + 'border': { + breakUp: breakUp.border, + canOverride: canOverride.generic.components([ + canOverride.generic.unit, + canOverride.property.borderStyle, + canOverride.generic.color + ]), + components: [ + 'border-width', + 'border-style', + 'border-color' + ], + defaultValue: 'none', + overridesShorthands: [ + 'border-bottom', + 'border-left', + 'border-right', + 'border-top' + ], + restore: restore.withoutDefaults, + shorthand: true, + shorthandComponents: true + }, + 'border-bottom': { + breakUp: breakUp.border, + canOverride: canOverride.generic.components([ + canOverride.generic.unit, + canOverride.property.borderStyle, + canOverride.generic.color + ]), + components: [ + 'border-bottom-width', + 'border-bottom-style', + 'border-bottom-color' + ], + defaultValue: 'none', + restore: restore.withoutDefaults, + shorthand: true + }, + 'border-bottom-color': { + canOverride: canOverride.generic.color, + componentOf: [ + 'border-bottom', + 'border-color' + ], + defaultValue: 'none' + }, + 'border-bottom-left-radius': { + canOverride: canOverride.generic.unit, + componentOf: [ + 'border-radius' + ], + defaultValue: '0', + vendorPrefixes: [ + '-moz-', + '-o-' + ] + }, + 'border-bottom-right-radius': { + canOverride: canOverride.generic.unit, + componentOf: [ + 'border-radius' + ], + defaultValue: '0', + vendorPrefixes: [ + '-moz-', + '-o-' + ] + }, + 'border-bottom-style': { + canOverride: canOverride.property.borderStyle, + componentOf: [ + 'border-bottom', + 'border-style' + ], + defaultValue: 'none' + }, + 'border-bottom-width': { + canOverride: canOverride.generic.unit, + componentOf: [ + 'border-bottom', + 'border-width' + ], + defaultValue: 'medium', + shortestValue: '0' + }, + 'border-collapse': { + canOverride: canOverride.property.borderCollapse, + defaultValue: 'separate' + }, + 'border-color': { + breakUp: breakUp.fourValues, + canOverride: canOverride.generic.components([ + canOverride.generic.color, + canOverride.generic.color, + canOverride.generic.color, + canOverride.generic.color + ]), + componentOf: ['border'], + components: [ + 'border-top-color', + 'border-right-color', + 'border-bottom-color', + 'border-left-color' + ], + defaultValue: 'none', + restore: restore.fourValues, + shortestValue: 'red', + shorthand: true + }, + 'border-left': { + breakUp: breakUp.border, + canOverride: canOverride.generic.components([ + canOverride.generic.unit, + canOverride.property.borderStyle, + canOverride.generic.color + ]), + components: [ + 'border-left-width', + 'border-left-style', + 'border-left-color' + ], + defaultValue: 'none', + restore: restore.withoutDefaults, + shorthand: true + }, + 'border-left-color': { + canOverride: canOverride.generic.color, + componentOf: [ + 'border-color', + 'border-left' + ], + defaultValue: 'none' + }, + 'border-left-style': { + canOverride: canOverride.property.borderStyle, + componentOf: [ + 'border-left', + 'border-style' + ], + defaultValue: 'none' + }, + 'border-left-width': { + canOverride: canOverride.generic.unit, + componentOf: [ + 'border-left', + 'border-width' + ], + defaultValue: 'medium', + shortestValue: '0' + }, + 'border-radius': { + breakUp: breakUp.borderRadius, + canOverride: canOverride.generic.components([ + canOverride.generic.unit, + canOverride.generic.unit, + canOverride.generic.unit, + canOverride.generic.unit + ]), + components: [ + 'border-top-left-radius', + 'border-top-right-radius', + 'border-bottom-right-radius', + 'border-bottom-left-radius' + ], + defaultValue: '0', + restore: restore.borderRadius, + shorthand: true, + vendorPrefixes: [ + '-moz-', + '-o-' + ] + }, + 'border-right': { + breakUp: breakUp.border, + canOverride: canOverride.generic.components([ + canOverride.generic.unit, + canOverride.property.borderStyle, + canOverride.generic.color + ]), + components: [ + 'border-right-width', + 'border-right-style', + 'border-right-color' + ], + defaultValue: 'none', + restore: restore.withoutDefaults, + shorthand: true + }, + 'border-right-color': { + canOverride: canOverride.generic.color, + componentOf: [ + 'border-color', + 'border-right' + ], + defaultValue: 'none' + }, + 'border-right-style': { + canOverride: canOverride.property.borderStyle, + componentOf: [ + 'border-right', + 'border-style' + ], + defaultValue: 'none' + }, + 'border-right-width': { + canOverride: canOverride.generic.unit, + componentOf: [ + 'border-right', + 'border-width' + ], + defaultValue: 'medium', + shortestValue: '0' + }, + 'border-style': { + breakUp: breakUp.fourValues, + canOverride: canOverride.generic.components([ + canOverride.property.borderStyle, + canOverride.property.borderStyle, + canOverride.property.borderStyle, + canOverride.property.borderStyle + ]), + componentOf: [ + 'border' + ], + components: [ + 'border-top-style', + 'border-right-style', + 'border-bottom-style', + 'border-left-style' + ], + defaultValue: 'none', + restore: restore.fourValues, + shorthand: true + }, + 'border-top': { + breakUp: breakUp.border, + canOverride: canOverride.generic.components([ + canOverride.generic.unit, + canOverride.property.borderStyle, + canOverride.generic.color + ]), + components: [ + 'border-top-width', + 'border-top-style', + 'border-top-color' + ], + defaultValue: 'none', + restore: restore.withoutDefaults, + shorthand: true + }, + 'border-top-color': { + canOverride: canOverride.generic.color, + componentOf: [ + 'border-color', + 'border-top' + ], + defaultValue: 'none' + }, + 'border-top-left-radius': { + canOverride: canOverride.generic.unit, + componentOf: [ + 'border-radius' + ], + defaultValue: '0', + vendorPrefixes: [ + '-moz-', + '-o-' + ] + }, + 'border-top-right-radius': { + canOverride: canOverride.generic.unit, + componentOf: [ + 'border-radius' + ], + defaultValue: '0', + vendorPrefixes: [ + '-moz-', + '-o-' + ] + }, + 'border-top-style': { + canOverride: canOverride.property.borderStyle, + componentOf: [ + 'border-style', + 'border-top' + ], + defaultValue: 'none' + }, + 'border-top-width': { + canOverride: canOverride.generic.unit, + componentOf: [ + 'border-top', + 'border-width' + ], + defaultValue: 'medium', + shortestValue: '0' + }, + 'border-width': { + breakUp: breakUp.fourValues, + canOverride: canOverride.generic.components([ + canOverride.generic.unit, + canOverride.generic.unit, + canOverride.generic.unit, + canOverride.generic.unit + ]), + components: [ + 'border-top-width', + 'border-right-width', + 'border-bottom-width', + 'border-left-width' + ], + defaultValue: 'medium', + restore: restore.fourValues, + shortestValue: '0', + shorthand: true + }, + 'clear': { + canOverride: canOverride.property.clear, + defaultValue: 'none' + }, + 'color': { + canOverride: canOverride.generic.color, + defaultValue: 'transparent', + shortestValue: 'red' + }, + 'cursor': { + canOverride: canOverride.property.cursor, + defaultValue: 'auto' + }, + 'display': { + canOverride: canOverride.property.display, + }, + 'float': { + canOverride: canOverride.property.float, + defaultValue: 'none' + }, + 'font-size': { + canOverride: canOverride.generic.unit, + defaultValue: 'medium', + shortestValue: '0' + }, + 'font-style': { + canOverride: canOverride.property.fontStyle, + defaultValue: 'normal' + }, + 'font-weight': { + canOverride: canOverride.property.fontWeight, + defaultValue: '400', + shortestValue: '400' + }, + 'height': { + canOverride: canOverride.generic.unit, + defaultValue: 'auto', + shortestValue: '0' + }, + 'left': { + canOverride: canOverride.property.left, + defaultValue: 'auto' + }, + 'line-height': { + canOverride: canOverride.generic.unit, + defaultValue: 'normal', + shortestValue: '0' + }, + 'list-style': { + canOverride: canOverride.generic.components([ + canOverride.property.listStyleType, + canOverride.property.listStylePosition, + canOverride.property.listStyleImage + ]), + components: [ + 'list-style-type', + 'list-style-position', + 'list-style-image' + ], + breakUp: breakUp.listStyle, + restore: restore.withoutDefaults, + defaultValue: 'outside', // can't use 'disc' because that'd override default 'decimal' for
    + shortestValue: 'none', + shorthand: true + }, + 'list-style-image' : { + canOverride: canOverride.generic.image, + componentOf: [ + 'list-style' + ], + defaultValue: 'none' + }, + 'list-style-position' : { + canOverride: canOverride.property.listStylePosition, + componentOf: [ + 'list-style' + ], + defaultValue: 'outside', + shortestValue: 'inside' + }, + 'list-style-type' : { + canOverride: canOverride.property.listStyleType, + componentOf: [ + 'list-style' + ], + // NOTE: we can't tell the real default value here, it's 'disc' for