clean-css
Advanced tools
Comparing version 4.1.11 to 4.2.0
@@ -49,2 +49,18 @@ /** | ||
// for compatibility with optimize-css-assets-webpack-plugin | ||
CleanCSS.process = function (input, opts) { | ||
var cleanCss; | ||
var optsTo = opts.to; | ||
delete opts.to; | ||
cleanCss = new CleanCSS(Object.assign({ returnPromise: true, rebaseTo: optsTo }, opts)); | ||
return cleanCss.minify(input) | ||
.then(function(output) { | ||
return { css: output.styles }; | ||
}); | ||
}; | ||
CleanCSS.prototype.minify = function (input, maybeSourceMap, maybeCallback) { | ||
@@ -51,0 +67,0 @@ var options = this.options; |
@@ -22,2 +22,4 @@ var shortenHex = require('./shorten-hex'); | ||
var serializeRules = require('../../writer/one-time').rules; | ||
var IgnoreProperty = 'ignore-property'; | ||
@@ -338,3 +340,3 @@ | ||
function removeQuotes(name, value) { | ||
if (name == 'content' || name.indexOf('font-feature-settings') > -1 || name.indexOf('grid-') > -1) { | ||
if (name == 'content' || name.indexOf('font-variation-settings') > -1 || name.indexOf('font-feature-settings') > -1 || name.indexOf('grid-') > -1) { | ||
return value; | ||
@@ -354,4 +356,5 @@ } | ||
function transformValue(propertyName, propertyValue, transformCallback) { | ||
var transformedValue = transformCallback(propertyName, propertyValue); | ||
function transformValue(propertyName, propertyValue, rule, transformCallback) { | ||
var selector = serializeRules(rule); | ||
var transformedValue = transformCallback(propertyName, propertyValue, selector); | ||
@@ -369,3 +372,3 @@ if (transformedValue === undefined) { | ||
function optimizeBody(properties, context) { | ||
function optimizeBody(rule, properties, context) { | ||
var options = context.options; | ||
@@ -415,3 +418,3 @@ var levelOptions = options.level[OptimizationLevel.One]; | ||
if (property.block) { | ||
optimizeBody(property.value[0][1], context); | ||
optimizeBody(rule, property.value[0][1], context); | ||
continue; | ||
@@ -475,3 +478,3 @@ } | ||
value = transformValue(name, value, levelOptions.transform); | ||
value = transformValue(name, value, rule, levelOptions.transform); | ||
@@ -646,3 +649,3 @@ if (value === IgnoreProperty) { | ||
case Token.AT_RULE_BLOCK: | ||
optimizeBody(token[2], context); | ||
optimizeBody(token[1], token[2], context); | ||
afterRules = true; | ||
@@ -661,3 +664,3 @@ break; | ||
token[1] = token[1].length > 1 ? sortSelectors(token[1], levelOptions.selectorsSortingMethod) : token[1]; | ||
optimizeBody(token[2], context); | ||
optimizeBody(token[1], token[2], context); | ||
afterRules = true; | ||
@@ -664,0 +667,0 @@ break; |
@@ -71,3 +71,3 @@ var Spaces = require('../../options/format').Spaces; | ||
isNewLineNix = character == Marker.NEW_LINE_NIX; | ||
isNewLineWin = character == Marker.NEW_LINE_NIX && value[i - 1] == Marker.NEW_LINE_WIN; | ||
isNewLineWin = character == Marker.NEW_LINE_NIX && value[i - 1] == Marker.CARRIAGE_RETURN; | ||
isQuoted = isSingleQuoted || isDoubleQuoted; | ||
@@ -74,0 +74,0 @@ isRelation = !isAttribute && !isEscaped && roundBracketLevel === 0 && RELATION_PATTERN.test(character); |
@@ -108,3 +108,3 @@ var InvalidPropertyError = require('./invalid-property-error'); | ||
delaySet = true; | ||
} else if ((validator.isGlobal(value[1]) || validator.isAnimationTimingFunction(value[1])) && !timingSet) { | ||
} else if ((validator.isGlobal(value[1]) || validator.isTimingFunction(value[1])) && !timingSet) { | ||
timing.value = [value]; | ||
@@ -527,2 +527,49 @@ timingSet = true; | ||
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) { | ||
@@ -597,3 +644,4 @@ var descriptor = compactable[property.name]; | ||
multiplex: multiplex, | ||
outline: widthStyleColor | ||
outline: widthStyleColor, | ||
transition: transition | ||
}; |
@@ -23,12 +23,2 @@ var understandable = require('./properties/understandable'); | ||
function animationTimingFunction(validator, value1, value2) { | ||
if (!understandable(validator, value1, value2, 0, true) && !(validator.isAnimationTimingFunction(value2) || validator.isGlobal(value2))) { | ||
return false; | ||
} else if (validator.isVariable(value1) && validator.isVariable(value2)) { | ||
return true; | ||
} | ||
return validator.isAnimationTimingFunction(value2) || validator.isGlobal(value2); | ||
} | ||
function areSameFunction(validator, value1, value2) { | ||
@@ -133,2 +123,12 @@ if (!validator.isFunction(value1) || !validator.isFunction(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) { | ||
@@ -140,4 +140,2 @@ return areSameFunction(validator, value1, value2) ? | ||
function textShadow(validator, value1, value2) { | ||
@@ -171,2 +169,12 @@ if (!understandable(validator, value1, value2, 0, true) && !(validator.isUnit(value2) || validator.isColor(value2) || validator.isGlobal(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) { | ||
@@ -231,3 +239,5 @@ if (!understandable(validator, value1, value2, 0, true) && !validator.isUnit(value2)) { | ||
image: image, | ||
propertyName: propertyName, | ||
time: time, | ||
timingFunction: timingFunction, | ||
unit: unit, | ||
@@ -242,3 +252,2 @@ unitOrNumber: unitOrNumber | ||
animationPlayState: keywordWithGlobal('animation-play-state'), | ||
animationTimingFunction: animationTimingFunction, | ||
backgroundAttachment: keyword('background-attachment'), | ||
@@ -245,0 +254,0 @@ backgroundClip: keywordWithGlobal('background-clip'), |
@@ -41,3 +41,3 @@ // Contains the interpretation of CSS properties, as used by the property optimizer | ||
canOverride.generic.time, | ||
canOverride.property.animationTimingFunction, | ||
canOverride.generic.timingFunction, | ||
canOverride.generic.time, | ||
@@ -163,3 +163,3 @@ canOverride.property.animationIterationCount, | ||
'animation-timing-function': { | ||
canOverride: canOverride.property.animationTimingFunction, | ||
canOverride: canOverride.generic.timingFunction, | ||
componentOf: [ | ||
@@ -923,2 +923,78 @@ 'animation' | ||
}, | ||
'transition': { | ||
breakUp: breakUp.multiplex(breakUp.transition), | ||
canOverride: canOverride.generic.components([ | ||
canOverride.property.transitionProperty, | ||
canOverride.generic.time, | ||
canOverride.generic.timingFunction, | ||
canOverride.generic.time | ||
]), | ||
components: [ | ||
'transition-property', | ||
'transition-duration', | ||
'transition-timing-function', | ||
'transition-delay' | ||
], | ||
defaultValue: 'none', | ||
restore: restore.multiplex(restore.withoutDefaults), | ||
shorthand: true, | ||
vendorPrefixes: [ | ||
'-moz-', | ||
'-o-', | ||
'-webkit-' | ||
] | ||
}, | ||
'transition-delay': { | ||
canOverride: canOverride.generic.time, | ||
componentOf: [ | ||
'transition' | ||
], | ||
defaultValue: '0s', | ||
intoMultiplexMode: 'real', | ||
vendorPrefixes: [ | ||
'-moz-', | ||
'-o-', | ||
'-webkit-' | ||
] | ||
}, | ||
'transition-duration': { | ||
canOverride: canOverride.generic.time, | ||
componentOf: [ | ||
'transition' | ||
], | ||
defaultValue: '0s', | ||
intoMultiplexMode: 'real', | ||
vendorPrefixes: [ | ||
'-moz-', | ||
'-o-', | ||
'-webkit-' | ||
] | ||
}, | ||
'transition-property': { | ||
canOverride: canOverride.generic.propertyName, | ||
componentOf: [ | ||
'transition' | ||
], | ||
defaultValue: 'all', | ||
intoMultiplexMode: 'placeholder', | ||
placeholderValue: '_', // it's a short value that won't match any property and still be a valid `transition-property` | ||
vendorPrefixes: [ | ||
'-moz-', | ||
'-o-', | ||
'-webkit-' | ||
] | ||
}, | ||
'transition-timing-function': { | ||
canOverride: canOverride.generic.timingFunction, | ||
componentOf: [ | ||
'transition' | ||
], | ||
defaultValue: 'ease', | ||
intoMultiplexMode: 'real', | ||
vendorPrefixes: [ | ||
'-moz-', | ||
'-o-', | ||
'-webkit-' | ||
] | ||
}, | ||
'vertical-align': { | ||
@@ -925,0 +1001,0 @@ canOverride: canOverride.property.verticalAlign, |
@@ -11,3 +11,2 @@ var hasInherit = require('./has-inherit'); | ||
var deepClone = require('../clone').deep; | ||
var deepClone = require('../clone').deep; | ||
var restoreWithComponents = require('../restore-with-components'); | ||
@@ -99,6 +98,7 @@ var shallowClone = require('../clone').shallow; | ||
function turnLonghandValueIntoMultiplex(property, size) { | ||
var withRealValue = compactable[property.name].intoMultiplexMode == 'real'; | ||
var withValue = withRealValue ? | ||
var descriptor = compactable[property.name]; | ||
var withRealValue = descriptor.intoMultiplexMode == 'real'; | ||
var withValue = descriptor.intoMultiplexMode == 'real' ? | ||
property.value.slice(0) : | ||
compactable[property.name].defaultValue; | ||
(descriptor.intoMultiplexMode == 'placeholder' ? descriptor.placeholderValue : descriptor.defaultValue); | ||
var i = multiplexSize(property); | ||
@@ -105,0 +105,0 @@ var j; |
@@ -6,3 +6,2 @@ var functionNoVendorRegexStr = '[A-Z]+(\\-|[A-Z]|[0-9])+\\(.*?\\)'; | ||
var animationTimingFunctionRegex = /^(cubic\-bezier|steps)\([^\)]+\)$/; | ||
var calcRegex = new RegExp('^(\\-moz\\-|\\-webkit\\-)?calc\\([^\\)]+\\)$', 'i'); | ||
@@ -13,7 +12,6 @@ var decimalRegex = /[0-9]/; | ||
var identifierRegex = /^(\-[a-z0-9_][a-z0-9\-_]*|[a-z][a-z0-9\-_]*)$/i; | ||
var longHexColorRegex = /^#[0-9a-f]{6}$/i; | ||
var namedEntityRegex = /^[a-z]+$/i; | ||
var prefixRegex = /^-([a-z0-9]|-)*$/i; | ||
var rgbColorRegex = /^rgb\(\s{0,31}[\d]{1,3}\s{0,31},\s{0,31}[\d]{1,3}\s{0,31},\s{0,31}[\d]{1,3}\s{0,31}\)|rgba\(\s{0,31}[\d]{1,3}\s{0,31},\s{0,31}[\d]{1,3}\s{0,31},\s{0,31}[\d]{1,3}\s{0,31},\s{0,31}[\.\d]+\s{0,31}\)$/; | ||
var shortHexColorRegex = /^#[0-9a-f]{3}$/i; | ||
var timingFunctionRegex = /^(cubic\-bezier|steps)\([^\)]+\)$/; | ||
var validTimeUnits = ['ms', 's']; | ||
@@ -23,2 +21,7 @@ var urlRegex = /^url\([\s\S]+\)$/i; | ||
var eightValueColorRegex = /^#[0-9a-f]{8}$/i; | ||
var fourValueColorRegex = /^#[0-9a-f]{4}$/i; | ||
var sixValueColorRegex = /^#[0-9a-f]{6}$/i; | ||
var threeValueColorRegex = /^#[0-9a-f]{3}$/i; | ||
var DECIMAL_DOT = '.'; | ||
@@ -47,2 +50,11 @@ var MINUS_SIGN = '-'; | ||
], | ||
'*-timing-function': [ | ||
'ease', | ||
'ease-in', | ||
'ease-in-out', | ||
'ease-out', | ||
'linear', | ||
'step-end', | ||
'step-start' | ||
], | ||
'animation-direction': [ | ||
@@ -70,11 +82,2 @@ 'alternate', | ||
], | ||
'animation-timing-function': [ | ||
'ease', | ||
'ease-in', | ||
'ease-in-out', | ||
'ease-out', | ||
'linear', | ||
'step-end', | ||
'step-start' | ||
], | ||
'background-attachment': [ | ||
@@ -350,10 +353,2 @@ 'fixed', | ||
function isAnimationTimingFunction() { | ||
var isTimingFunctionKeyword = isKeyword('animation-timing-function'); | ||
return function (value) { | ||
return isTimingFunctionKeyword(value) || animationTimingFunctionRegex.test(value); | ||
}; | ||
} | ||
function isColor(value) { | ||
@@ -382,3 +377,3 @@ return value != 'auto' && | ||
function isHexColor(value) { | ||
return shortHexColorRegex.test(value) || longHexColorRegex.test(value); | ||
return threeValueColorRegex.test(value) || fourValueColorRegex.test(value) || sixValueColorRegex.test(value) || eightValueColorRegex.test(value); | ||
} | ||
@@ -436,2 +431,10 @@ | ||
function isTimingFunction() { | ||
var isTimingFunctionKeyword = isKeyword('*-timing-function'); | ||
return function (value) { | ||
return isTimingFunctionKeyword(value) || timingFunctionRegex.test(value); | ||
}; | ||
} | ||
function isUnit(validUnits, value) { | ||
@@ -495,3 +498,3 @@ var numberUpTo = scanForNumber(value); | ||
isAnimationPlayStateKeyword: isKeyword('animation-play-state'), | ||
isAnimationTimingFunction: isAnimationTimingFunction(), | ||
isTimingFunction: isTimingFunction(), | ||
isBackgroundAttachmentKeyword: isKeyword('background-attachment'), | ||
@@ -498,0 +501,0 @@ isBackgroundClipKeyword: isKeyword('background-clip'), |
@@ -0,1 +1,3 @@ | ||
var systemLineBreak = require('os').EOL; | ||
var override = require('../utils/override'); | ||
@@ -15,2 +17,8 @@ | ||
var BreakWith = { | ||
CarriageReturnLineFeed: '\r\n', | ||
LineFeed: '\n', | ||
System: systemLineBreak | ||
}; | ||
var IndentWith = { | ||
@@ -29,6 +37,8 @@ Space: ' ', | ||
breaks: breaks(false), | ||
breakWith: BreakWith.System, | ||
indentBy: 0, | ||
indentWith: IndentWith.Space, | ||
spaces: spaces(false), | ||
wrapAt: false | ||
wrapAt: false, | ||
semicolonAfterLastProperty: false | ||
}; | ||
@@ -80,2 +90,6 @@ | ||
if (typeof source == 'object' && 'breakWith' in source) { | ||
source = override(source, { breakWith: mapBreakWith(source.breakWith) }); | ||
} | ||
if (typeof source == 'object' && 'indentBy' in source) { | ||
@@ -173,2 +187,17 @@ source = override(source, { indentBy: parseInt(source.indentBy) }); | ||
function mapBreakWith(value) { | ||
switch (value) { | ||
case 'windows': | ||
case 'crlf': | ||
case BreakWith.CarriageReturnLineFeed: | ||
return BreakWith.CarriageReturnLineFeed; | ||
case 'unix': | ||
case 'lf': | ||
case BreakWith.LineFeed: | ||
return BreakWith.LineFeed; | ||
default: | ||
return systemLineBreak; | ||
} | ||
} | ||
function mapIndentWith(value) { | ||
@@ -175,0 +204,0 @@ switch (value) { |
@@ -5,2 +5,3 @@ var Marker = { | ||
BACK_SLASH: '\\', | ||
CARRIAGE_RETURN: '\r', | ||
CLOSE_CURLY_BRACKET: '}', | ||
@@ -16,3 +17,2 @@ CLOSE_ROUND_BRACKET: ')', | ||
NEW_LINE_NIX: '\n', | ||
NEW_LINE_WIN: '\r', | ||
OPEN_CURLY_BRACKET: '{', | ||
@@ -19,0 +19,0 @@ OPEN_ROUND_BRACKET: '(', |
@@ -12,2 +12,3 @@ var Token = { | ||
PROPERTY_VALUE: 'property-value', // e.g. `red` | ||
RAW: 'raw', // e.g. anything between /* clean-css ignore:start */ and /* clean-css ignore:end */ comments | ||
RULE: 'rule', // e.g `div > a{...}` | ||
@@ -14,0 +15,0 @@ RULE_SCOPE: 'rule-scope' // e.g `div > a` |
@@ -31,2 +31,5 @@ var Marker = require('./marker'); | ||
var IGNORE_END_COMMENT_PATTERN = /\/\* clean\-css ignore:end \*\/$/; | ||
var IGNORE_START_COMMENT_PATTERN = /^\/\* clean\-css ignore:start \*\//; | ||
var PAGE_MARGIN_BOXES = [ | ||
@@ -92,2 +95,3 @@ '@bottom-center', | ||
var serializedBuffer; | ||
var serializedBufferPart; | ||
var roundBracketLevel = 0; | ||
@@ -98,2 +102,3 @@ var isQuoted; | ||
var isNewLineWin; | ||
var isCarriageReturn; | ||
var isCommentStart; | ||
@@ -106,5 +111,7 @@ var wasCommentStart = false; | ||
var wasEscaped = false; | ||
var isRaw = false; | ||
var seekingValue = false; | ||
var seekingPropertyBlockClosing = false; | ||
var position = internalContext.position; | ||
var lastCommentStartAt; | ||
@@ -117,3 +124,4 @@ for (; position.index < source.length; position.index++) { | ||
isNewLineNix = character == Marker.NEW_LINE_NIX; | ||
isNewLineWin = character == Marker.NEW_LINE_NIX && source[position.index - 1] == Marker.NEW_LINE_WIN; | ||
isNewLineWin = character == Marker.NEW_LINE_NIX && source[position.index - 1] == Marker.CARRIAGE_RETURN; | ||
isCarriageReturn = character == Marker.CARRIAGE_RETURN && source[position.index + 1] && source[position.index + 1] != Marker.NEW_LINE_NIX; | ||
isCommentStart = !wasCommentEnd && level != Level.COMMENT && !isQuoted && character == Marker.ASTERISK && source[position.index - 1] == Marker.FORWARD_SLASH; | ||
@@ -133,2 +141,4 @@ isCommentEndMarker = !wasCommentStart && !isQuoted && character == Marker.FORWARD_SLASH && source[position.index - 1] == Marker.ASTERISK; | ||
buffer.push(character); | ||
} else if (!isCommentStart && !isCommentEnd && isRaw) { | ||
buffer.push(character); | ||
} else if (isCommentStart && (level == Level.BLOCK || level == Level.RULE) && buffer.length > 1) { | ||
@@ -150,2 +160,29 @@ // comment start within block preceded by some content, e.g. div/*<-- | ||
buffer.push(character); | ||
} else if (isCommentEnd && isIgnoreStartComment(buffer)) { | ||
// ignore:start comment end, e.g. /* clean-css ignore:start */<-- | ||
serializedBuffer = buffer.join('').trim() + character; | ||
lastToken = [Token.COMMENT, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]; | ||
newTokens.push(lastToken); | ||
isRaw = true; | ||
metadata = metadatas.pop() || null; | ||
buffer = buffers.pop() || []; | ||
} else if (isCommentEnd && isIgnoreEndComment(buffer)) { | ||
// ignore:start comment end, e.g. /* clean-css ignore:end */<-- | ||
serializedBuffer = buffer.join('') + character; | ||
lastCommentStartAt = serializedBuffer.lastIndexOf(Marker.FORWARD_SLASH + Marker.ASTERISK); | ||
serializedBufferPart = serializedBuffer.substring(0, lastCommentStartAt); | ||
lastToken = [Token.RAW, serializedBufferPart, [originalMetadata(metadata, serializedBufferPart, externalContext)]]; | ||
newTokens.push(lastToken); | ||
serializedBufferPart = serializedBuffer.substring(lastCommentStartAt); | ||
metadata = [position.line, position.column - serializedBufferPart.length + 1, position.source]; | ||
lastToken = [Token.COMMENT, serializedBufferPart, [originalMetadata(metadata, serializedBufferPart, externalContext)]]; | ||
newTokens.push(lastToken); | ||
isRaw = false; | ||
level = levels.pop(); | ||
metadata = metadatas.pop() || null; | ||
buffer = buffers.pop() || []; | ||
} else if (isCommentEnd) { | ||
@@ -458,3 +495,3 @@ // comment end, e.g. /* comment */<-- | ||
buffer.pop(); | ||
} else if (buffer.length > 0 || !isSpace && !isNewLineNix && !isNewLineWin) { | ||
} else if (buffer.length > 0 || !isSpace && !isNewLineNix && !isNewLineWin && !isCarriageReturn) { | ||
// any character | ||
@@ -469,4 +506,4 @@ buffer.push(character); | ||
position.line = (isNewLineWin || isNewLineNix) ? position.line + 1 : position.line; | ||
position.column = (isNewLineWin || isNewLineNix) ? 0 : position.column + 1; | ||
position.line = (isNewLineWin || isNewLineNix || isCarriageReturn) ? position.line + 1 : position.line; | ||
position.column = (isNewLineWin || isNewLineNix || isCarriageReturn) ? 0 : position.column + 1; | ||
} | ||
@@ -492,2 +529,10 @@ | ||
function isIgnoreStartComment(buffer) { | ||
return IGNORE_START_COMMENT_PATTERN.test(buffer.join('') + Marker.FORWARD_SLASH); | ||
} | ||
function isIgnoreEndComment(buffer) { | ||
return IGNORE_END_COMMENT_PATTERN.test(buffer.join('') + Marker.FORWARD_SLASH); | ||
} | ||
function originalMetadata(metadata, value, externalContext, selectorFallbacks) { | ||
@@ -494,0 +539,0 @@ var source = metadata[2]; |
@@ -1,2 +0,1 @@ | ||
var lineBreak = require('os').EOL; | ||
var emptyCharacter = ''; | ||
@@ -82,3 +81,16 @@ | ||
var isPropertyBlock = token[2][0] == Token.PROPERTY_BLOCK; | ||
var needsSemicolon = position < lastPropertyAt || isPropertyBlock; | ||
var needsSemicolon; | ||
if ( context.format ) { | ||
if ( context.format.semicolonAfterLastProperty || isPropertyBlock ) { | ||
needsSemicolon = true; | ||
} else if ( position < lastPropertyAt ) { | ||
needsSemicolon = true; | ||
} else { | ||
needsSemicolon = false; | ||
} | ||
} else { | ||
needsSemicolon = position < lastPropertyAt || isPropertyBlock; | ||
} | ||
var isLast = position === lastPropertyAt; | ||
@@ -105,2 +117,5 @@ | ||
store(context, needsSemicolon ? semicolon(context, Breaks.AfterProperty, isLast) : emptyCharacter); | ||
break; | ||
case Token.RAW: | ||
store(context, token); | ||
} | ||
@@ -142,3 +157,3 @@ } | ||
Marker.OPEN_CURLY_BRACKET + | ||
(allowsBreak(context, where) ? lineBreak : emptyCharacter) + | ||
(allowsBreak(context, where) ? context.format.breakWith : emptyCharacter) + | ||
context.indentWith; | ||
@@ -154,6 +169,6 @@ } else { | ||
context.indentWith = context.format.indentWith.repeat(context.indentBy); | ||
return (allowsBreak(context, Breaks.AfterProperty) || beforeBlockEnd && allowsBreak(context, Breaks.BeforeBlockEnds) ? lineBreak : emptyCharacter) + | ||
return (allowsBreak(context, Breaks.AfterProperty) || beforeBlockEnd && allowsBreak(context, Breaks.BeforeBlockEnds) ? context.format.breakWith : emptyCharacter) + | ||
context.indentWith + | ||
Marker.CLOSE_CURLY_BRACKET + | ||
(isLast ? emptyCharacter : (allowsBreak(context, where) ? lineBreak : emptyCharacter) + context.indentWith); | ||
(isLast ? emptyCharacter : (allowsBreak(context, where) ? context.format.breakWith : emptyCharacter) + context.indentWith); | ||
} else { | ||
@@ -172,3 +187,3 @@ return Marker.CLOSE_CURLY_BRACKET; | ||
return context.format ? | ||
Marker.SEMICOLON + (isLast || !allowsBreak(context, where) ? emptyCharacter : lineBreak + context.indentWith) : | ||
Marker.SEMICOLON + (isLast || !allowsBreak(context, where) ? emptyCharacter : context.format.breakWith + context.indentWith) : | ||
Marker.SEMICOLON; | ||
@@ -179,3 +194,3 @@ } | ||
return context.format ? | ||
Marker.COMMA + (allowsBreak(context, Breaks.BetweenSelectors) ? lineBreak : emptyCharacter) + context.indentWith : | ||
Marker.COMMA + (allowsBreak(context, Breaks.BetweenSelectors) ? context.format.breakWith : emptyCharacter) + context.indentWith : | ||
Marker.COMMA; | ||
@@ -213,4 +228,7 @@ } | ||
store(context, token); | ||
store(context, allowsBreak(context, Breaks.AfterComment) ? lineBreak : emptyCharacter); | ||
store(context, allowsBreak(context, Breaks.AfterComment) ? context.format.breakWith : emptyCharacter); | ||
break; | ||
case Token.RAW: | ||
store(context, token); | ||
break; | ||
case Token.RULE: | ||
@@ -217,0 +235,0 @@ rules(context, token[1]); |
var all = require('./helpers').all; | ||
var lineBreak = require('os').EOL; | ||
function store(serializeContext, token) { | ||
@@ -18,4 +16,4 @@ var value = typeof token == 'string' ? | ||
if (serializeContext.column + value.length > serializeContext.format.wrapAt) { | ||
track(serializeContext, lineBreak); | ||
serializeContext.output.push(lineBreak); | ||
track(serializeContext, serializeContext.format.breakWith); | ||
serializeContext.output.push(serializeContext.format.breakWith); | ||
} | ||
@@ -22,0 +20,0 @@ } |
var SourceMapGenerator = require('source-map').SourceMapGenerator; | ||
var all = require('./helpers').all; | ||
var lineBreak = require('os').EOL; | ||
var isRemoteResource = require('../utils/is-remote-resource'); | ||
@@ -26,4 +25,4 @@ | ||
if (serializeContext.column + value.length > serializeContext.format.wrapAt) { | ||
track(serializeContext, lineBreak, false); | ||
serializeContext.output.push(lineBreak); | ||
track(serializeContext, serializeContext.format.breakWith, false); | ||
serializeContext.output.push(serializeContext.format.breakWith); | ||
} | ||
@@ -30,0 +29,0 @@ } |
{ | ||
"name": "clean-css", | ||
"version": "4.1.11", | ||
"version": "4.2.0", | ||
"author": "Jakub Pawlowicz <contact@jakubpawlowicz.com> (http://twitter.com/jakubpawlowicz)", | ||
@@ -34,3 +34,3 @@ "description": "A well-tested CSS minifier", | ||
"dependencies": { | ||
"source-map": "0.5.x" | ||
"source-map": "~0.6.0" | ||
}, | ||
@@ -37,0 +37,0 @@ "devDependencies": { |
@@ -12,3 +12,3 @@ <h1 align="center"> | ||
[![Dependency Status](https://img.shields.io/david/jakubpawlowicz/clean-css.svg?style=flat)](https://david-dm.org/jakubpawlowicz/clean-css) | ||
[![NPM Downloads](https://img.shields.io/npm/dm/clean-css.svg)](https://www.npmjs.com/package/clean-css) | ||
[![NPM Downloads](https://img.shields.io/npm/dm/clean-css.svg)](https://npmcharts.com/compare/clean-css?minimal=true) | ||
[![Twitter](https://img.shields.io/badge/Twitter-@cleancss-blue.svg)](https://twitter.com/cleancss) | ||
@@ -27,2 +27,3 @@ | ||
* [What's new in version 4.1](#whats-new-in-version-41) | ||
* [What's new in version 4.2](#whats-new-in-version-42) | ||
* [Constructor options](#constructor-options) | ||
@@ -45,2 +46,3 @@ * [Compatibility modes](#compatibility-modes) | ||
* [How to specify a custom rounding precision?](#how-to-specify-a-custom-rounding-precision) | ||
* [How to keep a CSS fragment intact?](#how-to-keep-a-css-fragment-intact) | ||
* [How to preserve a comment block?](#how-to-preserve-a-comment-block) | ||
@@ -65,3 +67,3 @@ * [How to rebase relative image URLs?](#how-to-rebase-relative-image-urls) | ||
``` | ||
npm install clean-css | ||
npm install --save-dev clean-css | ||
``` | ||
@@ -119,2 +121,12 @@ | ||
## What's new in version 4.2 | ||
clean-css 4.2 introduces the following changes / features: | ||
* Adds `process` method for compatibility with optimize-css-assets-webpack-plugin; | ||
* new `transition` property optimizer; | ||
* preserves any CSS content between `/* clean-css ignore:start */` and `/* clean-css ignore:end */` comments; | ||
* allows filtering based on selector in `transform` callback, see [example](#how-to-apply-arbitrary-transformations-to-css-properties); | ||
* adds configurable line breaks via `format: { breakWith: 'lf' }` option. | ||
## Constructor options | ||
@@ -261,2 +273,3 @@ | ||
}, | ||
breakWith: '\n', // controls the new line character, can be `'\r\n'` or `'\n'` (aliased as `'windows'` and `'unix'` or `'crlf'` and `'lf'`); defaults to system one, so former on Windows and latter on Unix | ||
indentBy: 0, // controls number of characters to indent with; defaults to `0` | ||
@@ -365,2 +378,3 @@ indentWith: 'space', // controls a character to indent with, can be `'space'` or `'tab'`; defaults to `'space'` | ||
tidySelectors: true, // controls selectors optimizing; defaults to `true`, | ||
semicolonAfterLastProperty: false, // controls removing trailing semicolons in rule; defaults to `false` - means remove | ||
transform: function () {} // defines a callback for fine-grained property optimization; defaults to no-op | ||
@@ -533,3 +547,3 @@ } | ||
1: { | ||
transform: function (propertyName, propertyValue) { | ||
transform: function (propertyName, propertyValue, selector /* `selector` available since 4.2.0-pre */) { | ||
if (propertyName == 'background-image' && propertyValue.indexOf('/path/to') > -1) { | ||
@@ -564,2 +578,32 @@ return propertyValue.replace('/path/to', '../valid/path/to'); | ||
## How to keep a CSS fragment intact? | ||
Note: available in the current master, to be released in 4.2.0. | ||
Wrap the CSS fragment in special comments which instruct clean-css to preserve it, e.g. | ||
```css | ||
.block-1 { | ||
color: red | ||
} | ||
/* clean-css ignore:start */ | ||
.block-special { | ||
color: transparent | ||
} | ||
/* clean-css ignore:end */ | ||
.block-2 { | ||
margin: 0 | ||
} | ||
``` | ||
Optimizing this CSS will result in the following output: | ||
```css | ||
.block-1{color:red} | ||
.block-special { | ||
color: transparent | ||
} | ||
.block-2{margin:0} | ||
``` | ||
## How to preserve a comment block? | ||
@@ -566,0 +610,0 @@ |
Sorry, the diff of this file is too big to display
435826
9188
765
+ Addedsource-map@0.6.1(transitive)
- Removedsource-map@0.5.7(transitive)
Updatedsource-map@~0.6.0