blob: ad8b01c303a51168a121e35a22c4e8031ca3172f [file] [log] [blame]
Jack Franklina5fd0a42022-12-09 11:30:24 +00001'use strict';
2const browserslist = require('browserslist');
3const { isSupported } = require('caniuse-api');
4const fromInitial = require('./data/fromInitial.json');
5const toInitial = require('./data/toInitial.json');
6
7const initial = 'initial';
8
9// In most of the browser including chrome the initial for `writing-mode` is not `horizontal-tb`. Ref https://github.com/cssnano/cssnano/pull/905
10const defaultIgnoreProps = ['writing-mode', 'transform-box'];
11
12/**
13 * @type {import('postcss').PluginCreator<void>}
14 * @return {import('postcss').Plugin}
15 */
16function pluginCreator() {
17 return {
18 postcssPlugin: 'postcss-reduce-initial',
19 /** @param {import('postcss').Result & {opts: browserslist.Options & {ignore?: string[]}}} result */
20 prepare(result) {
21 const resultOpts = result.opts || {};
22 const browsers = browserslist(null, {
23 stats: resultOpts.stats,
24 path: __dirname,
25 env: resultOpts.env,
26 });
27
28 const initialSupport = isSupported('css-initial-value', browsers);
29 return {
30 OnceExit(css) {
31 css.walkDecls((decl) => {
32 const lowerCasedProp = decl.prop.toLowerCase();
33 const ignoreProp = new Set(
34 defaultIgnoreProps.concat(resultOpts.ignore || [])
35 );
36
37 if (ignoreProp.has(lowerCasedProp)) {
38 return;
39 }
40
41 if (
42 initialSupport &&
43 Object.prototype.hasOwnProperty.call(toInitial, lowerCasedProp) &&
44 decl.value.toLowerCase() ===
45 toInitial[/** @type {keyof toInitial} */ (lowerCasedProp)]
46 ) {
47 decl.value = initial;
48 return;
49 }
50
51 if (
52 decl.value.toLowerCase() !== initial ||
53 !fromInitial[/** @type {keyof fromInitial} */ (lowerCasedProp)]
54 ) {
55 return;
56 }
57
58 decl.value =
59 fromInitial[/** @type {keyof fromInitial} */ (lowerCasedProp)];
60 });
61 },
62 };
63 },
64 };
65}
66
67pluginCreator.postcss = true;
68module.exports = pluginCreator;