1
- import postcss from 'postcss' ;
2
- import Tokenizer from 'css-selector-tokenizer' ;
1
+ 'use strict' ;
3
2
4
- let hasOwnProperty = Object . prototype . hasOwnProperty ;
3
+ const postcss = require ( 'postcss' ) ;
4
+ const Tokenizer = require ( 'css-selector-tokenizer' ) ;
5
+
6
+ const hasOwnProperty = Object . prototype . hasOwnProperty ;
5
7
6
8
function getSingleLocalNamesForComposes ( selectors ) {
7
- return selectors . nodes . map ( ( node ) => {
8
- if ( node . type !== 'selector' || node . nodes . length !== 1 ) {
9
- throw new Error ( 'composition is only allowed when selector is single :local class name not in "' +
10
- Tokenizer . stringify ( selectors ) + '"' ) ;
9
+ return selectors . nodes . map ( node => {
10
+ if ( node . type !== 'selector' || node . nodes . length !== 1 ) {
11
+ throw new Error (
12
+ 'composition is only allowed when selector is single :local class name not in "' +
13
+ Tokenizer . stringify ( selectors ) +
14
+ '"'
15
+ ) ;
11
16
}
12
17
node = node . nodes [ 0 ] ;
13
- if ( node . type !== 'nested-pseudo-class' || node . name !== 'local' || node . nodes . length !== 1 ) {
14
- throw new Error ( 'composition is only allowed when selector is single :local class name not in "' +
15
- Tokenizer . stringify ( selectors ) + '", "' + Tokenizer . stringify ( node ) + '" is weird' ) ;
18
+ if (
19
+ node . type !== 'nested-pseudo-class' ||
20
+ node . name !== 'local' ||
21
+ node . nodes . length !== 1
22
+ ) {
23
+ throw new Error (
24
+ 'composition is only allowed when selector is single :local class name not in "' +
25
+ Tokenizer . stringify ( selectors ) +
26
+ '", "' +
27
+ Tokenizer . stringify ( node ) +
28
+ '" is weird'
29
+ ) ;
16
30
}
17
31
node = node . nodes [ 0 ] ;
18
- if ( node . type !== 'selector' || node . nodes . length !== 1 ) {
19
- throw new Error ( 'composition is only allowed when selector is single :local class name not in "' +
20
- Tokenizer . stringify ( selectors ) + '", "' + Tokenizer . stringify ( node ) + '" is weird' ) ;
32
+ if ( node . type !== 'selector' || node . nodes . length !== 1 ) {
33
+ throw new Error (
34
+ 'composition is only allowed when selector is single :local class name not in "' +
35
+ Tokenizer . stringify ( selectors ) +
36
+ '", "' +
37
+ Tokenizer . stringify ( node ) +
38
+ '" is weird'
39
+ ) ;
21
40
}
22
41
node = node . nodes [ 0 ] ;
23
- if ( node . type !== 'class' ) { // 'id' is not possible, because you can't compose ids
24
- throw new Error ( 'composition is only allowed when selector is single :local class name not in "' +
25
- Tokenizer . stringify ( selectors ) + '", "' + Tokenizer . stringify ( node ) + '" is weird' ) ;
42
+ if ( node . type !== 'class' ) {
43
+ // 'id' is not possible, because you can't compose ids
44
+ throw new Error (
45
+ 'composition is only allowed when selector is single :local class name not in "' +
46
+ Tokenizer . stringify ( selectors ) +
47
+ '", "' +
48
+ Tokenizer . stringify ( node ) +
49
+ '" is weird'
50
+ ) ;
26
51
}
27
52
return node . name ;
28
53
} ) ;
29
54
}
30
55
31
56
const processor = postcss . plugin ( 'postcss-modules-scope' , function ( options ) {
32
- return ( css ) => {
33
- let generateScopedName = options && options . generateScopedName || processor . generateScopedName ;
57
+ return css => {
58
+ const generateScopedName =
59
+ ( options && options . generateScopedName ) || processor . generateScopedName ;
34
60
35
- let exports = { } ;
61
+ const exports = { } ;
36
62
37
63
function exportScopedName ( name ) {
38
- let scopedName = generateScopedName ( name , css . source . input . from , css . source . input . css ) ;
64
+ const scopedName = generateScopedName (
65
+ name ,
66
+ css . source . input . from ,
67
+ css . source . input . css
68
+ ) ;
39
69
exports [ name ] = exports [ name ] || [ ] ;
40
- if ( exports [ name ] . indexOf ( scopedName ) < 0 ) {
70
+ if ( exports [ name ] . indexOf ( scopedName ) < 0 ) {
41
71
exports [ name ] . push ( scopedName ) ;
42
72
}
43
73
return scopedName ;
44
74
}
45
75
46
76
function localizeNode ( node ) {
47
- let newNode = Object . create ( node ) ;
48
- switch ( node . type ) {
77
+ const newNode = Object . create ( node ) ;
78
+ switch ( node . type ) {
49
79
case 'selector' :
50
80
newNode . nodes = node . nodes . map ( localizeNode ) ;
51
81
return newNode ;
52
82
case 'class' :
53
- case 'id' :
54
- let scopedName = exportScopedName ( node . name ) ;
55
- newNode . name = scopedName ;
83
+ case 'id' : {
84
+ newNode . name = exportScopedName ( node . name ) ;
56
85
return newNode ;
86
+ }
57
87
}
58
- throw new Error ( node . type + ' ("' + Tokenizer . stringify ( node ) + '") is not allowed in a :local block' ) ;
88
+ throw new Error (
89
+ node . type +
90
+ ' ("' +
91
+ Tokenizer . stringify ( node ) +
92
+ '") is not allowed in a :local block'
93
+ ) ;
59
94
}
60
95
61
96
function traverseNode ( node ) {
62
- switch ( node . type ) {
97
+ switch ( node . type ) {
63
98
case 'nested-pseudo-class' :
64
- if ( node . name === 'local' ) {
65
- if ( node . nodes . length !== 1 ) {
99
+ if ( node . name === 'local' ) {
100
+ if ( node . nodes . length !== 1 ) {
66
101
throw new Error ( 'Unexpected comma (",") in :local block' ) ;
67
102
}
68
103
return localizeNode ( node . nodes [ 0 ] ) ;
69
104
}
70
- /* falls through */
105
+ /* falls through */
71
106
case 'selectors' :
72
- case 'selector' :
73
- let newNode = Object . create ( node ) ;
107
+ case 'selector' : {
108
+ const newNode = Object . create ( node ) ;
74
109
newNode . nodes = node . nodes . map ( traverseNode ) ;
75
110
return newNode ;
111
+ }
76
112
}
77
113
return node ;
78
114
}
79
115
80
116
// Find any :import and remember imported names
81
- let importedNames = { } ;
117
+ const importedNames = { } ;
82
118
css . walkRules ( rule => {
83
- if ( / ^ : i m p o r t \( .+ \) $ / . test ( rule . selector ) ) {
119
+ if ( / ^ : i m p o r t \( .+ \) $ / . test ( rule . selector ) ) {
84
120
rule . walkDecls ( decl => {
85
121
importedNames [ decl . prop ] = true ;
86
122
} ) ;
@@ -89,30 +125,32 @@ const processor = postcss.plugin('postcss-modules-scope', function(options) {
89
125
90
126
// Find any :local classes
91
127
css . walkRules ( rule => {
92
- let selector = Tokenizer . parse ( rule . selector ) ;
93
- let newSelector = traverseNode ( selector ) ;
128
+ const selector = Tokenizer . parse ( rule . selector ) ;
129
+ const newSelector = traverseNode ( selector ) ;
94
130
rule . selector = Tokenizer . stringify ( newSelector ) ;
95
131
rule . walkDecls ( / c o m p o s e s | c o m p o s e - w i t h / , decl => {
96
- let localNames = getSingleLocalNamesForComposes ( selector ) ;
97
- let classes = decl . value . split ( / \s + / ) ;
98
- classes . forEach ( ( className ) => {
99
- let global = / ^ g l o b a l \( ( [ ^ \) ] + ) \) $ / . exec ( className ) ;
132
+ const localNames = getSingleLocalNamesForComposes ( selector ) ;
133
+ const classes = decl . value . split ( / \s + / ) ;
134
+ classes . forEach ( className => {
135
+ const global = / ^ g l o b a l \( ( [ ^ \) ] + ) \) $ / . exec ( className ) ;
100
136
if ( global ) {
101
- localNames . forEach ( ( exportedName ) => {
137
+ localNames . forEach ( exportedName => {
102
138
exports [ exportedName ] . push ( global [ 1 ] ) ;
103
- } )
139
+ } ) ;
104
140
} else if ( hasOwnProperty . call ( importedNames , className ) ) {
105
- localNames . forEach ( ( exportedName ) => {
141
+ localNames . forEach ( exportedName => {
106
142
exports [ exportedName ] . push ( className ) ;
107
143
} ) ;
108
144
} else if ( hasOwnProperty . call ( exports , className ) ) {
109
- localNames . forEach ( ( exportedName ) => {
110
- exports [ className ] . forEach ( ( item ) => {
145
+ localNames . forEach ( exportedName => {
146
+ exports [ className ] . forEach ( item => {
111
147
exports [ exportedName ] . push ( item ) ;
112
148
} ) ;
113
149
} ) ;
114
150
} else {
115
- throw decl . error ( `referenced class name "${ className } " in ${ decl . prop } not found` ) ;
151
+ throw decl . error (
152
+ `referenced class name "${ className } " in ${ decl . prop } not found`
153
+ ) ;
116
154
}
117
155
} ) ;
118
156
decl . remove ( ) ;
@@ -121,10 +159,14 @@ const processor = postcss.plugin('postcss-modules-scope', function(options) {
121
159
rule . walkDecls ( decl => {
122
160
var tokens = decl . value . split ( / ( , | ' [ ^ ' ] * ' | " [ ^ " ] * " ) / ) ;
123
161
tokens = tokens . map ( ( token , idx ) => {
124
- if ( idx === 0 || tokens [ idx - 1 ] === ',' ) {
125
- let localMatch = / ^ ( \s * ) : l o c a l \s * \( ( .+ ?) \) / . exec ( token ) ;
126
- if ( localMatch ) {
127
- return localMatch [ 1 ] + exportScopedName ( localMatch [ 2 ] ) + token . substr ( localMatch [ 0 ] . length ) ;
162
+ if ( idx === 0 || tokens [ idx - 1 ] === ',' ) {
163
+ const localMatch = / ^ ( \s * ) : l o c a l \s * \( ( .+ ?) \) / . exec ( token ) ;
164
+ if ( localMatch ) {
165
+ return (
166
+ localMatch [ 1 ] +
167
+ exportScopedName ( localMatch [ 2 ] ) +
168
+ token . substr ( localMatch [ 0 ] . length )
169
+ ) ;
128
170
} else {
129
171
return token ;
130
172
}
@@ -138,19 +180,19 @@ const processor = postcss.plugin('postcss-modules-scope', function(options) {
138
180
139
181
// Find any :local keyframes
140
182
css . walkAtRules ( atrule => {
141
- if ( / k e y f r a m e s $ / . test ( atrule . name ) ) {
183
+ if ( / k e y f r a m e s $ / i . test ( atrule . name ) ) {
142
184
var localMatch = / ^ \s * : l o c a l \s * \( ( .+ ?) \) \s * $ / . exec ( atrule . params ) ;
143
- if ( localMatch ) {
185
+ if ( localMatch ) {
144
186
atrule . params = exportScopedName ( localMatch [ 1 ] ) ;
145
187
}
146
188
}
147
189
} ) ;
148
190
149
191
// If we found any :locals, insert an :export rule
150
- let exportedNames = Object . keys ( exports ) ;
192
+ const exportedNames = Object . keys ( exports ) ;
151
193
if ( exportedNames . length > 0 ) {
152
- let exportRule = postcss . rule ( { selector : ` :export` } ) ;
153
- exportedNames . forEach ( exportedName =>
194
+ const exportRule = postcss . rule ( { selector : ' :export' } ) ;
195
+ exportedNames . forEach ( exportedName =>
154
196
exportRule . append ( {
155
197
prop : exportedName ,
156
198
value : exports [ exportedName ] . join ( ' ' ) ,
@@ -163,8 +205,11 @@ const processor = postcss.plugin('postcss-modules-scope', function(options) {
163
205
} ) ;
164
206
165
207
processor . generateScopedName = function ( exportedName , path ) {
166
- let sanitisedPath = path . replace ( / \. [ ^ \. \/ \\ ] + $ / , '' ) . replace ( / [ \W _ ] + / g, '_' ) . replace ( / ^ _ | _ $ / g, '' ) ;
208
+ const sanitisedPath = path
209
+ . replace ( / \. [ ^ \. \/ \\ ] + $ / , '' )
210
+ . replace ( / [ \W _ ] + / g, '_' )
211
+ . replace ( / ^ _ | _ $ / g, '' ) ;
167
212
return `_${ sanitisedPath } __${ exportedName } ` ;
168
213
} ;
169
214
170
- export default processor ;
215
+ module . exports = processor ;
0 commit comments