@@ -4,7 +4,7 @@ use ego_tree::{NodeId, Tree, NodeMut, NodeRef};
4
4
use html5ever:: { Attribute , tendril:: StrTendril } ;
5
5
use lightningcss:: { traits:: ToCss , stylesheet:: PrinterOptions } ;
6
6
use swc_common:: { Span , DUMMY_SP } ;
7
- use swc_ecma_ast:: { JSXElement , JSXElementName , JSXAttrOrSpread , JSXAttrName , JSXAttrValue , Lit , JSXExpr , Expr , JSXElementChild , Module , Function , Stmt , ExportDefaultExpr , ExportDefaultDecl , DefaultDecl , ClassDecl , ClassMember , PropName , FnDecl , Callee , MemberProp , Str , JSXAttr , Ident } ;
7
+ use swc_ecma_ast:: { JSXElement , JSXElementName , JSXAttrOrSpread , JSXAttrName , JSXAttrValue , Lit , JSXExpr , Expr , JSXElementChild , Module , Function , Stmt , ExportDefaultExpr , ExportDefaultDecl , DefaultDecl , ClassDecl , ClassMember , PropName , FnDecl , Callee , MemberProp , Str , JSXAttr , Ident , PropOrSpread , Prop , KeyValueProp } ;
8
8
use swc_ecma_visit:: { Visit , VisitWith , VisitMut , noop_visit_type, noop_visit_mut_type, VisitMutWith } ;
9
9
10
10
use crate :: { scraper:: { Node , Element , Fragment } , utils:: { recursion_jsx_member, create_qualname, is_starts_with_uppercase} , style_parser:: StyleDeclaration } ;
@@ -479,12 +479,118 @@ impl<'a> VisitMut for AstMutVisitor<'a> {
479
479
let style_record = self . style_record . borrow ( ) ;
480
480
let attrs = & mut n. opening . attrs ;
481
481
let mut has_style = false ;
482
+ let mut has_empty_style = false ;
482
483
for attr in attrs {
483
484
if let JSXAttrOrSpread :: JSXAttr ( attr) = attr {
484
485
if let JSXAttrName :: Ident ( ident) = & attr. name {
485
486
if ident. sym . to_string ( ) == "style" {
486
487
has_style = true ;
487
- break ;
488
+ // 只支持值为字符串、对象形式的 style
489
+ match & mut attr. value {
490
+ Some ( value) => {
491
+ match value {
492
+ JSXAttrValue :: Lit ( lit) => {
493
+ match lit {
494
+ Lit :: Str ( str) => {
495
+ // 将 style 属性的值转换为对象形式
496
+ let mut properties = HashMap :: new ( ) ;
497
+ let style = str. value . to_string ( ) ;
498
+ let style = style. split ( ";" ) . map ( |s| s. to_owned ( ) ) . collect :: < Vec < String > > ( ) ;
499
+ if let Some ( style_declaration) = style_record. get ( node_id) {
500
+ for declaration in style_declaration. declaration . declarations . iter ( ) {
501
+ let property_id = declaration. property_id ( ) . to_css_string ( PrinterOptions :: default ( ) ) . unwrap ( ) ;
502
+ let property_value = declaration. value_to_css_string ( PrinterOptions :: default ( ) ) . unwrap ( ) ;
503
+ properties. insert ( property_id, property_value) ;
504
+ }
505
+ }
506
+ for property in style. iter ( ) {
507
+ let property = property. split ( ":" ) . map ( |s| s. to_owned ( ) ) . collect :: < Vec < String > > ( ) ;
508
+ if property. len ( ) == 2 {
509
+ properties. insert ( property[ 0 ] . clone ( ) , property[ 1 ] . clone ( ) ) ;
510
+ }
511
+ }
512
+ let mut style = String :: new ( ) ;
513
+ for ( property_id, property_value) in properties. iter ( ) {
514
+ style. push_str ( property_id. as_str ( ) ) ;
515
+ style. push_str ( ":" ) ;
516
+ style. push_str ( property_value. as_str ( ) ) ;
517
+ style. push_str ( ";" ) ;
518
+ }
519
+ attr. value = Some ( JSXAttrValue :: Lit ( Lit :: Str ( Str {
520
+ span : DUMMY_SP ,
521
+ value : style. into ( ) ,
522
+ raw : None ,
523
+ } ) ) ) ;
524
+ } ,
525
+ _ => { }
526
+ }
527
+ } ,
528
+ JSXAttrValue :: JSXExprContainer ( expr_container) => {
529
+ match & mut expr_container. expr {
530
+ JSXExpr :: JSXEmptyExpr ( _) => {
531
+ has_empty_style = true ;
532
+ has_style = false ;
533
+ } ,
534
+ JSXExpr :: Expr ( expr) => {
535
+ match & mut * * expr {
536
+ Expr :: Object ( lit) => {
537
+ let mut properties = Vec :: new ( ) ;
538
+ if let Some ( style_declaration) = style_record. get ( node_id) {
539
+ for declaration in style_declaration. declaration . declarations . iter ( ) {
540
+ let mut has_property = false ;
541
+ for prop in lit. props . iter_mut ( ) {
542
+ match prop {
543
+ PropOrSpread :: Prop ( prop) => {
544
+ match & * * prop {
545
+ Prop :: KeyValue ( key_value_prop) => {
546
+ match & key_value_prop. key {
547
+ PropName :: Ident ( ident) => {
548
+ let property_id = ident. sym . to_string ( ) ;
549
+ if property_id == declaration. property_id ( ) . to_css_string ( PrinterOptions :: default ( ) ) . unwrap ( ) {
550
+ has_property = true ;
551
+ break ;
552
+ }
553
+ } ,
554
+ _ => { }
555
+ }
556
+ } ,
557
+ _ => { }
558
+ }
559
+ } ,
560
+ PropOrSpread :: Spread ( _) => {
561
+ }
562
+ }
563
+ }
564
+ if !has_property {
565
+ properties. push ( declaration. clone ( ) ) ;
566
+ }
567
+ }
568
+ }
569
+ for property in properties. iter ( ) {
570
+ lit. props . push ( PropOrSpread :: Prop ( Box :: new ( Prop :: KeyValue ( KeyValueProp {
571
+ key : PropName :: Ident ( Ident :: new ( property. property_id ( ) . to_css_string ( PrinterOptions :: default ( ) ) . unwrap ( ) . into ( ) , DUMMY_SP ) ) ,
572
+ value : property. value_to_css_string ( PrinterOptions :: default ( ) ) . unwrap ( ) . into ( )
573
+ } ) ) ) ) ;
574
+ }
575
+ } ,
576
+ _ => { }
577
+ }
578
+ } ,
579
+ }
580
+ } ,
581
+ JSXAttrValue :: JSXElement ( _) => {
582
+
583
+ } ,
584
+ JSXAttrValue :: JSXFragment ( _) => {
585
+
586
+ }
587
+ }
588
+ } ,
589
+ None => {
590
+ has_empty_style = true ;
591
+ has_style = false ;
592
+ }
593
+ } ;
488
594
}
489
595
}
490
596
}
@@ -506,19 +612,33 @@ impl<'a> VisitMut for AstMutVisitor<'a> {
506
612
style. push_str ( property_value. as_str ( ) ) ;
507
613
style. push_str ( ";" ) ;
508
614
}
509
- n. opening . attrs . push ( JSXAttrOrSpread :: JSXAttr ( JSXAttr {
510
- span : DUMMY_SP ,
511
- name : JSXAttrName :: Ident ( Ident :: new ( "style" . into ( ) , DUMMY_SP ) ) ,
512
- value : Some ( JSXAttrValue :: Lit ( Lit :: Str ( Str {
615
+ println ! ( "has_empty_style{}" , has_empty_style) ;
616
+ if has_empty_style {
617
+ for attr in & mut n. opening . attrs {
618
+ if let JSXAttrOrSpread :: JSXAttr ( attr) = attr {
619
+ if let JSXAttrName :: Ident ( ident) = & attr. name {
620
+ if ident. sym . to_string ( ) == "style" {
621
+ attr. value = Some ( JSXAttrValue :: Lit ( Lit :: Str ( Str {
622
+ span : DUMMY_SP ,
623
+ value : style. clone ( ) . into ( ) ,
624
+ raw : None ,
625
+ } ) ) ) ;
626
+ }
627
+ }
628
+ }
629
+ }
630
+ } else {
631
+ n. opening . attrs . push ( JSXAttrOrSpread :: JSXAttr ( JSXAttr {
513
632
span : DUMMY_SP ,
514
- value : style. into ( ) ,
515
- raw : None ,
516
- } ) ) )
517
- } ) ) ;
633
+ name : JSXAttrName :: Ident ( Ident :: new ( "style" . into ( ) , DUMMY_SP ) ) ,
634
+ value : Some ( JSXAttrValue :: Lit ( Lit :: Str ( Str {
635
+ span : DUMMY_SP ,
636
+ value : style. into ( ) ,
637
+ raw : None ,
638
+ } ) ) )
639
+ } ) ) ;
640
+ }
518
641
}
519
- } else {
520
- // 处理 style 属性为对象的情况
521
-
522
642
}
523
643
}
524
644
n. visit_mut_children_with ( self ) ;
0 commit comments