| 1 | 'use strict';
|
|---|
| 2 | const valueParser = require('postcss-value-parser');
|
|---|
| 3 | const {
|
|---|
| 4 | normalizeGridAutoFlow,
|
|---|
| 5 | normalizeGridColumnRowGap,
|
|---|
| 6 | normalizeGridColumnRow,
|
|---|
| 7 | } = require('./rules/grid');
|
|---|
| 8 |
|
|---|
| 9 | // rules
|
|---|
| 10 | const animation = require('./rules/animation');
|
|---|
| 11 | const border = require('./rules/border');
|
|---|
| 12 | const boxShadow = require('./rules/boxShadow');
|
|---|
| 13 | const flexFlow = require('./rules/flexFlow');
|
|---|
| 14 | const transition = require('./rules/transition');
|
|---|
| 15 | const listStyle = require('./rules/listStyle');
|
|---|
| 16 | const column = require('./rules/columns');
|
|---|
| 17 | const vendorUnprefixed = require('./lib/vendorUnprefixed.js');
|
|---|
| 18 |
|
|---|
| 19 | /** @type {[string, (parsed: valueParser.ParsedValue) => string][]} */
|
|---|
| 20 | const borderRules = [
|
|---|
| 21 | ['border', border],
|
|---|
| 22 | ['border-block', border],
|
|---|
| 23 | ['border-inline', border],
|
|---|
| 24 | ['border-block-end', border],
|
|---|
| 25 | ['border-block-start', border],
|
|---|
| 26 | ['border-inline-end', border],
|
|---|
| 27 | ['border-inline-start', border],
|
|---|
| 28 | ['border-top', border],
|
|---|
| 29 | ['border-right', border],
|
|---|
| 30 | ['border-bottom', border],
|
|---|
| 31 | ['border-left', border],
|
|---|
| 32 | ];
|
|---|
| 33 |
|
|---|
| 34 | /** @type {[string, (parsed: valueParser.ParsedValue) => string | string[] | valueParser.ParsedValue][]} */
|
|---|
| 35 | const grid = [
|
|---|
| 36 | ['grid-auto-flow', normalizeGridAutoFlow],
|
|---|
| 37 | ['grid-column-gap', normalizeGridColumnRowGap], // normal | <length-percentage>
|
|---|
| 38 | ['grid-row-gap', normalizeGridColumnRowGap], // normal | <length-percentage>
|
|---|
| 39 | ['grid-column', normalizeGridColumnRow], // <grid-line>+
|
|---|
| 40 | ['grid-row', normalizeGridColumnRow], // <grid-line>+
|
|---|
| 41 | ['grid-row-start', normalizeGridColumnRow], // <grid-line>
|
|---|
| 42 | ['grid-row-end', normalizeGridColumnRow], // <grid-line>
|
|---|
| 43 | ['grid-column-start', normalizeGridColumnRow], // <grid-line>
|
|---|
| 44 | ['grid-column-end', normalizeGridColumnRow], // <grid-line>
|
|---|
| 45 | ];
|
|---|
| 46 |
|
|---|
| 47 | /** @type {[string, (parsed: valueParser.ParsedValue) => string | valueParser.ParsedValue][]} */
|
|---|
| 48 | const columnRules = [
|
|---|
| 49 | ['column-rule', border],
|
|---|
| 50 | ['columns', column],
|
|---|
| 51 | ];
|
|---|
| 52 |
|
|---|
| 53 | /** @type {Map<string, ((parsed: valueParser.ParsedValue) => string | string[] | valueParser.ParsedValue)>} */
|
|---|
| 54 | const rules = new Map([
|
|---|
| 55 | ['animation', animation],
|
|---|
| 56 | ['outline', border],
|
|---|
| 57 | ['box-shadow', boxShadow],
|
|---|
| 58 | ['flex-flow', flexFlow],
|
|---|
| 59 | ['list-style', listStyle],
|
|---|
| 60 | ['transition', transition],
|
|---|
| 61 | ...borderRules,
|
|---|
| 62 | ...grid,
|
|---|
| 63 | ...columnRules,
|
|---|
| 64 | ]);
|
|---|
| 65 |
|
|---|
| 66 | const variableFunctions = new Set(['var', 'env', 'constant']);
|
|---|
| 67 |
|
|---|
| 68 | /**
|
|---|
| 69 | * @param {valueParser.Node} node
|
|---|
| 70 | * @return {boolean}
|
|---|
| 71 | */
|
|---|
| 72 | function isVariableFunctionNode(node) {
|
|---|
| 73 | if (node.type !== 'function') {
|
|---|
| 74 | return false;
|
|---|
| 75 | }
|
|---|
| 76 |
|
|---|
| 77 | return variableFunctions.has(node.value.toLowerCase());
|
|---|
| 78 | }
|
|---|
| 79 |
|
|---|
| 80 | /**
|
|---|
| 81 | * @param {valueParser.ParsedValue} parsed
|
|---|
| 82 | * @return {boolean}
|
|---|
| 83 | */
|
|---|
| 84 | function shouldAbort(parsed) {
|
|---|
| 85 | let abort = false;
|
|---|
| 86 |
|
|---|
| 87 | parsed.walk((node) => {
|
|---|
| 88 | if (
|
|---|
| 89 | node.type === 'comment' ||
|
|---|
| 90 | isVariableFunctionNode(node) ||
|
|---|
| 91 | (node.type === 'word' && node.value.includes(`___CSS_LOADER_IMPORT___`))
|
|---|
| 92 | ) {
|
|---|
| 93 | abort = true;
|
|---|
| 94 |
|
|---|
| 95 | return false;
|
|---|
| 96 | }
|
|---|
| 97 | });
|
|---|
| 98 |
|
|---|
| 99 | return abort;
|
|---|
| 100 | }
|
|---|
| 101 |
|
|---|
| 102 | /**
|
|---|
| 103 | * @param {import('postcss').Declaration} decl
|
|---|
| 104 | * @return {string}
|
|---|
| 105 | */
|
|---|
| 106 | function getValue(decl) {
|
|---|
| 107 | let { value, raws } = decl;
|
|---|
| 108 |
|
|---|
| 109 | if (raws && raws.value && raws.value.raw) {
|
|---|
| 110 | value = raws.value.raw;
|
|---|
| 111 | }
|
|---|
| 112 |
|
|---|
| 113 | return value;
|
|---|
| 114 | }
|
|---|
| 115 | /**
|
|---|
| 116 | * @type {import('postcss').PluginCreator<void>}
|
|---|
| 117 | * @return {import('postcss').Plugin}
|
|---|
| 118 | */
|
|---|
| 119 | function pluginCreator() {
|
|---|
| 120 | return {
|
|---|
| 121 | postcssPlugin: 'postcss-ordered-values',
|
|---|
| 122 | prepare() {
|
|---|
| 123 | const cache = new Map();
|
|---|
| 124 | return {
|
|---|
| 125 | OnceExit(css) {
|
|---|
| 126 | css.walkDecls((decl) => {
|
|---|
| 127 | const lowerCasedProp = decl.prop.toLowerCase();
|
|---|
| 128 | const normalizedProp = vendorUnprefixed(lowerCasedProp);
|
|---|
| 129 | const processor = rules.get(normalizedProp);
|
|---|
| 130 |
|
|---|
| 131 | if (!processor) {
|
|---|
| 132 | return;
|
|---|
| 133 | }
|
|---|
| 134 |
|
|---|
| 135 | const value = getValue(decl);
|
|---|
| 136 |
|
|---|
| 137 | if (cache.has(value)) {
|
|---|
| 138 | decl.value = cache.get(value);
|
|---|
| 139 |
|
|---|
| 140 | return;
|
|---|
| 141 | }
|
|---|
| 142 |
|
|---|
| 143 | const parsed = valueParser(value);
|
|---|
| 144 |
|
|---|
| 145 | if (parsed.nodes.length < 2 || shouldAbort(parsed)) {
|
|---|
| 146 | cache.set(value, value);
|
|---|
| 147 |
|
|---|
| 148 | return;
|
|---|
| 149 | }
|
|---|
| 150 |
|
|---|
| 151 | const result = processor(parsed);
|
|---|
| 152 |
|
|---|
| 153 | decl.value = result.toString();
|
|---|
| 154 | cache.set(value, result.toString());
|
|---|
| 155 | });
|
|---|
| 156 | },
|
|---|
| 157 | };
|
|---|
| 158 | },
|
|---|
| 159 | };
|
|---|
| 160 | }
|
|---|
| 161 |
|
|---|
| 162 | pluginCreator.postcss = true;
|
|---|
| 163 | module.exports = pluginCreator;
|
|---|