From 26105034da4fcce7ac883c899d781f016559310d Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 8 Nov 2018 00:38:48 +0800 Subject: switch to vuepress --- .../clean-css/lib/optimizer/level-2/break-up.js | 644 ++++++++++++ .../lib/optimizer/level-2/can-override.js | 283 ++++++ .../clean-css/lib/optimizer/level-2/clone.js | 33 + .../clean-css/lib/optimizer/level-2/compactable.js | 1063 ++++++++++++++++++++ .../lib/optimizer/level-2/extract-properties.js | 73 ++ .../optimizer/level-2/invalid-property-error.js | 10 + .../lib/optimizer/level-2/is-mergeable.js | 259 +++++ .../lib/optimizer/level-2/merge-adjacent.js | 50 + .../lib/optimizer/level-2/merge-media-queries.js | 103 ++ .../level-2/merge-non-adjacent-by-body.js | 80 ++ .../level-2/merge-non-adjacent-by-selector.js | 78 ++ .../clean-css/lib/optimizer/level-2/optimize.js | 134 +++ .../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/is-mergeable-shorthand.js | 11 + .../level-2/properties/merge-into-shorthands.js | 445 ++++++++ .../lib/optimizer/level-2/properties/optimize.js | 40 + .../level-2/properties/override-properties.js | 484 +++++++++ .../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 | 180 ++++ .../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 + .../optimizer/level-2/remove-unused-at-rules.js | 249 +++++ .../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 | 303 ++++++ .../clean-css/lib/optimizer/level-2/restructure.js | 389 +++++++ .../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 + 37 files changed, 5473 insertions(+) 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/is-mergeable-shorthand.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/remove-unused-at-rules.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 (limited to 'node_modules/clean-css/lib/optimizer/level-2') 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 00000000..5301cb89 --- /dev/null +++ b/node_modules/clean-css/lib/optimizer/level-2/break-up.js @@ -0,0 +1,644 @@ +var InvalidPropertyError = require('./invalid-property-error'); + +var wrapSingle = require('../wrap-for-optimizing').single; + +var Token = require('../../tokenizer/token'); +var Marker = require('../../tokenizer/marker'); + +var formatPosition = require('../../utils/format-position'); + +function _anyIsInherit(values) { + var i, l; + + for (i = 0, l = values.length; i < l; i++) { + if (values[i][1] == 'inherit') { + return true; + } + } + + return false; +} + +function _colorFilter(validator) { + return function (value) { + return value[1] == 'invert' || validator.isColor(value[1]) || validator.isPrefixed(value[1]); + }; +} + +function _styleFilter(validator) { + return function (value) { + return value[1] != 'inherit' && validator.isStyleKeyword(value[1]) && !validator.isColorFunction(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.isWidth(value[1]) || validator.isUnit(value[1]) && !validator.isDynamicUnit(value[1])) && + !validator.isStyleKeyword(value[1]) && + !validator.isColorFunction(value[1]); + }; +} + +function animation(property, compactable, validator) { + var duration = _wrapDefault(property.name + '-duration', property, compactable); + var timing = _wrapDefault(property.name + '-timing-function', property, compactable); + var delay = _wrapDefault(property.name + '-delay', property, compactable); + var iteration = _wrapDefault(property.name + '-iteration-count', property, compactable); + var direction = _wrapDefault(property.name + '-direction', property, compactable); + var fill = _wrapDefault(property.name + '-fill-mode', property, compactable); + var play = _wrapDefault(property.name + '-play-state', property, compactable); + var name = _wrapDefault(property.name + '-name', property, compactable); + var components = [duration, timing, delay, iteration, direction, fill, play, name]; + var values = property.value; + var value; + var durationSet = false; + var timingSet = false; + var delaySet = false; + var iterationSet = false; + var directionSet = false; + var fillSet = false; + var playSet = false; + var nameSet = false; + var i; + var l; + + if (property.value.length == 1 && property.value[0][1] == 'inherit') { + duration.value = timing.value = delay.value = iteration.value = direction.value = fill.value = play.value = name.value = property.value; + return components; + } + + if (values.length > 1 && _anyIsInherit(values)) { + throw new InvalidPropertyError('Invalid animation values at ' + formatPosition(values[0][2][0]) + '. Ignoring.'); + } + + for (i = 0, l = values.length; i < l; i++) { + value = values[i]; + + if (validator.isTime(value[1]) && !durationSet) { + duration.value = [value]; + durationSet = true; + } else if (validator.isTime(value[1]) && !delaySet) { + delay.value = [value]; + delaySet = true; + } else if ((validator.isGlobal(value[1]) || validator.isTimingFunction(value[1])) && !timingSet) { + timing.value = [value]; + timingSet = true; + } else if ((validator.isAnimationIterationCountKeyword(value[1]) || validator.isPositiveNumber(value[1])) && !iterationSet) { + iteration.value = [value]; + iterationSet = true; + } else if (validator.isAnimationDirectionKeyword(value[1]) && !directionSet) { + direction.value = [value]; + directionSet = true; + } else if (validator.isAnimationFillModeKeyword(value[1]) && !fillSet) { + fill.value = [value]; + fillSet = true; + } else if (validator.isAnimationPlayStateKeyword(value[1]) && !playSet) { + play.value = [value]; + playSet = true; + } else if ((validator.isAnimationNameKeyword(value[1]) || validator.isIdentifier(value[1])) && !nameSet) { + name.value = [value]; + nameSet = true; + } else { + throw new InvalidPropertyError('Invalid animation value at ' + formatPosition(value[2][0]) + '. Ignoring.'); + } + } + + return components; +} + +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.isBackgroundAttachmentKeyword(value[1])) { + attachment.value = [value]; + anyValueSet = true; + } else if (validator.isBackgroundClipKeyword(value[1]) || validator.isBackgroundOriginKeyword(value[1])) { + if (clipSet) { + origin.value = [value]; + originSet = true; + } else { + clip.value = [value]; + clipSet = true; + } + anyValueSet = true; + } else if (validator.isBackgroundRepeatKeyword(value[1])) { + if (repeatSet) { + repeat.value.unshift(value); + } else { + repeat.value = [value]; + repeatSet = true; + } + anyValueSet = true; + } else if (validator.isBackgroundPositionKeyword(value[1]) || validator.isBackgroundSizeKeyword(value[1]) || validator.isUnit(value[1]) || validator.isDynamicUnit(value[1])) { + if (i > 0) { + var previousValue = values[i - 1]; + + if (previousValue[1] == Marker.FORWARD_SLASH) { + size.value = [value]; + } else if (i > 1 && values[i - 2][1] == Marker.FORWARD_SLASH) { + 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.isColor(value[1]) || validator.isPrefixed(value[1]))) { + color.value = [value]; + anyValueSet = true; + } else if (validator.isUrl(value[1]) || validator.isFunction(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] == Marker.FORWARD_SLASH) { + 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 font(property, compactable, validator) { + var style = _wrapDefault('font-style', property, compactable); + var variant = _wrapDefault('font-variant', property, compactable); + var weight = _wrapDefault('font-weight', property, compactable); + var stretch = _wrapDefault('font-stretch', property, compactable); + var size = _wrapDefault('font-size', property, compactable); + var height = _wrapDefault('line-height', property, compactable); + var family = _wrapDefault('font-family', property, compactable); + var components = [style, variant, weight, stretch, size, height, family]; + var values = property.value; + var fuzzyMatched = 4; // style, variant, weight, and stretch + var index = 0; + var isStretchSet = false; + var isStretchValid; + var isStyleSet = false; + var isStyleValid; + var isVariantSet = false; + var isVariantValid; + var isWeightSet = false; + var isWeightValid; + var isSizeSet = false; + var appendableFamilyName = false; + + if (!values[index]) { + throw new InvalidPropertyError('Missing font values at ' + formatPosition(property.all[property.position][1][2][0]) + '. Ignoring.'); + } + + if (values.length == 1 && values[0][1] == 'inherit') { + style.value = variant.value = weight.value = stretch.value = size.value = height.value = family.value = values; + return components; + } + + if (values.length == 1 && (validator.isFontKeyword(values[0][1]) || validator.isGlobal(values[0][1]) || validator.isPrefixed(values[0][1]))) { + values[0][1] = Marker.INTERNAL + values[0][1]; + style.value = variant.value = weight.value = stretch.value = size.value = height.value = family.value = values; + return components; + } + + if (values.length < 2 || !_anyIsFontSize(values, validator) || !_anyIsFontFamily(values, validator)) { + throw new InvalidPropertyError('Invalid font values at ' + formatPosition(property.all[property.position][1][2][0]) + '. Ignoring.'); + } + + if (values.length > 1 && _anyIsInherit(values)) { + throw new InvalidPropertyError('Invalid font values at ' + formatPosition(values[0][2][0]) + '. Ignoring.'); + } + + // fuzzy match style, variant, weight, and stretch on first elements + while (index < fuzzyMatched) { + isStretchValid = validator.isFontStretchKeyword(values[index][1]) || validator.isGlobal(values[index][1]); + isStyleValid = validator.isFontStyleKeyword(values[index][1]) || validator.isGlobal(values[index][1]); + isVariantValid = validator.isFontVariantKeyword(values[index][1]) || validator.isGlobal(values[index][1]); + isWeightValid = validator.isFontWeightKeyword(values[index][1]) || validator.isGlobal(values[index][1]); + + if (isStyleValid && !isStyleSet) { + style.value = [values[index]]; + isStyleSet = true; + } else if (isVariantValid && !isVariantSet) { + variant.value = [values[index]]; + isVariantSet = true; + } else if (isWeightValid && !isWeightSet) { + weight.value = [values[index]]; + isWeightSet = true; + } else if (isStretchValid && !isStretchSet) { + stretch.value = [values[index]]; + isStretchSet = true; + } else if (isStyleValid && isStyleSet || isVariantValid && isVariantSet || isWeightValid && isWeightSet || isStretchValid && isStretchSet) { + throw new InvalidPropertyError('Invalid font style / variant / weight / stretch value at ' + formatPosition(values[0][2][0]) + '. Ignoring.'); + } else { + break; + } + + index++; + } + + // now comes font-size ... + if (validator.isFontSizeKeyword(values[index][1]) || validator.isUnit(values[index][1]) && !validator.isDynamicUnit(values[index][1])) { + size.value = [values[index]]; + isSizeSet = true; + index++; + } else { + throw new InvalidPropertyError('Missing font size at ' + formatPosition(values[0][2][0]) + '. Ignoring.'); + } + + if (!values[index]) { + throw new InvalidPropertyError('Missing font family at ' + formatPosition(values[0][2][0]) + '. Ignoring.'); + } + + // ... and perhaps line-height + if (isSizeSet && values[index] && values[index][1] == Marker.FORWARD_SLASH && values[index + 1] && (validator.isLineHeightKeyword(values[index + 1][1]) || validator.isUnit(values[index + 1][1]) || validator.isNumber(values[index + 1][1]))) { + height.value = [values[index + 1]]; + index++; + index++; + } + + // ... and whatever comes next is font-family + family.value = []; + + while (values[index]) { + if (values[index][1] == Marker.COMMA) { + appendableFamilyName = false; + } else { + if (appendableFamilyName) { + family.value[family.value.length - 1][1] += Marker.SPACE + values[index][1]; + } else { + family.value.push(values[index]); + } + + appendableFamilyName = true; + } + + index++; + } + + if (family.value.length === 0) { + throw new InvalidPropertyError('Missing font family at ' + formatPosition(values[0][2][0]) + '. Ignoring.'); + } + + return components; +} + +function _anyIsFontSize(values, validator) { + var value; + var i, l; + + for (i = 0, l = values.length; i < l; i++) { + value = values[i]; + + if (validator.isFontSizeKeyword(value[1]) || validator.isUnit(value[1]) && !validator.isDynamicUnit(value[1]) || validator.isFunction(value[1])) { + return true; + } + } + + return false; +} + +function _anyIsFontFamily(values, validator) { + var value; + var i, l; + + for (i = 0, l = values.length; i < l; i++) { + value = values[i]; + + if (validator.isIdentifier(value[1])) { + return true; + } + } + + return false; +} + +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, Marker.COMMA]); + 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.isUrl(values[index][1]) || values[index][1] == '0') { + image.value = [values[index]]; + values.splice(index, 1); + break; + } + } + + // ... then `position` + for (index = 0, total = values.length; index < total; index++) { + if (validator.isListStylePositionKeyword(values[index][1])) { + position.value = [values[index]]; + values.splice(index, 1); + break; + } + } + + // ... and what's left is a `type` + if (values.length > 0 && (validator.isListStyleTypeKeyword(values[0][1]) || validator.isIdentifier(values[0][1]))) { + type.value = [values[0]]; + } + + return components; +} + +function transition(property, compactable, validator) { + var prop = _wrapDefault(property.name + '-property', property, compactable); + var duration = _wrapDefault(property.name + '-duration', property, compactable); + var timing = _wrapDefault(property.name + '-timing-function', property, compactable); + var delay = _wrapDefault(property.name + '-delay', property, compactable); + var components = [prop, duration, timing, delay]; + var values = property.value; + var value; + var durationSet = false; + var delaySet = false; + var propSet = false; + var timingSet = false; + var i; + var l; + + if (property.value.length == 1 && property.value[0][1] == 'inherit') { + prop.value = duration.value = timing.value = delay.value = property.value; + return components; + } + + if (values.length > 1 && _anyIsInherit(values)) { + throw new InvalidPropertyError('Invalid animation values at ' + formatPosition(values[0][2][0]) + '. Ignoring.'); + } + + for (i = 0, l = values.length; i < l; i++) { + value = values[i]; + + if (validator.isTime(value[1]) && !durationSet) { + duration.value = [value]; + durationSet = true; + } else if (validator.isTime(value[1]) && !delaySet) { + delay.value = [value]; + delaySet = true; + } else if ((validator.isGlobal(value[1]) || validator.isTimingFunction(value[1])) && !timingSet) { + timing.value = [value]; + timingSet = true; + } else if (validator.isIdentifier(value[1]) && !propSet) { + prop.value = [value]; + propSet = true; + } else { + throw new InvalidPropertyError('Invalid animation value at ' + formatPosition(value[2][0]) + '. Ignoring.'); + } + } + + 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 = { + animation: animation, + background: background, + border: widthStyleColor, + borderRadius: borderRadius, + font: font, + fourValues: fourValues, + listStyle: listStyle, + multiplex: multiplex, + outline: widthStyleColor, + transition: transition +}; 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 00000000..3dae08f0 --- /dev/null +++ b/node_modules/clean-css/lib/optimizer/level-2/can-override.js @@ -0,0 +1,283 @@ +var understandable = require('./properties/understandable'); + +function animationIterationCount(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !(validator.isAnimationIterationCountKeyword(value2) || validator.isPositiveNumber(value2))) { + return false; + } else if (validator.isVariable(value1) && validator.isVariable(value2)) { + return true; + } + + return validator.isAnimationIterationCountKeyword(value2) || validator.isPositiveNumber(value2); +} + +function animationName(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !(validator.isAnimationNameKeyword(value2) || validator.isIdentifier(value2))) { + return false; + } else if (validator.isVariable(value1) && validator.isVariable(value2)) { + return true; + } + + return validator.isAnimationNameKeyword(value2) || validator.isIdentifier(value2); +} + +function areSameFunction(validator, value1, value2) { + if (!validator.isFunction(value1) || !validator.isFunction(value2)) { + return false; + } + + var function1Name = value1.substring(0, value1.indexOf('(')); + var function2Name = value2.substring(0, value2.indexOf('(')); + + return function1Name === function2Name; +} + +function backgroundPosition(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !(validator.isBackgroundPositionKeyword(value2) || validator.isGlobal(value2))) { + return false; + } else if (validator.isVariable(value1) && validator.isVariable(value2)) { + return true; + } else if (validator.isBackgroundPositionKeyword(value2) || validator.isGlobal(value2)) { + return true; + } + + return unit(validator, value1, value2); +} + +function backgroundSize(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !(validator.isBackgroundSizeKeyword(value2) || validator.isGlobal(value2))) { + return false; + } else if (validator.isVariable(value1) && validator.isVariable(value2)) { + return true; + } else if (validator.isBackgroundSizeKeyword(value2) || validator.isGlobal(value2)) { + return true; + } + + return unit(validator, value1, value2); +} + +function color(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !validator.isColor(value2)) { + return false; + } else if (validator.isVariable(value1) && validator.isVariable(value2)) { + return true; + } else if (!validator.colorOpacity && (validator.isRgbColor(value1) || validator.isHslColor(value1))) { + return false; + } else if (!validator.colorOpacity && (validator.isRgbColor(value2) || validator.isHslColor(value2))) { + return false; + } else if (validator.isColor(value1) && validator.isColor(value2)) { + return true; + } + + return sameFunctionOrValue(validator, value1, value2); +} + +function components(overrideCheckers) { + return function (validator, value1, value2, position) { + return overrideCheckers[position](validator, value1, value2); + }; +} + +function fontFamily(validator, value1, value2) { + return understandable(validator, value1, value2, 0, true); +} + +function image(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !validator.isImage(value2)) { + return false; + } else if (validator.isVariable(value1) && validator.isVariable(value2)) { + return true; + } else if (validator.isImage(value2)) { + return true; + } else if (validator.isImage(value1)) { + return false; + } + + return sameFunctionOrValue(validator, value1, value2); +} + +function keyword(propertyName) { + return function(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !validator.isKeyword(propertyName)(value2)) { + return false; + } else if (validator.isVariable(value1) && validator.isVariable(value2)) { + return true; + } + + return validator.isKeyword(propertyName)(value2); + }; +} + +function keywordWithGlobal(propertyName) { + return function(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !(validator.isKeyword(propertyName)(value2) || validator.isGlobal(value2))) { + return false; + } else if (validator.isVariable(value1) && validator.isVariable(value2)) { + return true; + } + + return validator.isKeyword(propertyName)(value2) || validator.isGlobal(value2); + }; +} + +function propertyName(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !validator.isIdentifier(value2)) { + return false; + } else if (validator.isVariable(value1) && validator.isVariable(value2)) { + return true; + } + + return validator.isIdentifier(value2); +} + +function sameFunctionOrValue(validator, value1, value2) { + return areSameFunction(validator, value1, value2) ? + true : + value1 === value2; +} + +function textShadow(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !(validator.isUnit(value2) || validator.isColor(value2) || validator.isGlobal(value2))) { + return false; + } else if (validator.isVariable(value1) && validator.isVariable(value2)) { + return true; + } + + return validator.isUnit(value2) || validator.isColor(value2) || validator.isGlobal(value2); +} + +function time(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !validator.isTime(value2)) { + return false; + } else if (validator.isVariable(value1) && validator.isVariable(value2)) { + return true; + } else if (validator.isTime(value1) && !validator.isTime(value2)) { + return false; + } else if (validator.isTime(value2)) { + return true; + } else if (validator.isTime(value1)) { + return false; + } else if (validator.isFunction(value1) && !validator.isPrefixed(value1) && validator.isFunction(value2) && !validator.isPrefixed(value2)) { + return true; + } + + return sameFunctionOrValue(validator, value1, value2); +} + +function timingFunction(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !(validator.isTimingFunction(value2) || validator.isGlobal(value2))) { + return false; + } else if (validator.isVariable(value1) && validator.isVariable(value2)) { + return true; + } + + return validator.isTimingFunction(value2) || validator.isGlobal(value2); +} + +function unit(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !validator.isUnit(value2)) { + return false; + } else if (validator.isVariable(value1) && validator.isVariable(value2)) { + return true; + } else if (validator.isUnit(value1) && !validator.isUnit(value2)) { + return false; + } else if (validator.isUnit(value2)) { + return true; + } else if (validator.isUnit(value1)) { + return false; + } else if (validator.isFunction(value1) && !validator.isPrefixed(value1) && validator.isFunction(value2) && !validator.isPrefixed(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 unitOrNumber(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !(validator.isUnit(value2) || validator.isNumber(value2))) { + return false; + } else if (validator.isVariable(value1) && validator.isVariable(value2)) { + return true; + } else if ((validator.isUnit(value1) || validator.isNumber(value1)) && !(validator.isUnit(value2) || validator.isNumber(value2))) { + return false; + } else if (validator.isUnit(value2) || validator.isNumber(value2)) { + return true; + } else if (validator.isUnit(value1) || validator.isNumber(value1)) { + return false; + } else if (validator.isFunction(value1) && !validator.isPrefixed(value1) && validator.isFunction(value2) && !validator.isPrefixed(value2)) { + return true; + } + + return sameFunctionOrValue(validator, value1, value2); +} + +function zIndex(validator, value1, value2) { + if (!understandable(validator, value1, value2, 0, true) && !validator.isZIndex(value2)) { + return false; + } else if (validator.isVariable(value1) && validator.isVariable(value2)) { + return true; + } + + return validator.isZIndex(value2); +} + +module.exports = { + generic: { + color: color, + components: components, + image: image, + propertyName: propertyName, + time: time, + timingFunction: timingFunction, + unit: unit, + unitOrNumber: unitOrNumber + }, + property: { + animationDirection: keywordWithGlobal('animation-direction'), + animationFillMode: keyword('animation-fill-mode'), + animationIterationCount: animationIterationCount, + animationName: animationName, + animationPlayState: keywordWithGlobal('animation-play-state'), + 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'), + left: unitOrKeywordWithGlobal('left'), + fontFamily: fontFamily, + fontStretch: keywordWithGlobal('font-stretch'), + fontStyle: keywordWithGlobal('font-style'), + fontVariant: keywordWithGlobal('font-variant'), + 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 00000000..3830095e --- /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 00000000..73f42a10 --- /dev/null +++ b/node_modules/clean-css/lib/optimizer/level-2/compactable.js @@ -0,0 +1,1063 @@ +// 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 = { + 'animation': { + canOverride: canOverride.generic.components([ + canOverride.generic.time, + canOverride.generic.timingFunction, + canOverride.generic.time, + canOverride.property.animationIterationCount, + canOverride.property.animationDirection, + canOverride.property.animationFillMode, + canOverride.property.animationPlayState, + canOverride.property.animationName + ]), + components: [ + 'animation-duration', + 'animation-timing-function', + 'animation-delay', + 'animation-iteration-count', + 'animation-direction', + 'animation-fill-mode', + 'animation-play-state', + 'animation-name' + ], + breakUp: breakUp.multiplex(breakUp.animation), + defaultValue: 'none', + restore: restore.multiplex(restore.withoutDefaults), + shorthand: true, + vendorPrefixes: [ + '-moz-', + '-o-', + '-webkit-' + ] + }, + 'animation-delay': { + canOverride: canOverride.generic.time, + componentOf: [ + 'animation' + ], + defaultValue: '0s', + intoMultiplexMode: 'real', + vendorPrefixes: [ + '-moz-', + '-o-', + '-webkit-' + ] + }, + 'animation-direction': { + canOverride: canOverride.property.animationDirection, + componentOf: [ + 'animation' + ], + defaultValue: 'normal', + intoMultiplexMode: 'real', + vendorPrefixes: [ + '-moz-', + '-o-', + '-webkit-' + ] + }, + 'animation-duration': { + canOverride: canOverride.generic.time, + componentOf: [ + 'animation' + ], + defaultValue: '0s', + intoMultiplexMode: 'real', + keepUnlessDefault: 'animation-delay', + vendorPrefixes: [ + '-moz-', + '-o-', + '-webkit-' + ] + }, + 'animation-fill-mode': { + canOverride: canOverride.property.animationFillMode, + componentOf: [ + 'animation' + ], + defaultValue: 'none', + intoMultiplexMode: 'real', + vendorPrefixes: [ + '-moz-', + '-o-', + '-webkit-' + ] + }, + 'animation-iteration-count': { + canOverride: canOverride.property.animationIterationCount, + componentOf: [ + 'animation' + ], + defaultValue: '1', + intoMultiplexMode: 'real', + vendorPrefixes: [ + '-moz-', + '-o-', + '-webkit-' + ] + }, + 'animation-name': { + canOverride: canOverride.property.animationName, + componentOf: [ + 'animation' + ], + defaultValue: 'none', + intoMultiplexMode: 'real', + vendorPrefixes: [ + '-moz-', + '-o-', + '-webkit-' + ] + }, + 'animation-play-state': { + canOverride: canOverride.property.animationPlayState, + componentOf: [ + 'animation' + ], + defaultValue: 'running', + intoMultiplexMode: 'real', + vendorPrefixes: [ + '-moz-', + '-o-', + '-webkit-' + ] + }, + 'animation-timing-function': { + canOverride: canOverride.generic.timingFunction, + componentOf: [ + 'animation' + ], + defaultValue: 'ease', + intoMultiplexMode: 'real', + vendorPrefixes: [ + '-moz-', + '-o-', + '-webkit-' + ] + }, + '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', + intoMultiplexMode: 'real' + }, + 'background-clip': { + canOverride: canOverride.property.backgroundClip, + componentOf: [ + 'background' + ], + defaultValue: 'border-box', + intoMultiplexMode: 'real', + shortestValue: 'border-box' + }, + 'background-color': { + canOverride: canOverride.generic.color, + componentOf: [ + 'background' + ], + defaultValue: 'transparent', + intoMultiplexMode: 'real', // otherwise real color will turn into default since color appears in last multiplex only + multiplexLastOnly: true, + nonMergeableValue: 'none', + shortestValue: 'red' + }, + 'background-image': { + canOverride: canOverride.generic.image, + componentOf: [ + 'background' + ], + defaultValue: 'none', + intoMultiplexMode: 'default' + }, + 'background-origin': { + canOverride: canOverride.property.backgroundOrigin, + componentOf: [ + 'background' + ], + defaultValue: 'padding-box', + intoMultiplexMode: 'real', + shortestValue: 'border-box' + }, + 'background-position': { + canOverride: canOverride.property.backgroundPosition, + componentOf: [ + 'background' + ], + defaultValue: ['0', '0'], + doubleValues: true, + intoMultiplexMode: 'real', + shortestValue: '0' + }, + 'background-repeat': { + canOverride: canOverride.property.backgroundRepeat, + componentOf: [ + 'background' + ], + defaultValue: ['repeat'], + doubleValues: true, + intoMultiplexMode: 'real' + }, + 'background-size': { + canOverride: canOverride.property.backgroundSize, + componentOf: [ + 'background' + ], + defaultValue: ['auto'], + doubleValues: true, + intoMultiplexMode: 'real', + 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', + oppositeTo: 'border-top-width', + 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', + oppositeTo: 'border-right-width', + 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', + oppositeTo: 'border-left-width', + 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', + oppositeTo: 'border-bottom-width', + shortestValue: '0' + }, + 'border-width': { + breakUp: breakUp.fourValues, + canOverride: canOverride.generic.components([ + canOverride.generic.unit, + canOverride.generic.unit, + canOverride.generic.unit, + canOverride.generic.unit + ]), + componentOf: [ + 'border' + ], + 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': { + breakUp: breakUp.font, + canOverride: canOverride.generic.components([ + canOverride.property.fontStyle, + canOverride.property.fontVariant, + canOverride.property.fontWeight, + canOverride.property.fontStretch, + canOverride.generic.unit, + canOverride.generic.unit, + canOverride.property.fontFamily + ]), + components: [ + 'font-style', + 'font-variant', + 'font-weight', + 'font-stretch', + 'font-size', + 'line-height', + 'font-family' + ], + restore: restore.font, + shorthand: true + }, + 'font-family': { + canOverride: canOverride.property.fontFamily, + defaultValue: 'user|agent|specific' + }, + 'font-size': { + canOverride: canOverride.generic.unit, + defaultValue: 'medium', + shortestValue: '0' + }, + 'font-stretch': { + canOverride: canOverride.property.fontStretch, + defaultValue: 'normal' + }, + 'font-style': { + canOverride: canOverride.property.fontStyle, + defaultValue: 'normal' + }, + 'font-variant': { + canOverride: canOverride.property.fontVariant, + defaultValue: 'normal' + }, + 'font-weight': { + canOverride: canOverride.property.fontWeight, + defaultValue: 'normal', + shortestValue: '400' + }, + 'height': { + canOverride: canOverride.generic.unit, + defaultValue: 'auto', + shortestValue: '0' + }, + 'left': { + canOverride: canOverride.property.left, + defaultValue: 'auto' + }, + 'line-height': { + canOverride: canOverride.generic.unitOrNumber, + 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