Skip to content

Commit 79cb156

Browse files
committed
Remove circular dependency between rules and atrules parsers
1 parent be94304 commit 79cb156

File tree

8 files changed

+211
-142
lines changed

8 files changed

+211
-142
lines changed

src/@types/index.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import {
2+
Container,
3+
Root,
24
Rule,
35
AtRule,
46
Declaration
@@ -144,4 +146,37 @@ export type DeclarationHashMapProp = {
144146
export type DeclarationHashMap = Record<
145147
string,
146148
DeclarationHashMapProp
147-
>;
149+
>;
150+
151+
export type RuleParser = (
152+
parsers: Parsers,
153+
container: Container,
154+
parentSourceDirective?: string,
155+
hasParentRule?: boolean
156+
) => void;
157+
158+
export type AtRuleParser = (
159+
parsers: Parsers,
160+
container: Container,
161+
parentSourceDirective?: string,
162+
hasParentRule?: boolean
163+
) => void;
164+
165+
export type KeyframeParser = (
166+
css: Root
167+
) => void;
168+
169+
export type DeclarationParser = (
170+
container: DeclarationContainer,
171+
hasParentRule: boolean,
172+
ruleSourceDirectiveValue: string,
173+
processRule: boolean,
174+
rename: boolean
175+
) => void;
176+
177+
export type Parsers = {
178+
parseRules: RuleParser;
179+
parseAtRules: AtRuleParser;
180+
parseKeyFrames: KeyframeParser;
181+
parseDeclarations: DeclarationParser;
182+
};

src/data/store.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,11 @@ const normalizeOptions = (options: PluginOptions): PluginOptionsNormalized => {
233233
}
234234
if (isAcceptedProcessDeclarationPlugins(options.processDeclarationPlugins)) {
235235
returnOptions.plugins = options.processDeclarationPlugins.map(plugin => ({
236-
...plugin, directives: {control: {}, value: []},
236+
...plugin,
237+
directives: {
238+
control: {},
239+
value: [] as object[]
240+
},
237241
}));
238242
}
239243
if (options.aliases && isObjectWithStringKeys(options.aliases)) {

src/index.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
11
import { Root, Plugin } from 'postcss';
2-
import { PluginOptions } from '@types';
2+
import { PluginOptions, Parsers } from '@types';
33
import { initStore } from '@data/store';
4-
import { parseKeyFrames, parseAtRules } from '@parsers/atrules';
4+
import { parseAtRules } from '@parsers/atrules';
55
import { parseRules } from '@parsers/rules';
6+
import { parseKeyFrames } from '@parsers/keyframes';
7+
import { parseDeclarations } from '@parsers/declarations';
68
import {
79
appendRules,
810
appendKeyFrames,
911
parseRuleNames
1012
} from '@utilities/rules';
1113
import { clean } from '@utilities/clean';
1214

15+
const parsers: Parsers = {
16+
parseRules,
17+
parseAtRules,
18+
parseKeyFrames,
19+
parseDeclarations
20+
};
21+
1322
function postcssRTLCSS (options: PluginOptions = {}): Plugin {
1423
return ({
1524
postcssPlugin: 'postcss-rtlcss',
1625
Once(css: Root): void {
1726
initStore(options);
1827
parseKeyFrames(css);
19-
parseAtRules(css);
20-
parseRules(css);
28+
parseAtRules(parsers, css);
29+
parseRules(parsers, css);
2130
parseRuleNames();
2231
appendRules();
2332
appendKeyFrames();

src/parsers/atrules.ts

Lines changed: 8 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,14 @@
1-
import postcss, {
2-
Root,
1+
import{
32
Container,
43
Node,
5-
AtRule,
64
Comment
75
} from 'postcss';
8-
import rtlcss from 'rtlcss';
9-
import {
10-
Source,
11-
ControlDirective,
12-
Mode
13-
} from '@types';
6+
import { ControlDirective, Parsers } from '@types';
147
import {
158
TYPE,
169
KEYFRAMES_NAME,
1710
CONTROL_DIRECTIVE
1811
} from '@constants';
19-
import {
20-
store,
21-
initKeyframesData
22-
} from '@data/store';
2312
import { walkContainer } from '@utilities/containers';
2413
import {
2514
isIgnoreDirectiveInsideAnIgnoreBlock,
@@ -28,10 +17,9 @@ import {
2817
} from '@utilities/directives';
2918
import { isAtRule } from '@utilities/predicates';
3019
import { vendor } from '@utilities/vendor';
31-
import { parseRules } from '@parsers/rules';
32-
import { parseDeclarations } from './declarations';
3320

3421
export const parseAtRules = (
22+
parsers: Parsers,
3523
container: Container,
3624
parentSourceDirective: string = undefined,
3725
hasParentRule = false
@@ -70,7 +58,7 @@ export const parseAtRules = (
7058
hasParentRule &&
7159
node.nodes
7260
) {
73-
parseDeclarations(
61+
parsers.parseDeclarations(
7462
node,
7563
hasParentRule,
7664
sourceDirectiveValue,
@@ -79,13 +67,15 @@ export const parseAtRules = (
7967
);
8068
}
8169

82-
parseAtRules(
70+
parsers.parseAtRules(
71+
parsers,
8372
node,
8473
parentSourceDirective,
8574
hasParentRule
8675
);
8776

88-
parseRules(
77+
parsers.parseRules(
78+
parsers,
8979
node,
9080
sourceDirectiveValue,
9181
hasParentRule
@@ -95,108 +85,3 @@ export const parseAtRules = (
9585
);
9686

9787
};
98-
99-
const addToIgnoreKeyframesInDiffMode = (node: AtRule): void => {
100-
if (store.options.mode === Mode.diff) {
101-
store.keyframesToRemove.push(node);
102-
}
103-
};
104-
105-
export const parseKeyFrames = (css: Root): void => {
106-
107-
const { source, processUrls, useCalc, stringMap, processKeyFrames } = store.options;
108-
109-
if (!processKeyFrames) {
110-
return;
111-
}
112-
113-
const controlDirectives: Record<string, ControlDirective> = {};
114-
115-
walkContainer(
116-
css,
117-
[ TYPE.AT_RULE, TYPE.RULE ],
118-
(_comment: Comment, controlDirective: ControlDirective): void => {
119-
120-
if (isIgnoreDirectiveInsideAnIgnoreBlock(controlDirective, controlDirectives)) {
121-
return;
122-
}
123-
124-
controlDirectives[controlDirective.directive] = controlDirective;
125-
126-
},
127-
(node: Node): void => {
128-
129-
if ( checkDirective(controlDirectives, CONTROL_DIRECTIVE.IGNORE) ) {
130-
addToIgnoreKeyframesInDiffMode(node as AtRule);
131-
return;
132-
}
133-
134-
if (!isAtRule(node)) {
135-
return;
136-
}
137-
138-
if (vendor.unprefixed(node.name) !== KEYFRAMES_NAME) {
139-
return;
140-
}
141-
142-
const atRuleString = node.toString();
143-
const atRuleFlippedString = rtlcss.process(atRuleString, { processUrls, useCalc, stringMap });
144-
145-
if (atRuleString === atRuleFlippedString) {
146-
addToIgnoreKeyframesInDiffMode(node);
147-
return;
148-
}
149-
150-
/* the source could be undefined in certain cases but not during the tests */
151-
/* istanbul ignore next */
152-
const rootFlipped = postcss.parse(
153-
atRuleFlippedString,
154-
{
155-
from: node.source?.input?.from
156-
}
157-
);
158-
const atRuleFlipped = rootFlipped.first as AtRule;
159-
160-
const atRuleParams = node.params;
161-
const ltr = `${atRuleParams}-${Source.ltr}`;
162-
const rtl = `${atRuleParams}-${Source.rtl}`;
163-
const sourceDirectiveValue = getSourceDirectiveValue(controlDirectives);
164-
165-
node.params = (
166-
(
167-
!sourceDirectiveValue &&
168-
source === Source.ltr
169-
) ||
170-
(
171-
sourceDirectiveValue &&
172-
sourceDirectiveValue === Source.ltr
173-
)
174-
)
175-
? ltr
176-
: rtl;
177-
178-
atRuleFlipped.params = (
179-
(
180-
!sourceDirectiveValue &&
181-
source === Source.ltr
182-
) ||
183-
(
184-
sourceDirectiveValue &&
185-
sourceDirectiveValue === Source.ltr
186-
)
187-
)
188-
? rtl
189-
: ltr;
190-
191-
store.keyframes.push({
192-
atRuleParams,
193-
atRule: node,
194-
atRuleFlipped
195-
});
196-
197-
}
198-
);
199-
200-
initKeyframesData();
201-
202-
};

0 commit comments

Comments
 (0)