@@ -4,7 +4,7 @@ use ego_tree::{NodeId, Tree, NodeMut, NodeRef};
44use html5ever:: { Attribute , tendril:: StrTendril } ;
55use lightningcss:: { traits:: ToCss , stylesheet:: PrinterOptions } ;
66use 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 } ;
88use swc_ecma_visit:: { Visit , VisitWith , VisitMut , noop_visit_type, noop_visit_mut_type, VisitMutWith } ;
99
1010use 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> {
479479 let style_record = self . style_record . borrow ( ) ;
480480 let attrs = & mut n. opening . attrs ;
481481 let mut has_style = false ;
482+ let mut has_empty_style = false ;
482483 for attr in attrs {
483484 if let JSXAttrOrSpread :: JSXAttr ( attr) = attr {
484485 if let JSXAttrName :: Ident ( ident) = & attr. name {
485486 if ident. sym . to_string ( ) == "style" {
486487 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+ } ;
488594 }
489595 }
490596 }
@@ -506,19 +612,33 @@ impl<'a> VisitMut for AstMutVisitor<'a> {
506612 style. push_str ( property_value. as_str ( ) ) ;
507613 style. push_str ( ";" ) ;
508614 }
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 {
513632 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+ }
518641 }
519- } else {
520- // 处理 style 属性为对象的情况
521-
522642 }
523643 }
524644 n. visit_mut_children_with ( self ) ;
0 commit comments