55
66/* global document */
77
8- /**
9- * Handle comment parsing in CSS
10- */
11- const handleComments = ( char , nextChar , parseState ) => {
12- if (
13- ! parseState . inString &&
14- ! parseState . inComment &&
15- char === '/' &&
16- nextChar === '*'
17- ) {
18- parseState . inComment = true ;
19- return true ;
20- }
21-
22- if ( parseState . inComment && char === '*' && nextChar === '/' ) {
23- parseState . inComment = false ;
24- return true ;
25- }
26-
27- return false ;
28- } ;
29-
308/**
319 * Handle string parsing in CSS
3210 */
@@ -64,13 +42,38 @@ const parseCSSRules = (cssText) => {
6442 const nextChar = cssText [ i + 1 ] ;
6543 const previousChar = cssText [ i - 1 ] ;
6644
67- // Handle comments
68- if ( handleComments ( char , nextChar , parseState ) ) {
69- i ++ ; // Skip next character
45+ // Handle comment start
46+ if (
47+ ! parseState . inString &&
48+ ! parseState . inComment &&
49+ char === '/' &&
50+ nextChar === '*'
51+ ) {
52+ // If we have accumulated content before the comment, save it
53+ if ( currentRule . trim ( ) && ! inRule ) {
54+ rules . push ( currentRule . trim ( ) ) ;
55+ currentRule = '' ;
56+ }
57+
58+ parseState . inComment = true ;
59+ currentRule += char ;
60+ continue ;
61+ }
62+
63+ // Handle comment end
64+ if ( parseState . inComment && char === '*' && nextChar === '/' ) {
65+ currentRule += char + nextChar ;
66+ parseState . inComment = false ;
67+
68+ // Save the complete comment as a rule
69+ rules . push ( currentRule . trim ( ) ) ;
70+ currentRule = '' ;
71+ i ++ ; // Skip the next character
7072 continue ;
7173 }
7274
7375 if ( parseState . inComment ) {
76+ currentRule += char ;
7477 continue ;
7578 }
7679
@@ -354,6 +357,25 @@ const transformPropertyToNative = (selector, property, value) => {
354357 } ;
355358} ;
356359
360+ /**
361+ * Parse a CSS declaration string into property-value pairs
362+ */
363+ const parseDeclaration = ( declaration ) => {
364+ const colonIndex = declaration . indexOf ( ':' ) ;
365+ if ( colonIndex === - 1 ) {
366+ return null ;
367+ }
368+
369+ const property = declaration . slice ( 0 , colonIndex ) . trim ( ) ;
370+ const value = declaration . slice ( colonIndex + 1 ) . trim ( ) ;
371+
372+ if ( property && value ) {
373+ return { property, value } ;
374+ }
375+
376+ return null ;
377+ } ;
378+
357379/**
358380 * Parse a CSS rule and extract selector and properties
359381 */
@@ -369,17 +391,56 @@ const parseRule = (ruleText) => {
369391 const declarations = ruleText . slice ( openBrace + 1 , closeBrace ) . trim ( ) ;
370392
371393 const properties = [ ] ;
372- const declarationParts = declarations . split ( ';' ) ;
373394
374- for ( const declaration of declarationParts ) {
375- const colonIndex = declaration . indexOf ( ':' ) ;
376- if ( colonIndex === - 1 ) continue ;
395+ // Parse declarations with proper handling of semicolons in parentheses
396+ let currentDeclaration = '' ;
397+ let depth = 0 ;
398+ let inQuotes = false ;
399+ let quoteChar = '' ;
400+
401+ for ( let i = 0 ; i < declarations . length ; i ++ ) {
402+ const char = declarations [ i ] ;
403+ const previousChar = i > 0 ? declarations [ i - 1 ] : '' ;
404+
405+ // Handle quotes
406+ if ( ( char === '"' || char === "'" ) && previousChar !== '\\' ) {
407+ if ( ! inQuotes ) {
408+ inQuotes = true ;
409+ quoteChar = char ;
410+ } else if ( char === quoteChar ) {
411+ inQuotes = false ;
412+ quoteChar = '' ;
413+ }
414+ }
415+
416+ if ( ! inQuotes ) {
417+ if ( char === '(' ) {
418+ depth ++ ;
419+ } else if ( char === ')' ) {
420+ depth -- ;
421+ }
422+ }
377423
378- const property = declaration . slice ( 0 , colonIndex ) . trim ( ) ;
379- const value = declaration . slice ( colonIndex + 1 ) . trim ( ) ;
424+ if ( char === ';' && depth === 0 && ! inQuotes ) {
425+ // This is a real property separator
426+ if ( currentDeclaration . trim ( ) ) {
427+ const parsed = parseDeclaration ( currentDeclaration ) ;
428+ if ( parsed ) {
429+ properties . push ( parsed ) ;
430+ }
431+ }
432+
433+ currentDeclaration = '' ;
434+ } else {
435+ currentDeclaration += char ;
436+ }
437+ }
380438
381- if ( property && value ) {
382- properties . push ( { property, value } ) ;
439+ // Handle the last declaration
440+ if ( currentDeclaration . trim ( ) ) {
441+ const parsed = parseDeclaration ( currentDeclaration ) ;
442+ if ( parsed ) {
443+ properties . push ( parsed ) ;
383444 }
384445 }
385446
0 commit comments