Skip to content

Commit 04223f7

Browse files
committed
feat: add blocklist option
1 parent dc59d30 commit 04223f7

File tree

6 files changed

+84
-0
lines changed

6 files changed

+84
-0
lines changed

packages/purgecss/__tests__/safelist.test.ts

+24
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,27 @@ describe("safelist option: variables", () => {
176176
notFindInCSS(expect, ["--tertiary-color:"], purgedCSS);
177177
});
178178
});
179+
180+
describe("blocklist option", () => {
181+
let purgedCSS: string;
182+
beforeAll(async () => {
183+
const resultsPurge = await new PurgeCSS().purge({
184+
content: [`${ROOT_TEST_EXAMPLES}safelist/blocklist.html`],
185+
css: [`${ROOT_TEST_EXAMPLES}safelist/blocklist.css`],
186+
blocklist: ["h1", "yep", "button", /nav-/],
187+
});
188+
purgedCSS = resultsPurge[0].css;
189+
});
190+
191+
it("excludes blocklisted selectors", () => {
192+
notFindInCSS(
193+
expect,
194+
["h1", "yep", "button", "nav-blue", "nav-red"],
195+
purgedCSS
196+
);
197+
});
198+
199+
it("includes non-blocklisted selectors", () => {
200+
findInCSS(expect, ["data-v-test", ".random"], purgedCSS);
201+
});
202+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
h1 {
2+
color: blue;
3+
}
4+
5+
.random {
6+
color: green;
7+
}
8+
9+
#yep {
10+
color: red;
11+
}
12+
13+
button {
14+
color: rebeccapurple;
15+
}
16+
17+
.nav-blue {
18+
background-color: blue;
19+
}
20+
21+
.nav-red {
22+
background-color: red;
23+
}
24+
25+
[data-v-test] {
26+
color: green;
27+
}
28+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<html>
2+
3+
<body>
4+
<div class="nav-blue">is it blue?</div>
5+
<div class="nav-red">is it red?</div>
6+
<h1>Title</h1>
7+
<div class="random">random</div>
8+
<button id="yep" data-v-test="colorful">button</button>
9+
</body>
10+
11+
</html>

packages/purgecss/src/index.ts

+18
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,18 @@ class PurgeCSS {
554554
});
555555
}
556556

557+
/**
558+
* Check if the selector is blocklisted with the option blocklist
559+
* @param selector css selector
560+
*/
561+
private isSelectorBlocklisted(selector: string): boolean {
562+
return this.options.blocklist.some((blocklistItem) => {
563+
return typeof blocklistItem === "string"
564+
? blocklistItem === selector
565+
: blocklistItem.test(selector);
566+
});
567+
}
568+
557569
/**
558570
* Check if the selector is safelisted with the option safelist standard
559571
* @param selector css selector
@@ -718,6 +730,12 @@ class PurgeCSS {
718730
continue;
719731
}
720732

733+
// The selector is present in the blocklist
734+
if (selectorValue && this.isSelectorBlocklisted(selectorValue)) {
735+
isPresent = false;
736+
continue;
737+
}
738+
721739
switch (selectorNode.type) {
722740
case "attribute":
723741
// `value` is a dynamic attribute, highly used in input element

packages/purgecss/src/options.ts

+1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ export const defaultOptions: Options = {
1919
variables: [],
2020
keyframes: [],
2121
},
22+
blocklist: [],
2223
};

packages/purgecss/src/types/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export interface UserDefinedOptions {
6565
stdout?: boolean;
6666
variables?: boolean;
6767
safelist?: UserDefinedSafelist;
68+
blocklist?: StringRegExpArray;
6869
}
6970

7071
export interface Options {
@@ -80,6 +81,7 @@ export interface Options {
8081
stdout: boolean;
8182
variables: boolean;
8283
safelist: Required<ComplexSafelist>;
84+
blocklist: StringRegExpArray;
8385
}
8486

8587
export interface ResultPurge {

0 commit comments

Comments
 (0)