Skip to content

Commit

Permalink
Fixes #947 - selector based filtering.
Browse files Browse the repository at this point in the history
Why:

* Sometimes it may be useful to rewrite or drop certain properties based
  on selector value.
  • Loading branch information
jakubpawlowicz committed Jun 17, 2017
1 parent 933d157 commit 56d43e1
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 8 deletions.
1 change: 1 addition & 0 deletions History.md
Expand Up @@ -4,6 +4,7 @@
* Adds `process` method for compatibility with optimize-css-assets-webpack-plugin.
* Fixed issue [#861](https://github.com/jakubpawlowicz/clean-css/issues/861) - new `transition` property optimizer.
* Fixed issue [#895](https://github.com/jakubpawlowicz/clean-css/issues/895) - ignoring specific styles.
* Fixed issue [#947](https://github.com/jakubpawlowicz/clean-css/issues/947) - selector based filtering.

[4.1.4 / 2017-06-14](https://github.com/jakubpawlowicz/clean-css/compare/v4.1.3...v4.1.4)
==================
Expand Down
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -121,6 +121,7 @@ clean-css 4.2 will introduce 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);

## Constructor options

Expand Down Expand Up @@ -533,7 +534,7 @@ var source = '.block{background-image:url(/path/to/image.png)}';
var output = new CleanCSS({
level: {
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) {
return propertyValue.replace('/path/to', '../valid/path/to');
}
Expand Down
17 changes: 10 additions & 7 deletions lib/optimizer/level-1/optimize.js
Expand Up @@ -19,6 +19,8 @@ var Marker = require('../../tokenizer/marker');
var formatPosition = require('../../utils/format-position');
var split = require('../../utils/split');

var serializeRules = require('../../writer/one-time').rules;

var IgnoreProperty = 'ignore-property';

var CHARSET_TOKEN = '@charset';
Expand Down Expand Up @@ -344,8 +346,9 @@ function removeUrlQuotes(value) {
value;
}

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);

if (transformedValue === undefined) {
return propertyValue;
Expand All @@ -358,7 +361,7 @@ function transformValue(propertyName, propertyValue, transformCallback) {

//

function optimizeBody(properties, context) {
function optimizeBody(rule, properties, context) {
var options = context.options;
var levelOptions = options.level[OptimizationLevel.One];
var property, name, type, value;
Expand Down Expand Up @@ -403,7 +406,7 @@ function optimizeBody(properties, context) {
}

if (property.block) {
optimizeBody(property.value[0][1], context);
optimizeBody(rule, property.value[0][1], context);
continue;
}

Expand Down Expand Up @@ -462,7 +465,7 @@ function optimizeBody(properties, context) {
}
}

value = transformValue(name, value, levelOptions.transform);
value = transformValue(name, value, rule, levelOptions.transform);

if (value === IgnoreProperty) {
property.unused = true;
Expand Down Expand Up @@ -635,7 +638,7 @@ function level1Optimize(tokens, context) {
mayHaveCharset = true;
break;
case Token.AT_RULE_BLOCK:
optimizeBody(token[2], context);
optimizeBody(token[1], token[2], context);
afterRules = true;
break;
case Token.NESTED_BLOCK:
Expand All @@ -649,7 +652,7 @@ function level1Optimize(tokens, context) {
case Token.RULE:
token[1] = levelOptions.tidySelectors ? tidyRules(token[1], !ie7Hack, adjacentSpace, format, context.warnings) : token[1];
token[1] = token[1].length > 1 ? sortSelectors(token[1], levelOptions.selectorsSortingMethod) : token[1];
optimizeBody(token[2], context);
optimizeBody(token[1], token[2], context);
afterRules = true;
break;
}
Expand Down
18 changes: 18 additions & 0 deletions test/module-test.js
Expand Up @@ -447,6 +447,24 @@ vows.describe('module tests').addBatch({
assert.equal(output.styles, '.block{border-image:url(image.png)}');
}
},
'allows dropping properties based on selector': {
'topic': function () {
return new CleanCSS({
level: {
1: {
transform: function (propertyName, propertyValue, selector) {
if (propertyName.indexOf('-o-') === 0 && selector == '.block-2') {
return false;
}
}
}
}
}).minify('.block-1{-o-border-radius:2px}.block-2{-o-border-radius:5px;width:1rem}');
},
'gives right output': function (error, output) {
assert.equal(output.styles, '.block-1{-o-border-radius:2px}.block-2{width:1rem}');
}
},
'combined with level 2 optimization': {
'topic': function () {
return new CleanCSS({
Expand Down

0 comments on commit 56d43e1

Please sign in to comment.