1
1
use lightningcss:: {
2
2
properties:: { custom:: TokenOrValue , Property } ,
3
- stylesheet:: PrinterOptions ,
3
+ stylesheet:: PrinterOptions , traits :: ToCss ,
4
4
} ;
5
5
use swc_core:: ecma:: ast:: * ;
6
6
use swc_core:: {
@@ -15,100 +15,98 @@ use crate::{
15
15
generate_expr_lit_str,
16
16
style_parser:: KeyFrameItem ,
17
17
style_propetries:: {
18
- animation:: Animation ,
19
- animation_multi:: AnimationMulti ,
20
- aspect_ratio:: AspectRatio ,
21
- background:: Background ,
22
- background_image:: BackgroundImage ,
23
- background_position:: BackgroundPosition ,
24
- background_repeat:: BackgroundRepeat ,
25
- background_size:: BackgroundSize ,
26
- border:: Border ,
27
- border_color:: BorderColor ,
28
- border_radius:: BorderRadius ,
29
- border_style:: BorderStyle ,
30
- border_width:: BorderWidth ,
31
- box_orient:: BoxOrient ,
32
- box_shadow:: BoxShadow ,
33
- color:: ColorProperty ,
34
- display:: Display ,
35
- expr:: Expr ,
36
- flex:: Flex ,
37
- flex_align:: FlexAlign ,
38
- flex_basis:: FlexBasis ,
39
- flex_direction:: FlexDirection ,
40
- flex_wrap:: FlexWrap ,
41
- font_size:: FontSize ,
42
- font_style:: FontStyle ,
43
- font_weight:: FontWeight ,
44
- gap:: Gap ,
45
- item_align:: ItemAlign ,
46
- length_value:: LengthValueProperty ,
47
- letter_spacing:: LetterSpacing ,
48
- line_height:: LineHeight ,
49
- marin_padding:: MarginPadding ,
50
- max_size:: MaxSizeProperty ,
51
- normal:: Normal ,
52
- number:: NumberProperty ,
53
- opacity:: Opacity ,
54
- overflow:: Overflow ,
55
- pointer_events:: PointerEvents ,
56
- position:: Position ,
57
- size:: SizeProperty ,
58
- style_property_type:: { string_to_css_property_type, CSSPropertyType } ,
59
- style_value_type:: StyleValueType ,
60
- text_align:: TextAlign ,
61
- text_decoration:: TextDecoration ,
62
- text_overflow:: TextOverflow ,
63
- text_shadow:: TextShadow ,
64
- text_transform:: TextTransform ,
65
- transform:: Transform ,
66
- transform_origin:: TransformOrigin ,
67
- transition:: Transition ,
68
- unit:: { generate_expr_by_length_value, Platform } ,
69
- vertical_align:: VerticalAlign ,
70
- visibility:: Visibility ,
71
- white_space:: WhiteSpace ,
72
- word_break:: WordBreak ,
18
+ animation:: Animation , animation_multi:: AnimationMulti , aspect_ratio:: AspectRatio , background:: Background , background_image:: BackgroundImage , background_position:: BackgroundPosition , background_repeat:: BackgroundRepeat , background_size:: BackgroundSize , border:: Border , border_color:: BorderColor , border_radius:: BorderRadius , border_style:: BorderStyle , border_width:: BorderWidth , box_orient:: BoxOrient , box_shadow:: BoxShadow , color:: ColorProperty , display:: Display , expr:: Expr , flex:: Flex , flex_align:: FlexAlign , flex_basis:: FlexBasis , flex_direction:: FlexDirection , flex_wrap:: FlexWrap , font_size:: FontSize , font_style:: FontStyle , font_weight:: FontWeight , gap:: Gap , item_align:: ItemAlign , length_value:: LengthValueProperty , letter_spacing:: LetterSpacing , line_height:: LineHeight , marin_padding:: MarginPadding , max_size:: MaxSizeProperty , normal:: Normal , number:: NumberProperty , opacity:: Opacity , overflow:: Overflow , pointer_events:: PointerEvents , position:: Position , size:: SizeProperty , style_property_type:: { string_to_css_property_type, CSSPropertyType } , style_value_type:: { CssVariable , StyleValueType } , text_align:: TextAlign , text_decoration:: TextDecoration , text_overflow:: TextOverflow , text_shadow:: TextShadow , text_transform:: TextTransform , transform:: Transform , transform_origin:: TransformOrigin , transition:: Transition , unit:: { generate_expr_by_length_value, Platform } , variable:: Variable , vertical_align:: VerticalAlign , visibility:: Visibility , white_space:: WhiteSpace , word_break:: WordBreak
73
19
74
20
} ,
75
21
utils:: lowercase_first,
76
22
} ;
77
23
78
24
#[ derive( Debug , Clone ) ]
79
25
pub struct DeclsAndVars {
80
- pub decls : Vec < StyleValueType > ,
26
+ pub decls : Vec < StyleValueType > ,
27
+ pub vars : Vec < CssVariable > ,
81
28
pub has_env : bool
82
29
}
83
30
84
31
pub fn parse_style_properties ( properties : & Vec < ( String , Property ) > ) -> DeclsAndVars {
85
32
let mut final_properties = vec ! [ ] ;
33
+ let mut variable_properties = vec ! [ ] ;
86
34
let mut has_env = false ;
87
- for ( id, value) in properties. iter ( ) {
35
+ for ( id, value) in properties. iter ( ) {
36
+ let mut is_var: bool = false ;
88
37
let mut is_env: bool = false ;
89
38
match value {
90
39
Property :: Unparsed ( unparsed) => {
91
- unparsed. value . 0 . iter ( ) . for_each ( |item| match item {
92
- TokenOrValue :: Env ( env) => {
93
- is_env = true ;
94
- let env_result = value. value_to_css_string ( PrinterOptions :: default ( ) ) ;
95
- if ( env_result. is_ok ( ) ) {
96
- final_properties. push ( StyleValueType :: Expr ( Expr :: new (
97
- string_to_css_property_type ( id) ,
98
- generate_expr_lit_str ! ( env_result. unwrap( ) . to_string( ) ) ,
99
- ) ) ) ;
100
- }
40
+ // 检查是否包含 var() 函数
41
+ is_var = unparsed. value . 0 . iter ( ) . any ( |token| {
42
+ match token {
43
+ TokenOrValue :: Function ( f) => {
44
+ // 检查函数内的变量
45
+ f. arguments . 0 . iter ( ) . any ( |arg| matches ! ( arg, TokenOrValue :: Var ( _) ) )
46
+ } ,
47
+ TokenOrValue :: Var ( _) => true ,
48
+ _ => false
101
49
}
102
- _ => { }
103
50
} ) ;
51
+
52
+ // 分析属性值中的所有 token
53
+ for token in unparsed. value . 0 . iter ( ) {
54
+ match token {
55
+ TokenOrValue :: Env ( _) => is_env = true ,
56
+ _ => { }
57
+ }
58
+ }
59
+
60
+ // // 处理包含变量的情况
61
+ if is_var {
62
+ final_properties. push (
63
+ StyleValueType :: Variable (
64
+ Variable :: new (
65
+ string_to_css_property_type ( id) ,
66
+ generate_expr_lit_str ! (
67
+ value. value_to_css_string( PrinterOptions :: default ( ) ) . unwrap( )
68
+ )
69
+ )
70
+ )
71
+ ) ;
72
+ continue ;
73
+ }
74
+
75
+ // 处理环境变量
76
+ if is_env {
77
+ if let Ok ( env_value) = value. value_to_css_string ( PrinterOptions :: default ( ) ) {
78
+ has_env = true ;
79
+ final_properties. push (
80
+ StyleValueType :: Expr (
81
+ Expr :: new (
82
+ string_to_css_property_type ( id) ,
83
+ generate_expr_lit_str ! ( env_value)
84
+ )
85
+ )
86
+ ) ;
87
+ }
88
+ continue ;
89
+ }
90
+ } ,
91
+ Property :: Custom ( custom) => {
92
+ let id_ = custom. name . to_css_string ( Default :: default ( ) ) . unwrap ( ) ;
93
+ // css 变量
94
+ if id_. starts_with ( "--" ) {
95
+ variable_properties. push (
96
+ CssVariable {
97
+ id : id_,
98
+ value : value. value_to_css_string ( PrinterOptions :: default ( ) ) . unwrap ( ) . to_string ( ) ,
99
+ }
100
+ ) ;
101
+ }
104
102
}
105
103
_ => { }
106
104
} ;
107
- if is_env {
108
- has_env = true ;
105
+ if is_env || is_var {
109
106
continue ;
110
107
}
111
108
109
+
112
110
let mut property_name = id. as_str ( ) ;
113
111
114
112
// 移除部分厂商前缀: Webkit, Moz, 并且把首字母小写
@@ -549,6 +547,7 @@ pub fn parse_style_properties(properties: &Vec<(String, Property)>) -> DeclsAndV
549
547
550
548
DeclsAndVars {
551
549
has_env : has_env,
550
+ vars : variable_properties,
552
551
decls : final_properties
553
552
}
554
553
}
0 commit comments