|
1 | 1 | /* eslint-env node */
|
2 |
| -import postcss from 'postcss' |
3 |
| -import Tokenizer from 'css-selector-tokenizer' |
| 2 | +import postcss from "postcss"; |
| 3 | +import Tokenizer from "css-selector-tokenizer"; |
4 | 4 |
|
5 | 5 | function normalizeNodeArray(nodes) {
|
6 |
| - var array = [] |
| 6 | + var array = []; |
7 | 7 | nodes.forEach(function(x) {
|
8 | 8 | if (Array.isArray(x)) {
|
9 | 9 | normalizeNodeArray(x).forEach(function(item) {
|
10 |
| - array.push(item) |
11 |
| - }) |
| 10 | + array.push(item); |
| 11 | + }); |
12 | 12 | } else if (x) {
|
13 |
| - array.push(x) |
| 13 | + array.push(x); |
14 | 14 | }
|
15 |
| - }) |
16 |
| - if (array.length > 0 && array[array.length - 1].type === 'spacing') { |
17 |
| - array.pop() |
| 15 | + }); |
| 16 | + if (array.length > 0 && array[array.length - 1].type === "spacing") { |
| 17 | + array.pop(); |
18 | 18 | }
|
19 |
| - return array |
| 19 | + return array; |
20 | 20 | }
|
21 | 21 |
|
22 | 22 | function localizeNode(node, context) {
|
23 |
| - if (context.ignoreNextSpacing && node.type !== 'spacing') { |
24 |
| - throw new Error('Missing whitespace after :' + context.ignoreNextSpacing) |
| 23 | + if (context.ignoreNextSpacing && node.type !== "spacing") { |
| 24 | + throw new Error("Missing whitespace after :" + context.ignoreNextSpacing); |
25 | 25 | }
|
26 |
| - if (context.enforceNoSpacing && node.type === 'spacing') { |
27 |
| - throw new Error('Missing whitespace before :' + context.enforceNoSpacing) |
| 26 | + if (context.enforceNoSpacing && node.type === "spacing") { |
| 27 | + throw new Error("Missing whitespace before :" + context.enforceNoSpacing); |
28 | 28 | }
|
29 | 29 |
|
30 |
| - var newNodes |
| 30 | + var newNodes; |
31 | 31 | switch (node.type) {
|
32 |
| - case 'selectors': |
33 |
| - var resultingGlobal |
34 |
| - context.hasPureGlobals = false |
| 32 | + case "selectors": |
| 33 | + var resultingGlobal; |
| 34 | + context.hasPureGlobals = false; |
35 | 35 | newNodes = node.nodes.map(function(n) {
|
36 | 36 | var nContext = {
|
37 | 37 | global: context.global,
|
38 | 38 | lastWasSpacing: true,
|
39 | 39 | hasLocals: false,
|
40 | 40 | explicit: false
|
41 |
| - } |
42 |
| - n = localizeNode(n, nContext) |
43 |
| - if (typeof resultingGlobal === 'undefined') { |
44 |
| - resultingGlobal = nContext.global |
| 41 | + }; |
| 42 | + n = localizeNode(n, nContext); |
| 43 | + if (typeof resultingGlobal === "undefined") { |
| 44 | + resultingGlobal = nContext.global; |
45 | 45 | } else if (resultingGlobal !== nContext.global) {
|
46 | 46 | throw new Error(
|
47 | 47 | 'Inconsistent rule global/local result in rule "' +
|
48 | 48 | Tokenizer.stringify(node) +
|
49 | 49 | '" (multiple selectors must result in the same mode for the rule)'
|
50 |
| - ) |
| 50 | + ); |
51 | 51 | }
|
52 | 52 | if (!nContext.hasLocals) {
|
53 |
| - context.hasPureGlobals = true |
| 53 | + context.hasPureGlobals = true; |
54 | 54 | }
|
55 |
| - return n |
56 |
| - }) |
57 |
| - context.global = resultingGlobal |
58 |
| - node = Object.create(node) |
59 |
| - node.nodes = normalizeNodeArray(newNodes) |
60 |
| - break |
| 55 | + return n; |
| 56 | + }); |
| 57 | + context.global = resultingGlobal; |
| 58 | + node = Object.create(node); |
| 59 | + node.nodes = normalizeNodeArray(newNodes); |
| 60 | + break; |
61 | 61 |
|
62 |
| - case 'selector': |
| 62 | + case "selector": |
63 | 63 | newNodes = node.nodes.map(function(n) {
|
64 |
| - return localizeNode(n, context) |
65 |
| - }) |
66 |
| - node = Object.create(node) |
67 |
| - node.nodes = normalizeNodeArray(newNodes) |
68 |
| - break |
| 64 | + return localizeNode(n, context); |
| 65 | + }); |
| 66 | + node = Object.create(node); |
| 67 | + node.nodes = normalizeNodeArray(newNodes); |
| 68 | + break; |
69 | 69 |
|
70 |
| - case 'spacing': |
| 70 | + case "spacing": |
71 | 71 | if (context.ignoreNextSpacing) {
|
72 |
| - context.ignoreNextSpacing = false |
73 |
| - context.lastWasSpacing = false |
74 |
| - context.enforceNoSpacing = false |
75 |
| - return null |
| 72 | + context.ignoreNextSpacing = false; |
| 73 | + context.lastWasSpacing = false; |
| 74 | + context.enforceNoSpacing = false; |
| 75 | + return null; |
76 | 76 | }
|
77 |
| - context.lastWasSpacing = true |
78 |
| - return node |
| 77 | + context.lastWasSpacing = true; |
| 78 | + return node; |
79 | 79 |
|
80 |
| - case 'pseudo-class': |
81 |
| - if (node.name === 'local' || node.name === 'global') { |
| 80 | + case "pseudo-class": |
| 81 | + if (node.name === "local" || node.name === "global") { |
82 | 82 | if (context.inside) {
|
83 | 83 | throw new Error(
|
84 |
| - 'A :' + |
| 84 | + "A :" + |
85 | 85 | node.name +
|
86 |
| - ' is not allowed inside of a :' + |
| 86 | + " is not allowed inside of a :" + |
87 | 87 | context.inside +
|
88 |
| - '(...)' |
89 |
| - ) |
| 88 | + "(...)" |
| 89 | + ); |
90 | 90 | }
|
91 |
| - context.ignoreNextSpacing = context.lastWasSpacing ? node.name : false |
92 |
| - context.enforceNoSpacing = context.lastWasSpacing ? false : node.name |
93 |
| - context.global = node.name === 'global' |
94 |
| - context.explicit = true |
95 |
| - return null |
| 91 | + context.ignoreNextSpacing = context.lastWasSpacing ? node.name : false; |
| 92 | + context.enforceNoSpacing = context.lastWasSpacing ? false : node.name; |
| 93 | + context.global = node.name === "global"; |
| 94 | + context.explicit = true; |
| 95 | + return null; |
96 | 96 | }
|
97 |
| - break |
| 97 | + break; |
98 | 98 |
|
99 |
| - case 'nested-pseudo-class': |
100 |
| - var subContext |
101 |
| - if (node.name === 'local' || node.name === 'global') { |
| 99 | + case "nested-pseudo-class": |
| 100 | + var subContext; |
| 101 | + if (node.name === "local" || node.name === "global") { |
102 | 102 | if (context.inside) {
|
103 | 103 | throw new Error(
|
104 |
| - 'A :' + |
| 104 | + "A :" + |
105 | 105 | node.name +
|
106 |
| - '(...) is not allowed inside of a :' + |
| 106 | + "(...) is not allowed inside of a :" + |
107 | 107 | context.inside +
|
108 |
| - '(...)' |
109 |
| - ) |
| 108 | + "(...)" |
| 109 | + ); |
110 | 110 | }
|
111 | 111 | subContext = {
|
112 |
| - global: node.name === 'global', |
| 112 | + global: node.name === "global", |
113 | 113 | inside: node.name,
|
114 | 114 | hasLocals: false,
|
115 | 115 | explicit: true
|
116 |
| - } |
| 116 | + }; |
117 | 117 | node = node.nodes.map(function(n) {
|
118 |
| - return localizeNode(n, subContext) |
119 |
| - }) |
| 118 | + return localizeNode(n, subContext); |
| 119 | + }); |
120 | 120 | // don't leak spacing
|
121 |
| - node[0].before = undefined |
122 |
| - node[node.length - 1].after = undefined |
| 121 | + node[0].before = undefined; |
| 122 | + node[node.length - 1].after = undefined; |
123 | 123 | } else {
|
124 | 124 | subContext = {
|
125 | 125 | global: context.global,
|
126 | 126 | inside: context.inside,
|
127 | 127 | lastWasSpacing: true,
|
128 | 128 | hasLocals: false,
|
129 | 129 | explicit: context.explicit
|
130 |
| - } |
| 130 | + }; |
131 | 131 | newNodes = node.nodes.map(function(n) {
|
132 |
| - return localizeNode(n, subContext) |
133 |
| - }) |
134 |
| - node = Object.create(node) |
135 |
| - node.nodes = normalizeNodeArray(newNodes) |
| 132 | + return localizeNode(n, subContext); |
| 133 | + }); |
| 134 | + node = Object.create(node); |
| 135 | + node.nodes = normalizeNodeArray(newNodes); |
136 | 136 | }
|
137 | 137 | if (subContext.hasLocals) {
|
138 |
| - context.hasLocals = true |
| 138 | + context.hasLocals = true; |
139 | 139 | }
|
140 |
| - break |
| 140 | + break; |
141 | 141 |
|
142 |
| - case 'id': |
143 |
| - case 'class': |
| 142 | + case "id": |
| 143 | + case "class": |
144 | 144 | if (!context.global) {
|
145 | 145 | node = {
|
146 |
| - type: 'nested-pseudo-class', |
147 |
| - name: 'local', |
| 146 | + type: "nested-pseudo-class", |
| 147 | + name: "local", |
148 | 148 | nodes: [node]
|
149 |
| - } |
150 |
| - context.hasLocals = true |
| 149 | + }; |
| 150 | + context.hasLocals = true; |
151 | 151 | }
|
152 |
| - break |
| 152 | + break; |
153 | 153 | }
|
154 | 154 |
|
155 | 155 | // reset context
|
156 |
| - context.lastWasSpacing = false |
157 |
| - context.ignoreNextSpacing = false |
158 |
| - context.enforceNoSpacing = false |
159 |
| - return node |
| 156 | + context.lastWasSpacing = false; |
| 157 | + context.ignoreNextSpacing = false; |
| 158 | + context.enforceNoSpacing = false; |
| 159 | + return node; |
160 | 160 | }
|
161 | 161 |
|
162 | 162 | module.exports = postcss.plugin(
|
163 |
| - 'postcss-modules-local-by-default', |
| 163 | + "postcss-modules-local-by-default", |
164 | 164 | (options = {}) => css => {
|
165 | 165 | if (
|
166 | 166 | options.mode &&
|
167 |
| - options.mode !== 'global' && |
168 |
| - options.mode !== 'local' && |
169 |
| - options.mode !== 'pure' |
| 167 | + options.mode !== "global" && |
| 168 | + options.mode !== "local" && |
| 169 | + options.mode !== "pure" |
170 | 170 | ) {
|
171 | 171 | throw Error(
|
172 | 172 | 'options.mode must be either "global", "local" or "pure" (default "local")'
|
173 |
| - ) |
| 173 | + ); |
174 | 174 | }
|
175 |
| - var pureMode = options.mode === 'pure' |
176 |
| - var globalMode = options.mode === 'global' |
| 175 | + var pureMode = options.mode === "pure"; |
| 176 | + var globalMode = options.mode === "global"; |
177 | 177 | css.walkRules(function(rule) {
|
178 | 178 | if (
|
179 |
| - rule.parent.type === 'atrule' && |
| 179 | + rule.parent.type === "atrule" && |
180 | 180 | /keyframes$/.test(rule.parent.name)
|
181 | 181 | ) {
|
182 | 182 | // ignore keyframe rules
|
183 |
| - return |
| 183 | + return; |
184 | 184 | }
|
185 |
| - var selector = Tokenizer.parse(rule.selector) |
| 185 | + var selector = Tokenizer.parse(rule.selector); |
186 | 186 | var context = {
|
187 | 187 | options: options,
|
188 | 188 | global: globalMode,
|
189 | 189 | hasPureGlobals: false
|
190 |
| - } |
191 |
| - var newSelector |
| 190 | + }; |
| 191 | + var newSelector; |
192 | 192 | try {
|
193 |
| - newSelector = localizeNode(selector, context) |
| 193 | + newSelector = localizeNode(selector, context); |
194 | 194 | } catch (e) {
|
195 |
| - throw rule.error(e.message) |
| 195 | + throw rule.error(e.message); |
196 | 196 | }
|
197 | 197 | if (pureMode && context.hasPureGlobals) {
|
198 | 198 | throw rule.error(
|
199 | 199 | 'Selector "' +
|
200 | 200 | Tokenizer.stringify(selector) +
|
201 | 201 | '" is not pure ' +
|
202 |
| - '(pure selectors must contain at least one local class or id)' |
203 |
| - ) |
| 202 | + "(pure selectors must contain at least one local class or id)" |
| 203 | + ); |
204 | 204 | }
|
205 |
| - rule.selector = Tokenizer.stringify(newSelector) |
206 |
| - }) |
| 205 | + rule.selector = Tokenizer.stringify(newSelector); |
| 206 | + }); |
207 | 207 | }
|
208 |
| -) |
| 208 | +); |
0 commit comments