Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Machy8 committed Jan 29, 2023
1 parent 3a6475f commit c0fa0dd
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 58 deletions.
2 changes: 1 addition & 1 deletion packages/stylify/src/Compiler/CompilationResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ export class CompilationResult {
const newCssRecord = new CssRecord({
screenId: this.screensList.get(screen),
selector: selector,
pseudoClasses: macroMatch.pseudoClasses,
pseudoClasses: macroMatch.pseudoClasses ? [macroMatch.pseudoClasses] : [],
utilityShouldBeGenerated
});

Expand Down
18 changes: 9 additions & 9 deletions packages/stylify/src/Compiler/Compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ export class Compiler {

private readonly contentOptionsRegExp = /stylify-([a-zA-Z-_0-9]+)\s([\s\S]+?)\s\/stylify-[a-zA-Z-_0-9]+/;

private readonly macrosRegExpGenerators = [
// Match with media query and without pseudo class
(macroKey: string): RegExp => new RegExp(`(?:([a-zA-Z0-9\\-:&\\|]+):)${macroKey}${this.macroRegExpEndPart}`, 'g'),
// Match without media query and without pseudo class
// () - empty pseudo class and media query match
(macroKey: string): RegExp => new RegExp(`\\b()${macroKey}${this.macroRegExpEndPart}`, 'g')
];

private ignoredAreasRegExpString: string = null;

public ignoredAreas = [
Expand Down Expand Up @@ -722,15 +730,7 @@ export class Compiler {
return;
}

const regExpGenerators = [
// Match with media query and without pseudo class
(macroKey: string): RegExp => new RegExp(`\\b(?:([a-zA-Z0-9-:&|]+):)${macroKey}${this.macroRegExpEndPart}`, 'g'),
// Match without media query and without pseudo class
// () - empty pseudo class and media query match
(macroKey: string): RegExp => new RegExp(`\\b()${macroKey}${this.macroRegExpEndPart}`, 'g')
];

for (const regExpGenerator of regExpGenerators) {
for (const regExpGenerator of this.macrosRegExpGenerators) {
for (const macroKey in this.macros) {
content = content.replace(regExpGenerator(macroKey), (...args) => {
const macroMatches: string[] = args.slice(0, args.length - 2);
Expand Down
121 changes: 73 additions & 48 deletions packages/stylify/src/Compiler/MacroMatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,77 +8,102 @@ export class MacroMatch {

public static readonly selectorQuoteAlias = '^';

public fullMatch: string = null;
private readonly logicalOperandsReplacementMap = {
'&&': ' and ',
'||': ', '
};

private readonly logicalOperandsList = Object.keys(this.logicalOperandsReplacementMap);

public screenAndPseudoClassesMatch: string = null;
public fullMatch: string = null;

public selector: string = null;

public screen = '_';

public pseudoClasses: string[] = [];
public pseudoClasses: string = null;

public captures: string[] = [];

constructor(match: string[], screens: ScreensType) {
this.fullMatch = match[0].trim();
this.screenAndPseudoClassesMatch = match[1]?.trim() ?? null;
const screenAndPseudoClassesMatch = match[1]?.trim() ?? null;
this.selector = this.fullMatch;
this.pseudoClasses = [];
match.splice(0, 2);
this.captures = match.filter(matchToFilter => typeof matchToFilter !== 'undefined');

if (this.screenAndPseudoClassesMatch) {
const screenAndPseudoClassesMatchArray = this.screenAndPseudoClassesMatch.split(':');
const operators: string[] = [];
const possibleScreenMatchItems = screenAndPseudoClassesMatchArray[0]
.replace(/&&/ig, () => {
operators.push(' and ');
return '__OPERATOR__';
})
.replace(/\|\|/ig, () => {
operators.push(', ');
return '__OPERATOR__';
})
.split('__OPERATOR__');

let screenMatched = false;
let possibleScreenMatchString = '';

possibleScreenMatchItems.forEach((possibleScreenMatch) => {
for (const key in screens) {
const screenRegExp = new RegExp(`\\b${key}$`, 'g');
const screenMatches = screenRegExp.exec(possibleScreenMatch);

if (screenMatches === null) {
continue;
}

let screenData = screens[key];

if (typeof screenData === 'function') {
screenData = screenData(screenMatches[0]);
}

possibleScreenMatch = possibleScreenMatch.replace(screenRegExp, screenData);
screenMatched = true;
if (!screenAndPseudoClassesMatch) {
return;
}

const screensAndPseudoClassesParts = [];
const screensAndPseudoClassesTokens = screenAndPseudoClassesMatch.split('');
const tokensLength = screensAndPseudoClassesTokens.length;

let tokenQueue = '';
let screenMatched = false;
let pseudoClassesPart = screenAndPseudoClassesMatch;

for (let i = 0; i <= tokensLength; i ++) {
const token = screensAndPseudoClassesTokens[i];
const previousToken = screensAndPseudoClassesTokens[i - 1] ?? '';
const nextToken = screensAndPseudoClassesTokens[i + 1] ?? '';

const nextSequence = token + nextToken;
const nextSequenceIsLogicalSeparator = this.logicalOperandsList.includes(nextSequence);
const nextSequenceIsColonSeparator = token === '\\' && nextToken !== ':';
const isLastToken = i === tokensLength;

if (!(nextSequenceIsColonSeparator
|| nextSequenceIsLogicalSeparator
|| token === ':' && previousToken !== '\\'
|| isLastToken
)) {
tokenQueue += token;
continue;
}

for (const key in screens) {
const screenRegExp = new RegExp(`^${key}$`, 'g');
const screenMatches = screenRegExp.exec(tokenQueue);

if (screenMatches === null) {
continue;
}

const operator = operators[0] ?? '';
let screenData = screens[key];

if (operator) {
operators.shift();
if (typeof screenData === 'function') {
screenData = screenData(screenMatches[0]);
}

possibleScreenMatchString += `${possibleScreenMatch}${operator}`;
});
if (screenData) {
pseudoClassesPart = pseudoClassesPart.substring(screenMatches[0].length);
screensAndPseudoClassesParts.push(screenData);
screenMatched = true;
break;
}
}

tokenQueue += token;

if (screenMatched) {
this.screen = possibleScreenMatchString;
screenAndPseudoClassesMatchArray.shift();
if (nextSequenceIsLogicalSeparator) {
pseudoClassesPart = pseudoClassesPart.substring(2);
screensAndPseudoClassesParts.push(this.logicalOperandsReplacementMap[nextSequence]);
i ++;
tokenQueue = '';
continue;
}
}

if (screenMatched) {
this.screen = screensAndPseudoClassesParts.join('');
}

const pseudoClasses = pseudoClassesPart.replace(/^:/, '');

this.pseudoClasses = screenAndPseudoClassesMatchArray;
if (pseudoClasses.trim().length) {
this.pseudoClasses = pseudoClasses;
}
}

Expand Down

0 comments on commit c0fa0dd

Please sign in to comment.