Skip to content

Commit

Permalink
Remove circular dependency between rules and atrules parsers
Browse files Browse the repository at this point in the history
  • Loading branch information
elchininet committed Nov 24, 2024
1 parent be94304 commit 79cb156
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 142 deletions.
37 changes: 36 additions & 1 deletion src/@types/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import {
Container,
Root,
Rule,
AtRule,
Declaration
Expand Down Expand Up @@ -144,4 +146,37 @@ export type DeclarationHashMapProp = {
export type DeclarationHashMap = Record<
string,
DeclarationHashMapProp
>;
>;

export type RuleParser = (
parsers: Parsers,
container: Container,
parentSourceDirective?: string,
hasParentRule?: boolean
) => void;

export type AtRuleParser = (
parsers: Parsers,
container: Container,
parentSourceDirective?: string,
hasParentRule?: boolean
) => void;

export type KeyframeParser = (
css: Root
) => void;

export type DeclarationParser = (
container: DeclarationContainer,
hasParentRule: boolean,
ruleSourceDirectiveValue: string,
processRule: boolean,
rename: boolean
) => void;

export type Parsers = {
parseRules: RuleParser;
parseAtRules: AtRuleParser;
parseKeyFrames: KeyframeParser;
parseDeclarations: DeclarationParser;
};
6 changes: 5 additions & 1 deletion src/data/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,11 @@ const normalizeOptions = (options: PluginOptions): PluginOptionsNormalized => {
}
if (isAcceptedProcessDeclarationPlugins(options.processDeclarationPlugins)) {
returnOptions.plugins = options.processDeclarationPlugins.map(plugin => ({
...plugin, directives: {control: {}, value: []},
...plugin,
directives: {
control: {},
value: [] as object[]
},
}));
}
if (options.aliases && isObjectWithStringKeys(options.aliases)) {
Expand Down
17 changes: 13 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
import { Root, Plugin } from 'postcss';
import { PluginOptions } from '@types';
import { PluginOptions, Parsers } from '@types';
import { initStore } from '@data/store';
import { parseKeyFrames, parseAtRules } from '@parsers/atrules';
import { parseAtRules } from '@parsers/atrules';
import { parseRules } from '@parsers/rules';
import { parseKeyFrames } from '@parsers/keyframes';
import { parseDeclarations } from '@parsers/declarations';
import {
appendRules,
appendKeyFrames,
parseRuleNames
} from '@utilities/rules';
import { clean } from '@utilities/clean';

const parsers: Parsers = {
parseRules,
parseAtRules,
parseKeyFrames,
parseDeclarations
};

function postcssRTLCSS (options: PluginOptions = {}): Plugin {
return ({
postcssPlugin: 'postcss-rtlcss',
Once(css: Root): void {
initStore(options);
parseKeyFrames(css);
parseAtRules(css);
parseRules(css);
parseAtRules(parsers, css);
parseRules(parsers, css);
parseRuleNames();
appendRules();
appendKeyFrames();
Expand Down
131 changes: 8 additions & 123 deletions src/parsers/atrules.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
import postcss, {
Root,
import{
Container,
Node,
AtRule,
Comment
} from 'postcss';
import rtlcss from 'rtlcss';
import {
Source,
ControlDirective,
Mode
} from '@types';
import { ControlDirective, Parsers } from '@types';
import {
TYPE,
KEYFRAMES_NAME,
CONTROL_DIRECTIVE
} from '@constants';
import {
store,
initKeyframesData
} from '@data/store';
import { walkContainer } from '@utilities/containers';
import {
isIgnoreDirectiveInsideAnIgnoreBlock,
Expand All @@ -28,10 +17,9 @@ import {
} from '@utilities/directives';
import { isAtRule } from '@utilities/predicates';
import { vendor } from '@utilities/vendor';
import { parseRules } from '@parsers/rules';
import { parseDeclarations } from './declarations';

export const parseAtRules = (
parsers: Parsers,
container: Container,
parentSourceDirective: string = undefined,
hasParentRule = false
Expand Down Expand Up @@ -70,7 +58,7 @@ export const parseAtRules = (
hasParentRule &&
node.nodes
) {
parseDeclarations(
parsers.parseDeclarations(
node,
hasParentRule,
sourceDirectiveValue,
Expand All @@ -79,13 +67,15 @@ export const parseAtRules = (
);
}

parseAtRules(
parsers.parseAtRules(
parsers,
node,
parentSourceDirective,
hasParentRule
);

parseRules(
parsers.parseRules(
parsers,
node,
sourceDirectiveValue,
hasParentRule
Expand All @@ -95,108 +85,3 @@ export const parseAtRules = (
);

};

const addToIgnoreKeyframesInDiffMode = (node: AtRule): void => {
if (store.options.mode === Mode.diff) {
store.keyframesToRemove.push(node);
}
};

export const parseKeyFrames = (css: Root): void => {

const { source, processUrls, useCalc, stringMap, processKeyFrames } = store.options;

if (!processKeyFrames) {
return;
}

const controlDirectives: Record<string, ControlDirective> = {};

walkContainer(
css,
[ TYPE.AT_RULE, TYPE.RULE ],
(_comment: Comment, controlDirective: ControlDirective): void => {

if (isIgnoreDirectiveInsideAnIgnoreBlock(controlDirective, controlDirectives)) {
return;
}

controlDirectives[controlDirective.directive] = controlDirective;

},
(node: Node): void => {

if ( checkDirective(controlDirectives, CONTROL_DIRECTIVE.IGNORE) ) {
addToIgnoreKeyframesInDiffMode(node as AtRule);
return;
}

if (!isAtRule(node)) {
return;
}

if (vendor.unprefixed(node.name) !== KEYFRAMES_NAME) {
return;
}

const atRuleString = node.toString();
const atRuleFlippedString = rtlcss.process(atRuleString, { processUrls, useCalc, stringMap });

if (atRuleString === atRuleFlippedString) {
addToIgnoreKeyframesInDiffMode(node);
return;
}

/* the source could be undefined in certain cases but not during the tests */
/* istanbul ignore next */
const rootFlipped = postcss.parse(
atRuleFlippedString,
{
from: node.source?.input?.from
}
);
const atRuleFlipped = rootFlipped.first as AtRule;

const atRuleParams = node.params;
const ltr = `${atRuleParams}-${Source.ltr}`;
const rtl = `${atRuleParams}-${Source.rtl}`;
const sourceDirectiveValue = getSourceDirectiveValue(controlDirectives);

node.params = (
(
!sourceDirectiveValue &&
source === Source.ltr
) ||
(
sourceDirectiveValue &&
sourceDirectiveValue === Source.ltr
)
)
? ltr
: rtl;

atRuleFlipped.params = (
(
!sourceDirectiveValue &&
source === Source.ltr
) ||
(
sourceDirectiveValue &&
sourceDirectiveValue === Source.ltr
)
)
? rtl
: ltr;

store.keyframes.push({
atRuleParams,
atRule: node,
atRuleFlipped
});

}
);

initKeyframesData();

};
Loading

0 comments on commit 79cb156

Please sign in to comment.