Skip to content

Commit

Permalink
preserve important comments (#1223)
Browse files Browse the repository at this point in the history
  • Loading branch information
romainmenke authored Dec 26, 2023
1 parent b15603c commit 4a25af0
Show file tree
Hide file tree
Showing 7 changed files with 20 additions and 5 deletions.
4 changes: 4 additions & 0 deletions plugins/postcss-minify/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changes to PostCSS Minify

### Unreleased (minor)

- Preserve important comments (e.g. `/*! something important */`)

### 1.0.3

_December 15, 2023_
Expand Down
4 changes: 3 additions & 1 deletion plugins/postcss-minify/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ Compared to other minifiers, [PostCSS Minify] is purely focused on correctness a
* legal text is preserved
*/
/*! an important comment */
:root {
--mainColor: #12345678;
}
Expand Down Expand Up @@ -63,7 +65,7 @@ becomes :
*//*
* Copyright: CSSTools Authors
* legal text is preserved
*/:root{--mainColor: #12345678;}body{color:var(--mainColor);font-family:system-ui}a{color:rgb(0 0 100% / 90%);&:hover{color:rebeccapurple}> span{color:color-mix(in oklch, cyan, green 25%)}}:is(input, button):is(:hover, :focus){color:oklch(40% 0.268735435 34.568626)}
*//*! an important comment */:root{--mainColor: #12345678;}body{color:var(--mainColor);font-family:system-ui}a{color:rgb(0 0 100% / 90%);&:hover{color:rebeccapurple}> span{color:color-mix(in oklch, cyan, green 25%)}}:is(input, button):is(:hover, :focus){color:oklch(40% 0.268735435 34.568626)}
```

## Usage
Expand Down
2 changes: 1 addition & 1 deletion plugins/postcss-minify/dist/index.cjs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"use strict";var e=require("@csstools/css-tokenizer");const t=/(?:license|copyright)/i,r=/sourceMappingURL/i,s=/(?:\s|\/\*)/,o=/^layer$/i;function minify(t,r){if(!r)return r;if(t.has(r))return t.get(r);const o=r.trim();if(""===o)return t.set(r,""),"";if(!s.test(o))return t.set(r,o),o;const n=e.tokenize({css:o});let i,a=!1;for(let t=0;t<n.length;t++)i=n[t],i[0]===e.TokenType.Comment||i[0]===e.TokenType.Whitespace?(i[1]=a?"":" ",a=!0):a=!1;let c="";for(let e=0;e<n.length;e++)c+=n[e][1];return t.set(r,c),c}function removeEmptyNodes(e){if("rule"===e.type){if(0===e.nodes?.length){const t=e.parent;return!!t&&(e.remove(),removeEmptyNodes(t),!0)}}else if("atrule"===e.type&&0===e.nodes?.length&&!o.test(e.name)){const t=e.parent;return!!t&&(e.remove(),removeEmptyNodes(t),!0)}return!1}function setSemicolon(e){if(e.raws.semicolon){const t=e.last;"decl"===t?.type&&t.variable||(e.raws.semicolon=!1)}}const creator=()=>{const e=new Map;return{postcssPlugin:"postcss-minify",OnceExit(s){s.raws.before="",s.raws.after="\n",s.walk((s=>{switch(s.type){case"atrule":if(removeEmptyNodes(s))return;return s.raws.after="",s.raws.afterName=" ",s.raws.before="",s.raws.between="",s.raws.params=void 0,setSemicolon(s),void(s.params=minify(e,s.params));case"rule":if(removeEmptyNodes(s))return;return s.raws.after="",s.raws.before="",s.raws.between="",s.raws.selector=void 0,setSemicolon(s),void(s.selector=minify(e,s.selector));case"decl":return s.prop.startsWith("--")?void(s.raws.before=""):(s.raws.before="",s.raws.between=":",s.raws.important=s.important?"!important":"",s.raws.value=void 0,void(s.value=minify(e,s.value)));case"comment":return t.test(s.text)||r.test(s.text)?void(s.raws.before=""):void s.remove()}}))}}};creator.postcss=!0,module.exports=creator;
"use strict";var e=require("@csstools/css-tokenizer");const t=/(?:license|copyright)/i,r=/sourceMappingURL/i,s=/(?:\s|\/\*)/,o=/^layer$/i;function minify(t,r){if(!r)return r;if(t.has(r))return t.get(r);const o=r.trim();if(""===o)return t.set(r,""),"";if(!s.test(o))return t.set(r,o),o;const n=e.tokenize({css:o});let i,a=!1;for(let t=0;t<n.length;t++)i=n[t],i[0]===e.TokenType.Comment||i[0]===e.TokenType.Whitespace?(i[1]=a?"":" ",a=!0):a=!1;let c="";for(let e=0;e<n.length;e++)c+=n[e][1];return t.set(r,c),c}function removeEmptyNodes(e){if("rule"===e.type){if(0===e.nodes?.length){const t=e.parent;return!!t&&(e.remove(),removeEmptyNodes(t),!0)}}else if("atrule"===e.type&&0===e.nodes?.length&&!o.test(e.name)){const t=e.parent;return!!t&&(e.remove(),removeEmptyNodes(t),!0)}return!1}function setSemicolon(e){if(e.raws.semicolon){const t=e.last;"decl"===t?.type&&t.variable||(e.raws.semicolon=!1)}}const creator=()=>{const e=new Map;return{postcssPlugin:"postcss-minify",OnceExit(s){s.raws.before="",s.raws.after="\n",s.walk((s=>{switch(s.type){case"atrule":if(removeEmptyNodes(s))return;return s.raws.after="",s.raws.afterName=" ",s.raws.before="",s.raws.between="",s.raws.params=void 0,setSemicolon(s),void(s.params=minify(e,s.params));case"rule":if(removeEmptyNodes(s))return;return s.raws.after="",s.raws.before="",s.raws.between="",s.raws.selector=void 0,setSemicolon(s),void(s.selector=minify(e,s.selector));case"decl":return s.prop.startsWith("--")?void(s.raws.before=""):(s.raws.before="",s.raws.between=":",s.raws.important=s.important?"!important":"",s.raws.value=void 0,void(s.value=minify(e,s.value)));case"comment":return s.text.startsWith("!")||t.test(s.text)||r.test(s.text)?void(s.raws.before=""):void s.remove()}}))}}};creator.postcss=!0,module.exports=creator;
2 changes: 1 addition & 1 deletion plugins/postcss-minify/dist/index.mjs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
import{tokenize as e,TokenType as t}from"@csstools/css-tokenizer";const r=/(?:license|copyright)/i,s=/sourceMappingURL/i,o=/(?:\s|\/\*)/,n=/^layer$/i;function minify(r,s){if(!s)return s;if(r.has(s))return r.get(s);const n=s.trim();if(""===n)return r.set(s,""),"";if(!o.test(n))return r.set(s,n),n;const a=e({css:n});let i,c=!1;for(let e=0;e<a.length;e++)i=a[e],i[0]===t.Comment||i[0]===t.Whitespace?(i[1]=c?"":" ",c=!0):c=!1;let m="";for(let e=0;e<a.length;e++)m+=a[e][1];return r.set(s,m),m}function removeEmptyNodes(e){if("rule"===e.type){if(0===e.nodes?.length){const t=e.parent;return!!t&&(e.remove(),removeEmptyNodes(t),!0)}}else if("atrule"===e.type&&0===e.nodes?.length&&!n.test(e.name)){const t=e.parent;return!!t&&(e.remove(),removeEmptyNodes(t),!0)}return!1}function setSemicolon(e){if(e.raws.semicolon){const t=e.last;"decl"===t?.type&&t.variable||(e.raws.semicolon=!1)}}const creator=()=>{const e=new Map;return{postcssPlugin:"postcss-minify",OnceExit(t){t.raws.before="",t.raws.after="\n",t.walk((t=>{switch(t.type){case"atrule":if(removeEmptyNodes(t))return;return t.raws.after="",t.raws.afterName=" ",t.raws.before="",t.raws.between="",t.raws.params=void 0,setSemicolon(t),void(t.params=minify(e,t.params));case"rule":if(removeEmptyNodes(t))return;return t.raws.after="",t.raws.before="",t.raws.between="",t.raws.selector=void 0,setSemicolon(t),void(t.selector=minify(e,t.selector));case"decl":return t.prop.startsWith("--")?void(t.raws.before=""):(t.raws.before="",t.raws.between=":",t.raws.important=t.important?"!important":"",t.raws.value=void 0,void(t.value=minify(e,t.value)));case"comment":return r.test(t.text)||s.test(t.text)?void(t.raws.before=""):void t.remove()}}))}}};creator.postcss=!0;export{creator as default};
import{tokenize as e,TokenType as t}from"@csstools/css-tokenizer";const r=/(?:license|copyright)/i,s=/sourceMappingURL/i,o=/(?:\s|\/\*)/,n=/^layer$/i;function minify(r,s){if(!s)return s;if(r.has(s))return r.get(s);const n=s.trim();if(""===n)return r.set(s,""),"";if(!o.test(n))return r.set(s,n),n;const a=e({css:n});let i,c=!1;for(let e=0;e<a.length;e++)i=a[e],i[0]===t.Comment||i[0]===t.Whitespace?(i[1]=c?"":" ",c=!0):c=!1;let m="";for(let e=0;e<a.length;e++)m+=a[e][1];return r.set(s,m),m}function removeEmptyNodes(e){if("rule"===e.type){if(0===e.nodes?.length){const t=e.parent;return!!t&&(e.remove(),removeEmptyNodes(t),!0)}}else if("atrule"===e.type&&0===e.nodes?.length&&!n.test(e.name)){const t=e.parent;return!!t&&(e.remove(),removeEmptyNodes(t),!0)}return!1}function setSemicolon(e){if(e.raws.semicolon){const t=e.last;"decl"===t?.type&&t.variable||(e.raws.semicolon=!1)}}const creator=()=>{const e=new Map;return{postcssPlugin:"postcss-minify",OnceExit(t){t.raws.before="",t.raws.after="\n",t.walk((t=>{switch(t.type){case"atrule":if(removeEmptyNodes(t))return;return t.raws.after="",t.raws.afterName=" ",t.raws.before="",t.raws.between="",t.raws.params=void 0,setSemicolon(t),void(t.params=minify(e,t.params));case"rule":if(removeEmptyNodes(t))return;return t.raws.after="",t.raws.before="",t.raws.between="",t.raws.selector=void 0,setSemicolon(t),void(t.selector=minify(e,t.selector));case"decl":return t.prop.startsWith("--")?void(t.raws.before=""):(t.raws.before="",t.raws.between=":",t.raws.important=t.important?"!important":"",t.raws.value=void 0,void(t.value=minify(e,t.value)));case"comment":return t.text.startsWith("!")||r.test(t.text)||s.test(t.text)?void(t.raws.before=""):void t.remove()}}))}}};creator.postcss=!0;export{creator as default};
9 changes: 8 additions & 1 deletion plugins/postcss-minify/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,14 @@ const creator: PluginCreator<pluginOptions> = () => {

case 'comment':

if (HAS_LEGAL_KEYWORDS.test(node.text) || HAS_SOURCE_MAP.test(node.text)) {
if (
// `/*! ... */` is a common pattern to indicate that a comment is important and should not be removed.
node.text.startsWith('!') ||
// Comments containing the words `license` or `copyright` should not be removed.
HAS_LEGAL_KEYWORDS.test(node.text) ||
// Comments containing the word `sourceMappingURL` should not be removed.
HAS_SOURCE_MAP.test(node.text)
) {
node.raws.before = '';
return;
}
Expand Down
2 changes: 2 additions & 0 deletions plugins/postcss-minify/test/examples/example.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
* legal text is preserved
*/

/*! an important comment */

:root {
--mainColor: #12345678;
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/postcss-minify/test/examples/example.expect.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
*//*
* Copyright: CSSTools Authors
* legal text is preserved
*/:root{--mainColor: #12345678;}body{color:var(--mainColor);font-family:system-ui}a{color:rgb(0 0 100% / 90%);&:hover{color:rebeccapurple}> span{color:color-mix(in oklch, cyan, green 25%)}}:is(input, button):is(:hover, :focus){color:oklch(40% 0.268735435 34.568626)}
*//*! an important comment */:root{--mainColor: #12345678;}body{color:var(--mainColor);font-family:system-ui}a{color:rgb(0 0 100% / 90%);&:hover{color:rebeccapurple}> span{color:color-mix(in oklch, cyan, green 25%)}}:is(input, button):is(:hover, :focus){color:oklch(40% 0.268735435 34.568626)}

0 comments on commit 4a25af0

Please sign in to comment.