/
githubmirror
/
tabler
Обзор
Документация
Войти
/
githubmirror
/
tabler
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
core/scss/tests/css-var-prefix.test.mjs
61 строка
3 KB
Bartosz-Do
Move `--tblr-` custom-property prefixing from Sass to PostCSS (#2795)
06 авг 2026, 00:48
Не верифицирован
06 авг 2026, 00:48
cad8eb8
Код
Авторство
О чём код?
// Guards the build-time `--tblr-` prefixing configured in .build/css-var-prefix.ts. // // Custom properties are authored bare in scss, so a name Tabler owns and a name // a vendor library owns look identical in source — only `cssVarIgnore` tells // them apart. Get that wrong and nothing fails: the vendor's variable quietly // becomes `--tblr-fc-border-color`, the library never reads it, and the theming // is simply gone. // // tabler-vendors.scss is where every foreign name lives, so its full set of // custom-property names is snapshotted. A vendor override added without the // matching `cssVarIgnore` entry shows up in the snapshot diff as a `--tblr-` // name that plainly belongs to someone else. import { describe, expect, it } from 'vitest' import { readdirSync } from 'node:fs' import path from 'node:path' import { fileURLToPath } from 'node:url' import { compile as compileSass } from 'sass' import postcss from 'postcss' import prefixCustomProperties from 'postcss-prefix-custom-properties' import { cssVarIgnore, cssVarPrefix, inlineValueComments } from '../../../.build/css-var-prefix.ts' const scssDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..') // The same two passes build-css.ts runs before autoprefixer. async function buildCustomPropertyNames(entry) { const { css } = compileSass(path.join(scssDir, entry), { loadPaths: ['node_modules'], style: 'expanded' }) const result = await postcss([ inlineValueComments, prefixCustomProperties({ prefix: cssVarPrefix, ignore: cssVarIgnore }), ]).process(css, { from: undefined }) const names = new Set() result.root.walkDecls((decl) => { if (decl.prop.startsWith('--')) names.add(decl.prop) for (const [, name] of decl.value.matchAll(/var\(\s*(--[\w-]+)/g)) names.add(name) }) result.root.walkAtRules('property', (atRule) => names.add(atRule.params.trim())) return [...names].sort() } describe('css custom-property prefixing', () => { it('leaves vendor-owned names alone and prefixes everything else', async () => { await expect(buildCustomPropertyNames('tabler-vendors.scss')).resolves.toMatchSnapshot() }) it('has no dead entries in the ignore list', async () => { // A pattern matching nothing means the vendor it protected is gone, or the // name drifted — either way the entry no longer guards anything. // Every entry point, since foreign names are spread across the bundles. const entries = readdirSync(scssDir).filter((file) => file.endsWith('.scss') && !file.startsWith('_')) const perEntry = await Promise.all(entries.map(buildCustomPropertyNames)) const all = [...new Set(perEntry.flat())] for (const pattern of cssVarIgnore) { const matches = pattern instanceof RegExp ? all.some((name) => pattern.test(name)) : all.includes(pattern) expect(matches, `unused cssVarIgnore entry: ${pattern}`).toBe(true) } }) })