@@ -23,8 +23,8 @@ use swc_ecma_visit::{
2323} ;
2424
2525use crate :: {
26- constants:: { CALC_DYMAMIC_STYLE , CONVERT_STYLE_PX_FN , INNER_STYLE , INNER_STYLE_DATA , RN_CONVERT_STYLE_PX_FN , RN_CONVERT_STYLE_VU_FN } , parse_style_properties:: parse_style_properties, scraper:: Element , style_parser:: StyleValue , style_propetries:: { style_value_type:: StyleValueType , traits:: ToStyleValue , unit:: { Platform , PropertyTuple } } , utils:: {
27- create_qualname, get_callee_attributes, prefix_style_key, recursion_jsx_member, to_camel_case, to_kebab_case
26+ constants:: { CALC_DYMAMIC_STYLE , CONVERT_STYLE_PX_FN , INNER_STYLE , INNER_STYLE_DATA , NESTING_STYLE , NESTINT_STYLE_DATA , RN_CONVERT_STYLE_PX_FN , RN_CONVERT_STYLE_VU_FN } , parse_style_properties:: parse_style_properties, scraper:: Element , style_parser:: StyleValue , style_propetries:: { style_value_type:: StyleValueType , traits:: ToStyleValue , unit:: { Platform , PropertyTuple } } , utils:: {
27+ create_qualname, get_callee_attributes, prefix_style_key, recursion_jsx_member, split_selector , to_camel_case, to_kebab_case
2828 }
2929} ;
3030
@@ -479,26 +479,27 @@ impl VisitMut for ModuleMutVisitor {
479479 let binding = self . all_style . borrow ( ) ;
480480 let style_entries: BTreeMap < _ , _ > = binding. iter ( ) . collect ( ) ;
481481
482- let ident = Ident :: new ( INNER_STYLE_DATA . into ( ) , DUMMY_SP ) ;
483-
484- let identifier = Stmt :: Decl ( Decl :: Var ( Box :: new ( VarDecl {
485- span : DUMMY_SP ,
486- kind : swc_ecma_ast:: VarDeclKind :: Let ,
487- declare : false ,
488- decls : vec ! [ swc_ecma_ast:: VarDeclarator {
489- span: DUMMY_SP ,
490- name: swc_ecma_ast:: Pat :: Ident ( BindingIdent {
491- id: ident. clone( ) ,
492- type_ann: None ,
493- } ) ,
494- init: None ,
495- definite: false ,
496- } ]
497- } ) ) ) ;
482+
498483
484+ // __inner_style__普通样式对象
499485 let mut final_style_entries: BTreeMap < String , Vec < PropOrSpread > > = BTreeMap :: new ( ) ;
486+ // __nesting_style__嵌套样式对象
487+ let mut nesting_style_entries: BTreeMap < Vec < String > , Vec < PropOrSpread > > = BTreeMap :: new ( ) ;
488+
500489 // 合并伪类样式, .pesudo {}、.pesudo:after {} => .pesudo: { xxx, ["::after"]: {xxx}}
501490 style_entries. iter ( ) . for_each ( |( key, value) | {
491+ // 判断是否嵌套样式
492+ if self . platform == Platform :: Harmony {
493+ if key. contains ( " " ) {
494+ // 拆分选择器字符串,安装' ' 或 '>' 拆分,如:container > wrapper item => ['container', '>', 'wrapper', ' ', 'item']
495+ let selectors = split_selector ( key) ;
496+ println ! ( "{:?}" , key) ;
497+ println ! ( "{:?}" , selectors) ;
498+ nesting_style_entries. insert ( selectors, parse_style_values ( value. to_vec ( ) , self . platform . clone ( ) ) ) ;
499+ return ;
500+ }
501+ }
502+
502503 // 判断key是否伪类
503504 if key. contains ( ":" ) && self . platform == Platform :: Harmony {
504505 let mut element_key = String :: new ( ) ;
@@ -543,83 +544,6 @@ impl VisitMut for ModuleMutVisitor {
543544 }
544545 }
545546 } ) ;
546-
547-
548- let inner_style_func = {
549-
550- let style_object = Box :: new ( Expr :: Object ( ObjectLit {
551- span : DUMMY_SP ,
552- props : final_style_entries
553- . iter ( )
554- . map ( |( key, value) | {
555- PropOrSpread :: Prop ( Box :: new ( Prop :: KeyValue ( KeyValueProp {
556- key : PropName :: Str ( Str :: from ( key. as_str ( ) ) ) ,
557- value : Box :: new ( Expr :: Object ( ObjectLit {
558- span : DUMMY_SP ,
559- props : value. to_vec ( )
560- } ) ) ,
561- } ) ) )
562- } )
563- . collect :: < Vec < PropOrSpread > > ( )
564- . into ( ) ,
565- } ) ) ;
566-
567- let body = vec ! [
568- // if (__inner_style_data__) return __inner_style_data__
569- Stmt :: If ( IfStmt {
570- span: DUMMY_SP ,
571- test: Box :: new( Expr :: Ident ( ident. clone( ) ) ) ,
572- cons: Box :: new(
573- Stmt :: Return ( ReturnStmt {
574- span: DUMMY_SP ,
575- arg: Some ( Box :: new( Expr :: Ident ( ident. clone( ) ) ) )
576- } )
577- ) ,
578- alt: None
579- } ) ,
580- // __inner_style_data__ = { ... }
581- Stmt :: Expr (
582- ExprStmt {
583- span: DUMMY_SP ,
584- expr: Box :: new(
585- Expr :: Assign ( AssignExpr { span: DUMMY_SP , op: AssignOp :: Assign ,
586- left: swc_ecma_ast:: PatOrExpr :: Expr ( Box :: new( Expr :: Ident ( ident. clone( ) ) ) ) ,
587- right: style_object
588- } )
589- )
590- }
591- ) ,
592- // return __inner_style_data__
593- Stmt :: Return ( ReturnStmt {
594- span: DUMMY_SP ,
595- arg: Some ( Box :: new( Expr :: Ident ( ident) ) )
596- } )
597- ] ;
598-
599-
600- let func = FnExpr {
601- ident : Some ( Ident :: new ( INNER_STYLE . into ( ) , DUMMY_SP ) ) ,
602- function : Box :: new ( Function {
603- params : vec ! [ ] ,
604- decorators : vec ! [ ] ,
605- span : DUMMY_SP ,
606- body : Some ( BlockStmt {
607- span : DUMMY_SP ,
608- stmts : body,
609- } ) ,
610- is_generator : false ,
611- is_async : false ,
612- type_params : None ,
613- return_type : None ,
614- } )
615- } ;
616-
617- Stmt :: Decl ( Decl :: Fn ( FnDecl {
618- ident : func. ident . clone ( ) . unwrap ( ) ,
619- function : func. function ,
620- declare : false
621- } ) )
622- } ;
623547
624548 // 将 inner_style_stmt 插入到 module 的最后一条 import 语句之后
625549 let mut last_import_index = 0 ;
@@ -663,17 +587,166 @@ impl VisitMut for ModuleMutVisitor {
663587 let mut var_checker = VarChecker { found : false } ;
664588 module. visit_with ( & mut var_checker) ;
665589 if var_checker. found {
590+ let style_object = Box :: new ( Expr :: Object ( ObjectLit {
591+ span : DUMMY_SP ,
592+ props : final_style_entries
593+ . iter ( )
594+ . map ( |( key, value) | {
595+ PropOrSpread :: Prop ( Box :: new ( Prop :: KeyValue ( KeyValueProp {
596+ key : PropName :: Str ( Str :: from ( key. as_str ( ) ) ) ,
597+ value : Box :: new ( Expr :: Object ( ObjectLit {
598+ span : DUMMY_SP ,
599+ props : value. to_vec ( )
600+ } ) ) ,
601+ } ) ) )
602+ } )
603+ . collect :: < Vec < PropOrSpread > > ( )
604+ . into ( ) ,
605+ } ) ) ;
606+
607+ let ( identifier, style_func) = generate_stylesheet ( INNER_STYLE . to_string ( ) , INNER_STYLE_DATA . to_string ( ) , style_object) ;
666608 // 插入代码 let __inner_style_data__;
667609 module. body . insert ( last_import_index, ModuleItem :: Stmt ( identifier) ) ;
668610 last_import_index += 1 ;
669611 // 插入代码 function __inner_style__() { ... }
670612 module
671613 . body
672- . insert ( last_import_index, ModuleItem :: Stmt ( inner_style_func ) ) ;
614+ . insert ( last_import_index, ModuleItem :: Stmt ( style_func ) ) ;
673615 }
616+
617+ // 插入嵌套样式
618+ let nesting_style_object = Box :: new ( Expr :: Array ( ArrayLit {
619+ span : DUMMY_SP ,
620+ elems : nesting_style_entries
621+ . iter ( )
622+ . map ( |( key, value) | {
623+ Some ( ExprOrSpread {
624+ spread : None ,
625+ expr : Box :: new ( Expr :: Object ( ObjectLit {
626+ span : DUMMY_SP ,
627+ props : vec ! [
628+ PropOrSpread :: Prop ( Box :: new( Prop :: KeyValue ( KeyValueProp {
629+ key: PropName :: Str ( Str :: from( "selectors" ) ) ,
630+ value: Box :: new( Expr :: Array ( ArrayLit {
631+ span: DUMMY_SP ,
632+ elems: key. iter( ) . map( |prop| {
633+ Some ( ExprOrSpread {
634+ spread: None ,
635+ expr: Box :: new( Expr :: Lit ( Lit :: Str ( Str :: from( prop. as_str( ) ) ) ) )
636+ } )
637+ } ) . collect:: <Vec <Option <ExprOrSpread >>>( )
638+ } ) ) ,
639+ } ) ) ) ,
640+ PropOrSpread :: Prop ( Box :: new( Prop :: KeyValue ( KeyValueProp {
641+ key: PropName :: Str ( Str :: from( "declaration" ) ) ,
642+ value: Box :: new( Expr :: Object ( ObjectLit {
643+ span: DUMMY_SP ,
644+ props: value. to_vec( )
645+ } ) ) ,
646+ } ) ) )
647+
648+ ]
649+ } ) )
650+ } )
651+ } )
652+ . collect :: < Vec < Option < ExprOrSpread > > > ( )
653+ . into ( ) ,
654+ } ) ) ;
655+
656+ let ( identifier, style_func) = generate_stylesheet ( NESTING_STYLE . to_string ( ) , NESTINT_STYLE_DATA . to_string ( ) , nesting_style_object) ;
657+ // 插入代码 let __inner_style_data__;
658+ module. body . insert ( last_import_index, ModuleItem :: Stmt ( identifier) ) ;
659+ last_import_index += 1 ;
660+ // 插入代码 function __inner_style__() { ... }
661+ module
662+ . body
663+ . insert ( last_import_index, ModuleItem :: Stmt ( style_func) )
674664 }
675665}
676666
667+ fn generate_stylesheet ( fn_name : String , fn_data_name : String , style_object : Box < Expr > ) -> ( Stmt , Stmt ) {
668+
669+ let ident = Ident :: new ( fn_data_name. into ( ) , DUMMY_SP ) ;
670+
671+ let identifier = Stmt :: Decl ( Decl :: Var ( Box :: new ( VarDecl {
672+ span : DUMMY_SP ,
673+ kind : swc_ecma_ast:: VarDeclKind :: Let ,
674+ declare : false ,
675+ decls : vec ! [ swc_ecma_ast:: VarDeclarator {
676+ span: DUMMY_SP ,
677+ name: swc_ecma_ast:: Pat :: Ident ( BindingIdent {
678+ id: ident. clone( ) ,
679+ type_ann: None ,
680+ } ) ,
681+ init: None ,
682+ definite: false ,
683+ } ]
684+ } ) ) ) ;
685+
686+ let inner_style_func = {
687+
688+ let body = vec ! [
689+ // if (__inner_style_data__) return __inner_style_data__
690+ Stmt :: If ( IfStmt {
691+ span: DUMMY_SP ,
692+ test: Box :: new( Expr :: Ident ( ident. clone( ) ) ) ,
693+ cons: Box :: new(
694+ Stmt :: Return ( ReturnStmt {
695+ span: DUMMY_SP ,
696+ arg: Some ( Box :: new( Expr :: Ident ( ident. clone( ) ) ) )
697+ } )
698+ ) ,
699+ alt: None
700+ } ) ,
701+ // __inner_style_data__ = { ... }
702+ Stmt :: Expr (
703+ ExprStmt {
704+ span: DUMMY_SP ,
705+ expr: Box :: new(
706+ Expr :: Assign ( AssignExpr { span: DUMMY_SP , op: AssignOp :: Assign ,
707+ left: swc_ecma_ast:: PatOrExpr :: Expr ( Box :: new( Expr :: Ident ( ident. clone( ) ) ) ) ,
708+ right: style_object
709+ } )
710+ )
711+ }
712+ ) ,
713+ // return __inner_style_data__
714+ Stmt :: Return ( ReturnStmt {
715+ span: DUMMY_SP ,
716+ arg: Some ( Box :: new( Expr :: Ident ( ident) ) )
717+ } )
718+ ] ;
719+
720+
721+ let func = FnExpr {
722+ ident : Some ( Ident :: new ( fn_name. into ( ) , DUMMY_SP ) ) ,
723+ function : Box :: new ( Function {
724+ params : vec ! [ ] ,
725+ decorators : vec ! [ ] ,
726+ span : DUMMY_SP ,
727+ body : Some ( BlockStmt {
728+ span : DUMMY_SP ,
729+ stmts : body,
730+ } ) ,
731+ is_generator : false ,
732+ is_async : false ,
733+ type_params : None ,
734+ return_type : None ,
735+ } )
736+ } ;
737+
738+ Stmt :: Decl ( Decl :: Fn ( FnDecl {
739+ ident : func. ident . clone ( ) . unwrap ( ) ,
740+ function : func. function ,
741+ declare : false
742+ } ) )
743+ } ;
744+ (
745+ identifier,
746+ inner_style_func
747+ )
748+ }
749+
677750pub struct JSXMutVisitor < ' i > {
678751 pub jsx_record : Rc < RefCell < JSXRecord > > ,
679752 pub style_record : Rc < RefCell < HashMap < SpanKey , Vec < ( String , Property < ' i > ) > > > > ,
0 commit comments