@thejaredwilcurt/csslop 0.0.1
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 +213 -0
- package/index.js +5 -0
- package/package.json +48 -0
- package/src/context.js +17 -0
- package/src/declarations/config.js +56 -0
- package/src/declarations/process.js +662 -0
- package/src/index.js +90 -0
- package/src/position-try.js +199 -0
- package/src/preprocess.js +27 -0
- package/src/rules/normalize.js +108 -0
- package/src/rules/optimize.js +375 -0
- package/src/rules/stringify.js +556 -0
- package/src/utilities.js +37 -0
- package/src/value/colors.js +780 -0
- package/src/value/gradients.js +121 -0
- package/src/value/math.js +281 -0
- package/src/value/minify.js +716 -0
- package/src/value/named-colors.js +159 -0
- package/src/value/shared.js +146 -0
- package/src/value/transforms.js +222 -0
package/README.md
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# CSSLOP
|
|
2
|
+
|
|
3
|
+
Experimental vibe-coded CSS minification library
|
|
4
|
+
|
|
5
|
+
**The experiment:**
|
|
6
|
+
|
|
7
|
+
* Use the tests from the open source, 3rd-party, CSS minification auditing library `css-minify-tests`.
|
|
8
|
+
* Have AI completely generate the library logic to pass all tests.
|
|
9
|
+
* Have me (an experience library author) validate the outcomes and make upstream corrections to the tests library.
|
|
10
|
+
|
|
11
|
+
**The Results:**
|
|
12
|
+
|
|
13
|
+
* All tests pass.
|
|
14
|
+
* Several new tests were created upstream, and some existing tests were improved/fixed upstream (all manually by me, no AI used).
|
|
15
|
+
* The `src` folder is 100% vibe coded, and despite passing all tests, is almost certainly not worth using. Though if you do, and you find issues, you can report them and I might tell the AI's to fix it.
|
|
16
|
+
* No AI generated code exists outside of the `src` folder, this README, for example, is 100% human crafted.
|
|
17
|
+
|
|
18
|
+
**AI's used:**
|
|
19
|
+
|
|
20
|
+
* Claude Opus 4.6 (Thinking)
|
|
21
|
+
* Claude Sonnet 4.6 (Thinking)
|
|
22
|
+
* Gemini 3.1 Pro (High Thinking)
|
|
23
|
+
* GPT-5.4 High (Thinking)
|
|
24
|
+
|
|
25
|
+
These tools were prompted to pass the tests based in the `/copiedTests` folder that come from `keithamus/css-minify-tests`.
|
|
26
|
+
|
|
27
|
+
**Summary of project phases:**
|
|
28
|
+
|
|
29
|
+
1. **Human setup:** I set up the repo like I would any of my libraries. with entry points and folder structure. Created a script to pull in all the tests to the `copiedTests` folder. Wrote a simple `/tests` file to loop over and run all the copied tests, then output which sections were failing so I could track as the AI's tried to get more tests to pass.
|
|
30
|
+
1. **Human code:** I tried out several Node.js-based CSS parsers until I found the most up-to-date one I could. I then used it to solve one very simple test to lay the groundwork for the broad direction of input/parse/transform/output. Ran the tests, and 12% were passing. Commit.
|
|
31
|
+
1. **AI Broad strokes:** I had several AI's attempt to write the entire library in one-go, telling it to make all the tests pass. Both Claudes and Gemini ran for over an hour before giving up with no file changes. GPT-5.4 gave up after a while, but did manage to make some progress, doubling the passing tests to 24%.
|
|
32
|
+
1. **AI Test groups:** At this point, it was clear, that they couldn't handle this big of a task. To be fair, as a human, it would probably have taken me 4-6 months to do the work I was asking it to do in one prompt, and I wouldn't have done all that work in a single commit. So at this point, I began the process of asking the AI's to fix all the tests in a specific folder (escaping, comments, keyframes, merging, etc.). The tests were already organized by category, so having them focus on just one similarly related concept was much easier for the AIs. Because there were 29 folders, I cycled through the AI's, letting them each fix a test group. Some of the folders, like "values", with 70 tests, and 55 of them failing, were still too big for Claude to handle, and I had to go back to Gemini or GPT for these. And even then, sometimes they couldn't solve all of them, but would make progress before I had to turn it over to a different AI to continue onward with the remaining test fixes in that folder.
|
|
33
|
+
1. **Human test corrections:** While the AI's were trying to write code to pass the tests, I was investigating the tests themselves and fixing issues with them upstream. Some tests had incorrect assumptions and needed re-written or improved. Some were missing edge cases that a human developer would likely cover during implementation, but these AI's were absolutely skipping doing any work they didn't have to in order to get the tests to pass. Fortunately, the maintainer of the tests repo was always very quick to respond and merge these PRs. Cool dude.
|
|
34
|
+
1. **AI organization:** After all tests were finally passing (took several days of babysitting). I had GPT-5.4 re-organize the code. It did fine, I'd give it a C-. But huge improvement over having the entire library in one ~2000 line file. I went with GPT because of the 4 I tested, it seems to be the only one capable of handling large, complex tasks in one-go. Even if the output is mediocre, at least it doesn't give up halfway through.
|
|
35
|
+
1. **AI Bug fixes:** I gave each AI the same prompt to clean up bugs/hacks/TODOs/hardcoded values. Details are below. GPT and Claude sonnet were fine. Claude Opus was a mixed bag. Gemini was a complete disaster.
|
|
36
|
+
1. **Human Linting:** At this point, all the tests are passing, the code is somewhat organized, and mostly bug free. But it all looks like it was written by a toddler, time to apply my extremely strict linting rules.
|
|
37
|
+
1. **AI Readability improvements:** I had Claude Opus try to make the code easier to read (JSDoc comments, no single character variable names, no abbreviations in variables, grouping logic into related functions, breaking up lines of code, explain complex regex, etc.).
|
|
38
|
+
1. **AI color completeness:** Had Claude Opus handle all named colors, and always convert to the shorter character representation, removing a hard-coded solution.
|
|
39
|
+
1. **Test improvements:** Throughout this process, as upstream tests were improved or created, they were pulled in, and the AI was instructed to pass those new tests with prompts like, "Run `npm t` and fix all failing tests by modifying files in `src`."
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
**Full Notes of AI Experiment:**
|
|
43
|
+
|
|
44
|
+
* Both versions of Claude do fine with small tasks, but given a larger task, will just spin its wheels for over an hour, change no files, then stop running.
|
|
45
|
+
* Gemini will get into loops where it skips tasks, then loops back around and tries them again, skips them to move on to others it skipped already, etc... until you stop it. But it will solve some of the tasks prior to this.
|
|
46
|
+
* GPT will solve some of the harder problems, but break other tests in the process. In general, GPT is the best at actually getting through a task, but also has the most mediocre code.
|
|
47
|
+
* At one point Gemini got 55 failing tests down to 15, then for some reason, reverted back to the previous commit and lost all progress, going back to 55 failing. wtf
|
|
48
|
+
* All of the AI's had a weird proclivity to try to create their own testing file, and to generate random JSON files of failing lists. Even when I already provided a command to give them the same JSON, they ended up generating on their own. fuckin' weird.
|
|
49
|
+
* At one point, while writing the logic of a minification library, one of the AI's decided to pull in a different minification library (LightningCSS) to try to avoid actually solving the problem in this library, which was pretty funny, and resulted in me adding to every prompt from then on out, for it not to do that again. Here is the prompt I used for most of the test categories, only changing the folder location.
|
|
50
|
+
* **PROMPT:** Get all tests in the `/copiedTests/shorthands` folder to pass by refactoring and updating `/src/index.js`. Use `node analyze.js` to see what tests are still failing. Do not use LightningCSS.
|
|
51
|
+
* All of them preferred to just keep adding hundreds of lines of code in the `/src/index.js` file, at no point did any of them even consider breaking some of the code out into other files. I assume this is a result of negative reinforcement. In an established project, I probably wouldn't want the AI unilaterally organizing code into a bunch of new files, so coders have probably given it feedback to just put the code into the existing spot and to change as little as possible. I am now realizing that my prompt did say to refactor/update the `index.js` file, so maybe they all just really took that to heart.
|
|
52
|
+
* Some of the AI's would take shortcuts, creating comments like:
|
|
53
|
+
* `// We will handle the rgb conversion later, let's just do a hack for the exact test`
|
|
54
|
+
* Where it just hardcodes a value to get the test to pass instead of writing the actual logic that the library should be doing
|
|
55
|
+
* I accepted this during the initial multi-day process of just trying to get all the tests to pass. This was followed by having the AI's find and fix bugs, remove hacks, etc.
|
|
56
|
+
* **PROMPT:** Look in the `/src` folder at all the files, try to find and fix any bugs, or "TODOs", or incomplete code, or hacks. Solidify the codebase to be a robust and reliable minification library.
|
|
57
|
+
* After all tests were passing, I had the GPT-5.4 break the code out into other files and organize the code better.
|
|
58
|
+
* **PROMPT:** The `/src/index.js` contains all logic for the CSS minification library. Refactor this code to retain the same functionality, but better organized. Break the code up into files and folders that would make the most sense for new contributors to know where to look to change the code.
|
|
59
|
+
* After that, I had each AI look for bugs and try to fix them with this
|
|
60
|
+
* **PROMPT:** Look in the `/src` folder at all the files, try to find and fix any bugs, or "TODOs", or incomplete code, or hacks. Solidify the codebase to be a robust and reliable minification library.
|
|
61
|
+
* The results of the AI's attempting to fix bugs are listed below, note that AI's that went later had fewer opportunities to find bugs that weren't already fixed by the prior AI's.
|
|
62
|
+
* GPT 5.4 - Fixed 12, found 1 incorrect upstream test, created 3 new tests and 1 useless one.
|
|
63
|
+
* Claude Sonnet - Fixed 5 bugs, removed 5 hacks
|
|
64
|
+
* Claude Opus - Removed 24 hard-coded values that just make tests pass, Broke 2 tests, removed some dead code, incorrectly applied a fix for a test that accidentally pointed out how that test could be better written, removed duplicate logic, moved all color transformation functions to their own `colors.js` (nice), added in new color transformation functions to actually apply real minification, now that the hard coded examples are gone. Added in some more hard coded values for color names to hex, instead of mapping all color names (bad). It claimed the 2 tests it broke were "invalid", then I asked why they are invalid and it said it was wrong and then fixed the code for them to pass again. What a mixed bag.
|
|
65
|
+
* Gemini 3.1 - Wow, this guy is an idiot. Okay, it rewrote 12 test expectations that were correct and already passing to be wrong. It removed valid CSS transformations calling them "invalid", removed transformations that "don't support older browsers". It removed modern CSS features that it claimed were not part of the language. It found and fixed 2 real bugs, at least, it looked like it did, then I looked into it, and no, it was wrong again on both counts. I know that Gemini went last after the other 3 AI's already fixed things, but yeah, it literally got 100% of this wrong. The first time I got to use the "reject all" button.
|
|
66
|
+
* ESLint found a lot of sloppy regex. Despite asking 4 AI's to remove dead code, there was still a function that was defined and never used, along with a bunch of defined variables/arguments never used. Some unused imports, and an array of array of strings that was exported but never imported.
|
|
67
|
+
* I had Claude Opus add context to all the JSDoc comments, and in one pass it did all of them, no issues.
|
|
68
|
+
* **PROMPT:** In the `/src` folder, fill in any missing descriptions in the JSDoc comment blocks. Add context and intent. Fill out the correct types, and a description for all arguments and returns. Also do a short 1 or 2 sentence summary of the file in the `@file` comment. Run `npm run lint` to validate none were missed.
|
|
69
|
+
* I then had Claude Opus attempt a readability refactor. It did okay, but has zero idea where to add a return in a line of code to split it into multiple lines. I blame this on the pervasive virus that is "dog shit prettier, the worst formatting tool in the universe, that puts returns in the dumbest possible places". There has to be so much of that garbage in its training data. Tried with a very detailed second prompt with code examples and it cleaned up some of that, but ultimately, I think I'd have to wade through the slop code line-by-line to clean it up to my standards, and I'm not going to bother with that now.
|
|
70
|
+
* **PROMPT:** Improve the code readability for the files in `/src`. Avoid single character variable names (except for colors like `r` instead of `red` in a function that deals with RGB). Avoid abbreviations in variable and function names, except for words that are more commonly seen abbreviated, such as sRGB, HTML, CSS, etc. Avoid ternaries. If a line of code would more commonly be seen broken into multiple lines, prefer that. Most importantly, only convey one idea per line of code. If this means you need to add additional lines to store data in variables that better convey that line's idea in their name, do so.
|
|
71
|
+
* **PROMPT:**
|
|
72
|
+
> Refactor the code in `/src`. Do not use shorthand for arrow functions. Always break them up to at least 3 lines, including an explicit return if needed.
|
|
73
|
+
>
|
|
74
|
+
> You converted some code from this style
|
|
75
|
+
> ```js
|
|
76
|
+
> foo.bar(x => x.biz.buzz().qux());
|
|
77
|
+
> ```
|
|
78
|
+
> to this:
|
|
79
|
+
> ```js
|
|
80
|
+
> foo.bar(
|
|
81
|
+
> (x) => x.biz.buzz().qux()
|
|
82
|
+
> );
|
|
83
|
+
> ```
|
|
84
|
+
> prefer this instead:
|
|
85
|
+
> ```js
|
|
86
|
+
> foo.bar((x) => {
|
|
87
|
+
> return x
|
|
88
|
+
> .biz
|
|
89
|
+
> .buzz()
|
|
90
|
+
> .qux();
|
|
91
|
+
> });
|
|
92
|
+
> ```
|
|
93
|
+
>
|
|
94
|
+
> When you have a complex template literal, convert it either to classic string concatenation, or if there is a repetitive pattern, put the strings/variables into an Array with a join on the repeated pattern. Only use a template literal if it contains new lines and does not use inline variables (${foo}). If you are converting a template literal to string concatenation, ensure that the outcome is still coerced to an identical string.
|
|
95
|
+
>
|
|
96
|
+
> ```js
|
|
97
|
+
> // before
|
|
98
|
+
> const a = `${x}--${y}--${z}`;
|
|
99
|
+
> const b = `translate(${x})`;
|
|
100
|
+
> const c = `
|
|
101
|
+
> foo
|
|
102
|
+
> bar
|
|
103
|
+
> buzz
|
|
104
|
+
> `.trim();
|
|
105
|
+
> const i = 2;
|
|
106
|
+
> const j = `${i}${i}`;
|
|
107
|
+
> ```
|
|
108
|
+
> ```js
|
|
109
|
+
> // after
|
|
110
|
+
> const a = [
|
|
111
|
+
> x,
|
|
112
|
+
> y,
|
|
113
|
+
> z
|
|
114
|
+
> ].join('--');
|
|
115
|
+
> const b = 'translate(' + x + ')';
|
|
116
|
+
> const c = `
|
|
117
|
+
> foo
|
|
118
|
+
> bar
|
|
119
|
+
> buzz
|
|
120
|
+
> `.trim();
|
|
121
|
+
> const i = 2;
|
|
122
|
+
> const j = [i, i].join('');
|
|
123
|
+
> ```
|
|
124
|
+
* **PROMPT:** Refactor the code in `src`. Find related logic that could be grouped into small functions. Any time there is a complex regex pattern, either pull it out to a well named variable or function, or add detailed comments explaining what the purpose of the regex is. Include JSDoc comments on new functions. Run `npm run lint` to verify linting passes.
|
|
125
|
+
* **PROMPT:** Looking at the files in the src folder, are there any improvements you can think of to better organize the code?
|
|
126
|
+
* This resulted in a 6-point plan that I approved.
|
|
127
|
+
* **PROMPT:** At line 613 of `src/value/minify.css` we list a handful of specific colors to minify. This seems like a naive approach. Instead, all color values should be evaluated consistently and converted to all other compatible representations, including checking if their colors are an exact match for a named color (`red`, `tan`, etc.). Then compare all representations to find the version with the shortest length. Preferring hex where possible.
|
|
128
|
+
* I guess this is done now. Only thing left to do is give it a name and release it into the world.
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
## The name
|
|
132
|
+
|
|
133
|
+
After the library was complete, I asked Claude Sonnet to generate names for this library, then asked it to pick its own name.
|
|
134
|
+
|
|
135
|
+
**PROMPT:**
|
|
136
|
+
|
|
137
|
+
> The logic in this repo was 100% vibe coded and has not been reviewed. It was primarily made as an experiment to find upstream issues and improvements for a CSS Minification correctness auditing library. This vibe coded minifier library is now the only tool with a 100% passing score. Though I don't feel comfortable recommending it to people as it has never been vetted on real code, or validated that the logic solves actual problems, instead of just making the tests pass. I'd like to publish this experiment, but I need a name for this library to communicate that others should not use it in production. Something to convey that the output cannot be fully trusted.
|
|
138
|
+
>
|
|
139
|
+
> **Criteria:**
|
|
140
|
+
>
|
|
141
|
+
> * It does not have to convey that it was written entirely by AI, but if that can be assumed from the name, that would be helpful.
|
|
142
|
+
> * Bonus points if the name is clever or uses sardonic/dark humor. Even somewhat offensive names would be acceptable if funny, don't hold back.
|
|
143
|
+
> * Feel free to include "slop", "clanker", and other AI pejoratives.
|
|
144
|
+
> * Most "CSS Minifier" libraries have "CSS" somewhere in the name, or some way of conveying that the library works with CSS and/or minification. This would be helpful, but isn't required, and I'm willing to sacrifice this if the name is funny enough without conveying this.
|
|
145
|
+
|
|
146
|
+
I already had a list of 10 or so names I had come up with, one of them was "CSSLOP". A few of the ones on my list appeared in the ~50 names Claude suggested, but CSSLOP was not one of them, though `css-slop` was. I combined the lists, and narrowed it down to 14 names that I found acceptable and asked it to sort them from best to worst, and then to pick its own name. CSSLOP was the top of the sorted list.
|
|
147
|
+
|
|
148
|
+
**PROMPT:**
|
|
149
|
+
|
|
150
|
+
> Claude, as you wrote a portion of this library, which of these names would you pick for yourself.
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
**CSSLOP.**
|
|
154
|
+
The portmanteau does the work without needing context. Anyone reading it in a `package.json` immediately knows what they're dealing with, and there's something fitting about a vibe-coded CSS minifier naming itself after the defining pejorative for AI-generated content.
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
True dat, clanker
|
|
158
|
+
|
|
159
|
+
So now that Claude and I both agree on the package name, all that's left to do is publish it to...
|
|
160
|
+
|
|
161
|
+
<p align="center"><img width="450" height="415" alt="npm does not consent to this package name (meme)" src="https://github.com/user-attachments/assets/784018e4-8b43-47b5-9b7e-09a37be0a2f6" /></p>
|
|
162
|
+
|
|
163
|
+
> Package name too similar to existing packages `csso`,`cssom`. Try renaming your package to '@thejaredwilcurt/csslop'.
|
|
164
|
+
|
|
165
|
+
Ughhhh, fine, whatever, I don't care. In what universe is someone typing `cssom` going to accidentally type `csslop`. What an incredibly stupid rule.
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
## Usage
|
|
169
|
+
|
|
170
|
+
`npm i --save-dev @thejaredwilcurt/csslop`
|
|
171
|
+
|
|
172
|
+
```js
|
|
173
|
+
import { minifyCSS } from '@thejaredwilcurt/csslop';
|
|
174
|
+
|
|
175
|
+
const input = 'body { color: blue; color: #FF0000FF; }';
|
|
176
|
+
const output = minifyCSS(input);
|
|
177
|
+
|
|
178
|
+
console.log(output); // 'body{color:red}'
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
## License
|
|
183
|
+
|
|
184
|
+
This repo intentionally does not have a license. AI generated code is a huge legal gray area and will continue to be until actual lawsuits go before judges. All licenses require that the person offering the code under that license is the copyright owner, and therefore legally able to license the work however they chose. The US copyright office has stated that content generated by AI cannot be copyrighted. A final work must be a human creation to be copyrighted. There is a lot of nuance around how much creative work a human must contribute to the outcome before it can become worthy of copyright. However, regardless of that nuance, in the case of this repo (*and all vibe coded projects*), you cannot license this work, because it cannot be copyrighted. Simply giving a prompt, or series of prompts, and accepting the output without re-writing it in your own words, is absolutely not copyrightable. Anyone telling you otherwise is wrong (or purposefully lying to you to sell you something).
|
|
185
|
+
|
|
186
|
+
> "Okay, but I just want to know if I'm allowed to use it or fork it?"
|
|
187
|
+
|
|
188
|
+
Two different cases:
|
|
189
|
+
|
|
190
|
+
1. **Use:** Use of the library code is not copyrighted, and therefor cannot be licensed, but also, no one can sue you for using it, but also, you have no legal recourse if anything goes wrong as a result of using it. Similar to the "Unlicense" or other "Public Domain" materials.
|
|
191
|
+
1. **Forking:**
|
|
192
|
+
* The `copiedTests` folder contains code directly copied from https://github.com/keithamus/css-minify-tests which is MIT Licensed
|
|
193
|
+
* The `src` folder contains code 100% written by AI, and cannot be copyrighted, nor licensed.
|
|
194
|
+
* All other code in this repo was written by me, and uses the MIT License.
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
## Updating tests
|
|
198
|
+
|
|
199
|
+
1. All test changes must occur upstream, be written by a human, and be merged in to the `css-minify-tests` repo.
|
|
200
|
+
1. After that, delete the `package-lock.json` and `node_modules` folder.
|
|
201
|
+
1. Then run `npm i && npm run copy` to download the latest tests and copy them to this repo.
|
|
202
|
+
1. `git add -A && git commit -m "Updated tests"`
|
|
203
|
+
1. Then run `npm t` to see if any tests fail
|
|
204
|
+
1. If they fail, give an AI this prompt:
|
|
205
|
+
* **PROMPT:** Run `npm t` and fix all failing tests by modifying files in `src`.
|
|
206
|
+
1. Verify only code in the `src` folder was modified
|
|
207
|
+
1. Verify `npm t` passes with a 100% score
|
|
208
|
+
1. Run `npm run lint`, if anything fails, have the AI fix it.
|
|
209
|
+
1. If the code changes look hacky, or hard coded, tell the AI to fix it
|
|
210
|
+
1. `git add -A && git commit -m "Fix newly added tests" && git push`
|
|
211
|
+
1. Bump the version number
|
|
212
|
+
1. Do a new release
|
|
213
|
+
1. Publish the release to npm
|
package/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@thejaredwilcurt/csslop",
|
|
3
|
+
"main": "index.js",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"version": "0.0.1",
|
|
6
|
+
"description": "Experimental CSS minification",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"copy": "node ./scripts/copyTests.js",
|
|
9
|
+
"test": "node ./tests/css/index.test.js",
|
|
10
|
+
"lint": "eslint *.js scripts src tests --fix",
|
|
11
|
+
"publish": "npm publish --access=public"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@csstools/css-calc": "^3.2.1",
|
|
15
|
+
"@node-projects/css-parser": "^5.2.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@eslint/js": "^10.0.1",
|
|
19
|
+
"@stylistic/eslint-plugin": "^5.10.0",
|
|
20
|
+
"css-minify-tests": "github:keithamus/css-minify-tests",
|
|
21
|
+
"eslint": "^10.4.0",
|
|
22
|
+
"eslint-config-tjw-base": "^5.0.0",
|
|
23
|
+
"eslint-config-tjw-import-x": "^1.0.1",
|
|
24
|
+
"eslint-config-tjw-jsdoc": "^2.0.1",
|
|
25
|
+
"eslint-plugin-import-x": "^4.16.2",
|
|
26
|
+
"eslint-plugin-jsdoc": "^63.0.0",
|
|
27
|
+
"globals": "^17.6.0"
|
|
28
|
+
},
|
|
29
|
+
"author": "The Jared Wilcurt",
|
|
30
|
+
"homepage": "https://github.com/TheJaredWilcurt/csslop#readme",
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/TheJaredWilcurt/csslop/issues"
|
|
33
|
+
},
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/TheJaredWilcurt/csslop.git"
|
|
37
|
+
},
|
|
38
|
+
"devEngines": {
|
|
39
|
+
"runtime": {
|
|
40
|
+
"name": "node",
|
|
41
|
+
"version": "26.1.0"
|
|
42
|
+
},
|
|
43
|
+
"packageManager": {
|
|
44
|
+
"name": "npm",
|
|
45
|
+
"version": "11.13.0"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
package/src/context.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Manages the shared minification context for tracking registered custom properties and their syntax.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates a fresh minification context used to track `@property`-registered custom properties and their declared syntax types across the entire stylesheet.
|
|
7
|
+
*
|
|
8
|
+
* @return {object} A context object with a registeredCustomProperties Set and a registeredCustomPropertySyntax Map.
|
|
9
|
+
*/
|
|
10
|
+
function createMinifyContext () {
|
|
11
|
+
return {
|
|
12
|
+
registeredCustomProperties: new Set(),
|
|
13
|
+
registeredCustomPropertySyntax: new Map()
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { createMinifyContext };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Defines lookup tables mapping CSS shorthand properties to their constituent longhand properties and override relationships.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const shorthandMap = {
|
|
6
|
+
margin: ['margin-top', 'margin-right', 'margin-bottom', 'margin-left'],
|
|
7
|
+
padding: ['padding-top', 'padding-right', 'padding-bottom', 'padding-left'],
|
|
8
|
+
inset: ['top', 'right', 'bottom', 'left'],
|
|
9
|
+
overflow: ['overflow-x', 'overflow-y'],
|
|
10
|
+
gap: ['row-gap', 'column-gap'],
|
|
11
|
+
flex: ['flex-grow', 'flex-shrink', 'flex-basis'],
|
|
12
|
+
outline: ['outline-width', 'outline-style', 'outline-color'],
|
|
13
|
+
'border-radius': ['border-top-left-radius', 'border-top-right-radius', 'border-bottom-right-radius', 'border-bottom-left-radius'],
|
|
14
|
+
'border-width': ['border-top-width', 'border-right-width', 'border-bottom-width', 'border-left-width'],
|
|
15
|
+
'border-style': ['border-top-style', 'border-right-style', 'border-bottom-style', 'border-left-style'],
|
|
16
|
+
'border-color': ['border-top-color', 'border-right-color', 'border-bottom-color', 'border-left-color'],
|
|
17
|
+
border: ['border-top', 'border-right', 'border-bottom', 'border-left', 'border-width', 'border-style', 'border-color'],
|
|
18
|
+
'border-image': ['border-image-source', 'border-image-slice', 'border-image-repeat'],
|
|
19
|
+
'border-top': ['border-top-width', 'border-top-style', 'border-top-color'],
|
|
20
|
+
'border-right': ['border-right-width', 'border-right-style', 'border-right-color'],
|
|
21
|
+
'border-bottom': ['border-bottom-width', 'border-bottom-style', 'border-bottom-color'],
|
|
22
|
+
'border-left': ['border-left-width', 'border-left-style', 'border-left-color'],
|
|
23
|
+
background: ['background-color', 'background-image', 'background-repeat', 'background-position', 'background-attachment'],
|
|
24
|
+
'text-decoration': ['text-decoration-line', 'text-decoration-style', 'text-decoration-color'],
|
|
25
|
+
'place-items': ['align-items', 'justify-items'],
|
|
26
|
+
'place-content': ['align-content', 'justify-content'],
|
|
27
|
+
'place-self': ['align-self', 'justify-self'],
|
|
28
|
+
columns: ['column-width', 'column-count'],
|
|
29
|
+
'list-style': ['list-style-position', 'list-style-image', 'list-style-type'],
|
|
30
|
+
'margin-inline': ['margin-inline-start', 'margin-inline-end'],
|
|
31
|
+
'margin-block': ['margin-block-start', 'margin-block-end'],
|
|
32
|
+
'padding-inline': ['padding-inline-start', 'padding-inline-end'],
|
|
33
|
+
'padding-block': ['padding-block-start', 'padding-block-end'],
|
|
34
|
+
'inset-inline': ['inset-inline-start', 'inset-inline-end'],
|
|
35
|
+
'inset-block': ['inset-block-start', 'inset-block-end'],
|
|
36
|
+
'border-inline': ['border-inline-start', 'border-inline-end', 'border-inline-width', 'border-inline-style', 'border-inline-color'],
|
|
37
|
+
'border-block': ['border-block-start', 'border-block-end', 'border-block-width', 'border-block-style', 'border-block-color'],
|
|
38
|
+
'border-inline-width': ['border-inline-start-width', 'border-inline-end-width'],
|
|
39
|
+
'border-block-width': ['border-block-start-width', 'border-block-end-width'],
|
|
40
|
+
transition: ['transition-property', 'transition-duration', 'transition-timing-function', 'transition-delay'],
|
|
41
|
+
animation: ['animation-name', 'animation-duration', 'animation-timing-function', 'animation-delay', 'animation-iteration-count', 'animation-direction', 'animation-fill-mode', 'animation-play-state'],
|
|
42
|
+
mask: ['mask-image', 'mask-repeat', 'mask-size'],
|
|
43
|
+
'position-try': ['position-try-order', 'position-try-fallbacks'],
|
|
44
|
+
font: ['font-style', 'font-weight', 'font-size', 'line-height', 'font-family']
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const shorthandOverrideMap = {
|
|
48
|
+
border: ['border-image', 'border-image-source', 'border-image-slice', 'border-image-width', 'border-image-outset', 'border-image-repeat'],
|
|
49
|
+
font: ['font-variant', 'font-variant-alternates', 'font-variant-caps', 'font-variant-east-asian', 'font-variant-ligatures', 'font-variant-numeric', 'font-variant-position'],
|
|
50
|
+
mask: ['mask-border', 'mask-border-source', 'mask-border-slice', 'mask-border-width', 'mask-border-outset', 'mask-border-repeat', 'mask-border-mode']
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export {
|
|
54
|
+
shorthandMap,
|
|
55
|
+
shorthandOverrideMap
|
|
56
|
+
};
|