Skip to content

Commit

Permalink
Merge pull request #210 from n1kk/master
Browse files Browse the repository at this point in the history
added ability to exclude current rule with an ignore comment placed in…
  • Loading branch information
Ffloriel committed Oct 6, 2019
2 parents 0a0b921 + 16d0730 commit d08ca7e
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 55 deletions.
4 changes: 3 additions & 1 deletion __tests__/purgecssDefault.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,14 @@ describe('purge methods with files and default extractor', () => {
})
purgecssResult = purgecss.purge()[0].css
})
it('ignores h1', () => {
it('ignores h1 h2', () => {
expect(purgecssResult.includes('h1')).toBe(true)
expect(purgecssResult.includes('h3')).toBe(true)
})

it('removes the comment', () => {
expect(purgecssResult.includes('/* purgecss ignore */')).toBe(false)
expect(purgecssResult.includes('/* purgecss ignore current */')).toBe(false)
})
})

Expand Down
7 changes: 6 additions & 1 deletion __tests__/test_examples/ignore_comment/ignore_comment.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@
h1 {
color: blue;

}
}

h3 {
/* purgecss ignore current */
color: red;
}
107 changes: 81 additions & 26 deletions lib/purgecss.es.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ var defaultOptions = {
rejected: false
};

var IGNORE_ANNOTATION_CURRENT = 'purgecss ignore current';
var IGNORE_ANNOTATION_NEXT = 'purgecss ignore';
var IGNORE_ANNOTATION_START = 'purgecss start ignore';
var IGNORE_ANNOTATION_END = 'purgecss end ignore';
Expand Down Expand Up @@ -582,6 +583,16 @@ function () {
}
}
}
/**
* Strips quotes at the end and at the end of a string
* @param {string} value the string to be stripped
*/

}, {
key: "stripQuotes",
value: function stripQuotes(value) {
return value.replace(/(^["'])|(["']$)/g, '');
}
/**
* Extract the selectors present in the passed string using a purgecss extractor
* @param {array} content Array of content
Expand Down Expand Up @@ -787,6 +798,10 @@ function () {
return;
}

if (this.hasIgnoreAnnotation(node)) {
return;
}

var keepSelector = true;
node.selector = selectorParser(function (selectorsParsed) {
selectorsParsed.walk(function (selector) {
Expand Down Expand Up @@ -881,7 +896,30 @@ function () {

if (this.options.fontFace) {
if (prop === 'font-family') {
this.usedFontFaces.add(value);
var _iteratorNormalCompletion10 = true;
var _didIteratorError10 = false;
var _iteratorError10 = undefined;

try {
for (var _iterator10 = value.split(',')[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
var fontName = _step10.value;
var cleanedFontFace = this.stripQuotes(fontName.trim());
this.usedFontFaces.add(cleanedFontFace);
}
} catch (err) {
_didIteratorError10 = true;
_iteratorError10 = err;
} finally {
try {
if (!_iteratorNormalCompletion10 && _iterator10.return != null) {
_iterator10.return();
}
} finally {
if (_didIteratorError10) {
throw _iteratorError10;
}
}
}
}
}
}
Expand Down Expand Up @@ -920,34 +958,34 @@ function () {
}

if (this.options.fontFace && node.name === 'font-face') {
var _iteratorNormalCompletion10 = true;
var _didIteratorError10 = false;
var _iteratorError10 = undefined;
var _iteratorNormalCompletion11 = true;
var _didIteratorError11 = false;
var _iteratorError11 = undefined;

try {
for (var _iterator10 = node.nodes[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
var _step10$value = _step10.value,
prop = _step10$value.prop,
value = _step10$value.value;
for (var _iterator11 = node.nodes[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
var _step11$value = _step11.value,
prop = _step11$value.prop,
value = _step11$value.value;

if (prop === 'font-family') {
this.atRules.fontFace.push({
name: value,
name: this.stripQuotes(value),
node: node
});
}
}
} catch (err) {
_didIteratorError10 = true;
_iteratorError10 = err;
_didIteratorError11 = true;
_iteratorError11 = err;
} finally {
try {
if (!_iteratorNormalCompletion10 && _iterator10.return != null) {
_iterator10.return();
if (!_iteratorNormalCompletion11 && _iterator11.return != null) {
_iterator11.return();
}
} finally {
if (_didIteratorError10) {
throw _iteratorError10;
if (_didIteratorError11) {
throw _iteratorError11;
}
}
}
Expand Down Expand Up @@ -979,6 +1017,23 @@ function () {

return false;
}
/**
* Check if the node has a css comment to ignore current selector rule
* @param {object} rule Node of postcss abstract syntax tree
*/

}, {
key: "hasIgnoreAnnotation",
value: function hasIgnoreAnnotation(rule) {
var found = false;
rule.walkComments(function (node) {
if (node && node.type === 'comment' && node.text.includes(IGNORE_ANNOTATION_CURRENT)) {
found = true;
node.remove();
}
});
return found;
}
/**
* Check if the node correspond to an empty css rule
* @param {object} node Node of postcss abstract syntax tree
Expand All @@ -1002,13 +1057,13 @@ function () {
}, {
key: "shouldKeepSelector",
value: function shouldKeepSelector(selectorsInContent, selectorsInRule) {
var _iteratorNormalCompletion11 = true;
var _didIteratorError11 = false;
var _iteratorError11 = undefined;
var _iteratorNormalCompletion12 = true;
var _didIteratorError12 = false;
var _iteratorError12 = undefined;

try {
for (var _iterator11 = selectorsInRule[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
var selector = _step11.value;
for (var _iterator12 = selectorsInRule[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {
var selector = _step12.value;
// pseudo class
var unescapedSelector = selector.replace(/\\/g, '');

Expand All @@ -1027,16 +1082,16 @@ function () {
}
}
} catch (err) {
_didIteratorError11 = true;
_iteratorError11 = err;
_didIteratorError12 = true;
_iteratorError12 = err;
} finally {
try {
if (!_iteratorNormalCompletion11 && _iterator11.return != null) {
_iterator11.return();
if (!_iteratorNormalCompletion12 && _iterator12.return != null) {
_iterator12.return();
}
} finally {
if (_didIteratorError11) {
throw _iteratorError11;
if (_didIteratorError12) {
throw _iteratorError12;
}
}
}
Expand Down
107 changes: 81 additions & 26 deletions lib/purgecss.js
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ var defaultOptions = {
rejected: false
};

var IGNORE_ANNOTATION_CURRENT = 'purgecss ignore current';
var IGNORE_ANNOTATION_NEXT = 'purgecss ignore';
var IGNORE_ANNOTATION_START = 'purgecss start ignore';
var IGNORE_ANNOTATION_END = 'purgecss end ignore';
Expand Down Expand Up @@ -586,6 +587,16 @@ function () {
}
}
}
/**
* Strips quotes at the end and at the end of a string
* @param {string} value the string to be stripped
*/

}, {
key: "stripQuotes",
value: function stripQuotes(value) {
return value.replace(/(^["'])|(["']$)/g, '');
}
/**
* Extract the selectors present in the passed string using a purgecss extractor
* @param {array} content Array of content
Expand Down Expand Up @@ -791,6 +802,10 @@ function () {
return;
}

if (this.hasIgnoreAnnotation(node)) {
return;
}

var keepSelector = true;
node.selector = selectorParser(function (selectorsParsed) {
selectorsParsed.walk(function (selector) {
Expand Down Expand Up @@ -885,7 +900,30 @@ function () {

if (this.options.fontFace) {
if (prop === 'font-family') {
this.usedFontFaces.add(value);
var _iteratorNormalCompletion10 = true;
var _didIteratorError10 = false;
var _iteratorError10 = undefined;

try {
for (var _iterator10 = value.split(',')[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
var fontName = _step10.value;
var cleanedFontFace = this.stripQuotes(fontName.trim());
this.usedFontFaces.add(cleanedFontFace);
}
} catch (err) {
_didIteratorError10 = true;
_iteratorError10 = err;
} finally {
try {
if (!_iteratorNormalCompletion10 && _iterator10.return != null) {
_iterator10.return();
}
} finally {
if (_didIteratorError10) {
throw _iteratorError10;
}
}
}
}
}
}
Expand Down Expand Up @@ -924,34 +962,34 @@ function () {
}

if (this.options.fontFace && node.name === 'font-face') {
var _iteratorNormalCompletion10 = true;
var _didIteratorError10 = false;
var _iteratorError10 = undefined;
var _iteratorNormalCompletion11 = true;
var _didIteratorError11 = false;
var _iteratorError11 = undefined;

try {
for (var _iterator10 = node.nodes[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
var _step10$value = _step10.value,
prop = _step10$value.prop,
value = _step10$value.value;
for (var _iterator11 = node.nodes[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
var _step11$value = _step11.value,
prop = _step11$value.prop,
value = _step11$value.value;

if (prop === 'font-family') {
this.atRules.fontFace.push({
name: value,
name: this.stripQuotes(value),
node: node
});
}
}
} catch (err) {
_didIteratorError10 = true;
_iteratorError10 = err;
_didIteratorError11 = true;
_iteratorError11 = err;
} finally {
try {
if (!_iteratorNormalCompletion10 && _iterator10.return != null) {
_iterator10.return();
if (!_iteratorNormalCompletion11 && _iterator11.return != null) {
_iterator11.return();
}
} finally {
if (_didIteratorError10) {
throw _iteratorError10;
if (_didIteratorError11) {
throw _iteratorError11;
}
}
}
Expand Down Expand Up @@ -983,6 +1021,23 @@ function () {

return false;
}
/**
* Check if the node has a css comment to ignore current selector rule
* @param {object} rule Node of postcss abstract syntax tree
*/

}, {
key: "hasIgnoreAnnotation",
value: function hasIgnoreAnnotation(rule) {
var found = false;
rule.walkComments(function (node) {
if (node && node.type === 'comment' && node.text.includes(IGNORE_ANNOTATION_CURRENT)) {
found = true;
node.remove();
}
});
return found;
}
/**
* Check if the node correspond to an empty css rule
* @param {object} node Node of postcss abstract syntax tree
Expand All @@ -1006,13 +1061,13 @@ function () {
}, {
key: "shouldKeepSelector",
value: function shouldKeepSelector(selectorsInContent, selectorsInRule) {
var _iteratorNormalCompletion11 = true;
var _didIteratorError11 = false;
var _iteratorError11 = undefined;
var _iteratorNormalCompletion12 = true;
var _didIteratorError12 = false;
var _iteratorError12 = undefined;

try {
for (var _iterator11 = selectorsInRule[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
var selector = _step11.value;
for (var _iterator12 = selectorsInRule[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {
var selector = _step12.value;
// pseudo class
var unescapedSelector = selector.replace(/\\/g, '');

Expand All @@ -1031,16 +1086,16 @@ function () {
}
}
} catch (err) {
_didIteratorError11 = true;
_iteratorError11 = err;
_didIteratorError12 = true;
_iteratorError12 = err;
} finally {
try {
if (!_iteratorNormalCompletion11 && _iterator11.return != null) {
_iterator11.return();
if (!_iteratorNormalCompletion12 && _iterator12.return != null) {
_iterator12.return();
}
} finally {
if (_didIteratorError11) {
throw _iteratorError11;
if (_didIteratorError12) {
throw _iteratorError12;
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/constants/constants.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const IGNORE_ANNOTATION_CURRENT = 'purgecss ignore current'
export const IGNORE_ANNOTATION_NEXT = 'purgecss ignore'
export const IGNORE_ANNOTATION_START = 'purgecss start ignore'
export const IGNORE_ANNOTATION_END = 'purgecss end ignore'
Expand Down

0 comments on commit d08ca7e

Please sign in to comment.