Skip to content

Commit 0944777

Browse files
committed
feat: make postcssIsolateStyles idempotent
BREAKING CHANGE: `includeFiles` option in `postcssIsolateStyles` now defaults to `[/vp-doc\.css/, /base\.css/]` You can remove explicit `includeFiles` if you were using it just to run it on `vp-doc.css`. To revert back to older behavior pass `includeFiles: [/base\.css/]`. The underlying implementation is changed and `transform` and `exclude` options are no longer supported. Use `postcss-prefix-selector` directly if you've advanced use cases.
1 parent 991c780 commit 0944777

File tree

12 files changed

+460
-459
lines changed

12 files changed

+460
-459
lines changed

__tests__/unit/node/postcss/isolateStyles.test.ts

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,26 @@
1-
import {
2-
postcssIsolateStyles,
3-
splitSelectorPseudo
4-
} from 'node/postcss/isolateStyles'
1+
import { postcssIsolateStyles } from 'node/postcss/isolateStyles'
2+
import postcss from 'postcss'
53

6-
// helper to run plugin transform on selector
7-
function apply(
8-
prefixPlugin: ReturnType<typeof postcssIsolateStyles>,
9-
selector: string
10-
) {
11-
// `prepare` is available on the runtime plugin but missing from the types, thus cast to `any`
12-
const { Rule } = (prefixPlugin as any).prepare({
13-
root: { source: { input: { file: 'foo/base.css' } } }
14-
})
15-
const rule = { selectors: [selector] }
16-
Rule(rule, { result: {} })
17-
return rule.selectors[0]
4+
function apply(selector: string) {
5+
const { root } = postcss([postcssIsolateStyles()]).process(`${selector} {}`)
6+
return (root.nodes[0] as any).selector
187
}
198

209
describe('node/postcss/isolateStyles', () => {
21-
const plugin = postcssIsolateStyles()
22-
2310
test('splitSelectorPseudo skips escaped colon', () => {
24-
const input = '.foo\\:bar'
25-
const [selector, pseudo] = splitSelectorPseudo(input)
26-
expect(selector).toBe(input)
27-
expect(pseudo).toBe('')
11+
expect(apply('.foo\\:bar')).toBe(
12+
'.foo\\:bar:not(:where(.vp-raw, .vp-raw *))'
13+
)
2814
})
2915

3016
test('splitSelectorPseudo splits on pseudo selectors', () => {
31-
const input = '.button:hover'
32-
const [selector, pseudo] = splitSelectorPseudo(input)
33-
expect(selector).toBe('.button')
34-
expect(pseudo).toBe(':hover')
17+
expect(apply('.button:hover')).toBe(
18+
'.button:not(:where(.vp-raw, .vp-raw *)):hover'
19+
)
3520
})
3621

37-
it('postcssIsolateStyles inserts :not(...) in the right place', () => {
38-
const input = '.disabled\\:opacity-50:disabled'
39-
const result = apply(plugin, input)
40-
expect(result).toBe(
22+
test('postcssIsolateStyles inserts :not(...) in the right place', () => {
23+
expect(apply('.disabled\\:opacity-50:disabled')).toBe(
4124
'.disabled\\:opacity-50:not(:where(.vp-raw, .vp-raw *)):disabled'
4225
)
4326
})

docs/en/guide/markdown.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,11 +277,11 @@ Wraps in a `<div class="vp-raw">`
277277
}
278278
```
279279

280-
It uses [`postcss-prefix-selector`](https://github.com/RadValentin/postcss-prefix-selector) under the hood. You can pass its options like this:
280+
You can pass its options like this:
281281

282282
```js
283283
postcssIsolateStyles({
284-
includeFiles: [/vp-doc\.css/] // defaults to /base\.css/
284+
includeFiles: [/custom\.css/] // defaults to [/vp-doc\.css/, /base\.css/]
285285
})
286286
```
287287

docs/es/guide/markdown.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,11 +256,11 @@ La clase `vp-raw` también puede ser usada directamente en elementos. El aislami
256256
}
257257
```
258258

259-
El utiliza [`postcss-prefix-selector`](https://github.com/RadValentin/postcss-prefix-selector) internamente. Puede pasar opciones así:
259+
Puede pasar opciones así:
260260

261261
```js
262262
postcssIsolateStyles({
263-
includeFiles: [/vp-doc\.css/] // o padrão é /base\.css/
263+
includeFiles: [/custom\.css/] // o padrão é [/vp-doc\.css/, /base\.css/]
264264
})
265265
```
266266

docs/fa/guide/markdown.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,11 +255,11 @@ export default defineConfig({
255255
}
256256
```
257257

258-
این از [`postcss-prefix-selector`](https://github.com/RadValentin/postcss-prefix-selector) استفاده می‌کند. می‌توانید گزینه‌های آن را به این صورت پاس بدهید:
258+
می‌توانید گزینه‌های آن را به این صورت پاس بدهید:
259259

260260
```js
261261
postcssIsolateStyles({
262-
includeFiles: [/vp-doc\.css/] // به طور پیش‌فرض /base\.css/
262+
includeFiles: [/custom\.css/] // به طور پیش‌فرض [/vp-doc\.css/, /base\.css/]
263263
})
264264
```
265265

docs/ko/guide/markdown.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,11 +255,11 @@ export default defineConfig({
255255
}
256256
```
257257

258-
이것은 기본적으로 [`postcss-prefix-selector`](https://github.com/RadValentin/postcss-prefix-selector)를 사용합니다. 다음과 같이 옵션을 전달할 수 있습니다:
258+
다음과 같이 옵션을 전달할 수 있습니다:
259259

260260
```js
261261
postcssIsolateStyles({
262-
includeFiles: [/vp-doc\.css/] // 기본값은 /base\.css/
262+
includeFiles: [/custom\.css/] // 기본값은 [/vp-doc\.css/, /base\.css/]
263263
})
264264
```
265265

docs/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"open-cli": "^8.0.0",
1616
"postcss-rtlcss": "^5.7.1",
1717
"vitepress": "workspace:*",
18-
"vitepress-plugin-group-icons": "^1.6.2",
19-
"vitepress-plugin-llms": "^1.7.2"
18+
"vitepress-plugin-group-icons": "^1.6.3",
19+
"vitepress-plugin-llms": "^1.7.3"
2020
}
2121
}

docs/pt/guide/markdown.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,11 +255,11 @@ A classe `vp-raw` também pode ser usada diretamente em elementos. O isolamento
255255
}
256256
```
257257

258-
Ele utiliza [`postcss-prefix-selector`](https://github.com/RadValentin/postcss-prefix-selector) internamente. Você pode passar opções assim:
258+
Você pode passar opções assim:
259259

260260
```js
261261
postcssIsolateStyles({
262-
includeFiles: [/vp-doc\.css/] // o padrão é /base\.css/
262+
includeFiles: [/custom\.css/] // o padrão é [/vp-doc\.css/, /base\.css/]
263263
})
264264
```
265265

docs/ru/guide/markdown.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,11 +281,11 @@ console.log('Привет, VitePress!')
281281
}
282282
```
283283

284-
Он использует [`postcss-prefix-selector`](https://github.com/RadValentin/postcss-prefix-selector) под капотом. Вы можете передать ему параметры следующим образом:
284+
Вы можете передать ему параметры следующим образом:
285285

286286
```js
287287
postcssIsolateStyles({
288-
includeFiles: [/vp-doc\.css/] // по умолчанию /base\.css/
288+
includeFiles: [/custom\.css/] // по умолчанию [/vp-doc\.css/, /base\.css/]
289289
})
290290
```
291291

docs/zh/guide/markdown.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,11 +255,11 @@ Wraps in a `<div class="vp-raw">`
255255
}
256256
```
257257

258-
它在底层使用 [`postcss-prefix-selector`](https://github.com/RadValentin/postcss-prefix-selector)你可以像这样传递它的选项:
258+
你可以像这样传递它的选项:
259259

260260
```js
261261
postcssIsolateStyles({
262-
includeFiles: [/vp-doc\.css/] // 默认为 /base\.css/
262+
includeFiles: [/custom\.css/] // 默认为 [/vp-doc\.css/, /base\.css/]
263263
})
264264
```
265265

package.json

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -111,19 +111,19 @@
111111
"mark.js": "8.11.1",
112112
"minisearch": "^7.1.2",
113113
"shiki": "^3.9.2",
114-
"vite": "^7.1.1",
114+
"vite": "^7.1.2",
115115
"vue": "^3.5.18"
116116
},
117117
"devDependencies": {
118-
"@clack/prompts": "^1.0.0-alpha.1",
119-
"@iconify/utils": "^3.0.0",
120-
"@mdit-vue/plugin-component": "^3.0.0",
121-
"@mdit-vue/plugin-frontmatter": "^3.0.0",
122-
"@mdit-vue/plugin-headers": "^3.0.0",
123-
"@mdit-vue/plugin-sfc": "^3.0.0",
124-
"@mdit-vue/plugin-title": "^3.0.0",
125-
"@mdit-vue/plugin-toc": "^3.0.0",
126-
"@mdit-vue/shared": "^3.0.0",
118+
"@clack/prompts": "^1.0.0-alpha.3",
119+
"@iconify/utils": "^3.0.1",
120+
"@mdit-vue/plugin-component": "^3.0.2",
121+
"@mdit-vue/plugin-frontmatter": "^3.0.2",
122+
"@mdit-vue/plugin-headers": "^3.0.2",
123+
"@mdit-vue/plugin-sfc": "^3.0.2",
124+
"@mdit-vue/plugin-title": "^3.0.2",
125+
"@mdit-vue/plugin-toc": "^3.0.2",
126+
"@mdit-vue/shared": "^3.0.2",
127127
"@polka/compression": "^1.0.0-next.28",
128128
"@rollup/plugin-alias": "^5.1.1",
129129
"@rollup/plugin-commonjs": "^28.0.6",
@@ -141,13 +141,12 @@
141141
"@types/minimist": "^1.2.5",
142142
"@types/node": "^24.2.1",
143143
"@types/picomatch": "^4.0.2",
144-
"@types/postcss-prefix-selector": "^1.16.3",
145144
"@types/prompts": "^2.4.9",
146145
"chokidar": "^4.0.3",
147146
"conventional-changelog-cli": "^5.0.0",
148147
"cross-spawn": "^7.0.6",
149148
"debug": "^4.4.1",
150-
"esbuild": "^0.25.8",
149+
"esbuild": "^0.25.9",
151150
"execa": "^9.6.0",
152151
"fs-extra": "^11.3.1",
153152
"get-port": "^7.1.0",
@@ -165,7 +164,7 @@
165164
"minimist": "^1.2.8",
166165
"nanoid": "^5.1.5",
167166
"ora": "^8.2.0",
168-
"oxc-minify": "^0.81.0",
167+
"oxc-minify": "^0.82.1",
169168
"p-map": "^7.0.3",
170169
"package-directory": "^8.1.0",
171170
"path-to-regexp": "^6.3.0",
@@ -174,7 +173,7 @@
174173
"playwright-chromium": "^1.54.2",
175174
"polka": "^1.0.0-next.28",
176175
"postcss": "^8.5.6",
177-
"postcss-prefix-selector": "^2.1.1",
176+
"postcss-selector-parser": "^7.1.0",
178177
"prettier": "^3.6.2",
179178
"prompts": "^2.4.2",
180179
"punycode": "^2.3.1",
@@ -194,7 +193,7 @@
194193
},
195194
"peerDependencies": {
196195
"markdown-it-mathjax3": "^4",
197-
"oxc-minify": "^0.81.0",
196+
"oxc-minify": "^0.82.1",
198197
"postcss": "^8"
199198
},
200199
"peerDependenciesMeta": {

0 commit comments

Comments
 (0)