@@ -2622,7 +2622,7 @@ function wrapError(fn, hookName) {
26222622 result . catch ( ( ) => { } ) ,
26232623 new Promise ( ( resolve ) => setTimeout ( ( ) => resolve ( TIMEOUT ) , 3000 ) ) ,
26242624 ] ) . then ( ( res ) => {
2625- if ( res === TIMEOUT && node . fiber === fiber ) {
2625+ if ( res === TIMEOUT && node . fiber === fiber && node . status <= 2 ) {
26262626 console . warn ( timeoutError ) ;
26272627 }
26282628 } ) ;
@@ -3512,7 +3512,7 @@ function compileExprToArray(expr) {
35123512 const localVars = new Set ( ) ;
35133513 const tokens = tokenize ( expr ) ;
35143514 let i = 0 ;
3515- let stack = [ ] ; // to track last opening [ or {
3515+ let stack = [ ] ; // to track last opening (, [ or {
35163516 while ( i < tokens . length ) {
35173517 let token = tokens [ i ] ;
35183518 let prevToken = tokens [ i - 1 ] ;
@@ -3521,10 +3521,12 @@ function compileExprToArray(expr) {
35213521 switch ( token . type ) {
35223522 case "LEFT_BRACE" :
35233523 case "LEFT_BRACKET" :
3524+ case "LEFT_PAREN" :
35243525 stack . push ( token . type ) ;
35253526 break ;
35263527 case "RIGHT_BRACE" :
35273528 case "RIGHT_BRACKET" :
3529+ case "RIGHT_PAREN" :
35283530 stack . pop ( ) ;
35293531 }
35303532 let isVar = token . type === "SYMBOL" && ! RESERVED_WORDS . includes ( token . value ) ;
@@ -3636,6 +3638,13 @@ function isProp(tag, key) {
36363638 }
36373639 return false ;
36383640}
3641+ /**
3642+ * Returns a template literal that evaluates to str. You can add interpolation
3643+ * sigils into the string if required
3644+ */
3645+ function toStringExpression ( str ) {
3646+ return `\`${ str . replace ( / \\ / g, "\\\\" ) . replace ( / ` / g, "\\`" ) . replace ( / \$ \{ / , "\\${" ) } \`` ;
3647+ }
36393648// -----------------------------------------------------------------------------
36403649// BlockDescription
36413650// -----------------------------------------------------------------------------
@@ -3816,15 +3825,14 @@ class CodeGenerator {
38163825 mainCode . push ( `` ) ;
38173826 for ( let block of this . blocks ) {
38183827 if ( block . dom ) {
3819- let xmlString = block . asXmlString ( ) ;
3820- xmlString = xmlString . replace ( / \\ / g, "\\\\" ) . replace ( / ` / g, "\\`" ) ;
3828+ let xmlString = toStringExpression ( block . asXmlString ( ) ) ;
38213829 if ( block . dynamicTagName ) {
3822- xmlString = xmlString . replace ( / ^ < \w + / , `<\${tag || '${ block . dom . nodeName } '}` ) ;
3823- xmlString = xmlString . replace ( / \w + > $ / , `\${tag || '${ block . dom . nodeName } '}>` ) ;
3824- mainCode . push ( `let ${ block . blockName } = tag => createBlock(\` ${ xmlString } \` );` ) ;
3830+ xmlString = xmlString . replace ( / ^ ` < \w + / , `\ `<\${tag || '${ block . dom . nodeName } '}`) ;
3831+ xmlString = xmlString . replace ( / \w + > ` $ / , `\${tag || '${ block . dom . nodeName } '}>\` ` ) ;
3832+ mainCode . push ( `let ${ block . blockName } = tag => createBlock(${ xmlString } );` ) ;
38253833 }
38263834 else {
3827- mainCode . push ( `let ${ block . blockName } = createBlock(\` ${ xmlString } \` );` ) ;
3835+ mainCode . push ( `let ${ block . blockName } = createBlock(${ xmlString } );` ) ;
38283836 }
38293837 }
38303838 }
@@ -4002,7 +4010,7 @@ class CodeGenerator {
40024010 const isNewBlock = ! block || forceNewBlock ;
40034011 if ( isNewBlock ) {
40044012 block = this . createBlock ( block , "comment" , ctx ) ;
4005- this . insertBlock ( `comment(\` ${ ast . value } \` )` , block , {
4013+ this . insertBlock ( `comment(${ toStringExpression ( ast . value ) } )` , block , {
40064014 ...ctx ,
40074015 forceNewBlock : forceNewBlock && ! block ,
40084016 } ) ;
@@ -4024,7 +4032,7 @@ class CodeGenerator {
40244032 }
40254033 if ( ! block || forceNewBlock ) {
40264034 block = this . createBlock ( block , "text" , ctx ) ;
4027- this . insertBlock ( `text(\` ${ value } \` )` , block , {
4035+ this . insertBlock ( `text(${ toStringExpression ( value ) } )` , block , {
40284036 ...ctx ,
40294037 forceNewBlock : forceNewBlock && ! block ,
40304038 } ) ;
@@ -4245,7 +4253,8 @@ class CodeGenerator {
42454253 expr = compileExpr ( ast . expr ) ;
42464254 if ( ast . defaultValue ) {
42474255 this . helpers . add ( "withDefault" ) ;
4248- expr = `withDefault(${ expr } , \`${ ast . defaultValue } \`)` ;
4256+ // FIXME: defaultValue is not translated
4257+ expr = `withDefault(${ expr } , ${ toStringExpression ( ast . defaultValue ) } )` ;
42494258 }
42504259 }
42514260 if ( ! block || forceNewBlock ) {
@@ -4498,7 +4507,7 @@ class CodeGenerator {
44984507 this . addLine ( `${ ctxVar } [zero] = ${ bl } ;` ) ;
44994508 }
45004509 }
4501- const key = `key + \` ${ this . generateComponentKey ( ) } \`` ;
4510+ const key = this . generateComponentKey ( ) ;
45024511 if ( isDynamic ) {
45034512 const templateVar = generateId ( "template" ) ;
45044513 if ( ! this . staticDefs . find ( ( d ) => d . id === "call" ) ) {
@@ -4550,12 +4559,12 @@ class CodeGenerator {
45504559 else {
45514560 let value ;
45524561 if ( ast . defaultValue ) {
4553- const defaultValue = ctx . translate ? this . translate ( ast . defaultValue ) : ast . defaultValue ;
4562+ const defaultValue = toStringExpression ( ctx . translate ? this . translate ( ast . defaultValue ) : ast . defaultValue ) ;
45544563 if ( ast . value ) {
4555- value = `withDefault(${ expr } , \` ${ defaultValue } \` )` ;
4564+ value = `withDefault(${ expr } , ${ defaultValue } )` ;
45564565 }
45574566 else {
4558- value = `\` ${ defaultValue } \`` ;
4567+ value = defaultValue ;
45594568 }
45604569 }
45614570 else {
@@ -4566,12 +4575,12 @@ class CodeGenerator {
45664575 }
45674576 return null ;
45684577 }
4569- generateComponentKey ( ) {
4578+ generateComponentKey ( currentKey = "key" ) {
45704579 const parts = [ generateId ( "__" ) ] ;
45714580 for ( let i = 0 ; i < this . target . loopLevel ; i ++ ) {
45724581 parts . push ( `\${key${ i + 1 } }` ) ;
45734582 }
4574- return parts . join ( "__" ) ;
4583+ return ` ${ currentKey } + \` ${ parts . join ( "__" ) } \`` ;
45754584 }
45764585 /**
45774586 * Formats a prop name and value into a string suitable to be inserted in the
@@ -4662,7 +4671,6 @@ class CodeGenerator {
46624671 this . addLine ( `${ propVar } .slots = markRaw(Object.assign(${ slotDef } , ${ propVar } .slots))` ) ;
46634672 }
46644673 // cmap key
4665- const key = this . generateComponentKey ( ) ;
46664674 let expr ;
46674675 if ( ast . isDynamic ) {
46684676 expr = generateId ( "Comp" ) ;
@@ -4678,7 +4686,7 @@ class CodeGenerator {
46784686 // todo: check the forcenewblock condition
46794687 this . insertAnchor ( block ) ;
46804688 }
4681- let keyArg = `key + \` ${ key } \`` ;
4689+ let keyArg = this . generateComponentKey ( ) ;
46824690 if ( ctx . tKeyExpr ) {
46834691 keyArg = `${ ctx . tKeyExpr } + ${ keyArg } ` ;
46844692 }
@@ -4751,7 +4759,7 @@ class CodeGenerator {
47514759 }
47524760 let key = this . target . loopLevel ? `key${ this . target . loopLevel } ` : "key" ;
47534761 if ( isMultiple ) {
4754- key = ` ${ key } + \` ${ this . generateComponentKey ( ) } \`` ;
4762+ key = this . generateComponentKey ( key ) ;
47554763 }
47564764 const props = ast . attrs ? this . formatPropObject ( ast . attrs ) : [ ] ;
47574765 const scope = this . getPropString ( props , dynProps ) ;
@@ -4792,7 +4800,6 @@ class CodeGenerator {
47924800 }
47934801 let { block } = ctx ;
47944802 const name = this . compileInNewTarget ( "slot" , ast . content , ctx ) ;
4795- const key = this . generateComponentKey ( ) ;
47964803 let ctxStr = "ctx" ;
47974804 if ( this . target . loopLevel || ! this . hasSafeContext ) {
47984805 ctxStr = generateId ( "ctx" ) ;
@@ -4805,7 +4812,8 @@ class CodeGenerator {
48054812 expr : `app.createComponent(null, false, true, false, false)` ,
48064813 } ) ;
48074814 const target = compileExpr ( ast . target ) ;
4808- const blockString = `${ id } ({target: ${ target } ,slots: {'default': {__render: ${ name } .bind(this), __ctx: ${ ctxStr } }}}, key + \`${ key } \`, node, ctx, Portal)` ;
4815+ const key = this . generateComponentKey ( ) ;
4816+ const blockString = `${ id } ({target: ${ target } ,slots: {'default': {__render: ${ name } .bind(this), __ctx: ${ ctxStr } }}}, ${ key } , node, ctx, Portal)` ;
48094817 if ( block ) {
48104818 this . insertAnchor ( block ) ;
48114819 }
@@ -5538,7 +5546,7 @@ function compile(template, options = {}) {
55385546}
55395547
55405548// do not modify manually. This file is generated by the release script.
5541- const version = "2.2.10 " ;
5549+ const version = "2.2.11 " ;
55425550
55435551// -----------------------------------------------------------------------------
55445552// Scheduler
@@ -5964,9 +5972,9 @@ TemplateSet.prototype._compileTemplate = function _compileTemplate(name, templat
59645972 } ) ;
59655973} ;
59665974
5967- export { App , Component , EventBus , OwlError , __info__ , blockDom , loadFile , markRaw , markup , mount , onError , onMounted , onPatched , onRendered , onWillDestroy , onWillPatch , onWillRender , onWillStart , onWillUnmount , onWillUpdateProps , reactive , status , toRaw , useChildSubEnv , useComponent , useEffect , useEnv , useExternalListener , useRef , useState , useSubEnv , validate , validateType , whenReady , xml } ;
5975+ export { App , Component , EventBus , OwlError , __info__ , batched , blockDom , loadFile , markRaw , markup , mount , onError , onMounted , onPatched , onRendered , onWillDestroy , onWillPatch , onWillRender , onWillStart , onWillUnmount , onWillUpdateProps , reactive , status , toRaw , useChildSubEnv , useComponent , useEffect , useEnv , useExternalListener , useRef , useState , useSubEnv , validate , validateType , whenReady , xml } ;
59685976
59695977
5970- __info__ . date = '2024-04-02T10:25:32.577Z ' ;
5971- __info__ . hash = '97b69f1 ' ;
5978+ __info__ . date = '2024-06-17T13:31:12.099Z ' ;
5979+ __info__ . hash = 'e7f405c ' ;
59725980__info__ . url = 'https://github.com/odoo/owl' ;
0 commit comments