Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add whitelistPatternsGreedy option #424

Merged
merged 1 commit into from Jun 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 22 additions & 9 deletions docs/configuration.md
Expand Up @@ -51,6 +51,7 @@ interface UserDefinedOptions {
whitelist?: string[]
whitelistPatterns?: Array<RegExp>
whitelistPatternsChildren?: Array<RegExp>
whitelistPatternsGreedy?: Array<RegExp>
}

interface RawContent {
Expand Down Expand Up @@ -168,7 +169,7 @@ You can learn more about extractors [here](extractors.md).

- **fontFace \(default: false\)**

If there are any unused @font-face rules in your css, you can remove them by setting the `fontFace` option to `true`
If there are any unused @font-face rules in your css, you can remove them by setting the `fontFace` option to `true`.

```js
await new PurgeCSS().purge({
Expand All @@ -192,7 +193,7 @@ await new PurgeCSS().purge({

- **variables \(default: false\)**

If your are using Custom Properties (CSS variables), or a library using them such as Bootstrap, you can remove unused CSS variables by setting the `variables` option to `true`.
If you are using Custom Properties (CSS variables), or a library using them such as Bootstrap, you can remove unused CSS variables by setting the `variables` option to `true`.

```js
await new PurgeCSS().purge({
Expand All @@ -204,8 +205,7 @@ await new PurgeCSS().purge({

- **rejected \(default: false\)**

It can sometimes be more practical to scan through the removed list to see if there's anything obviously wrong.
If you want to do it, use the `rejected` option.
It can sometimes be more practical to scan through the removed list to see if there's anything obviously wrong. If you want to do it, use the `rejected` option.

```js
await new PurgeCSS().purge({
Expand All @@ -217,7 +217,7 @@ await new PurgeCSS().purge({

- **whitelist**

You can whitelist selectors to stop PurgeCSS from removing them from your CSS. This can be accomplished with the options `whitelist` and `whitelistPatterns`.
You can whitelist selectors to stop PurgeCSS from removing them from your CSS. This can be accomplished with the options `whitelist`, `whitelistPatterns`, `whitelistPatternsChildren`, and `whitelistPatternsGreedy`.

```js
const purgecss = await new PurgeCSS().purge({
Expand All @@ -227,7 +227,7 @@ const purgecss = await new PurgeCSS().purge({
})
```

In the example, the selectors `.random`, `#yep`, `button` will be left in the final CSS.
In this example, the selectors `.random`, `#yep`, `button` will be left in the final CSS.

- **whitelistPatterns**

Expand All @@ -241,11 +241,11 @@ const purgecss = await new PurgeCSS().purge({
})
```

In the example, selectors ending with `red` such as `.bg-red` will be left in the final CSS.
In this example, selectors ending with `red` such as `.bg-red` will be left in the final CSS.

- **whitelistPatternsChildren**

You can whitelist selectors based on a regular expression with `whitelistPatternsChildren`. Contrary to `whitelistPatterns`, it will also whitelist children of the selectors.
You can whitelist selectors and their children based on a regular expression with `whitelistPatternsChildren`.

```js
const purgecss = await new PurgeCSS().purge({
Expand All @@ -255,5 +255,18 @@ const purgecss = await new PurgeCSS().purge({
})
```

In the example, selectors such as `red p` or `.bg-red .child-of-bg` will be left in the final CSS.
In this example, selectors such as `.bg-red .child-of-bg` will be left in the final CSS, even if `child-of-bg` is not found.

- **whitelistPatternsGreedy**

Finally, you can whitelist whole selectors if any part of that selector matches a regular expression with `whitelistPatternsGreedy`.

```js
const purgecss = await new PurgeCSS().purge({
content: [], // content
css: [], // css
whitelistPatternsGreedy: [/red$/]
})
```

In this example, selectors such as `button.bg-red.nonexistent-class` will be left in the final CSS, even if `button` and `nonexistent-class` are not found.
10 changes: 8 additions & 2 deletions docs/plugins/webpack.md
Expand Up @@ -121,7 +121,7 @@ new PurgecssPlugin({
})
```

* #### whitelist, whitelistPatterns and whitelistPatternsChildren
* #### whitelist, whitelistPatterns, whitelistPatternsChildren, and whitelistPatternsGreedy

Similar as for the `paths` option, you can also define functions for the following options:

Expand All @@ -141,11 +141,17 @@ function collectWhitelistPatternsChildren() {
return [/^whitelisted-/];
}

function collectWhitelistPatternsGreedy() {
// do something to collect the whitelist
return [/^whitelisted-/];
}

// In the webpack configuration
new PurgecssPlugin({
whitelist: collectWhitelist,
whitelistPatterns: collectWhitelistPatterns,
whitelistPatternsChildren: collectWhitelistPatternsChildren
whitelistPatternsChildren: collectWhitelistPatternsChildren,
whitelistPatternsGreedy: collectWhitelistPatternsGreedy
})
```

Expand Down
9 changes: 5 additions & 4 deletions docs/whitelisting.md
Expand Up @@ -10,7 +10,7 @@ meta:

# Whitelisting

You can whitelist selectors to stop PurgeCSS from removing them from your CSS. This can be accomplished with the PurgeCSS options `whitelist`, `whitelistPatterns`, `whitelistPatternsChildren`, or directly in your CSS with a special comment.
You can whitelist selectors to stop PurgeCSS from removing them from your CSS. This can be accomplished with the PurgeCSS options `whitelist`, `whitelistPatterns`, `whitelistPatternsChildren`, `whitelistPatternsGreedy`, or directly in your CSS with a special comment.

## Specific selectors

Expand All @@ -28,18 +28,19 @@ In the example, the selectors `.random`, `#yep`, `button` will be left in the fi

## Patterns

You can whitelist selectors based on a regular expression with `whitelistPatterns` and `whitelistPatternsChildren`.
You can whitelist selectors based on a regular expression with `whitelistPatterns`, `whitelistPatternsChildren`, and `whitelistPatternsGreedy`.

```javascript
const purgecss = new Purgecss({
content: [], // content
css: [], // css
whitelistPatterns: [/red$/],
whitelistPatternsChildren: [/blue$/]
whitelistPatternsChildren: [/blue$/],
whitelistPatternsGreedy: [/yellow$/]
})
```

In the example, selectors ending with `red` such as `.bg-red`, and children of selectors ending with `blue` such as `blue p` or `.bg-blue .child-of-bg`, will be left in the final CSS.
In the example, selectors ending with `red` such as `.bg-red`, selectors ending with `blue` as well as their children such as `blue p` or `.bg-blue .child-of-bg`, and selectors that have any part ending with `yellow` such as `button.bg-yellow.other-class`, will be left in the final CSS.

Patterns are regular expressions. You can use [regexr](https://regexr.com) to verify the regular expressions correspond to what you are looking for.

Expand Down
1 change: 1 addition & 0 deletions packages/gulp-purgecss/src/types/index.ts
Expand Up @@ -24,4 +24,5 @@ export interface UserDefinedOptions {
whitelist?: string[];
whitelistPatterns?: Array<RegExp>;
whitelistPatternsChildren?: Array<RegExp>;
whitelistPatternsGreedy?: Array<RegExp>;
}
1 change: 1 addition & 0 deletions packages/postcss-purgecss/src/types/index.ts
Expand Up @@ -26,4 +26,5 @@ export interface UserDefinedOptions {
whitelist?: string[];
whitelistPatterns?: Array<RegExp>;
whitelistPatternsChildren?: Array<RegExp>;
whitelistPatternsGreedy?: Array<RegExp>;
}
10 changes: 8 additions & 2 deletions packages/purgecss-webpack-plugin/README.md
Expand Up @@ -157,7 +157,7 @@ new PurgecssPlugin({
})
```

* #### whitelist, whitelistPatterns and whitelistPatternsChildren
* #### whitelist, whitelistPatterns, whitelistPatternsChildren, and whitelistPatternsGreedy

Similar as for the `paths` option, you also can define functions for the these options:

Expand All @@ -176,11 +176,17 @@ function collectWhitelistPatternsChildren() {
return [/^whitelisted-/];
}

function collectWhitelistPatternsGreedy() {
// do something to collect the whitelist
return [/^whitelisted-/];
}

// In the webpack configuration
new PurgecssPlugin({
whitelist: collectWhitelist,
whitelistPatterns: collectWhitelistPatterns,
whitelistPatternsChildren: collectWhitelistPatternsChildren
whitelistPatternsChildren: collectWhitelistPatternsChildren,
whitelistPatternsGreedy: collectWhitelistPatternsGreedy
})
```

Expand Down
Expand Up @@ -42,6 +42,7 @@ module.exports = {
whitelist: () => ['whitelisted'],
whitelistPatterns: () => [/^whitelistedPat/],
whitelistPatternsChildren: () => [/^whitelistedPatternChildren/],
whitelistPatternsGreedy: () => [/^whitelistedPatternGreedy/],
extractors: [
{
extractor: customExtractor,
Expand Down
4 changes: 4 additions & 0 deletions packages/purgecss-webpack-plugin/src/index.ts
Expand Up @@ -116,6 +116,9 @@ export default class PurgeCSSPlugin {
if (typeof options.whitelistPatternsChildren === "function") {
options.whitelistPatternsChildren = options.whitelistPatternsChildren();
}
if (typeof options.whitelistPatternsGreedy === "function") {
options.whitelistPatternsGreedy = options.whitelistPatternsGreedy();
}

const purgecss = await new PurgeCSS().purge({
content: options.content,
Expand All @@ -130,6 +133,7 @@ export default class PurgeCSSPlugin {
whitelist: options.whitelist,
whitelistPatterns: options.whitelistPatterns,
whitelistPatternsChildren: options.whitelistPatternsChildren,
whitelistPatternsGreedy: options.whitelistPatternsGreedy,
});
const purged = purgecss[0];

Expand Down
1 change: 1 addition & 0 deletions packages/purgecss-webpack-plugin/src/types/index.ts
Expand Up @@ -31,6 +31,7 @@ export interface UserDefinedOptions {
whitelist?: string[] | WhitelistFunction;
whitelistPatterns?: Array<RegExp> | WhitelistPatternsFunction;
whitelistPatternsChildren?: Array<RegExp> | WhitelistPatternsFunction;
whitelistPatternsGreedy?: Array<RegExp> | WhitelistPatternsFunction;
only?: string[];
}

Expand Down
@@ -0,0 +1,6 @@
.card {}
.card[data-v-test] {}
.card.card--large {}
.card[data-v-test].card--large {}
.card .card-content {}
.card[data-v-test] .card-content {}
@@ -0,0 +1,5 @@
<html>
<body>
<div class="card"></div>
</body>
</html>
38 changes: 38 additions & 0 deletions packages/purgecss/__tests__/whitelist.test.ts
Expand Up @@ -87,3 +87,41 @@ describe("whitelistPatternsChildren", () => {
expect(purgedCSS.includes(".btn__green")).toBe(false);
});
});

describe("whitelistPatternsGreedy", () => {
let purgedCSS: string;
beforeAll(async () => {
const resultsPurge = await new PurgeCSS().purge({
content: [
`${root}whitelist_patterns_greedy/whitelist_patterns_greedy.html`,
],
css: [`${root}whitelist_patterns_greedy/whitelist_patterns_greedy.css`],
whitelistPatternsGreedy: [/data-v-.*/],
});
purgedCSS = resultsPurge[0].css;
});

it("finds card", () => {
expect(purgedCSS.includes(".card")).toBe(true);
});

it("finds card with data-v attribute", () => {
expect(purgedCSS.includes(".card[data-v-test]")).toBe(true);
});

it("excludes card--large", () => {
expect(purgedCSS.includes(".card.card--large")).toBe(false);
});

it("finds card--large with data-v attribute", () => {
expect(purgedCSS.includes(".card[data-v-test].card--large")).toBe(true);
});

it("excludes card-content", () => {
expect(purgedCSS.includes(".card .card-content")).toBe(false);
});

it("finds card-content inside card with data-v attribute", () => {
expect(purgedCSS.includes(".card[data-v-test] .card-content")).toBe(true);
});
});