summaryrefslogtreecommitdiff
path: root/node_modules/postcss-reduce-initial/src/index.js
blob: 5432f7fea80b8375b7374163f0df2e6285b3842c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
'use strict';
const browserslist = require('browserslist');
const { isSupported } = require('caniuse-api');
const fromInitial = require('./data/fromInitial.json');
const toInitial = require('./data/toInitial.json');

const initial = 'initial';

// In most of the browser including chrome the initial for `writing-mode` is not `horizontal-tb`. Ref https://github.com/cssnano/cssnano/pull/905
const defaultIgnoreProps = ['writing-mode', 'transform-box'];
/** @typedef {{ignore?: string[]}} Options */

/**
 * @type {import('postcss').PluginCreator<Options>}
 * @param {Options} options
 * @return {import('postcss').Plugin}
 */
function pluginCreator(options = {}) {
  return {
    postcssPlugin: 'postcss-reduce-initial',
    /** @param {import('postcss').Result & {opts: browserslist.Options & {ignore?: string[]}}} result */
    prepare(result) {
      const resultOpts = result.opts || {};
      const browsers = browserslist(null, {
        stats: resultOpts.stats,
        path: __dirname,
        env: resultOpts.env,
      });

      const initialSupport = isSupported('css-initial-value', browsers);
      return {
        OnceExit(css) {
          css.walkDecls((decl) => {
            const lowerCasedProp = decl.prop.toLowerCase();
            const ignoreProp = new Set(
              defaultIgnoreProps.concat(options.ignore || [])
            );

            if (ignoreProp.has(lowerCasedProp)) {
              return;
            }

            if (
              initialSupport &&
              Object.prototype.hasOwnProperty.call(toInitial, lowerCasedProp) &&
              decl.value.toLowerCase() ===
                toInitial[/** @type {keyof toInitial} */ (lowerCasedProp)]
            ) {
              decl.value = initial;
              return;
            }

            if (
              decl.value.toLowerCase() !== initial ||
              !fromInitial[/** @type {keyof fromInitial} */ (lowerCasedProp)]
            ) {
              return;
            }

            decl.value =
              fromInitial[/** @type {keyof fromInitial} */ (lowerCasedProp)];
          });
        },
      };
    },
  };
}

pluginCreator.postcss = true;
module.exports = pluginCreator;