@@ -30,12 +30,15 @@ function localizeNode(node, context) {
30
30
switch ( node . type ) {
31
31
case "selectors" :
32
32
var resultingGlobal ;
33
- context . locals = true ;
33
+ context . hasPureGlobals = false ;
34
+ context . hasPureImplicitGlobals = false ;
34
35
newNodes = node . nodes . map ( function ( n ) {
35
36
var nContext = {
36
37
global : context . global ,
37
38
lastWasSpacing : true ,
38
- locals : false
39
+ hasLocals : false ,
40
+ hasImplicitGlobals : false ,
41
+ explicit : false
39
42
} ;
40
43
n = localizeNode ( n , nContext ) ;
41
44
if ( typeof resultingGlobal === "undefined" ) {
@@ -44,8 +47,11 @@ function localizeNode(node, context) {
44
47
throw new Error ( "Inconsistent rule global/local result in rule '" +
45
48
Tokenizer . stringify ( node ) + "' (multiple selectors must result in the same mode for the rule)" ) ;
46
49
}
47
- if ( ! nContext . locals ) {
48
- context . locals = false ;
50
+ if ( ! nContext . hasLocals ) {
51
+ context . hasPureGlobals = true ;
52
+ if ( nContext . hasImplicitGlobals ) {
53
+ context . hasPureImplicitGlobals = true ;
54
+ }
49
55
}
50
56
return n ;
51
57
} ) ;
@@ -80,6 +86,7 @@ function localizeNode(node, context) {
80
86
context . ignoreNextSpacing = context . lastWasSpacing ? node . name : false ;
81
87
context . enforceNoSpacing = context . lastWasSpacing ? false : node . name ;
82
88
context . global = ( node . name === "global" ) ;
89
+ context . explicit = true ;
83
90
return null ;
84
91
}
85
92
break ;
@@ -93,32 +100,43 @@ function localizeNode(node, context) {
93
100
subContext = {
94
101
global : ( node . name === "global" ) ,
95
102
inside : node . name ,
96
- locals : false
103
+ hasLocals : false ,
104
+ hasImplicitGlobals : false ,
105
+ explicit : true
97
106
} ;
98
107
node = node . nodes . map ( function ( n ) {
99
108
return localizeNode ( n , subContext ) ;
100
109
} ) ;
101
110
// don't leak spacing
102
111
node [ 0 ] . before = undefined ;
103
112
node [ node . length - 1 ] . after = undefined ;
104
- if ( subContext . locals ) {
105
- context . locals = true ;
106
- }
107
113
} else {
108
114
subContext = {
109
115
global : context . global ,
110
116
inside : context . inside ,
111
117
lastWasSpacing : true ,
112
- locals : false
118
+ hasLocals : false ,
119
+ hasImplicitGlobals : false ,
120
+ explicit : context . explicit
113
121
} ;
114
122
newNodes = node . nodes . map ( function ( n ) {
115
123
return localizeNode ( n , subContext ) ;
116
124
} ) ;
117
125
node = Object . create ( node ) ;
118
126
node . nodes = normalizeNodeArray ( newNodes ) ;
119
- if ( subContext . locals ) {
120
- context . locals = true ;
121
- }
127
+ }
128
+ if ( subContext . hasLocals ) {
129
+ context . hasLocals = true ;
130
+ }
131
+ if ( subContext . hasImplicitGlobals ) {
132
+ context . hasImplicitGlobals = true ;
133
+ }
134
+ break ;
135
+
136
+ case "attribute" :
137
+ case "element" :
138
+ if ( ! context . global && ! context . explicit ) {
139
+ context . hasImplicitGlobals = true ;
122
140
}
123
141
break ;
124
142
@@ -130,7 +148,7 @@ function localizeNode(node, context) {
130
148
name : "local" ,
131
149
nodes : [ node ]
132
150
} ;
133
- context . locals = true ;
151
+ context . hasLocals = true ;
134
152
}
135
153
break ;
136
154
}
@@ -177,13 +195,18 @@ module.exports = postcss.plugin('postcss-modules-local-by-default', function (op
177
195
var selector = Tokenizer . parse ( rule . selector ) ;
178
196
var context = {
179
197
global : globalMode ,
180
- locals : false
198
+ hasPureGlobals : false ,
199
+ hasPureImplicitGlobals : false
181
200
} ;
182
201
var newSelector = localizeNode ( selector , context ) ;
183
- if ( pureMode && ! context . locals ) {
202
+ if ( pureMode && context . hasPureGlobals ) {
184
203
throw new Error ( "Selector '" + Tokenizer . stringify ( selector ) + "' is not pure " +
185
204
"(pure selectors must contain at least one local class or id)" ) ;
186
205
}
206
+ if ( ! globalMode && context . hasPureImplicitGlobals ) {
207
+ throw new Error ( "Selector '" + Tokenizer . stringify ( selector ) + "' must be explicit flagged :global " +
208
+ "(elsewise it would leak globally)" ) ;
209
+ }
187
210
if ( ! context . global ) {
188
211
rule . nodes . forEach ( localizeDecl ) ;
189
212
}
0 commit comments