Skip to content

Commit

Permalink
Fixes #996 - outstanding issue with spaces removed inside pseudoclasses.
Browse files Browse the repository at this point in the history
I thought we fixed it with #1062 but this case was different.
  • Loading branch information
jakubpawlowicz committed Mar 19, 2021
1 parent ebf9ea7 commit 5d7d6aa
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 2 deletions.
5 changes: 5 additions & 0 deletions History.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
[5.1.2 / 2021-xx-xx](https://github.com/jakubpawlowicz/clean-css/compare/v5.1.1...5.1)
==================

* Fixed issue [#996](https://github.com/jakubpawlowicz/clean-css/issues/996) - space removed from pseudo classes.

[5.1.1 / 2021-03-03](https://github.com/jakubpawlowicz/clean-css/compare/v5.1.0...v5.1.1)
==================

Expand Down
29 changes: 27 additions & 2 deletions lib/optimizer/level-1/tidy-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ var ASTERISK_PLUS_HTML_HACK = '*+html ';
var ASTERISK_FIRST_CHILD_PLUS_HTML_HACK = '*:first-child+html ';
var LESS_THAN = '<';

var PSEUDO_CLASSES_WITH_SELECTORS = [
':current',
':future',
':has',
':host',
':host-context',
':is',
':not',
':past',
':where'
];

function hasInvalidCharacters(value) {
var isEscaped;
var isInvalid = false;
Expand Down Expand Up @@ -57,8 +69,9 @@ function removeWhitespace(value, format) {
var isAttribute;
var isRelation;
var isWhitespace;
var isPseudoClass = value[0] == Marker.COLON;
var isSpaceAwarePseudoClass;
var roundBracketLevel = 0;
var wasComma = false;
var wasRelation = false;
var wasWhitespace = false;
var withCaseAttribute = CASE_ATTRIBUTE_PATTERN.test(value);
Expand All @@ -73,6 +86,9 @@ function removeWhitespace(value, format) {
isQuoted = isSingleQuoted || isDoubleQuoted;
isRelation = !isAttribute && !isEscaped && roundBracketLevel === 0 && RELATION_PATTERN.test(character);
isWhitespace = WHITESPACE_PATTERN.test(character);
isSpaceAwarePseudoClass = roundBracketLevel == 1 && character == Marker.CLOSE_ROUND_BRACKET ?
false :
isSpaceAwarePseudoClass || (roundBracketLevel === 0 && character == Marker.COLON && isPseudoClassWithSelectors(value, i));

if (wasEscaped && isQuoted && isNewLineWin) {
// swallow escaped new windows lines in comments
Expand Down Expand Up @@ -112,7 +128,9 @@ function removeWhitespace(value, format) {
} else if (!isWhitespace && wasRelation && spaceAroundRelation) {
stripped.push(Marker.SPACE);
stripped.push(character);
} else if (isWhitespace && !wasWhitespace && roundBracketLevel > 0 && isPseudoClass) {
} else if (isWhitespace && !wasWhitespace && wasComma && roundBracketLevel > 0 && isSpaceAwarePseudoClass) {
// skip space
} else if (isWhitespace && !wasWhitespace && roundBracketLevel > 0 && isSpaceAwarePseudoClass) {
stripped.push(character);
} else if (isWhitespace && (isAttribute || roundBracketLevel > 0) && !isQuoted) {
// skip space
Expand All @@ -136,13 +154,20 @@ function removeWhitespace(value, format) {
isEscaped = character == Marker.BACK_SLASH;
wasRelation = isRelation;
wasWhitespace = isWhitespace;
wasComma = character == Marker.COMMA;
}

return withCaseAttribute ?
stripped.join('').replace(CASE_RESTORE_PATTERN, '$1 $2]') :
stripped.join('');
}

function isPseudoClassWithSelectors(value, colonPosition) {
var pseudoClass = value.substring(colonPosition, value.indexOf(Marker.OPEN_ROUND_BRACKET, colonPosition));

return PSEUDO_CLASSES_WITH_SELECTORS.indexOf(pseudoClass) > -1;
}

function removeQuotes(value) {
if (value.indexOf('\'') == -1 && value.indexOf('"') == -1) {
return value;
Expand Down
8 changes: 8 additions & 0 deletions test/optimizer/level-1/optimize-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,13 +257,21 @@ vows.describe('level 1 optimizations')
':host-context(main article){color:red}',
':host-context(main article){color:red}'
],
'extra spaces with comma are removed': [
':host-context(main, article){color:red}',
':host-context(main,article){color:red}'
],
'space is not removed in multiple rules': [
':host-context(main footer),:host-context(main header){color:red}',
':host-context(main footer),:host-context(main header){color:red}'
],
'space is not removed from :not pseudo-class': [
':not(.block1 .block1__block2){color:red}',
':not(.block1 .block1__block2){color:red}'
],
'space in scoped pseudo class': [
'.container:not(#BorlabsCookieBox .container){max-width:1280px!important}',
'.container:not(#BorlabsCookieBox .container){max-width:1280px!important}'
]
}, { level: 1 })
)
Expand Down

0 comments on commit 5d7d6aa

Please sign in to comment.