purgecss 4.0.3 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,11 +1,10 @@
1
1
  # PurgeCSS
2
2
 
3
- ![David](https://img.shields.io/david/FullHuman/purgecss?path=packages%2Fpurgecss&style=for-the-badge)
4
- ![David](https://img.shields.io/david/dev/FullHuman/purgecss?path=packages%2Fpurgecss&style=for-the-badge)
5
- ![Dependabot](https://img.shields.io/badge/dependabot-enabled-%23024ea4?style=for-the-badge)
6
- ![npm](https://img.shields.io/npm/v/purgecss?style=for-the-badge)
7
- ![npm](https://img.shields.io/npm/dw/purgecss?style=for-the-badge)
3
+ [![npm](https://img.shields.io/npm/v/purgecss?style=for-the-badge)](https://www.npmjs.com/package/purgecss)
4
+ ![npm](https://img.shields.io/npm/dm/purgecss?style=for-the-badge)
8
5
  ![GitHub](https://img.shields.io/github/license/FullHuman/purgecss?style=for-the-badge)
6
+ ![Dependabot](https://img.shields.io/badge/dependabot-enabled-%23024ea4?style=for-the-badge)
7
+ [![Coverage Status](https://img.shields.io/coveralls/github/FullHuman/purgecss/main?style=for-the-badge)](https://coveralls.io/github/FullHuman/purgecss?branch=main)
9
8
 
10
9
  <p align="center">
11
10
  <img src="https://i.imgur.com/UEiUiJ0.png" height="200" width="200" alt="PurgeCSS logo"/>
@@ -0,0 +1 @@
1
+ export {};
package/bin/purgecss.js CHANGED
@@ -1,92 +1,2 @@
1
1
  #!/usr/bin/env node
2
- const program = require("commander");
3
- const fs = require("fs");
4
- const {
5
- default: PurgeCSS,
6
- defaultOptions,
7
- setOptions,
8
- standardizeSafelist,
9
- } = require("../lib/purgecss");
10
-
11
- async function writeCSSToFile(filePath, css) {
12
- try {
13
- await fs.promises.writeFile(filePath, css);
14
- } catch (err) {
15
- console.error(err.message);
16
- }
17
- }
18
-
19
- program
20
- .usage("--css <css...> --content <content...> [options]")
21
- .option("-con, --content <files...>", "glob of content files")
22
- .option("-css, --css <files...>", "glob of css files")
23
- .option("-c, --config <path>", "path to the configuration file")
24
- .option(
25
- "-o, --output <path>",
26
- "file path directory to write purged css files to"
27
- )
28
- .option("-font, --font-face", "option to remove unused font-faces")
29
- .option("-keyframes, --keyframes", "option to remove unused keyframes")
30
- .option("-rejected, --rejected", "option to output rejected selectors")
31
- .option(
32
- "-s, --safelist <list...>",
33
- "list of classes that should not be removed"
34
- )
35
- .option(
36
- "-b, --blocklist <list...>",
37
- "list of selectors that should be removed"
38
- )
39
- .option(
40
- "-k, --skippedContentGlobs <list...>",
41
- "list of glob patterns for folders/files that should not be scanned"
42
- );
43
-
44
- program.parse(process.argv);
45
-
46
- const run = async () => {
47
- // config file is not specified or the content and css are not,
48
- // PurgeCSS will not run
49
- if (!program.config && !(program.content && program.css)) {
50
- program.help();
51
- }
52
-
53
- // if the config file is present, use it
54
- // other options specified will override
55
- let options = defaultOptions;
56
- if (program.config) {
57
- options = await setOptions(program.config);
58
- }
59
- if (program.content) options.content = program.content;
60
- if (program.css) options.css = program.css;
61
- if (program.fontFace) options.fontFace = program.fontFace;
62
- if (program.keyframes) options.keyframes = program.keyframes;
63
- if (program.rejected) options.rejected = program.rejected;
64
- if (program.variables) options.variables = program.variables;
65
- if (program.safelist) options.safelist = standardizeSafelist(program.safelist);
66
- if (program.blocklist) options.blocklist = program.blocklist;
67
- if (program.skippedContentGlobs) options.skippedContentGlobs = program.skippedContentGlobs;
68
-
69
- const purged = await new PurgeCSS().purge(options);
70
- const output = options.output || program.output;
71
- // output results in specified directory
72
- if (output) {
73
- if (purged.length === 1 && output.endsWith(".css")) {
74
- await writeCSSToFile(output, purged[0].css);
75
- return;
76
- }
77
-
78
- for (const purgedResult of purged) {
79
- const fileName = purgedResult.file.split("/").pop();
80
- await writeCSSToFile(`${output}/${fileName}`, purgedResult.css);
81
- }
82
- } else {
83
- console.log(JSON.stringify(purged));
84
- }
85
- };
86
-
87
- try {
88
- run();
89
- } catch (error) {
90
- console.error(error.message);
91
- process.exit(1);
92
- }
2
+ "use strict";var e=require("commander"),t=require("fs"),s=require("glob"),r=require("path"),o=require("postcss"),i=require("postcss-selector-parser"),n=require("util");function a(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function c(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(s){if("default"!==s){var r=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(t,s,r.get?r:{enumerable:!0,get:function(){return e[s]}})}})),t.default=e,Object.freeze(t)}var l=c(t),u=a(t),d=a(s),f=a(r),h=c(o),p=a(i),m="4.0.3",g="Remove unused css selectors";function v(e,t){t&&t.forEach(e.add,e)}class y{constructor(e){this.undetermined=new Set,this.attrNames=new Set,this.attrValues=new Set,this.classes=new Set,this.ids=new Set,this.tags=new Set,this.merge(e)}merge(e){return Array.isArray(e)?v(this.undetermined,e):e instanceof y?(v(this.undetermined,e.undetermined),v(this.attrNames,e.attrNames),v(this.attrValues,e.attrValues),v(this.classes,e.classes),v(this.ids,e.ids),v(this.tags,e.tags)):(v(this.undetermined,e.undetermined),e.attributes&&(v(this.attrNames,e.attributes.names),v(this.attrValues,e.attributes.values)),v(this.classes,e.classes),v(this.ids,e.ids),v(this.tags,e.tags)),this}hasAttrName(e){return this.attrNames.has(e)||this.undetermined.has(e)}someAttrValue(e){for(const t of this.attrValues)if(e(t))return!0;for(const t of this.undetermined)if(e(t))return!0;return!1}hasAttrPrefix(e){return this.someAttrValue((t=>t.startsWith(e)))}hasAttrSuffix(e){return this.someAttrValue((t=>t.endsWith(e)))}hasAttrSubstr(e){return e.trim().split(" ").every((e=>this.someAttrValue((t=>t.includes(e)))))}hasAttrValue(e){return this.attrValues.has(e)||this.undetermined.has(e)}hasClass(e){return this.classes.has(e)||this.undetermined.has(e)}hasId(e){return this.ids.has(e)||this.undetermined.has(e)}hasTag(e){return this.tags.has(e)||this.undetermined.has(e)}}const b=["*","::-webkit-scrollbar","::selection",":root","::before","::after"],S={css:[],content:[],defaultExtractor:e=>e.match(/[A-Za-z0-9_-]+/g)||[],extractors:[],fontFace:!1,keyframes:!1,rejected:!1,rejectedCss:!1,stdin:!1,stdout:!1,variables:!1,safelist:{standard:[],deep:[],greedy:[],variables:[],keyframes:[]},blocklist:[],skippedContentGlobs:[],dynamicAttributes:[]};function w(e,t){const s=[];return e.replace(t,(function(){const t=arguments,r=Array.prototype.slice.call(t,0,-2);return r.input=t[t.length-1],r.index=t[t.length-2],s.push(r),e})),s}class k{constructor(e){this.nodes=[],this.isUsed=!1,this.value=e}}class F{constructor(){this.nodes=new Map,this.usedVariables=new Set,this.safelist=[]}addVariable(e){const{prop:t}=e;if(!this.nodes.has(t)){const s=new k(e);this.nodes.set(t,s)}}addVariableUsage(e,t){const{prop:s}=e,r=this.nodes.get(s);for(const e of t){const t=e[1];if(this.nodes.has(t)){const e=this.nodes.get(t);null==r||r.nodes.push(e)}}}addVariableUsageInProperties(e){for(const t of e){const e=t[1];this.usedVariables.add(e)}}setAsUsed(e){const t=[this.nodes.get(e)];for(;0!==t.length;){const e=t.pop();e&&!e.isUsed&&(e.isUsed=!0,t.push(...e.nodes))}}removeUnused(){for(const e of this.usedVariables){const t=this.nodes.get(e);if(t){w(t.value.value,/var\((.+?)[,)]/g).forEach((e=>{this.usedVariables.has(e[1])||this.usedVariables.add(e[1])}))}}for(const e of this.usedVariables)this.setAsUsed(e);for(const[e,t]of this.nodes)t.isUsed||this.isVariablesSafelisted(e)||t.value.remove()}isVariablesSafelisted(e){return this.safelist.some((t=>"string"==typeof t?t===e:t.test(e)))}}const V={access:n.promisify(l.access),readFile:n.promisify(l.readFile)};function A(e=[]){return Array.isArray(e)?{...S.safelist,standard:e}:{...S.safelist,...e}}async function j(e="purgecss.config.js"){let t;try{const s=f.default.resolve(process.cwd(),e);t=await function(e){return Promise.resolve().then((function(){return c(require(e))}))}(s)}catch(e){throw new Error(`Error loading the config file ${e.message}`)}return{...S,...t,safelist:A(t.safelist)}}async function x(e,t){return new y(await t(e))}function C(e,t){switch(t){case"next":return e.text.includes("purgecss ignore");case"start":return e.text.includes("purgecss start ignore");case"end":return e.text.includes("purgecss end ignore")}}function U(e){return!!(G(e)&&!e.selector||(null==e?void 0:e.nodes)&&!e.nodes.length||q(e)&&(!e.nodes&&!e.params||!e.params&&e.nodes&&!e.nodes.length))}function R(e){return e.replace(/(^["'])|(["']$)/g,"")}function N(e,t){if(!t.hasAttrName(e.attribute))return!1;if(void 0===e.value)return!0;switch(e.operator){case"$=":return t.hasAttrSuffix(e.value);case"~=":case"*=":return t.hasAttrSubstr(e.value);case"=":return t.hasAttrValue(e.value);case"|=":case"^=":return t.hasAttrPrefix(e.value);default:return!0}}function E(e,t){return t.hasId(e.value)}function P(e,t){return t.hasTag(e.value)}function q(e){return"atrule"===(null==e?void 0:e.type)}function G(e){return"rule"===(null==e?void 0:e.type)}class O{constructor(){this.ignore=!1,this.atRules={fontFace:[],keyframes:[]},this.usedAnimations=new Set,this.usedFontFaces=new Set,this.selectorsRemoved=new Set,this.removedNodes=[],this.variablesStructure=new F,this.options=S}collectDeclarationsData(e){const{prop:t,value:s}=e;if(this.options.variables){const r=w(s,/var\((.+?)[,)]/g);t.startsWith("--")?(this.variablesStructure.addVariable(e),r.length>0&&this.variablesStructure.addVariableUsage(e,r)):r.length>0&&this.variablesStructure.addVariableUsageInProperties(r)}if(!this.options.keyframes||"animation"!==t&&"animation-name"!==t)if(this.options.fontFace){if("font-family"===t)for(const e of s.split(",")){const t=R(e.trim());this.usedFontFaces.add(t)}}else;else for(const e of s.split(/[\s,]+/))this.usedAnimations.add(e)}getFileExtractor(e,t){const s=t.find((t=>t.extensions.find((t=>e.endsWith(t)))));return void 0===s?this.options.defaultExtractor:s.extractor}async extractSelectorsFromFiles(e,t){const s=new y([]);for(const r of e){let e=[];try{await V.access(r,l.constants.F_OK),e.push(r)}catch(t){e=d.default.sync(r,{nodir:!0,ignore:this.options.skippedContentGlobs})}for(const r of e){const e=await V.readFile(r,"utf-8"),o=this.getFileExtractor(r,t),i=await x(e,o);s.merge(i)}}return s}async extractSelectorsFromString(e,t){const s=new y([]);for(const{raw:r,extension:o}of e){const e=this.getFileExtractor(`.${o}`,t),i=await x(r,e);s.merge(i)}return s}evaluateAtRule(e){if(this.options.keyframes&&e.name.endsWith("keyframes"))this.atRules.keyframes.push(e);else if(this.options.fontFace&&"font-face"===e.name&&e.nodes)for(const t of e.nodes)"decl"===t.type&&"font-family"===t.prop&&this.atRules.fontFace.push({name:R(t.value),node:e})}evaluateRule(e,t){if(this.ignore)return;const s=e.prev();if(function(e){return"comment"===(null==e?void 0:e.type)}(s)&&C(s,"next"))return void s.remove();if(e.parent&&q(e.parent)&&e.parent.name.endsWith("keyframes"))return;if(!G(e))return;if(function(e){let t=!1;return e.walkComments((e=>{e&&"comment"===e.type&&e.text.includes("purgecss ignore current")&&(t=!0,e.remove())})),t}(e))return;let r=!0;const o=e.selector;if(e.selector=p.default((e=>{e.walk((e=>{"selector"===e.type&&(r=this.shouldKeepSelector(e,t),r||(this.options.rejected&&this.selectorsRemoved.add(e.toString()),e.remove()))}))})).processSync(e.selector),r&&void 0!==e.nodes)for(const t of e.nodes)"decl"===t.type&&this.collectDeclarationsData(t);const i=e.parent;if(!e.selector&&(e.remove(),this.options.rejectedCss))if(e.selector=o,i&&U(i)){const t=i.clone();t.append(e),this.removedNodes.push(t)}else this.removedNodes.push(e);U(i)&&(null==i||i.remove())}async getPurgedCSS(e,t){const s=[],r=[];for(const t of e)"string"==typeof t?r.push(...d.default.sync(t,{nodir:!0,ignore:this.options.skippedContentGlobs})):r.push(t);for(const e of r){const r="string"==typeof e?this.options.stdin?e:await V.readFile(e,"utf-8"):e.raw,o=h.parse(r);this.walkThroughCSS(o,t),this.options.fontFace&&this.removeUnusedFontFaces(),this.options.keyframes&&this.removeUnusedKeyframes(),this.options.variables&&this.removeUnusedCSSVariables();const i={css:o.toString(),file:"string"==typeof e?e:e.name};this.options.rejected&&(i.rejected=Array.from(this.selectorsRemoved),this.selectorsRemoved.clear()),this.options.rejectedCss&&(i.rejectedCss=h.root({nodes:this.removedNodes}).toString()),s.push(i)}return s}isKeyframesSafelisted(e){return this.options.safelist.keyframes.some((t=>"string"==typeof t?t===e:t.test(e)))}isSelectorBlocklisted(e){return this.options.blocklist.some((t=>"string"==typeof t?t===e:t.test(e)))}isSelectorSafelisted(e){const t=this.options.safelist.standard.some((t=>"string"==typeof t?t===e:t.test(e)));return b.includes(e)||t}isSelectorSafelistedDeep(e){return this.options.safelist.deep.some((t=>t.test(e)))}isSelectorSafelistedGreedy(e){return this.options.safelist.greedy.some((t=>t.test(e)))}async purge(e){this.options="object"!=typeof e?await j(e):{...S,...e,safelist:A(e.safelist)};const{content:t,css:s,extractors:r,safelist:o}=this.options;this.options.variables&&(this.variablesStructure.safelist=o.variables||[]);const i=t.filter((e=>"string"==typeof e)),n=t.filter((e=>"object"==typeof e)),a=await this.extractSelectorsFromFiles(i,r),c=await this.extractSelectorsFromString(n,r);return this.getPurgedCSS(s,function(...e){const t=new y([]);return e.forEach(t.merge,t),t}(a,c))}removeUnusedCSSVariables(){this.variablesStructure.removeUnused()}removeUnusedFontFaces(){for(const{name:e,node:t}of this.atRules.fontFace)this.usedFontFaces.has(e)||t.remove()}removeUnusedKeyframes(){for(const e of this.atRules.keyframes)this.usedAnimations.has(e.params)||this.isKeyframesSafelisted(e.params)||e.remove()}getSelectorValue(e){return"attribute"===e.type&&e.attribute||e.value}shouldKeepSelector(e,t){if(function(e){return e.parent&&"pseudo"===e.parent.type&&e.parent.value.startsWith(":")||!1}(e))return!0;if(this.options.safelist.greedy.length>0){if(e.nodes.map(this.getSelectorValue).some((e=>e&&this.isSelectorSafelistedGreedy(e))))return!0}let s=!1;for(const o of e.nodes){const e=this.getSelectorValue(o);if(e&&this.isSelectorSafelistedDeep(e))return!0;if(e&&(b.includes(e)||this.isSelectorSafelisted(e)))s=!0;else{if(e&&this.isSelectorBlocklisted(e))return!1;switch(o.type){case"attribute":s=!![...this.options.dynamicAttributes,"value","checked","selected","open"].includes(o.attribute)||N(o,t);break;case"class":r=o,s=t.hasClass(r.value);break;case"id":s=E(o,t);break;case"tag":s=P(o,t);break;default:continue}if(!s)return!1}}var r;return s}walkThroughCSS(e,t){e.walk((e=>"rule"===e.type?this.evaluateRule(e,t):"atrule"===e.type?this.evaluateAtRule(e):void("comment"===e.type&&(C(e,"start")?(this.ignore=!0,e.remove()):C(e,"end")&&(this.ignore=!1,e.remove())))))}}async function W(e,t){try{await u.default.promises.writeFile(e,t)}catch(e){console.error(e.message)}}try{!async function(){var t;e.program.description(g).version(m).usage("--css <css...> --content <content...> [options]"),e.program.option("-con, --content <files...>","glob of content files").option("-css, --css <files...>","glob of css files").option("-c, --config <path>","path to the configuration file").option("-o, --output <path>","file path directory to write purged css files to").option("-font, --font-face","option to remove unused font-faces").option("-keyframes, --keyframes","option to remove unused keyframes").option("-v, --variables","option to remove unused variables").option("-rejected, --rejected","option to output rejected selectors").option("-rejected-css, --rejected-css","option to output rejected css").option("-s, --safelist <list...>","list of classes that should not be removed").option("-b, --blocklist <list...>","list of selectors that should be removed").option("-k, --skippedContentGlobs <list...>","list of glob patterns for folders/files that should not be scanned"),e.program.parse(process.argv);const{config:s,css:r,content:o,output:i,fontFace:n,keyframes:a,variables:c,rejected:l,rejectedCss:u,safelist:d,blocklist:f,skippedContentGlobs:h}=e.program.opts();s||o&&r||e.program.help();let p=S;s&&(p=await j(s)),o&&(p.content=o),r&&(p.css=r),n&&(p.fontFace=n),a&&(p.keyframes=a),l&&(p.rejected=l),u&&(p.rejectedCss=u),c&&(p.variables=c),d&&(p.safelist=A(d)),f&&(p.blocklist=f),h&&(p.skippedContentGlobs=h);const v=await(new O).purge(p),y=p.output||i;if(y){if(1===v.length&&y.endsWith(".css"))return void await W(y,v[0].css);for(const e of v){const s=null===(t=null==e?void 0:e.file)||void 0===t?void 0:t.split("/").pop();await W(`${i}/${s}`,e.css)}}else console.log(JSON.stringify(v))}()}catch(e){console.error(e.message),process.exit(1)}
package/lib/purgecss.d.ts CHANGED
@@ -1,10 +1,19 @@
1
1
  import * as postcss from "postcss";
2
+ type PostCSSRoot = postcss.Root;
3
+ interface AtRules {
4
+ fontFace: Array<{
5
+ name: string;
6
+ node: postcss.AtRule;
7
+ }>;
8
+ keyframes: postcss.AtRule[];
9
+ }
2
10
  interface RawContent<T = string> {
3
11
  extension: string;
4
12
  raw: T;
5
13
  }
6
14
  interface RawCSS {
7
15
  raw: string;
16
+ name?: string;
8
17
  }
9
18
  interface ExtractorResultDetailed {
10
19
  attributes: {
@@ -22,6 +31,7 @@ interface Extractors {
22
31
  extensions: string[];
23
32
  extractor: ExtractorFunction;
24
33
  }
34
+ type IgnoreType = "end" | "start" | "next";
25
35
  type StringRegExpArray = Array<RegExp | string>;
26
36
  type ComplexSafelist = {
27
37
  standard?: StringRegExpArray;
@@ -40,6 +50,7 @@ interface UserDefinedOptions {
40
50
  keyframes?: boolean;
41
51
  output?: string;
42
52
  rejected?: boolean;
53
+ rejectedCss?: boolean;
43
54
  stdin?: boolean;
44
55
  stdout?: boolean;
45
56
  variables?: boolean;
@@ -57,6 +68,7 @@ interface Options {
57
68
  keyframes: boolean;
58
69
  output?: string;
59
70
  rejected: boolean;
71
+ rejectedCss: boolean;
60
72
  stdin: boolean;
61
73
  stdout: boolean;
62
74
  variables: boolean;
@@ -67,6 +79,7 @@ interface Options {
67
79
  }
68
80
  interface ResultPurge {
69
81
  css: string;
82
+ rejectedCss?: string;
70
83
  file?: string;
71
84
  rejected?: string[];
72
85
  }
@@ -108,6 +121,7 @@ declare class PurgeCSS {
108
121
  private usedAnimations;
109
122
  private usedFontFaces;
110
123
  selectorsRemoved: Set<string>;
124
+ removedNodes: postcss.Node[];
111
125
  private variablesStructure;
112
126
  options: Options;
113
127
  private collectDeclarationsData;
@@ -278,6 +292,6 @@ declare class PurgeCSS {
278
292
  * @param root root node of the postcss AST
279
293
  * @param selectors selectors used in content files
280
294
  */
281
- walkThroughCSS(root: postcss.Root, selectors: ExtractorResultSets): void;
295
+ walkThroughCSS(root: PostCSSRoot, selectors: ExtractorResultSets): void;
282
296
  }
283
- export { PurgeCSS as default, PurgeCSS, defaultOptions, standardizeSafelist, setOptions, mergeExtractorSelectors };
297
+ export { PurgeCSS as default, PurgeCSS, defaultOptions, PostCSSRoot, AtRules, RawContent, RawCSS, ExtractorResultDetailed, ExtractorResult, ExtractorFunction, Extractors, IgnoreType, StringRegExpArray, ComplexSafelist, UserDefinedSafelist, UserDefinedOptions, Options, ResultPurge, standardizeSafelist, setOptions, mergeExtractorSelectors };
@@ -1,10 +1,19 @@
1
1
  import * as postcss from "postcss";
2
+ type PostCSSRoot = postcss.Root;
3
+ interface AtRules {
4
+ fontFace: Array<{
5
+ name: string;
6
+ node: postcss.AtRule;
7
+ }>;
8
+ keyframes: postcss.AtRule[];
9
+ }
2
10
  interface RawContent<T = string> {
3
11
  extension: string;
4
12
  raw: T;
5
13
  }
6
14
  interface RawCSS {
7
15
  raw: string;
16
+ name?: string;
8
17
  }
9
18
  interface ExtractorResultDetailed {
10
19
  attributes: {
@@ -22,6 +31,7 @@ interface Extractors {
22
31
  extensions: string[];
23
32
  extractor: ExtractorFunction;
24
33
  }
34
+ type IgnoreType = "end" | "start" | "next";
25
35
  type StringRegExpArray = Array<RegExp | string>;
26
36
  type ComplexSafelist = {
27
37
  standard?: StringRegExpArray;
@@ -40,6 +50,7 @@ interface UserDefinedOptions {
40
50
  keyframes?: boolean;
41
51
  output?: string;
42
52
  rejected?: boolean;
53
+ rejectedCss?: boolean;
43
54
  stdin?: boolean;
44
55
  stdout?: boolean;
45
56
  variables?: boolean;
@@ -57,6 +68,7 @@ interface Options {
57
68
  keyframes: boolean;
58
69
  output?: string;
59
70
  rejected: boolean;
71
+ rejectedCss: boolean;
60
72
  stdin: boolean;
61
73
  stdout: boolean;
62
74
  variables: boolean;
@@ -67,6 +79,7 @@ interface Options {
67
79
  }
68
80
  interface ResultPurge {
69
81
  css: string;
82
+ rejectedCss?: string;
70
83
  file?: string;
71
84
  rejected?: string[];
72
85
  }
@@ -108,6 +121,7 @@ declare class PurgeCSS {
108
121
  private usedAnimations;
109
122
  private usedFontFaces;
110
123
  selectorsRemoved: Set<string>;
124
+ removedNodes: postcss.Node[];
111
125
  private variablesStructure;
112
126
  options: Options;
113
127
  private collectDeclarationsData;
@@ -278,6 +292,6 @@ declare class PurgeCSS {
278
292
  * @param root root node of the postcss AST
279
293
  * @param selectors selectors used in content files
280
294
  */
281
- walkThroughCSS(root: postcss.Root, selectors: ExtractorResultSets): void;
295
+ walkThroughCSS(root: PostCSSRoot, selectors: ExtractorResultSets): void;
282
296
  }
283
- export { PurgeCSS as default, PurgeCSS, defaultOptions, standardizeSafelist, setOptions, mergeExtractorSelectors };
297
+ export { PurgeCSS as default, PurgeCSS, defaultOptions, PostCSSRoot, AtRules, RawContent, RawCSS, ExtractorResultDetailed, ExtractorResult, ExtractorFunction, Extractors, IgnoreType, StringRegExpArray, ComplexSafelist, UserDefinedSafelist, UserDefinedOptions, Options, ResultPurge, standardizeSafelist, setOptions, mergeExtractorSelectors };
@@ -1 +1 @@
1
- import{access as e,readFile as t,constants as s}from"fs";import r from"glob";import i from"path";import{parse as a}from"postcss";import n from"postcss-selector-parser";import{promisify as o}from"util";function c(e,t){t&&t.forEach(e.add,e)}class l{constructor(e){this.undetermined=new Set,this.attrNames=new Set,this.attrValues=new Set,this.classes=new Set,this.ids=new Set,this.tags=new Set,this.merge(e)}merge(e){return Array.isArray(e)?c(this.undetermined,e):e instanceof l?(c(this.undetermined,e.undetermined),c(this.attrNames,e.attrNames),c(this.attrValues,e.attrValues),c(this.classes,e.classes),c(this.ids,e.ids),c(this.tags,e.tags)):(c(this.undetermined,e.undetermined),e.attributes&&(c(this.attrNames,e.attributes.names),c(this.attrValues,e.attributes.values)),c(this.classes,e.classes),c(this.ids,e.ids),c(this.tags,e.tags)),this}hasAttrName(e){return this.attrNames.has(e)||this.undetermined.has(e)}someAttrValue(e){for(const t of this.attrValues)if(e(t))return!0;for(const t of this.undetermined)if(e(t))return!0;return!1}hasAttrPrefix(e){return this.someAttrValue((t=>t.startsWith(e)))}hasAttrSuffix(e){return this.someAttrValue((t=>t.endsWith(e)))}hasAttrSubstr(e){return e.trim().split(" ").every((e=>this.someAttrValue((t=>t.includes(e)))))}hasAttrValue(e){return this.attrValues.has(e)||this.undetermined.has(e)}hasClass(e){return this.classes.has(e)||this.undetermined.has(e)}hasId(e){return this.ids.has(e)||this.undetermined.has(e)}hasTag(e){return this.tags.has(e)||this.undetermined.has(e)}}const u=["*","::-webkit-scrollbar","::selection",":root","::before","::after"],h={css:[],content:[],defaultExtractor:e=>e.match(/[A-Za-z0-9_-]+/g)||[],extractors:[],fontFace:!1,keyframes:!1,rejected:!1,stdin:!1,stdout:!1,variables:!1,safelist:{standard:[],deep:[],greedy:[],variables:[],keyframes:[]},blocklist:[],skippedContentGlobs:[],dynamicAttributes:[]};class d{constructor(e){this.nodes=[],this.isUsed=!1,this.value=e}}class f{constructor(){this.nodes=new Map,this.usedVariables=new Set,this.safelist=[]}addVariable(e){const{prop:t}=e;if(!this.nodes.has(t)){const s=new d(e);this.nodes.set(t,s)}}addVariableUsage(e,t){const{prop:s}=e,r=this.nodes.get(s);for(const e of t){const t=e[1];if(this.nodes.has(t)){const e=this.nodes.get(t);null==r||r.nodes.push(e)}}}addVariableUsageInProperties(e){for(const t of e){const e=t[1];this.usedVariables.add(e)}}setAsUsed(e){const t=[this.nodes.get(e)];for(;0!==t.length;){const e=t.pop();e&&!e.isUsed&&(e.isUsed=!0,t.push(...e.nodes))}}removeUnused(){for(const e of this.usedVariables)this.setAsUsed(e);for(const[e,t]of this.nodes)t.isUsed||this.isVariablesSafelisted(e)||t.value.remove()}isVariablesSafelisted(e){return this.safelist.some((t=>"string"==typeof t?t===e:t.test(e)))}}const p={access:o(e),readFile:o(t)};function m(e=[]){return Array.isArray(e)?{...h.safelist,standard:e}:{...h.safelist,...e}}async function g(e="purgecss.config.js"){let t;try{const s=i.join(process.cwd(),e);t=await import(s)}catch(e){throw new Error("Error loading the config file "+e.message)}return{...h,...t,safelist:m(t.safelist)}}async function v(e,t){return new l(await t(e))}function y(e,t){switch(t){case"next":return e.text.includes("purgecss ignore");case"start":return e.text.includes("purgecss start ignore");case"end":return e.text.includes("purgecss end ignore")}}function S(...e){const t=new l([]);return e.forEach(t.merge,t),t}function b(e){return e.replace(/(^["'])|(["']$)/g,"")}function w(e,t){if(!t.hasAttrName(e.attribute))return!1;if(void 0===e.value)return!0;switch(e.operator){case"$=":return t.hasAttrSuffix(e.value);case"~=":case"*=":return t.hasAttrSubstr(e.value);case"=":return t.hasAttrValue(e.value);case"|=":case"^=":return t.hasAttrPrefix(e.value);default:return!0}}function A(e,t){return t.hasId(e.value)}function F(e,t){return t.hasTag(e.value)}function k(e){return"atrule"===(null==e?void 0:e.type)}function V(e){return"rule"===(null==e?void 0:e.type)}class x{constructor(){this.ignore=!1,this.atRules={fontFace:[],keyframes:[]},this.usedAnimations=new Set,this.usedFontFaces=new Set,this.selectorsRemoved=new Set,this.variablesStructure=new f,this.options=h}collectDeclarationsData(e){const{prop:t,value:s}=e;if(this.options.variables){const r=function(e,t){const s=[];return e.replace(t,(function(){const t=arguments,r=Array.prototype.slice.call(t,0,-2);return r.input=t[t.length-1],r.index=t[t.length-2],s.push(r),e})),s}(s,/var\((.+?)[,)]/g);t.startsWith("--")?(this.variablesStructure.addVariable(e),r.length>0&&this.variablesStructure.addVariableUsage(e,r)):r.length>0&&this.variablesStructure.addVariableUsageInProperties(r)}if(!this.options.keyframes||"animation"!==t&&"animation-name"!==t)if(this.options.fontFace){if("font-family"===t)for(const e of s.split(",")){const t=b(e.trim());this.usedFontFaces.add(t)}}else;else for(const e of s.split(/[\s,]+/))this.usedAnimations.add(e)}getFileExtractor(e,t){const s=t.find((t=>t.extensions.find((t=>e.endsWith(t)))));return void 0===s?this.options.defaultExtractor:s.extractor}async extractSelectorsFromFiles(e,t){const i=new l([]);for(const a of e){let e=[];try{await p.access(a,s.F_OK),e.push(a)}catch(t){e=r.sync(a,{nodir:!0,ignore:this.options.skippedContentGlobs})}for(const s of e){const e=await p.readFile(s,"utf-8"),r=this.getFileExtractor(s,t),a=await v(e,r);i.merge(a)}}return i}async extractSelectorsFromString(e,t){const s=new l([]);for(const{raw:r,extension:i}of e){const e=this.getFileExtractor("."+i,t),a=await v(r,e);s.merge(a)}return s}evaluateAtRule(e){if(this.options.keyframes&&e.name.endsWith("keyframes"))this.atRules.keyframes.push(e);else if(this.options.fontFace&&"font-face"===e.name&&e.nodes)for(const t of e.nodes)"decl"===t.type&&"font-family"===t.prop&&this.atRules.fontFace.push({name:b(t.value),node:e})}async evaluateRule(e,t){if(this.ignore)return;const s=e.prev();if(function(e){return"comment"===(null==e?void 0:e.type)}(s)&&y(s,"next"))return void s.remove();if(e.parent&&k(e.parent)&&"keyframes"===e.parent.name)return;if(!V(e))return;if(function(e){let t=!1;return e.walkComments((e=>{e&&"comment"===e.type&&e.text.includes("purgecss ignore current")&&(t=!0,e.remove())})),t}(e))return;let r=!0;if(e.selector=n((e=>{e.walk((e=>{"selector"===e.type&&(r=this.shouldKeepSelector(e,t),r||(this.options.rejected&&this.selectorsRemoved.add(e.toString()),e.remove()))}))})).processSync(e.selector),r&&void 0!==e.nodes)for(const t of e.nodes)"decl"===t.type&&this.collectDeclarationsData(t);const i=e.parent;e.selector||e.remove(),function(e){return!!(V(e)&&!e.selector||(null==e?void 0:e.nodes)&&!e.nodes.length||k(e)&&(!e.nodes&&!e.params||!e.params&&e.nodes&&!e.nodes.length))}(i)&&(null==i||i.remove())}async getPurgedCSS(e,t){const s=[],i=[];for(const t of e)"string"==typeof t?i.push(...r.sync(t,{nodir:!0,ignore:this.options.skippedContentGlobs})):i.push(t);for(const e of i){const r="string"==typeof e?this.options.stdin?e:await p.readFile(e,"utf-8"):e.raw,i=a(r);this.walkThroughCSS(i,t),this.options.fontFace&&this.removeUnusedFontFaces(),this.options.keyframes&&this.removeUnusedKeyframes(),this.options.variables&&this.removeUnusedCSSVariables();const n={css:i.toString(),file:"string"==typeof e?e:void 0};"string"==typeof e&&(n.file=e),this.options.rejected&&(n.rejected=Array.from(this.selectorsRemoved),this.selectorsRemoved.clear()),s.push(n)}return s}isKeyframesSafelisted(e){return this.options.safelist.keyframes.some((t=>"string"==typeof t?t===e:t.test(e)))}isSelectorBlocklisted(e){return this.options.blocklist.some((t=>"string"==typeof t?t===e:t.test(e)))}isSelectorSafelisted(e){const t=this.options.safelist.standard.some((t=>"string"==typeof t?t===e:t.test(e)));return u.includes(e)||t}isSelectorSafelistedDeep(e){return this.options.safelist.deep.some((t=>t.test(e)))}isSelectorSafelistedGreedy(e){return this.options.safelist.greedy.some((t=>t.test(e)))}async purge(e){this.options="object"!=typeof e?await g(e):{...h,...e,safelist:m(e.safelist)};const{content:t,css:s,extractors:r,safelist:i}=this.options;this.options.variables&&(this.variablesStructure.safelist=i.variables||[]);const a=t.filter((e=>"string"==typeof e)),n=t.filter((e=>"object"==typeof e)),o=await this.extractSelectorsFromFiles(a,r),c=await this.extractSelectorsFromString(n,r);return this.getPurgedCSS(s,S(o,c))}removeUnusedCSSVariables(){this.variablesStructure.removeUnused()}removeUnusedFontFaces(){for(const{name:e,node:t}of this.atRules.fontFace)this.usedFontFaces.has(e)||t.remove()}removeUnusedKeyframes(){for(const e of this.atRules.keyframes)this.usedAnimations.has(e.params)||this.isKeyframesSafelisted(e.params)||e.remove()}getSelectorValue(e){return"attribute"===e.type&&e.attribute||e.value}shouldKeepSelector(e,t){if(function(e){return e.parent&&"pseudo"===e.parent.type&&e.parent.value.startsWith(":")||!1}(e))return!0;if(this.options.safelist.greedy.length>0){if(e.nodes.map(this.getSelectorValue).some((e=>e&&this.isSelectorSafelistedGreedy(e))))return!0}let s=!1;for(const i of e.nodes){const e=this.getSelectorValue(i);if(e&&this.isSelectorSafelistedDeep(e))return!0;if(e&&(u.includes(e)||this.isSelectorSafelisted(e)))s=!0;else{if(e&&this.isSelectorBlocklisted(e))return!1;switch(i.type){case"attribute":s=!![...this.options.dynamicAttributes,"value","checked","selected","open"].includes(i.attribute)||w(i,t);break;case"class":r=i,s=t.hasClass(r.value);break;case"id":s=A(i,t);break;case"tag":s=F(i,t);break;default:continue}if(!s)return!1}}var r;return s}walkThroughCSS(e,t){e.walk((e=>"rule"===e.type?this.evaluateRule(e,t):"atrule"===e.type?this.evaluateAtRule(e):void("comment"===e.type&&(y(e,"start")?(this.ignore=!0,e.remove()):y(e,"end")&&(this.ignore=!1,e.remove())))))}}export default x;export{x as PurgeCSS,h as defaultOptions,S as mergeExtractorSelectors,g as setOptions,m as standardizeSafelist};
1
+ import*as e from"fs";import t from"glob";import s from"path";import*as r from"postcss";import i from"postcss-selector-parser";import{promisify as a}from"util";function o(e,t){t&&t.forEach(e.add,e)}class n{constructor(e){this.undetermined=new Set,this.attrNames=new Set,this.attrValues=new Set,this.classes=new Set,this.ids=new Set,this.tags=new Set,this.merge(e)}merge(e){return Array.isArray(e)?o(this.undetermined,e):e instanceof n?(o(this.undetermined,e.undetermined),o(this.attrNames,e.attrNames),o(this.attrValues,e.attrValues),o(this.classes,e.classes),o(this.ids,e.ids),o(this.tags,e.tags)):(o(this.undetermined,e.undetermined),e.attributes&&(o(this.attrNames,e.attributes.names),o(this.attrValues,e.attributes.values)),o(this.classes,e.classes),o(this.ids,e.ids),o(this.tags,e.tags)),this}hasAttrName(e){return this.attrNames.has(e)||this.undetermined.has(e)}someAttrValue(e){for(const t of this.attrValues)if(e(t))return!0;for(const t of this.undetermined)if(e(t))return!0;return!1}hasAttrPrefix(e){return this.someAttrValue((t=>t.startsWith(e)))}hasAttrSuffix(e){return this.someAttrValue((t=>t.endsWith(e)))}hasAttrSubstr(e){return e.trim().split(" ").every((e=>this.someAttrValue((t=>t.includes(e)))))}hasAttrValue(e){return this.attrValues.has(e)||this.undetermined.has(e)}hasClass(e){return this.classes.has(e)||this.undetermined.has(e)}hasId(e){return this.ids.has(e)||this.undetermined.has(e)}hasTag(e){return this.tags.has(e)||this.undetermined.has(e)}}const c=["*","::-webkit-scrollbar","::selection",":root","::before","::after"],l={css:[],content:[],defaultExtractor:e=>e.match(/[A-Za-z0-9_-]+/g)||[],extractors:[],fontFace:!1,keyframes:!1,rejected:!1,rejectedCss:!1,stdin:!1,stdout:!1,variables:!1,safelist:{standard:[],deep:[],greedy:[],variables:[],keyframes:[]},blocklist:[],skippedContentGlobs:[],dynamicAttributes:[]};function u(e,t){const s=[];return e.replace(t,(function(){const t=arguments,r=Array.prototype.slice.call(t,0,-2);return r.input=t[t.length-1],r.index=t[t.length-2],s.push(r),e})),s}class d{constructor(e){this.nodes=[],this.isUsed=!1,this.value=e}}class h{constructor(){this.nodes=new Map,this.usedVariables=new Set,this.safelist=[]}addVariable(e){const{prop:t}=e;if(!this.nodes.has(t)){const s=new d(e);this.nodes.set(t,s)}}addVariableUsage(e,t){const{prop:s}=e,r=this.nodes.get(s);for(const e of t){const t=e[1];if(this.nodes.has(t)){const e=this.nodes.get(t);null==r||r.nodes.push(e)}}}addVariableUsageInProperties(e){for(const t of e){const e=t[1];this.usedVariables.add(e)}}setAsUsed(e){const t=[this.nodes.get(e)];for(;0!==t.length;){const e=t.pop();e&&!e.isUsed&&(e.isUsed=!0,t.push(...e.nodes))}}removeUnused(){for(const e of this.usedVariables){const t=this.nodes.get(e);if(t){u(t.value.value,/var\((.+?)[,)]/g).forEach((e=>{this.usedVariables.has(e[1])||this.usedVariables.add(e[1])}))}}for(const e of this.usedVariables)this.setAsUsed(e);for(const[e,t]of this.nodes)t.isUsed||this.isVariablesSafelisted(e)||t.value.remove()}isVariablesSafelisted(e){return this.safelist.some((t=>"string"==typeof t?t===e:t.test(e)))}}const f={access:a(e.access),readFile:a(e.readFile)};function p(e=[]){return Array.isArray(e)?{...l.safelist,standard:e}:{...l.safelist,...e}}async function m(e="purgecss.config.js"){let t;try{const r=s.resolve(process.cwd(),e);t=await import(r)}catch(e){throw new Error(`Error loading the config file ${e.message}`)}return{...l,...t,safelist:p(t.safelist)}}async function g(e,t){return new n(await t(e))}function v(e,t){switch(t){case"next":return e.text.includes("purgecss ignore");case"start":return e.text.includes("purgecss start ignore");case"end":return e.text.includes("purgecss end ignore")}}function y(e){return!!(k(e)&&!e.selector||(null==e?void 0:e.nodes)&&!e.nodes.length||A(e)&&(!e.nodes&&!e.params||!e.params&&e.nodes&&!e.nodes.length))}function S(...e){const t=new n([]);return e.forEach(t.merge,t),t}function b(e){return e.replace(/(^["'])|(["']$)/g,"")}function w(e,t){if(!t.hasAttrName(e.attribute))return!1;if(void 0===e.value)return!0;switch(e.operator){case"$=":return t.hasAttrSuffix(e.value);case"~=":case"*=":return t.hasAttrSubstr(e.value);case"=":return t.hasAttrValue(e.value);case"|=":case"^=":return t.hasAttrPrefix(e.value);default:return!0}}function F(e,t){return t.hasId(e.value)}function V(e,t){return t.hasTag(e.value)}function A(e){return"atrule"===(null==e?void 0:e.type)}function k(e){return"rule"===(null==e?void 0:e.type)}class x{constructor(){this.ignore=!1,this.atRules={fontFace:[],keyframes:[]},this.usedAnimations=new Set,this.usedFontFaces=new Set,this.selectorsRemoved=new Set,this.removedNodes=[],this.variablesStructure=new h,this.options=l}collectDeclarationsData(e){const{prop:t,value:s}=e;if(this.options.variables){const r=u(s,/var\((.+?)[,)]/g);t.startsWith("--")?(this.variablesStructure.addVariable(e),r.length>0&&this.variablesStructure.addVariableUsage(e,r)):r.length>0&&this.variablesStructure.addVariableUsageInProperties(r)}if(!this.options.keyframes||"animation"!==t&&"animation-name"!==t)if(this.options.fontFace){if("font-family"===t)for(const e of s.split(",")){const t=b(e.trim());this.usedFontFaces.add(t)}}else;else for(const e of s.split(/[\s,]+/))this.usedAnimations.add(e)}getFileExtractor(e,t){const s=t.find((t=>t.extensions.find((t=>e.endsWith(t)))));return void 0===s?this.options.defaultExtractor:s.extractor}async extractSelectorsFromFiles(s,r){const i=new n([]);for(const a of s){let s=[];try{await f.access(a,e.constants.F_OK),s.push(a)}catch(e){s=t.sync(a,{nodir:!0,ignore:this.options.skippedContentGlobs})}for(const e of s){const t=await f.readFile(e,"utf-8"),s=this.getFileExtractor(e,r),a=await g(t,s);i.merge(a)}}return i}async extractSelectorsFromString(e,t){const s=new n([]);for(const{raw:r,extension:i}of e){const e=this.getFileExtractor(`.${i}`,t),a=await g(r,e);s.merge(a)}return s}evaluateAtRule(e){if(this.options.keyframes&&e.name.endsWith("keyframes"))this.atRules.keyframes.push(e);else if(this.options.fontFace&&"font-face"===e.name&&e.nodes)for(const t of e.nodes)"decl"===t.type&&"font-family"===t.prop&&this.atRules.fontFace.push({name:b(t.value),node:e})}evaluateRule(e,t){if(this.ignore)return;const s=e.prev();if(function(e){return"comment"===(null==e?void 0:e.type)}(s)&&v(s,"next"))return void s.remove();if(e.parent&&A(e.parent)&&e.parent.name.endsWith("keyframes"))return;if(!k(e))return;if(function(e){let t=!1;return e.walkComments((e=>{e&&"comment"===e.type&&e.text.includes("purgecss ignore current")&&(t=!0,e.remove())})),t}(e))return;let r=!0;const a=e.selector;if(e.selector=i((e=>{e.walk((e=>{"selector"===e.type&&(r=this.shouldKeepSelector(e,t),r||(this.options.rejected&&this.selectorsRemoved.add(e.toString()),e.remove()))}))})).processSync(e.selector),r&&void 0!==e.nodes)for(const t of e.nodes)"decl"===t.type&&this.collectDeclarationsData(t);const o=e.parent;if(!e.selector&&(e.remove(),this.options.rejectedCss))if(e.selector=a,o&&y(o)){const t=o.clone();t.append(e),this.removedNodes.push(t)}else this.removedNodes.push(e);y(o)&&(null==o||o.remove())}async getPurgedCSS(e,s){const i=[],a=[];for(const s of e)"string"==typeof s?a.push(...t.sync(s,{nodir:!0,ignore:this.options.skippedContentGlobs})):a.push(s);for(const e of a){const t="string"==typeof e?this.options.stdin?e:await f.readFile(e,"utf-8"):e.raw,a=r.parse(t);this.walkThroughCSS(a,s),this.options.fontFace&&this.removeUnusedFontFaces(),this.options.keyframes&&this.removeUnusedKeyframes(),this.options.variables&&this.removeUnusedCSSVariables();const o={css:a.toString(),file:"string"==typeof e?e:e.name};this.options.rejected&&(o.rejected=Array.from(this.selectorsRemoved),this.selectorsRemoved.clear()),this.options.rejectedCss&&(o.rejectedCss=r.root({nodes:this.removedNodes}).toString()),i.push(o)}return i}isKeyframesSafelisted(e){return this.options.safelist.keyframes.some((t=>"string"==typeof t?t===e:t.test(e)))}isSelectorBlocklisted(e){return this.options.blocklist.some((t=>"string"==typeof t?t===e:t.test(e)))}isSelectorSafelisted(e){const t=this.options.safelist.standard.some((t=>"string"==typeof t?t===e:t.test(e)));return c.includes(e)||t}isSelectorSafelistedDeep(e){return this.options.safelist.deep.some((t=>t.test(e)))}isSelectorSafelistedGreedy(e){return this.options.safelist.greedy.some((t=>t.test(e)))}async purge(e){this.options="object"!=typeof e?await m(e):{...l,...e,safelist:p(e.safelist)};const{content:t,css:s,extractors:r,safelist:i}=this.options;this.options.variables&&(this.variablesStructure.safelist=i.variables||[]);const a=t.filter((e=>"string"==typeof e)),o=t.filter((e=>"object"==typeof e)),n=await this.extractSelectorsFromFiles(a,r),c=await this.extractSelectorsFromString(o,r);return this.getPurgedCSS(s,S(n,c))}removeUnusedCSSVariables(){this.variablesStructure.removeUnused()}removeUnusedFontFaces(){for(const{name:e,node:t}of this.atRules.fontFace)this.usedFontFaces.has(e)||t.remove()}removeUnusedKeyframes(){for(const e of this.atRules.keyframes)this.usedAnimations.has(e.params)||this.isKeyframesSafelisted(e.params)||e.remove()}getSelectorValue(e){return"attribute"===e.type&&e.attribute||e.value}shouldKeepSelector(e,t){if(function(e){return e.parent&&"pseudo"===e.parent.type&&e.parent.value.startsWith(":")||!1}(e))return!0;if(this.options.safelist.greedy.length>0){if(e.nodes.map(this.getSelectorValue).some((e=>e&&this.isSelectorSafelistedGreedy(e))))return!0}let s=!1;for(const i of e.nodes){const e=this.getSelectorValue(i);if(e&&this.isSelectorSafelistedDeep(e))return!0;if(e&&(c.includes(e)||this.isSelectorSafelisted(e)))s=!0;else{if(e&&this.isSelectorBlocklisted(e))return!1;switch(i.type){case"attribute":s=!![...this.options.dynamicAttributes,"value","checked","selected","open"].includes(i.attribute)||w(i,t);break;case"class":r=i,s=t.hasClass(r.value);break;case"id":s=F(i,t);break;case"tag":s=V(i,t);break;default:continue}if(!s)return!1}}var r;return s}walkThroughCSS(e,t){e.walk((e=>"rule"===e.type?this.evaluateRule(e,t):"atrule"===e.type?this.evaluateAtRule(e):void("comment"===e.type&&(v(e,"start")?(this.ignore=!0,e.remove()):v(e,"end")&&(this.ignore=!1,e.remove())))))}}export{x as PurgeCSS,x as default,l as defaultOptions,S as mergeExtractorSelectors,m as setOptions,p as standardizeSafelist};
package/lib/purgecss.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("fs"),t=require("glob"),s=require("path"),r=require("postcss"),i=require("postcss-selector-parser"),n=require("util");function a(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function o(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(s){if("default"!==s){var r=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(t,s,r.get?r:{enumerable:!0,get:function(){return e[s]}})}})),t.default=e,Object.freeze(t)}var u=a(t),c=a(s),l=a(i);function d(e,t){t&&t.forEach(e.add,e)}class f{constructor(e){this.undetermined=new Set,this.attrNames=new Set,this.attrValues=new Set,this.classes=new Set,this.ids=new Set,this.tags=new Set,this.merge(e)}merge(e){return Array.isArray(e)?d(this.undetermined,e):e instanceof f?(d(this.undetermined,e.undetermined),d(this.attrNames,e.attrNames),d(this.attrValues,e.attrValues),d(this.classes,e.classes),d(this.ids,e.ids),d(this.tags,e.tags)):(d(this.undetermined,e.undetermined),e.attributes&&(d(this.attrNames,e.attributes.names),d(this.attrValues,e.attributes.values)),d(this.classes,e.classes),d(this.ids,e.ids),d(this.tags,e.tags)),this}hasAttrName(e){return this.attrNames.has(e)||this.undetermined.has(e)}someAttrValue(e){for(const t of this.attrValues)if(e(t))return!0;for(const t of this.undetermined)if(e(t))return!0;return!1}hasAttrPrefix(e){return this.someAttrValue((t=>t.startsWith(e)))}hasAttrSuffix(e){return this.someAttrValue((t=>t.endsWith(e)))}hasAttrSubstr(e){return e.trim().split(" ").every((e=>this.someAttrValue((t=>t.includes(e)))))}hasAttrValue(e){return this.attrValues.has(e)||this.undetermined.has(e)}hasClass(e){return this.classes.has(e)||this.undetermined.has(e)}hasId(e){return this.ids.has(e)||this.undetermined.has(e)}hasTag(e){return this.tags.has(e)||this.undetermined.has(e)}}const h=["*","::-webkit-scrollbar","::selection",":root","::before","::after"],p={css:[],content:[],defaultExtractor:e=>e.match(/[A-Za-z0-9_-]+/g)||[],extractors:[],fontFace:!1,keyframes:!1,rejected:!1,stdin:!1,stdout:!1,variables:!1,safelist:{standard:[],deep:[],greedy:[],variables:[],keyframes:[]},blocklist:[],skippedContentGlobs:[],dynamicAttributes:[]};class m{constructor(e){this.nodes=[],this.isUsed=!1,this.value=e}}class g{constructor(){this.nodes=new Map,this.usedVariables=new Set,this.safelist=[]}addVariable(e){const{prop:t}=e;if(!this.nodes.has(t)){const s=new m(e);this.nodes.set(t,s)}}addVariableUsage(e,t){const{prop:s}=e,r=this.nodes.get(s);for(const e of t){const t=e[1];if(this.nodes.has(t)){const e=this.nodes.get(t);null==r||r.nodes.push(e)}}}addVariableUsageInProperties(e){for(const t of e){const e=t[1];this.usedVariables.add(e)}}setAsUsed(e){const t=[this.nodes.get(e)];for(;0!==t.length;){const e=t.pop();e&&!e.isUsed&&(e.isUsed=!0,t.push(...e.nodes))}}removeUnused(){for(const e of this.usedVariables)this.setAsUsed(e);for(const[e,t]of this.nodes)t.isUsed||this.isVariablesSafelisted(e)||t.value.remove()}isVariablesSafelisted(e){return this.safelist.some((t=>"string"==typeof t?t===e:t.test(e)))}}const y={access:n.promisify(e.access),readFile:n.promisify(e.readFile)};function v(e=[]){return Array.isArray(e)?{...p.safelist,standard:e}:{...p.safelist,...e}}async function S(e="purgecss.config.js"){let t;try{const s=c.default.join(process.cwd(),e);t=await Promise.resolve().then((function(){return o(require(s))}))}catch(e){throw new Error("Error loading the config file "+e.message)}return{...p,...t,safelist:v(t.safelist)}}async function b(e,t){return new f(await t(e))}function w(e,t){switch(t){case"next":return e.text.includes("purgecss ignore");case"start":return e.text.includes("purgecss start ignore");case"end":return e.text.includes("purgecss end ignore")}}function x(...e){const t=new f([]);return e.forEach(t.merge,t),t}function F(e){return e.replace(/(^["'])|(["']$)/g,"")}function k(e,t){if(!t.hasAttrName(e.attribute))return!1;if(void 0===e.value)return!0;switch(e.operator){case"$=":return t.hasAttrSuffix(e.value);case"~=":case"*=":return t.hasAttrSubstr(e.value);case"=":return t.hasAttrValue(e.value);case"|=":case"^=":return t.hasAttrPrefix(e.value);default:return!0}}function A(e,t){return t.hasId(e.value)}function V(e,t){return t.hasTag(e.value)}function U(e){return"atrule"===(null==e?void 0:e.type)}function j(e){return"rule"===(null==e?void 0:e.type)}class C{constructor(){this.ignore=!1,this.atRules={fontFace:[],keyframes:[]},this.usedAnimations=new Set,this.usedFontFaces=new Set,this.selectorsRemoved=new Set,this.variablesStructure=new g,this.options=p}collectDeclarationsData(e){const{prop:t,value:s}=e;if(this.options.variables){const r=function(e,t){const s=[];return e.replace(t,(function(){const t=arguments,r=Array.prototype.slice.call(t,0,-2);return r.input=t[t.length-1],r.index=t[t.length-2],s.push(r),e})),s}(s,/var\((.+?)[,)]/g);t.startsWith("--")?(this.variablesStructure.addVariable(e),r.length>0&&this.variablesStructure.addVariableUsage(e,r)):r.length>0&&this.variablesStructure.addVariableUsageInProperties(r)}if(!this.options.keyframes||"animation"!==t&&"animation-name"!==t)if(this.options.fontFace){if("font-family"===t)for(const e of s.split(",")){const t=F(e.trim());this.usedFontFaces.add(t)}}else;else for(const e of s.split(/[\s,]+/))this.usedAnimations.add(e)}getFileExtractor(e,t){const s=t.find((t=>t.extensions.find((t=>e.endsWith(t)))));return void 0===s?this.options.defaultExtractor:s.extractor}async extractSelectorsFromFiles(t,s){const r=new f([]);for(const i of t){let t=[];try{await y.access(i,e.constants.F_OK),t.push(i)}catch(e){t=u.default.sync(i,{nodir:!0,ignore:this.options.skippedContentGlobs})}for(const e of t){const t=await y.readFile(e,"utf-8"),i=this.getFileExtractor(e,s),n=await b(t,i);r.merge(n)}}return r}async extractSelectorsFromString(e,t){const s=new f([]);for(const{raw:r,extension:i}of e){const e=this.getFileExtractor("."+i,t),n=await b(r,e);s.merge(n)}return s}evaluateAtRule(e){if(this.options.keyframes&&e.name.endsWith("keyframes"))this.atRules.keyframes.push(e);else if(this.options.fontFace&&"font-face"===e.name&&e.nodes)for(const t of e.nodes)"decl"===t.type&&"font-family"===t.prop&&this.atRules.fontFace.push({name:F(t.value),node:e})}async evaluateRule(e,t){if(this.ignore)return;const s=e.prev();if(function(e){return"comment"===(null==e?void 0:e.type)}(s)&&w(s,"next"))return void s.remove();if(e.parent&&U(e.parent)&&"keyframes"===e.parent.name)return;if(!j(e))return;if(function(e){let t=!1;return e.walkComments((e=>{e&&"comment"===e.type&&e.text.includes("purgecss ignore current")&&(t=!0,e.remove())})),t}(e))return;let r=!0;if(e.selector=l.default((e=>{e.walk((e=>{"selector"===e.type&&(r=this.shouldKeepSelector(e,t),r||(this.options.rejected&&this.selectorsRemoved.add(e.toString()),e.remove()))}))})).processSync(e.selector),r&&void 0!==e.nodes)for(const t of e.nodes)"decl"===t.type&&this.collectDeclarationsData(t);const i=e.parent;e.selector||e.remove(),function(e){return!!(j(e)&&!e.selector||(null==e?void 0:e.nodes)&&!e.nodes.length||U(e)&&(!e.nodes&&!e.params||!e.params&&e.nodes&&!e.nodes.length))}(i)&&(null==i||i.remove())}async getPurgedCSS(e,t){const s=[],i=[];for(const t of e)"string"==typeof t?i.push(...u.default.sync(t,{nodir:!0,ignore:this.options.skippedContentGlobs})):i.push(t);for(const e of i){const i="string"==typeof e?this.options.stdin?e:await y.readFile(e,"utf-8"):e.raw,n=r.parse(i);this.walkThroughCSS(n,t),this.options.fontFace&&this.removeUnusedFontFaces(),this.options.keyframes&&this.removeUnusedKeyframes(),this.options.variables&&this.removeUnusedCSSVariables();const a={css:n.toString(),file:"string"==typeof e?e:void 0};"string"==typeof e&&(a.file=e),this.options.rejected&&(a.rejected=Array.from(this.selectorsRemoved),this.selectorsRemoved.clear()),s.push(a)}return s}isKeyframesSafelisted(e){return this.options.safelist.keyframes.some((t=>"string"==typeof t?t===e:t.test(e)))}isSelectorBlocklisted(e){return this.options.blocklist.some((t=>"string"==typeof t?t===e:t.test(e)))}isSelectorSafelisted(e){const t=this.options.safelist.standard.some((t=>"string"==typeof t?t===e:t.test(e)));return h.includes(e)||t}isSelectorSafelistedDeep(e){return this.options.safelist.deep.some((t=>t.test(e)))}isSelectorSafelistedGreedy(e){return this.options.safelist.greedy.some((t=>t.test(e)))}async purge(e){this.options="object"!=typeof e?await S(e):{...p,...e,safelist:v(e.safelist)};const{content:t,css:s,extractors:r,safelist:i}=this.options;this.options.variables&&(this.variablesStructure.safelist=i.variables||[]);const n=t.filter((e=>"string"==typeof e)),a=t.filter((e=>"object"==typeof e)),o=await this.extractSelectorsFromFiles(n,r),u=await this.extractSelectorsFromString(a,r);return this.getPurgedCSS(s,x(o,u))}removeUnusedCSSVariables(){this.variablesStructure.removeUnused()}removeUnusedFontFaces(){for(const{name:e,node:t}of this.atRules.fontFace)this.usedFontFaces.has(e)||t.remove()}removeUnusedKeyframes(){for(const e of this.atRules.keyframes)this.usedAnimations.has(e.params)||this.isKeyframesSafelisted(e.params)||e.remove()}getSelectorValue(e){return"attribute"===e.type&&e.attribute||e.value}shouldKeepSelector(e,t){if(function(e){return e.parent&&"pseudo"===e.parent.type&&e.parent.value.startsWith(":")||!1}(e))return!0;if(this.options.safelist.greedy.length>0){if(e.nodes.map(this.getSelectorValue).some((e=>e&&this.isSelectorSafelistedGreedy(e))))return!0}let s=!1;for(const i of e.nodes){const e=this.getSelectorValue(i);if(e&&this.isSelectorSafelistedDeep(e))return!0;if(e&&(h.includes(e)||this.isSelectorSafelisted(e)))s=!0;else{if(e&&this.isSelectorBlocklisted(e))return!1;switch(i.type){case"attribute":s=!![...this.options.dynamicAttributes,"value","checked","selected","open"].includes(i.attribute)||k(i,t);break;case"class":r=i,s=t.hasClass(r.value);break;case"id":s=A(i,t);break;case"tag":s=V(i,t);break;default:continue}if(!s)return!1}}var r;return s}walkThroughCSS(e,t){e.walk((e=>"rule"===e.type?this.evaluateRule(e,t):"atrule"===e.type?this.evaluateAtRule(e):void("comment"===e.type&&(w(e,"start")?(this.ignore=!0,e.remove()):w(e,"end")&&(this.ignore=!1,e.remove())))))}}exports.PurgeCSS=C,exports.default=C,exports.defaultOptions=p,exports.mergeExtractorSelectors=x,exports.setOptions=S,exports.standardizeSafelist=v;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("fs"),t=require("glob"),s=require("path"),r=require("postcss"),i=require("postcss-selector-parser"),n=require("util");function a(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function o(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(s){if("default"!==s){var r=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(t,s,r.get?r:{enumerable:!0,get:function(){return e[s]}})}})),t.default=e,Object.freeze(t)}var c=o(e),u=a(t),l=a(s),d=o(r),h=a(i);function f(e,t){t&&t.forEach(e.add,e)}class p{constructor(e){this.undetermined=new Set,this.attrNames=new Set,this.attrValues=new Set,this.classes=new Set,this.ids=new Set,this.tags=new Set,this.merge(e)}merge(e){return Array.isArray(e)?f(this.undetermined,e):e instanceof p?(f(this.undetermined,e.undetermined),f(this.attrNames,e.attrNames),f(this.attrValues,e.attrValues),f(this.classes,e.classes),f(this.ids,e.ids),f(this.tags,e.tags)):(f(this.undetermined,e.undetermined),e.attributes&&(f(this.attrNames,e.attributes.names),f(this.attrValues,e.attributes.values)),f(this.classes,e.classes),f(this.ids,e.ids),f(this.tags,e.tags)),this}hasAttrName(e){return this.attrNames.has(e)||this.undetermined.has(e)}someAttrValue(e){for(const t of this.attrValues)if(e(t))return!0;for(const t of this.undetermined)if(e(t))return!0;return!1}hasAttrPrefix(e){return this.someAttrValue((t=>t.startsWith(e)))}hasAttrSuffix(e){return this.someAttrValue((t=>t.endsWith(e)))}hasAttrSubstr(e){return e.trim().split(" ").every((e=>this.someAttrValue((t=>t.includes(e)))))}hasAttrValue(e){return this.attrValues.has(e)||this.undetermined.has(e)}hasClass(e){return this.classes.has(e)||this.undetermined.has(e)}hasId(e){return this.ids.has(e)||this.undetermined.has(e)}hasTag(e){return this.tags.has(e)||this.undetermined.has(e)}}const m=["*","::-webkit-scrollbar","::selection",":root","::before","::after"],g={css:[],content:[],defaultExtractor:e=>e.match(/[A-Za-z0-9_-]+/g)||[],extractors:[],fontFace:!1,keyframes:!1,rejected:!1,rejectedCss:!1,stdin:!1,stdout:!1,variables:!1,safelist:{standard:[],deep:[],greedy:[],variables:[],keyframes:[]},blocklist:[],skippedContentGlobs:[],dynamicAttributes:[]};function v(e,t){const s=[];return e.replace(t,(function(){const t=arguments,r=Array.prototype.slice.call(t,0,-2);return r.input=t[t.length-1],r.index=t[t.length-2],s.push(r),e})),s}class y{constructor(e){this.nodes=[],this.isUsed=!1,this.value=e}}class S{constructor(){this.nodes=new Map,this.usedVariables=new Set,this.safelist=[]}addVariable(e){const{prop:t}=e;if(!this.nodes.has(t)){const s=new y(e);this.nodes.set(t,s)}}addVariableUsage(e,t){const{prop:s}=e,r=this.nodes.get(s);for(const e of t){const t=e[1];if(this.nodes.has(t)){const e=this.nodes.get(t);null==r||r.nodes.push(e)}}}addVariableUsageInProperties(e){for(const t of e){const e=t[1];this.usedVariables.add(e)}}setAsUsed(e){const t=[this.nodes.get(e)];for(;0!==t.length;){const e=t.pop();e&&!e.isUsed&&(e.isUsed=!0,t.push(...e.nodes))}}removeUnused(){for(const e of this.usedVariables){const t=this.nodes.get(e);if(t){v(t.value.value,/var\((.+?)[,)]/g).forEach((e=>{this.usedVariables.has(e[1])||this.usedVariables.add(e[1])}))}}for(const e of this.usedVariables)this.setAsUsed(e);for(const[e,t]of this.nodes)t.isUsed||this.isVariablesSafelisted(e)||t.value.remove()}isVariablesSafelisted(e){return this.safelist.some((t=>"string"==typeof t?t===e:t.test(e)))}}const b={access:n.promisify(c.access),readFile:n.promisify(c.readFile)};function w(e=[]){return Array.isArray(e)?{...g.safelist,standard:e}:{...g.safelist,...e}}async function x(e="purgecss.config.js"){let t;try{const s=l.default.resolve(process.cwd(),e);t=await function(e){return Promise.resolve().then((function(){return o(require(e))}))}(s)}catch(e){throw new Error(`Error loading the config file ${e.message}`)}return{...g,...t,safelist:w(t.safelist)}}async function F(e,t){return new p(await t(e))}function V(e,t){switch(t){case"next":return e.text.includes("purgecss ignore");case"start":return e.text.includes("purgecss start ignore");case"end":return e.text.includes("purgecss end ignore")}}function k(e){return!!(N(e)&&!e.selector||(null==e?void 0:e.nodes)&&!e.nodes.length||E(e)&&(!e.nodes&&!e.params||!e.params&&e.nodes&&!e.nodes.length))}function A(...e){const t=new p([]);return e.forEach(t.merge,t),t}function j(e){return e.replace(/(^["'])|(["']$)/g,"")}function U(e,t){if(!t.hasAttrName(e.attribute))return!1;if(void 0===e.value)return!0;switch(e.operator){case"$=":return t.hasAttrSuffix(e.value);case"~=":case"*=":return t.hasAttrSubstr(e.value);case"=":return t.hasAttrValue(e.value);case"|=":case"^=":return t.hasAttrPrefix(e.value);default:return!0}}function C(e,t){return t.hasId(e.value)}function R(e,t){return t.hasTag(e.value)}function E(e){return"atrule"===(null==e?void 0:e.type)}function N(e){return"rule"===(null==e?void 0:e.type)}class P{constructor(){this.ignore=!1,this.atRules={fontFace:[],keyframes:[]},this.usedAnimations=new Set,this.usedFontFaces=new Set,this.selectorsRemoved=new Set,this.removedNodes=[],this.variablesStructure=new S,this.options=g}collectDeclarationsData(e){const{prop:t,value:s}=e;if(this.options.variables){const r=v(s,/var\((.+?)[,)]/g);t.startsWith("--")?(this.variablesStructure.addVariable(e),r.length>0&&this.variablesStructure.addVariableUsage(e,r)):r.length>0&&this.variablesStructure.addVariableUsageInProperties(r)}if(!this.options.keyframes||"animation"!==t&&"animation-name"!==t)if(this.options.fontFace){if("font-family"===t)for(const e of s.split(",")){const t=j(e.trim());this.usedFontFaces.add(t)}}else;else for(const e of s.split(/[\s,]+/))this.usedAnimations.add(e)}getFileExtractor(e,t){const s=t.find((t=>t.extensions.find((t=>e.endsWith(t)))));return void 0===s?this.options.defaultExtractor:s.extractor}async extractSelectorsFromFiles(e,t){const s=new p([]);for(const r of e){let e=[];try{await b.access(r,c.constants.F_OK),e.push(r)}catch(t){e=u.default.sync(r,{nodir:!0,ignore:this.options.skippedContentGlobs})}for(const r of e){const e=await b.readFile(r,"utf-8"),i=this.getFileExtractor(r,t),n=await F(e,i);s.merge(n)}}return s}async extractSelectorsFromString(e,t){const s=new p([]);for(const{raw:r,extension:i}of e){const e=this.getFileExtractor(`.${i}`,t),n=await F(r,e);s.merge(n)}return s}evaluateAtRule(e){if(this.options.keyframes&&e.name.endsWith("keyframes"))this.atRules.keyframes.push(e);else if(this.options.fontFace&&"font-face"===e.name&&e.nodes)for(const t of e.nodes)"decl"===t.type&&"font-family"===t.prop&&this.atRules.fontFace.push({name:j(t.value),node:e})}evaluateRule(e,t){if(this.ignore)return;const s=e.prev();if(function(e){return"comment"===(null==e?void 0:e.type)}(s)&&V(s,"next"))return void s.remove();if(e.parent&&E(e.parent)&&e.parent.name.endsWith("keyframes"))return;if(!N(e))return;if(function(e){let t=!1;return e.walkComments((e=>{e&&"comment"===e.type&&e.text.includes("purgecss ignore current")&&(t=!0,e.remove())})),t}(e))return;let r=!0;const i=e.selector;if(e.selector=h.default((e=>{e.walk((e=>{"selector"===e.type&&(r=this.shouldKeepSelector(e,t),r||(this.options.rejected&&this.selectorsRemoved.add(e.toString()),e.remove()))}))})).processSync(e.selector),r&&void 0!==e.nodes)for(const t of e.nodes)"decl"===t.type&&this.collectDeclarationsData(t);const n=e.parent;if(!e.selector&&(e.remove(),this.options.rejectedCss))if(e.selector=i,n&&k(n)){const t=n.clone();t.append(e),this.removedNodes.push(t)}else this.removedNodes.push(e);k(n)&&(null==n||n.remove())}async getPurgedCSS(e,t){const s=[],r=[];for(const t of e)"string"==typeof t?r.push(...u.default.sync(t,{nodir:!0,ignore:this.options.skippedContentGlobs})):r.push(t);for(const e of r){const r="string"==typeof e?this.options.stdin?e:await b.readFile(e,"utf-8"):e.raw,i=d.parse(r);this.walkThroughCSS(i,t),this.options.fontFace&&this.removeUnusedFontFaces(),this.options.keyframes&&this.removeUnusedKeyframes(),this.options.variables&&this.removeUnusedCSSVariables();const n={css:i.toString(),file:"string"==typeof e?e:e.name};this.options.rejected&&(n.rejected=Array.from(this.selectorsRemoved),this.selectorsRemoved.clear()),this.options.rejectedCss&&(n.rejectedCss=d.root({nodes:this.removedNodes}).toString()),s.push(n)}return s}isKeyframesSafelisted(e){return this.options.safelist.keyframes.some((t=>"string"==typeof t?t===e:t.test(e)))}isSelectorBlocklisted(e){return this.options.blocklist.some((t=>"string"==typeof t?t===e:t.test(e)))}isSelectorSafelisted(e){const t=this.options.safelist.standard.some((t=>"string"==typeof t?t===e:t.test(e)));return m.includes(e)||t}isSelectorSafelistedDeep(e){return this.options.safelist.deep.some((t=>t.test(e)))}isSelectorSafelistedGreedy(e){return this.options.safelist.greedy.some((t=>t.test(e)))}async purge(e){this.options="object"!=typeof e?await x(e):{...g,...e,safelist:w(e.safelist)};const{content:t,css:s,extractors:r,safelist:i}=this.options;this.options.variables&&(this.variablesStructure.safelist=i.variables||[]);const n=t.filter((e=>"string"==typeof e)),a=t.filter((e=>"object"==typeof e)),o=await this.extractSelectorsFromFiles(n,r),c=await this.extractSelectorsFromString(a,r);return this.getPurgedCSS(s,A(o,c))}removeUnusedCSSVariables(){this.variablesStructure.removeUnused()}removeUnusedFontFaces(){for(const{name:e,node:t}of this.atRules.fontFace)this.usedFontFaces.has(e)||t.remove()}removeUnusedKeyframes(){for(const e of this.atRules.keyframes)this.usedAnimations.has(e.params)||this.isKeyframesSafelisted(e.params)||e.remove()}getSelectorValue(e){return"attribute"===e.type&&e.attribute||e.value}shouldKeepSelector(e,t){if(function(e){return e.parent&&"pseudo"===e.parent.type&&e.parent.value.startsWith(":")||!1}(e))return!0;if(this.options.safelist.greedy.length>0){if(e.nodes.map(this.getSelectorValue).some((e=>e&&this.isSelectorSafelistedGreedy(e))))return!0}let s=!1;for(const i of e.nodes){const e=this.getSelectorValue(i);if(e&&this.isSelectorSafelistedDeep(e))return!0;if(e&&(m.includes(e)||this.isSelectorSafelisted(e)))s=!0;else{if(e&&this.isSelectorBlocklisted(e))return!1;switch(i.type){case"attribute":s=!![...this.options.dynamicAttributes,"value","checked","selected","open"].includes(i.attribute)||U(i,t);break;case"class":r=i,s=t.hasClass(r.value);break;case"id":s=C(i,t);break;case"tag":s=R(i,t);break;default:continue}if(!s)return!1}}var r;return s}walkThroughCSS(e,t){e.walk((e=>"rule"===e.type?this.evaluateRule(e,t):"atrule"===e.type?this.evaluateAtRule(e):void("comment"===e.type&&(V(e,"start")?(this.ignore=!0,e.remove()):V(e,"end")&&(this.ignore=!1,e.remove())))))}}exports.PurgeCSS=P,exports.default=P,exports.defaultOptions=g,exports.mergeExtractorSelectors=A,exports.setOptions=x,exports.standardizeSafelist=w;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "purgecss",
3
- "version": "4.0.3",
3
+ "version": "4.1.0",
4
4
  "description": "Remove unused css selectors",
5
5
  "author": "Ffloriel",
6
6
  "homepage": "https://purgecss.com",
@@ -39,10 +39,10 @@
39
39
  "test": "echo \"Error: run tests from root\" && exit 1"
40
40
  },
41
41
  "dependencies": {
42
- "commander": "^6.0.0",
43
- "glob": "^7.0.0",
44
- "postcss": "^8.2.1",
45
- "postcss-selector-parser": "^6.0.2"
42
+ "commander": "^8.0.0",
43
+ "glob": "^7.1.7",
44
+ "postcss": "^8.3.5",
45
+ "postcss-selector-parser": "^6.0.6"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@types/glob": "^7.1.1"
@@ -50,5 +50,8 @@
50
50
  "bugs": {
51
51
  "url": "https://github.com/FullHuman/purgecss/issues"
52
52
  },
53
- "gitHead": "ff1c5582383288e5300ecfb798a89e262d65c071"
53
+ "publishConfig": {
54
+ "access": "public",
55
+ "registry": "https://registry.npmjs.org/"
56
+ }
54
57
  }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2020 Full Human
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.