Skip to content

Commit a95029e

Browse files
committed
Split selectors localizer
1 parent 7c2bed0 commit a95029e

File tree

2 files changed

+50
-37
lines changed

2 files changed

+50
-37
lines changed

src/index.js

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -31,34 +31,6 @@ function localizeNode(node, context) {
3131

3232
var newNodes;
3333
switch (node.type) {
34-
case "selectors":
35-
var resultingGlobal;
36-
context.hasPureGlobals = false;
37-
newNodes = node.nodes.map(function(n) {
38-
var nContext = {
39-
global: context.global,
40-
lastWasSpacing: true,
41-
hasLocals: false,
42-
explicit: false
43-
};
44-
n = localizeNode(n, nContext);
45-
if (typeof resultingGlobal === "undefined") {
46-
resultingGlobal = nContext.global;
47-
} else if (resultingGlobal !== nContext.global) {
48-
throw Error(
49-
`Inconsistent rule global/local result in rule "${Tokenizer.stringify(node)}" (multiple selectors must result in the same mode for the rule)`
50-
);
51-
}
52-
if (!nContext.hasLocals) {
53-
context.hasPureGlobals = true;
54-
}
55-
return n;
56-
});
57-
context.global = resultingGlobal;
58-
node = Object.create(node);
59-
node.nodes = normalizeNodeArray(newNodes);
60-
break;
61-
6234
case "selector":
6335
newNodes = node.nodes.map(function(n) {
6436
return localizeNode(n, context);
@@ -159,6 +131,35 @@ function localizeNode(node, context) {
159131
return node;
160132
}
161133

134+
const localizeSelectors = (selectors, context) => {
135+
const node = Tokenizer.parse(selectors);
136+
var resultingGlobal;
137+
context.hasPureGlobals = false;
138+
const newNodes = node.nodes.map(function(n) {
139+
var nContext = {
140+
global: context.global,
141+
lastWasSpacing: true,
142+
hasLocals: false,
143+
explicit: false
144+
};
145+
n = localizeNode(n, nContext);
146+
if (typeof resultingGlobal === "undefined") {
147+
resultingGlobal = nContext.global;
148+
} else if (resultingGlobal !== nContext.global) {
149+
throw Error(
150+
`Inconsistent rule global/local result in rule "${Tokenizer.stringify(node)}" (multiple selectors must result in the same mode for the rule)`
151+
);
152+
}
153+
if (!nContext.hasLocals) {
154+
context.hasPureGlobals = true;
155+
}
156+
return n;
157+
});
158+
context.global = resultingGlobal;
159+
node.nodes = normalizeNodeArray(newNodes);
160+
return Tokenizer.stringify(node);
161+
};
162+
162163
module.exports = postcss.plugin(plugin, (options = {}) => css => {
163164
if (
164165
options.mode &&
@@ -177,23 +178,21 @@ module.exports = postcss.plugin(plugin, (options = {}) => css => {
177178
// ignore keyframe rules
178179
return;
179180
}
180-
var selector = Tokenizer.parse(rule.selector);
181181
var context = {
182182
options: options,
183183
global: globalMode,
184184
hasPureGlobals: false
185185
};
186-
var newSelector;
187186
try {
188-
newSelector = localizeNode(selector, context);
187+
const newSelector = localizeSelectors(rule.selector, context);
188+
if (pureMode && context.hasPureGlobals) {
189+
throw Error(
190+
`Selector "${rule.selector}" is not pure (pure selectors must contain at least one local class or id)`
191+
);
192+
}
193+
rule.selector = newSelector;
189194
} catch (e) {
190195
throw rule.error(e.message);
191196
}
192-
if (pureMode && context.hasPureGlobals) {
193-
throw rule.error(
194-
`Selector "${Tokenizer.stringify(selector)}" is not pure (pure selectors must contain at least one local class or id)`
195-
);
196-
}
197-
rule.selector = Tokenizer.stringify(newSelector);
198197
});
199198
});

test/test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ test("scope sibling selectors", () => {
4949
});
5050
});
5151

52+
test("scope next sibling selectors", () => {
53+
return runCSS({
54+
fixture: ".foo + .bar {}",
55+
expected: ":local(.foo) + :local(.bar) {}"
56+
});
57+
});
58+
5259
test("scope psuedo elements", () => {
5360
return runCSS({
5461
fixture: ".foo:after {}",
@@ -70,6 +77,13 @@ test("allow narrow global selectors", () => {
7077
});
7178
});
7279

80+
test("allow operators before :global", () => {
81+
return runCSS({
82+
fixture: ".foo > :global .bar {}",
83+
expected: ":local(.foo) > .bar {}"
84+
});
85+
});
86+
7387
test("allow narrow local selectors", () => {
7488
return runCSS({
7589
fixture: ":local(.foo .bar) {}",

0 commit comments

Comments
 (0)