@@ -32,6 +32,8 @@ import {
3232}  from  "./parser" ; 
3333import  {  OwlError  }  from  "../common/owl_error" ; 
3434
35+ const  zero  =  Symbol ( "zero" ) ; 
36+ 
3537type  BlockType  =  "block"  |  "text"  |  "multi"  |  "list"  |  "html"  |  "comment" ; 
3638const  whitespaceRE  =  / \s + / g; 
3739
@@ -279,7 +281,7 @@ export class CodeGenerator {
279281  translatableAttributes : string [ ]  =  TRANSLATABLE_ATTRS ; 
280282  ast : AST ; 
281283  staticDefs : {  id : string ;  expr : string  } [ ]  =  [ ] ; 
282-   slotNames : Set < String >  =  new  Set ( ) ; 
284+   slotNames : Set < String   |   Symbol >  =  new  Set ( ) ; 
283285  helpers : Set < string >  =  new  Set ( ) ; 
284286
285287  constructor ( ast : AST ,  options : CodeGenOptions )  { 
@@ -791,12 +793,22 @@ export class CodeGenerator {
791793    return  block ! . varName ; 
792794  } 
793795
796+   compileZero ( )  { 
797+     this . helpers . add ( "zero" ) ; 
798+     const  isMultiple  =  this . slotNames . has ( zero ) ; 
799+     this . slotNames . add ( zero ) ; 
800+     let  key  =  this . target . loopLevel  ? `key${ this . target . loopLevel }   : "key" ; 
801+     if  ( isMultiple )  { 
802+       key  =  this . generateComponentKey ( key ) ; 
803+     } 
804+     return  `ctx[zero]?.(node, ${ key }  ; 
805+   } 
806+ 
794807  compileTEsc ( ast : ASTTEsc ,  ctx : Context ) : string  { 
795808    let  {  block,  forceNewBlock }  =  ctx ; 
796809    let  expr : string ; 
797810    if  ( ast . expr  ===  "0" )  { 
798-       this . helpers . add ( "zero" ) ; 
799-       expr  =  `ctx[zero]` ; 
811+       expr  =  this . compileZero ( ) ; 
800812    }  else  { 
801813      expr  =  compileExpr ( ast . expr ) ; 
802814      if  ( ast . defaultValue )  { 
@@ -824,8 +836,7 @@ export class CodeGenerator {
824836    block  =  this . createBlock ( block ,  "html" ,  ctx ) ; 
825837    let  blockStr ; 
826838    if  ( ast . expr  ===  "0" )  { 
827-       this . helpers . add ( "zero" ) ; 
828-       blockStr  =  `ctx[zero]` ; 
839+       blockStr  =  this . compileZero ( ) ; 
829840    }  else  if  ( ast . body )  { 
830841      let  bodyValue  =  null ; 
831842      bodyValue  =  BlockDescription . nextBlockId ; 
@@ -1044,8 +1055,12 @@ export class CodeGenerator {
10441055
10451056  compileTCall ( ast : ASTTCall ,  ctx : Context ) : string  { 
10461057    let  {  block,  forceNewBlock }  =  ctx ; 
1058+ 
1059+     const  attrs : string [ ]  =  ast . attrs 
1060+       ? this . formatPropObject ( ast . attrs ,  ast . attrsTranslationCtx ,  ctx . translationCtx ) 
1061+       : [ ] ; 
10471062    let  ctxVar  =  ctx . ctxVar  ||  "ctx" ; 
1048-     if  ( ast . context )  { 
1063+     if  ( ! ast . attrs   &&   ast . context )  { 
10491064      ctxVar  =  generateId ( "ctx" ) ; 
10501065      this . addLine ( `let ${ ctxVar } ${ compileExpr ( ast . context ) }  ) ; 
10511066    } 
@@ -1056,38 +1071,53 @@ export class CodeGenerator {
10561071    } 
10571072    block  =  this . createBlock ( block ,  "multi" ,  ctx ) ; 
10581073    if  ( ast . body )  { 
1059-       this . addLine ( `${ ctxVar } ${ ctxVar }  ) ; 
1060-       this . addLine ( `${ ctxVar }  ) ; 
1061-       this . helpers . add ( "isBoundary" ) ; 
1062-       const  subCtx  =  createContext ( ctx ,  {  ctxVar } ) ; 
1063-       const  bl  =  this . compileMulti ( {  type : ASTType . Multi ,  content : ast . body  } ,  subCtx ) ; 
1064-       if  ( bl )  { 
1074+       if  ( ast . attrs )  { 
10651075        this . helpers . add ( "zero" ) ; 
1066-         this . addLine ( `${ ctxVar } ${ bl }  ) ; 
1076+         const  name  =  this . compileInNewTarget ( "callBody" ,  ast . body ,  ctx ) ; 
1077+         const  zeroStr  =  generateId ( "lazyBlock" ) ; 
1078+         this . define ( zeroStr ,  `${ name }  ) ; 
1079+         attrs . push ( `[zero]: ${ zeroStr }  ) ; 
1080+       }  else  { 
1081+         this . addLine ( `${ ctxVar } ${ ctxVar }  ) ; 
1082+         this . addLine ( `${ ctxVar }  ) ; 
1083+         this . helpers . add ( "isBoundary" ) ; 
1084+         const  subCtx  =  createContext ( ctx ,  {  ctxVar } ) ; 
1085+         const  bl  =  this . compileAST ( ast . body ,  subCtx ) ; 
1086+         if  ( bl )  { 
1087+           this . helpers . add ( "zero" ) ; 
1088+           this . addLine ( `${ ctxVar } ${ bl }  ) ; 
1089+         } 
10671090      } 
10681091    } 
10691092
1093+     let  ctxString  =  `{${ attrs . join ( ", " ) }  ; 
1094+     if  ( ast . attrs  &&  ast . context )  { 
1095+       const  dynCtxVar  =  generateId ( "ctx" ) ; 
1096+       this . addLine ( `let ${ dynCtxVar } ${ compileExpr ( ast . context ) }  ) ; 
1097+       ctxString  =  `Object.assign({}, ${ dynCtxVar } ${ attrs . length  ? ", "  +  ctxString  : "" }  ; 
1098+     } 
1099+     const  ctxExpr  =  ast . attrs  ? ctxString  : ctxVar ; 
10701100    const  key  =  this . generateComponentKey ( ) ; 
10711101    if  ( isDynamic )  { 
10721102      const  templateVar  =  generateId ( "template" ) ; 
10731103      if  ( ! this . staticDefs . find ( ( d )  =>  d . id  ===  "call" ) )  { 
10741104        this . staticDefs . push ( {  id : "call" ,  expr : `app.callTemplate.bind(app)`  } ) ; 
10751105      } 
10761106      this . define ( templateVar ,  subTemplate ) ; 
1077-       this . insertBlock ( `call(this, ${ templateVar } ${ ctxVar } ${ key }  ,  block ! ,  { 
1107+       this . insertBlock ( `call(this, ${ templateVar } ${ ctxExpr } ${ key }  ,  block ! ,  { 
10781108        ...ctx , 
10791109        forceNewBlock : ! block , 
10801110      } ) ; 
10811111    }  else  { 
10821112      const  id  =  generateId ( `callTemplate_` ) ; 
10831113      this . staticDefs . push ( {  id,  expr : `app.getTemplate(${ subTemplate }   } ) ; 
1084-       this . insertBlock ( `${ id } ${ ctxVar } ${ key }  ,  block ! ,  { 
1114+       this . insertBlock ( `${ id } ${ ctxExpr } ${ key }  ,  block ! ,  { 
10851115        ...ctx , 
10861116        forceNewBlock : ! block , 
10871117      } ) ; 
10881118    } 
1089-     if  ( ast . body  &&  ! ctx . isLast )  { 
1090-       this . addLine ( `${ ctxVar } ${ ctxVar }  ) ; 
1119+     if  ( ! ast . attrs   &&   ast . body  &&  ! ctx . isLast )  { 
1120+       this . addLine ( `${ ctxExpr } ${ ctxExpr }  ) ; 
10911121    } 
10921122    return  block . varName ; 
10931123  } 
0 commit comments