source: trip-planner-front/node_modules/css-declaration-sorter/src/main.mjs@ 6a80231

Last change on this file since 6a80231 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 3.8 KB
Line 
1import shorthandData from './shorthand-data.mjs';
2import { sort as timsort } from 'timsort';
3
4const builtInOrders = [
5 'alphabetical',
6 'concentric-css',
7 'smacss',
8];
9
10const pluginEntrypoint = ({ order = 'alphabetical', keepOverrides = false } = {}) => ({
11 postcssPlugin: 'css-declaration-sorter',
12 OnceExit (css) {
13 let withKeepOverrides = comparator => comparator;
14 if (keepOverrides) {
15 withKeepOverrides = withOverridesComparator(shorthandData);
16 }
17
18 if (typeof order === 'function') {
19 return processCss({ css, comparator: withKeepOverrides(order) });
20 }
21
22 if (!builtInOrders.includes(order))
23 return Promise.reject(
24 Error([
25 `Invalid built-in order '${order}' provided.`,
26 `Available built-in orders are: ${builtInOrders}`,
27 ].join('\n'))
28 );
29
30 return import(`../orders/${order}.mjs`)
31 .then(({ properties }) => processCss({
32 css,
33 comparator: withKeepOverrides(orderComparator(properties)),
34 }));
35 },
36});
37
38pluginEntrypoint.postcss = true;
39export default pluginEntrypoint;
40
41function processCss ({ css, comparator }) {
42 const comments = [];
43 const rulesCache = [];
44
45 css.walk(node => {
46 const nodes = node.nodes;
47 const type = node.type;
48
49 if (type === 'comment') {
50 // Don't do anything to root comments or the last newline comment
51 const isNewlineNode = node.raws.before && node.raws.before.includes('\n');
52 const lastNewlineNode = isNewlineNode && !node.next();
53 const onlyNode = !node.prev() && !node.next() || !node.parent;
54
55 if (lastNewlineNode || onlyNode || node.parent.type === 'root') {
56 return;
57 }
58
59 if (isNewlineNode) {
60 const pairedNode = node.next() || node.prev();
61 if (pairedNode) {
62 comments.unshift({
63 'comment': node,
64 'pairedNode': pairedNode,
65 'insertPosition': node.next() ? 'Before' : 'After',
66 });
67 node.remove();
68 }
69 } else {
70 const pairedNode = node.prev() || node.next();
71 if (pairedNode) {
72 comments.push({
73 'comment': node,
74 'pairedNode': pairedNode,
75 'insertPosition': 'After',
76 });
77 node.remove();
78 }
79 }
80 return;
81 }
82
83 // Add rule-like nodes to a cache so that we can remove all
84 // comment nodes before we start sorting.
85 const isRule = type === 'rule' || type === 'atrule';
86 if (isRule && nodes && nodes.length > 1) {
87 rulesCache.push(nodes);
88 }
89 });
90
91 // Perform a sort once all comment nodes are removed
92 rulesCache.forEach(nodes => {
93 sortCssDeclarations({ nodes, comparator });
94 });
95
96 // Add comments back to the nodes they are paired with
97 comments.forEach(node => {
98 const pairedNode = node.pairedNode;
99 node.comment.remove();
100 pairedNode.parent['insert' + node.insertPosition](pairedNode, node.comment);
101 });
102}
103
104function sortCssDeclarations ({ nodes, comparator }) {
105 timsort(nodes, (a, b) => {
106 if (a.type === 'decl' && b.type === 'decl') {
107 return comparator(a.prop, b.prop);
108 } else {
109 return compareDifferentType(a, b);
110 }
111 });
112}
113
114function withOverridesComparator (shorthandData) {
115 return function (comparator) {
116 return function (a, b) {
117 a = removeVendorPrefix(a);
118 b = removeVendorPrefix(b);
119
120 if (shorthandData[a] && shorthandData[a].includes(b)) return 0;
121 if (shorthandData[b] && shorthandData[b].includes(a)) return 0;
122
123 return comparator(a, b);
124 };
125 };
126}
127
128function orderComparator (order) {
129 return function (a, b) {
130 return order.indexOf(a) - order.indexOf(b);
131 };
132}
133
134function compareDifferentType (a, b) {
135 if (b.type === 'atrule') {
136 return 0;
137 }
138
139 return a.type === 'decl' ? -1 : b.type === 'decl' ? 1 : 0;
140}
141
142function removeVendorPrefix (property) {
143 return property.replace(/^-\w+-/, '');
144}
Note: See TracBrowser for help on using the repository browser.