Comparing version 3.1.1 to 3.2.0
@@ -0,1 +1,10 @@ | ||
## 3.2.0 (September 10, 2017) | ||
- Fixed named color compression to apply only when an identifier is guaranteed to be a color | ||
- Added lifting of `@keyframes` to the beginning of style sheet (chunk), but after `@charset` and `@import` rules | ||
- Added removal of `@keyframes`, `@media` and `@supports` with no prelude | ||
- Added removal of duplicate `@keyframes` (#202) | ||
- Added new option `forceMediaMerge` to force media rules merging. It's unsafe in general, but works fine in many cases. Use it on your own risk (#350) | ||
- Bumped `CSSTree` to `1.0.0-alpha23` | ||
## 3.1.1 (April 25, 2017) | ||
@@ -13,3 +22,3 @@ | ||
- Improved white space removing, now white spaces are removing in the beginning and at the ending of sequences, and between stylesheet and block nodes | ||
- Bumped `css-tree` to `1.0.0-alpha19` | ||
- Bumped `CSSTree` to `1.0.0-alpha19` | ||
@@ -16,0 +25,0 @@ ## 3.0.1 (March 14, 2017) |
@@ -0,1 +1,3 @@ | ||
var resolveKeyword = require('css-tree').keyword; | ||
module.exports = function cleanAtrule(node, item, list) { | ||
@@ -16,3 +18,3 @@ if (node.block) { | ||
case 'charset': | ||
if (!node.expression || node.expression.children.isEmpty()) { | ||
if (!node.prelude || node.prelude.children.isEmpty()) { | ||
list.remove(item); | ||
@@ -51,3 +53,15 @@ return; | ||
break; | ||
default: | ||
var keyword = resolveKeyword(node.name); | ||
if (keyword.name === 'keyframes' || | ||
keyword.name === 'media' || | ||
keyword.name === 'supports') { | ||
// drop at-rule with no prelude | ||
if (!node.prelude || node.prelude.children.isEmpty()) { | ||
list.remove(item); | ||
} | ||
} | ||
} | ||
}; |
@@ -12,8 +12,8 @@ var walk = require('css-tree').walkUp; | ||
module.exports = function(ast, usageData) { | ||
module.exports = function(ast, options) { | ||
walk(ast, function(node, item, list) { | ||
if (handlers.hasOwnProperty(node.type)) { | ||
handlers[node.type].call(this, node, item, list, usageData); | ||
handlers[node.type].call(this, node, item, list, options); | ||
} | ||
}); | ||
}; |
@@ -76,3 +76,5 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; | ||
module.exports = function cleanRuleset(node, item, list, usageData) { | ||
module.exports = function cleanRuleset(node, item, list, options) { | ||
var usageData = options.usage; | ||
if (usageData && (usageData.whitelist !== null || usageData.blacklist !== null)) { | ||
@@ -79,0 +81,0 @@ cleanUnused(node.selector, usageData); |
@@ -6,3 +6,3 @@ var List = require('css-tree').List; | ||
var replace = require('./replace'); | ||
var restructureBlock = require('./restructure'); | ||
var restructure = require('./restructure'); | ||
var walkRules = require('css-tree').walkRules; | ||
@@ -48,4 +48,4 @@ | ||
function compressChunk(ast, firstAtrulesAllowed, usageData, num, logger) { | ||
logger('Compress block #' + num, null, true); | ||
function compressChunk(ast, firstAtrulesAllowed, num, options) { | ||
options.logger('Compress block #' + num, null, true); | ||
@@ -64,12 +64,17 @@ var seed = 1; | ||
}); | ||
logger('init', ast); | ||
options.logger('init', ast); | ||
// remove redundant | ||
clean(ast, usageData); | ||
logger('clean', ast); | ||
clean(ast, options); | ||
options.logger('clean', ast); | ||
// replace nodes for shortened forms | ||
replace(ast, usageData); | ||
logger('replace', ast); | ||
replace(ast, options); | ||
options.logger('replace', ast); | ||
// structure optimisations | ||
if (options.restructuring) { | ||
restructure(ast, options); | ||
} | ||
return ast; | ||
@@ -99,8 +104,12 @@ } | ||
type: 'Rule', | ||
loc: null, | ||
selector: { | ||
type: 'SelectorList', | ||
loc: null, | ||
children: new List().appendData({ | ||
type: 'Selector', | ||
loc: null, | ||
children: new List().appendData({ | ||
type: 'Identifier', | ||
type: 'TypeSelector', | ||
loc: null, | ||
name: 'x' | ||
@@ -118,12 +127,15 @@ }) | ||
var logger = typeof options.logger === 'function' ? options.logger : function() {}; | ||
var compressOptions = { | ||
logger: typeof options.logger === 'function' ? options.logger : function() {}, | ||
restructuring: getRestructureOption(options), | ||
forceMediaMerge: Boolean(options.forceMediaMerge), | ||
usage: options.usage ? usageUtils.buildIndex(options.usage) : false | ||
}; | ||
var specialComments = getCommentsOption(options); | ||
var restructuring = getRestructureOption(options); | ||
var firstAtrulesAllowed = true; | ||
var usageData = false; | ||
var inputRules; | ||
var outputRules = new List(); | ||
var input; | ||
var output = new List(); | ||
var chunk; | ||
var chunkNum = 1; | ||
var chunkRules; | ||
var chunkChildren; | ||
@@ -135,28 +147,17 @@ if (options.clone) { | ||
if (ast.type === 'StyleSheet') { | ||
inputRules = ast.children; | ||
ast.children = outputRules; | ||
input = ast.children; | ||
ast.children = output; | ||
} else { | ||
inputRules = wrapBlock(ast); | ||
input = wrapBlock(ast); | ||
} | ||
if (options.usage) { | ||
usageData = usageUtils.buildIndex(options.usage); | ||
} | ||
do { | ||
chunk = readChunk(inputRules, Boolean(specialComments)); | ||
chunk = readChunk(input, Boolean(specialComments)); | ||
compressChunk(chunk.stylesheet, firstAtrulesAllowed, chunkNum++, compressOptions); | ||
chunkChildren = chunk.stylesheet.children; | ||
compressChunk(chunk.stylesheet, firstAtrulesAllowed, usageData, chunkNum++, logger); | ||
// structure optimisations | ||
if (restructuring) { | ||
restructureBlock(chunk.stylesheet, usageData, logger); | ||
} | ||
chunkRules = chunk.stylesheet.children; | ||
if (chunk.comment) { | ||
// add \n before comment if there is another content in outputRules | ||
if (!outputRules.isEmpty()) { | ||
outputRules.insert(List.createItem({ | ||
// add \n before comment if there is another content in output | ||
if (!output.isEmpty()) { | ||
output.insert(List.createItem({ | ||
type: 'Raw', | ||
@@ -167,7 +168,7 @@ value: '\n' | ||
outputRules.insert(List.createItem(chunk.comment)); | ||
output.insert(List.createItem(chunk.comment)); | ||
// add \n after comment if chunk is not empty | ||
if (!chunkRules.isEmpty()) { | ||
outputRules.insert(List.createItem({ | ||
if (!chunkChildren.isEmpty()) { | ||
output.insert(List.createItem({ | ||
type: 'Raw', | ||
@@ -179,4 +180,4 @@ value: '\n' | ||
if (firstAtrulesAllowed && !chunkRules.isEmpty()) { | ||
var lastRule = chunkRules.last(); | ||
if (firstAtrulesAllowed && !chunkChildren.isEmpty()) { | ||
var lastRule = chunkChildren.last(); | ||
@@ -193,4 +194,4 @@ if (lastRule.type !== 'Atrule' || | ||
outputRules.appendList(chunkRules); | ||
} while (!inputRules.isEmpty()); | ||
output.appendList(chunkChildren); | ||
} while (!input.isEmpty()); | ||
@@ -197,0 +198,0 @@ return { |
@@ -125,3 +125,3 @@ var csstree = require('css-tree'); | ||
return minify('stylesheet', source, options); | ||
}; | ||
} | ||
@@ -128,0 +128,0 @@ function minifyBlock(source, options) { |
var resolveKeyword = require('css-tree').keyword; | ||
var compressKeyframes = require('./atrule/keyframes.js'); | ||
var compressKeyframes = require('./atrule/keyframes'); | ||
@@ -4,0 +4,0 @@ module.exports = function(node) { |
@@ -1,2 +0,3 @@ | ||
var packNumber = require('./Number.js').pack; | ||
var lexer = require('css-tree').lexer; | ||
var packNumber = require('./Number').pack; | ||
@@ -460,3 +461,4 @@ // http://www.w3.org/TR/css3-color/#svg-color | ||
if (NAME_TO_HEX.hasOwnProperty(color)) { | ||
if (NAME_TO_HEX.hasOwnProperty(color) && | ||
lexer.matchDeclaration(this.declaration).isType(node, 'color')) { | ||
var hex = NAME_TO_HEX[color]; | ||
@@ -463,0 +465,0 @@ |
@@ -1,2 +0,2 @@ | ||
var packNumber = require('./Number.js').pack; | ||
var packNumber = require('./Number').pack; | ||
var LENGTH_UNIT = { | ||
@@ -30,3 +30,3 @@ // absolute length units | ||
if (value === '0' && this.declaration !== null && this.atruleExpression === null) { | ||
if (value === '0' && this.declaration !== null && this.atrulePrelude === null) { | ||
var unit = node.unit.toLowerCase(); | ||
@@ -33,0 +33,0 @@ |
@@ -34,3 +34,3 @@ var OMIT_PLUSSIGN = /^(?:\+|(-))?0*(\d*)(?:\.0*|(\.\d*?)0*)?$/; | ||
return value; | ||
}; | ||
} | ||
@@ -37,0 +37,0 @@ module.exports = function(node, item) { |
var resolveName = require('css-tree').property; | ||
var handlers = { | ||
'font': require('./property/font.js'), | ||
'font-weight': require('./property/font-weight.js'), | ||
'background': require('./property/background.js'), | ||
'border': require('./property/border.js'), | ||
'outline': require('./property/border.js') | ||
'font': require('./property/font'), | ||
'font-weight': require('./property/font-weight'), | ||
'background': require('./property/background'), | ||
'border': require('./property/border'), | ||
'outline': require('./property/border') | ||
}; | ||
@@ -9,0 +9,0 @@ |
@@ -1,3 +0,3 @@ | ||
var utils = require('./utils.js'); | ||
var walkRules = require('css-tree').walkRules; | ||
var utils = require('./utils'); | ||
@@ -4,0 +4,0 @@ /* |
var List = require('css-tree').List; | ||
var walkRulesRight = require('css-tree').walkRulesRight; | ||
var utils = require('./utils.js'); | ||
var utils = require('./utils'); | ||
@@ -5,0 +5,0 @@ function calcSelectorLength(list) { |
@@ -1,35 +0,35 @@ | ||
var prepare = require('./prepare/index.js'); | ||
var initialMergeRuleset = require('./1-initialMergeRuleset.js'); | ||
var mergeAtrule = require('./2-mergeAtrule.js'); | ||
var disjoinRuleset = require('./3-disjoinRuleset.js'); | ||
var restructShorthand = require('./4-restructShorthand.js'); | ||
var restructBlock = require('./6-restructBlock.js'); | ||
var mergeRuleset = require('./7-mergeRuleset.js'); | ||
var restructRuleset = require('./8-restructRuleset.js'); | ||
var prepare = require('./prepare/index'); | ||
var mergeAtrule = require('./1-mergeAtrule'); | ||
var initialMergeRuleset = require('./2-initialMergeRuleset'); | ||
var disjoinRuleset = require('./3-disjoinRuleset'); | ||
var restructShorthand = require('./4-restructShorthand'); | ||
var restructBlock = require('./6-restructBlock'); | ||
var mergeRuleset = require('./7-mergeRuleset'); | ||
var restructRuleset = require('./8-restructRuleset'); | ||
module.exports = function(ast, usageData, debug) { | ||
module.exports = function(ast, options) { | ||
// prepare ast for restructing | ||
var indexer = prepare(ast, usageData); | ||
debug('prepare', ast); | ||
var indexer = prepare(ast, options); | ||
options.logger('prepare', ast); | ||
mergeAtrule(ast, options); | ||
options.logger('mergeAtrule', ast); | ||
initialMergeRuleset(ast); | ||
debug('initialMergeRuleset', ast); | ||
options.logger('initialMergeRuleset', ast); | ||
mergeAtrule(ast); | ||
debug('mergeAtrule', ast); | ||
disjoinRuleset(ast); | ||
debug('disjoinRuleset', ast); | ||
options.logger('disjoinRuleset', ast); | ||
restructShorthand(ast, indexer); | ||
debug('restructShorthand', ast); | ||
options.logger('restructShorthand', ast); | ||
restructBlock(ast); | ||
debug('restructBlock', ast); | ||
options.logger('restructBlock', ast); | ||
mergeRuleset(ast); | ||
debug('mergeRuleset', ast); | ||
options.logger('mergeRuleset', ast); | ||
restructRuleset(ast); | ||
debug('restructRuleset', ast); | ||
options.logger('restructRuleset', ast); | ||
}; |
var resolveKeyword = require('css-tree').keyword; | ||
var walkRules = require('css-tree').walkRules; | ||
var translate = require('css-tree').translate; | ||
var createDeclarationIndexer = require('./createDeclarationIndexer.js'); | ||
var processSelector = require('./processSelector.js'); | ||
var createDeclarationIndexer = require('./createDeclarationIndexer'); | ||
var processSelector = require('./processSelector'); | ||
function walk(node, markDeclaration, usageData) { | ||
function walk(node, markDeclaration, options) { | ||
switch (node.type) { | ||
case 'Rule': | ||
node.block.children.each(markDeclaration); | ||
processSelector(node, usageData); | ||
processSelector(node, options.usage); | ||
break; | ||
case 'Atrule': | ||
if (node.expression) { | ||
node.expression.id = null; // pre-init property to avoid multiple hidden class for translate | ||
node.expression.id = translate(node.expression); | ||
if (node.prelude) { | ||
node.prelude.id = null; // pre-init property to avoid multiple hidden class for translate | ||
node.prelude.id = translate(node.prelude); | ||
} | ||
@@ -33,9 +33,9 @@ | ||
} | ||
}; | ||
} | ||
module.exports = function prepare(ast, usageData) { | ||
module.exports = function prepare(ast, options) { | ||
var markDeclaration = createDeclarationIndexer(); | ||
walkRules(ast, function(node) { | ||
walk(node, markDeclaration, usageData); | ||
walk(node, markDeclaration, options); | ||
}); | ||
@@ -42,0 +42,0 @@ |
var translate = require('css-tree').translate; | ||
var specificity = require('./specificity.js'); | ||
var specificity = require('./specificity'); | ||
@@ -29,3 +29,3 @@ var nonFreezePseudoElements = { | ||
simpleSelector.children.some(function(node) { | ||
simpleSelector.children.each(function(node) { | ||
switch (node.type) { | ||
@@ -32,0 +32,0 @@ case 'ClassSelector': |
{ | ||
"name": "csso", | ||
"version": "3.1.1", | ||
"description": "CSSO (CSS Optimizer) is a CSS minifier with structural optimisations", | ||
"version": "3.2.0", | ||
"description": "CSS minifier with structural optimisations", | ||
"keywords": [ | ||
"css", | ||
"compress", | ||
"minifier", | ||
"minify", | ||
"compress", | ||
"optimisation" | ||
"optimise", | ||
"optimisation", | ||
"csstree" | ||
], | ||
@@ -58,3 +60,3 @@ "homepage": "https://github.com/css/csso", | ||
"dependencies": { | ||
"css-tree": "1.0.0-alpha19" | ||
"css-tree": "1.0.0-alpha23" | ||
}, | ||
@@ -61,0 +63,0 @@ "devDependencies": { |
@@ -21,2 +21,3 @@ [![NPM version](https://img.shields.io/npm/v/csso.svg)](https://www.npmjs.com/package/csso) | ||
- [csso-loader](https://github.com/sandark7/csso-loader) – `webpack` loader | ||
- [csso-webpack-plugin](https://github.com/zoobestik/csso-webpack-plugin) – `webpack` plugin | ||
@@ -159,2 +160,9 @@ ## Install | ||
- forceMediaMerge | ||
Type: `Boolean` | ||
Default: `false` | ||
Enables merging of `@media` rules with the same media query by splitted by other rules. The optimisation is unsafe in general, but should work fine in most cases. Use it on your own risk. | ||
- clone | ||
@@ -161,0 +169,0 @@ |
Sorry, the diff of this file is too big to display
Uses eval
Supply chain riskPackage uses eval() which is a dangerous function. This prevents the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses eval() which is a dangerous function. This prevents the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
323421
3359
377
+ Addedcss-tree@1.0.0-alpha23(transitive)
+ Addedmdn-data@1.2.0(transitive)
- Removedcss-tree@1.0.0-alpha19(transitive)
Updatedcss-tree@1.0.0-alpha23