@@ -70,6 +70,38 @@ const re_positionTry = /@position-try\s+(--[-\w]+)\s*/y;
7070const re_startingStyle = / @ s t a r t i n g - s t y l e \s * / y;
7171const 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+ / @ i m p o r t \s * ( (?: : ? [ ^ ; ' " ] | " (?: \\ " | [ ^ " ] ) * ?" | ' (?: \\ ' | [ ^ ' ] ) * ?' ) + ) (?: ; | $ ) / y;
100+ const re_atCharset =
101+ / @ c h a r s e t \s * ( (?: : ? [ ^ ; ' " ] | " (?: \\ " | [ ^ " ] ) * ?" | ' (?: \\ ' | [ ^ ' ] ) * ?' ) + ) (?: ; | $ ) / y;
102+ const re_atNamespace =
103+ / @ n a m e s p a c e \s * ( (?: : ? [ ^ ; ' " ] | " (?: \\ " | [ ^ " ] ) * ?" | ' (?: \\ ' | [ ^ ' ] ) * ?' ) + ) (?: ; | $ ) / y;
104+
73105export 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