Skip to content

Commit c5f3a51

Browse files
Copilotjogibear9988
andcommitted
perf: move regex constants to module scope, use regex literals
- Move pageMarginBoxRegex to module-level pre-compiled constant - Replace _compileAtRule with explicit pre-compiled regex constants for import, charset, and namespace at-rules - Convert new RegExp() to regex literals per biome lint recommendations Co-authored-by: jogibear9988 <364896+jogibear9988@users.noreply.github.com>
1 parent a63143a commit c5f3a51

1 file changed

Lines changed: 65 additions & 51 deletions

File tree

src/parse/index.ts

Lines changed: 65 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,38 @@ const re_positionTry = /@position-try\s+(--[-\w]+)\s*/y;
7070
const re_startingStyle = /@starting-style\s*/y;
7171
const re_genericAtRule = /@([-\w]+)\s*/y;
7272

73+
// Pre-compiled page margin box regex (moved to module scope to avoid re-creation)
74+
const pageMarginBoxNames = [
75+
'top-left-corner',
76+
'top-left',
77+
'top-center',
78+
'top-right',
79+
'top-right-corner',
80+
'bottom-left-corner',
81+
'bottom-left',
82+
'bottom-center',
83+
'bottom-right',
84+
'bottom-right-corner',
85+
'left-top',
86+
'left-middle',
87+
'left-bottom',
88+
'right-top',
89+
'right-middle',
90+
'right-bottom',
91+
];
92+
const re_pageMarginBox = new RegExp(
93+
`@(${pageMarginBoxNames.join('|')})(?![\\w-])\\s*`,
94+
'y',
95+
);
96+
97+
// Pre-compiled non-block at-rule regexes
98+
const re_atImport =
99+
/@import\s*((?::?[^;'"]|"(?:\\"|[^"])*?"|'(?:\\'|[^'])*?')+)(?:;|$)/y;
100+
const re_atCharset =
101+
/@charset\s*((?::?[^;'"]|"(?:\\"|[^"])*?"|'(?:\\'|[^'])*?')+)(?:;|$)/y;
102+
const re_atNamespace =
103+
/@namespace\s*((?::?[^;'"]|"(?:\\"|[^"])*?"|'(?:\\'|[^'])*?')+)(?:;|$)/y;
104+
73105
export const parse = (
74106
css: string,
75107
options?: { source?: string; silent?: boolean },
@@ -713,32 +745,9 @@ export const parse = (
713745
/**
714746
* Parse @page margin box at-rules (@top-left, @bottom-right, @left-middle, etc.).
715747
*/
716-
const pageMarginBoxNames = [
717-
'top-left-corner',
718-
'top-left',
719-
'top-center',
720-
'top-right',
721-
'top-right-corner',
722-
'bottom-left-corner',
723-
'bottom-left',
724-
'bottom-center',
725-
'bottom-right',
726-
'bottom-right-corner',
727-
'left-top',
728-
'left-middle',
729-
'left-bottom',
730-
'right-top',
731-
'right-middle',
732-
'right-bottom',
733-
];
734-
const pageMarginBoxRegex = new RegExp(
735-
`@(${pageMarginBoxNames.join('|')})(?![\\w-])\\s*`,
736-
'y',
737-
);
738-
739748
function atPageMarginBox(): CssPageMarginBoxAST | undefined {
740749
const pos = position();
741-
const m = lexer.matchRegex(pageMarginBoxRegex);
750+
const m = lexer.matchRegex(re_pageMarginBox);
742751
if (!m) {
743752
return;
744753
}
@@ -1087,41 +1096,46 @@ export const parse = (
10871096
/**
10881097
* Parse import
10891098
*/
1090-
const atImport = _compileAtRule<CssImportAST>('import');
1099+
function atImport(): CssImportAST | undefined {
1100+
const pos = position();
1101+
const m = lexer.matchRegex(re_atImport);
1102+
if (!m) {
1103+
return;
1104+
}
1105+
return pos<CssImportAST>({
1106+
type: CssTypes.import,
1107+
import: m[1].trim(),
1108+
} as unknown as CssImportAST) as CssImportAST;
1109+
}
10911110

10921111
/**
10931112
* Parse charset
10941113
*/
1095-
const atCharset = _compileAtRule<CssCharsetAST>('charset');
1114+
function atCharset(): CssCharsetAST | undefined {
1115+
const pos = position();
1116+
const m = lexer.matchRegex(re_atCharset);
1117+
if (!m) {
1118+
return;
1119+
}
1120+
return pos<CssCharsetAST>({
1121+
type: CssTypes.charset,
1122+
charset: m[1].trim(),
1123+
} as unknown as CssCharsetAST) as CssCharsetAST;
1124+
}
10961125

10971126
/**
10981127
* Parse namespace
10991128
*/
1100-
const atNamespace = _compileAtRule<CssNamespaceAST>('namespace');
1101-
1102-
/**
1103-
* Parse non-block at-rules
1104-
*/
1105-
function _compileAtRule<T1 extends CssCommonPositionAST>(
1106-
name: string,
1107-
): () => T1 | undefined {
1108-
const re = new RegExp(
1109-
'@' +
1110-
name +
1111-
'\\s*((?::?[^;\'"]|"(?:\\\\"|[^"])*?"|\'(?:\\\\\'|[^\'])*?\')+)(?:;|$)',
1112-
'y',
1113-
);
1114-
1115-
return (): T1 | undefined => {
1116-
const pos = position();
1117-
const m = lexer.matchRegex(re);
1118-
if (!m) {
1119-
return;
1120-
}
1121-
const ret: Record<string, string> = { type: name };
1122-
ret[name] = m[1].trim();
1123-
return pos<T1>(ret as unknown as T1) as T1;
1124-
};
1129+
function atNamespace(): CssNamespaceAST | undefined {
1130+
const pos = position();
1131+
const m = lexer.matchRegex(re_atNamespace);
1132+
if (!m) {
1133+
return;
1134+
}
1135+
return pos<CssNamespaceAST>({
1136+
type: CssTypes.namespace,
1137+
namespace: m[1].trim(),
1138+
} as unknown as CssNamespaceAST) as CssNamespaceAST;
11251139
}
11261140

11271141
/**

0 commit comments

Comments
 (0)