@odoo/owl 2.2.10 → 2.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
package/dist/owl.cjs.js CHANGED
@@ -2626,7 +2626,7 @@ function wrapError(fn, hookName) {
2626
2626
  result.catch(() => { }),
2627
2627
  new Promise((resolve) => setTimeout(() => resolve(TIMEOUT), 3000)),
2628
2628
  ]).then((res) => {
2629
- if (res === TIMEOUT && node.fiber === fiber) {
2629
+ if (res === TIMEOUT && node.fiber === fiber && node.status <= 2) {
2630
2630
  console.warn(timeoutError);
2631
2631
  }
2632
2632
  });
@@ -3516,7 +3516,7 @@ function compileExprToArray(expr) {
3516
3516
  const localVars = new Set();
3517
3517
  const tokens = tokenize(expr);
3518
3518
  let i = 0;
3519
- let stack = []; // to track last opening [ or {
3519
+ let stack = []; // to track last opening (, [ or {
3520
3520
  while (i < tokens.length) {
3521
3521
  let token = tokens[i];
3522
3522
  let prevToken = tokens[i - 1];
@@ -3525,10 +3525,12 @@ function compileExprToArray(expr) {
3525
3525
  switch (token.type) {
3526
3526
  case "LEFT_BRACE":
3527
3527
  case "LEFT_BRACKET":
3528
+ case "LEFT_PAREN":
3528
3529
  stack.push(token.type);
3529
3530
  break;
3530
3531
  case "RIGHT_BRACE":
3531
3532
  case "RIGHT_BRACKET":
3533
+ case "RIGHT_PAREN":
3532
3534
  stack.pop();
3533
3535
  }
3534
3536
  let isVar = token.type === "SYMBOL" && !RESERVED_WORDS.includes(token.value);
@@ -3640,6 +3642,13 @@ function isProp(tag, key) {
3640
3642
  }
3641
3643
  return false;
3642
3644
  }
3645
+ /**
3646
+ * Returns a template literal that evaluates to str. You can add interpolation
3647
+ * sigils into the string if required
3648
+ */
3649
+ function toStringExpression(str) {
3650
+ return `\`${str.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/, "\\${")}\``;
3651
+ }
3643
3652
  // -----------------------------------------------------------------------------
3644
3653
  // BlockDescription
3645
3654
  // -----------------------------------------------------------------------------
@@ -3820,15 +3829,14 @@ class CodeGenerator {
3820
3829
  mainCode.push(``);
3821
3830
  for (let block of this.blocks) {
3822
3831
  if (block.dom) {
3823
- let xmlString = block.asXmlString();
3824
- xmlString = xmlString.replace(/\\/g, "\\\\").replace(/`/g, "\\`");
3832
+ let xmlString = toStringExpression(block.asXmlString());
3825
3833
  if (block.dynamicTagName) {
3826
- xmlString = xmlString.replace(/^<\w+/, `<\${tag || '${block.dom.nodeName}'}`);
3827
- xmlString = xmlString.replace(/\w+>$/, `\${tag || '${block.dom.nodeName}'}>`);
3828
- mainCode.push(`let ${block.blockName} = tag => createBlock(\`${xmlString}\`);`);
3834
+ xmlString = xmlString.replace(/^`<\w+/, `\`<\${tag || '${block.dom.nodeName}'}`);
3835
+ xmlString = xmlString.replace(/\w+>`$/, `\${tag || '${block.dom.nodeName}'}>\``);
3836
+ mainCode.push(`let ${block.blockName} = tag => createBlock(${xmlString});`);
3829
3837
  }
3830
3838
  else {
3831
- mainCode.push(`let ${block.blockName} = createBlock(\`${xmlString}\`);`);
3839
+ mainCode.push(`let ${block.blockName} = createBlock(${xmlString});`);
3832
3840
  }
3833
3841
  }
3834
3842
  }
@@ -4006,7 +4014,7 @@ class CodeGenerator {
4006
4014
  const isNewBlock = !block || forceNewBlock;
4007
4015
  if (isNewBlock) {
4008
4016
  block = this.createBlock(block, "comment", ctx);
4009
- this.insertBlock(`comment(\`${ast.value}\`)`, block, {
4017
+ this.insertBlock(`comment(${toStringExpression(ast.value)})`, block, {
4010
4018
  ...ctx,
4011
4019
  forceNewBlock: forceNewBlock && !block,
4012
4020
  });
@@ -4028,7 +4036,7 @@ class CodeGenerator {
4028
4036
  }
4029
4037
  if (!block || forceNewBlock) {
4030
4038
  block = this.createBlock(block, "text", ctx);
4031
- this.insertBlock(`text(\`${value}\`)`, block, {
4039
+ this.insertBlock(`text(${toStringExpression(value)})`, block, {
4032
4040
  ...ctx,
4033
4041
  forceNewBlock: forceNewBlock && !block,
4034
4042
  });
@@ -4249,7 +4257,8 @@ class CodeGenerator {
4249
4257
  expr = compileExpr(ast.expr);
4250
4258
  if (ast.defaultValue) {
4251
4259
  this.helpers.add("withDefault");
4252
- expr = `withDefault(${expr}, \`${ast.defaultValue}\`)`;
4260
+ // FIXME: defaultValue is not translated
4261
+ expr = `withDefault(${expr}, ${toStringExpression(ast.defaultValue)})`;
4253
4262
  }
4254
4263
  }
4255
4264
  if (!block || forceNewBlock) {
@@ -4502,7 +4511,7 @@ class CodeGenerator {
4502
4511
  this.addLine(`${ctxVar}[zero] = ${bl};`);
4503
4512
  }
4504
4513
  }
4505
- const key = `key + \`${this.generateComponentKey()}\``;
4514
+ const key = this.generateComponentKey();
4506
4515
  if (isDynamic) {
4507
4516
  const templateVar = generateId("template");
4508
4517
  if (!this.staticDefs.find((d) => d.id === "call")) {
@@ -4554,12 +4563,12 @@ class CodeGenerator {
4554
4563
  else {
4555
4564
  let value;
4556
4565
  if (ast.defaultValue) {
4557
- const defaultValue = ctx.translate ? this.translate(ast.defaultValue) : ast.defaultValue;
4566
+ const defaultValue = toStringExpression(ctx.translate ? this.translate(ast.defaultValue) : ast.defaultValue);
4558
4567
  if (ast.value) {
4559
- value = `withDefault(${expr}, \`${defaultValue}\`)`;
4568
+ value = `withDefault(${expr}, ${defaultValue})`;
4560
4569
  }
4561
4570
  else {
4562
- value = `\`${defaultValue}\``;
4571
+ value = defaultValue;
4563
4572
  }
4564
4573
  }
4565
4574
  else {
@@ -4570,12 +4579,12 @@ class CodeGenerator {
4570
4579
  }
4571
4580
  return null;
4572
4581
  }
4573
- generateComponentKey() {
4582
+ generateComponentKey(currentKey = "key") {
4574
4583
  const parts = [generateId("__")];
4575
4584
  for (let i = 0; i < this.target.loopLevel; i++) {
4576
4585
  parts.push(`\${key${i + 1}}`);
4577
4586
  }
4578
- return parts.join("__");
4587
+ return `${currentKey} + \`${parts.join("__")}\``;
4579
4588
  }
4580
4589
  /**
4581
4590
  * Formats a prop name and value into a string suitable to be inserted in the
@@ -4666,7 +4675,6 @@ class CodeGenerator {
4666
4675
  this.addLine(`${propVar}.slots = markRaw(Object.assign(${slotDef}, ${propVar}.slots))`);
4667
4676
  }
4668
4677
  // cmap key
4669
- const key = this.generateComponentKey();
4670
4678
  let expr;
4671
4679
  if (ast.isDynamic) {
4672
4680
  expr = generateId("Comp");
@@ -4682,7 +4690,7 @@ class CodeGenerator {
4682
4690
  // todo: check the forcenewblock condition
4683
4691
  this.insertAnchor(block);
4684
4692
  }
4685
- let keyArg = `key + \`${key}\``;
4693
+ let keyArg = this.generateComponentKey();
4686
4694
  if (ctx.tKeyExpr) {
4687
4695
  keyArg = `${ctx.tKeyExpr} + ${keyArg}`;
4688
4696
  }
@@ -4755,7 +4763,7 @@ class CodeGenerator {
4755
4763
  }
4756
4764
  let key = this.target.loopLevel ? `key${this.target.loopLevel}` : "key";
4757
4765
  if (isMultiple) {
4758
- key = `${key} + \`${this.generateComponentKey()}\``;
4766
+ key = this.generateComponentKey(key);
4759
4767
  }
4760
4768
  const props = ast.attrs ? this.formatPropObject(ast.attrs) : [];
4761
4769
  const scope = this.getPropString(props, dynProps);
@@ -4796,7 +4804,6 @@ class CodeGenerator {
4796
4804
  }
4797
4805
  let { block } = ctx;
4798
4806
  const name = this.compileInNewTarget("slot", ast.content, ctx);
4799
- const key = this.generateComponentKey();
4800
4807
  let ctxStr = "ctx";
4801
4808
  if (this.target.loopLevel || !this.hasSafeContext) {
4802
4809
  ctxStr = generateId("ctx");
@@ -4809,7 +4816,8 @@ class CodeGenerator {
4809
4816
  expr: `app.createComponent(null, false, true, false, false)`,
4810
4817
  });
4811
4818
  const target = compileExpr(ast.target);
4812
- const blockString = `${id}({target: ${target},slots: {'default': {__render: ${name}.bind(this), __ctx: ${ctxStr}}}}, key + \`${key}\`, node, ctx, Portal)`;
4819
+ const key = this.generateComponentKey();
4820
+ const blockString = `${id}({target: ${target},slots: {'default': {__render: ${name}.bind(this), __ctx: ${ctxStr}}}}, ${key}, node, ctx, Portal)`;
4813
4821
  if (block) {
4814
4822
  this.insertAnchor(block);
4815
4823
  }
@@ -5542,7 +5550,7 @@ function compile(template, options = {}) {
5542
5550
  }
5543
5551
 
5544
5552
  // do not modify manually. This file is generated by the release script.
5545
- const version = "2.2.10";
5553
+ const version = "2.2.11";
5546
5554
 
5547
5555
  // -----------------------------------------------------------------------------
5548
5556
  // Scheduler
@@ -5973,6 +5981,7 @@ exports.Component = Component;
5973
5981
  exports.EventBus = EventBus;
5974
5982
  exports.OwlError = OwlError;
5975
5983
  exports.__info__ = __info__;
5984
+ exports.batched = batched;
5976
5985
  exports.blockDom = blockDom;
5977
5986
  exports.loadFile = loadFile;
5978
5987
  exports.markRaw = markRaw;
@@ -6005,6 +6014,6 @@ exports.whenReady = whenReady;
6005
6014
  exports.xml = xml;
6006
6015
 
6007
6016
 
6008
- __info__.date = '2024-04-02T10:25:32.577Z';
6009
- __info__.hash = '97b69f1';
6017
+ __info__.date = '2024-06-17T13:31:12.099Z';
6018
+ __info__.hash = 'e7f405c';
6010
6019
  __info__.url = 'https://github.com/odoo/owl';
package/dist/owl.es.js CHANGED
@@ -2622,7 +2622,7 @@ function wrapError(fn, hookName) {
2622
2622
  result.catch(() => { }),
2623
2623
  new Promise((resolve) => setTimeout(() => resolve(TIMEOUT), 3000)),
2624
2624
  ]).then((res) => {
2625
- if (res === TIMEOUT && node.fiber === fiber) {
2625
+ if (res === TIMEOUT && node.fiber === fiber && node.status <= 2) {
2626
2626
  console.warn(timeoutError);
2627
2627
  }
2628
2628
  });
@@ -3512,7 +3512,7 @@ function compileExprToArray(expr) {
3512
3512
  const localVars = new Set();
3513
3513
  const tokens = tokenize(expr);
3514
3514
  let i = 0;
3515
- let stack = []; // to track last opening [ or {
3515
+ let stack = []; // to track last opening (, [ or {
3516
3516
  while (i < tokens.length) {
3517
3517
  let token = tokens[i];
3518
3518
  let prevToken = tokens[i - 1];
@@ -3521,10 +3521,12 @@ function compileExprToArray(expr) {
3521
3521
  switch (token.type) {
3522
3522
  case "LEFT_BRACE":
3523
3523
  case "LEFT_BRACKET":
3524
+ case "LEFT_PAREN":
3524
3525
  stack.push(token.type);
3525
3526
  break;
3526
3527
  case "RIGHT_BRACE":
3527
3528
  case "RIGHT_BRACKET":
3529
+ case "RIGHT_PAREN":
3528
3530
  stack.pop();
3529
3531
  }
3530
3532
  let isVar = token.type === "SYMBOL" && !RESERVED_WORDS.includes(token.value);
@@ -3636,6 +3638,13 @@ function isProp(tag, key) {
3636
3638
  }
3637
3639
  return false;
3638
3640
  }
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
+ }
3639
3648
  // -----------------------------------------------------------------------------
3640
3649
  // BlockDescription
3641
3650
  // -----------------------------------------------------------------------------
@@ -3816,15 +3825,14 @@ class CodeGenerator {
3816
3825
  mainCode.push(``);
3817
3826
  for (let block of this.blocks) {
3818
3827
  if (block.dom) {
3819
- let xmlString = block.asXmlString();
3820
- xmlString = xmlString.replace(/\\/g, "\\\\").replace(/`/g, "\\`");
3828
+ let xmlString = toStringExpression(block.asXmlString());
3821
3829
  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});`);
3825
3833
  }
3826
3834
  else {
3827
- mainCode.push(`let ${block.blockName} = createBlock(\`${xmlString}\`);`);
3835
+ mainCode.push(`let ${block.blockName} = createBlock(${xmlString});`);
3828
3836
  }
3829
3837
  }
3830
3838
  }
@@ -4002,7 +4010,7 @@ class CodeGenerator {
4002
4010
  const isNewBlock = !block || forceNewBlock;
4003
4011
  if (isNewBlock) {
4004
4012
  block = this.createBlock(block, "comment", ctx);
4005
- this.insertBlock(`comment(\`${ast.value}\`)`, block, {
4013
+ this.insertBlock(`comment(${toStringExpression(ast.value)})`, block, {
4006
4014
  ...ctx,
4007
4015
  forceNewBlock: forceNewBlock && !block,
4008
4016
  });
@@ -4024,7 +4032,7 @@ class CodeGenerator {
4024
4032
  }
4025
4033
  if (!block || forceNewBlock) {
4026
4034
  block = this.createBlock(block, "text", ctx);
4027
- this.insertBlock(`text(\`${value}\`)`, block, {
4035
+ this.insertBlock(`text(${toStringExpression(value)})`, block, {
4028
4036
  ...ctx,
4029
4037
  forceNewBlock: forceNewBlock && !block,
4030
4038
  });
@@ -4245,7 +4253,8 @@ class CodeGenerator {
4245
4253
  expr = compileExpr(ast.expr);
4246
4254
  if (ast.defaultValue) {
4247
4255
  this.helpers.add("withDefault");
4248
- expr = `withDefault(${expr}, \`${ast.defaultValue}\`)`;
4256
+ // FIXME: defaultValue is not translated
4257
+ expr = `withDefault(${expr}, ${toStringExpression(ast.defaultValue)})`;
4249
4258
  }
4250
4259
  }
4251
4260
  if (!block || forceNewBlock) {
@@ -4498,7 +4507,7 @@ class CodeGenerator {
4498
4507
  this.addLine(`${ctxVar}[zero] = ${bl};`);
4499
4508
  }
4500
4509
  }
4501
- const key = `key + \`${this.generateComponentKey()}\``;
4510
+ const key = this.generateComponentKey();
4502
4511
  if (isDynamic) {
4503
4512
  const templateVar = generateId("template");
4504
4513
  if (!this.staticDefs.find((d) => d.id === "call")) {
@@ -4550,12 +4559,12 @@ class CodeGenerator {
4550
4559
  else {
4551
4560
  let value;
4552
4561
  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);
4554
4563
  if (ast.value) {
4555
- value = `withDefault(${expr}, \`${defaultValue}\`)`;
4564
+ value = `withDefault(${expr}, ${defaultValue})`;
4556
4565
  }
4557
4566
  else {
4558
- value = `\`${defaultValue}\``;
4567
+ value = defaultValue;
4559
4568
  }
4560
4569
  }
4561
4570
  else {
@@ -4566,12 +4575,12 @@ class CodeGenerator {
4566
4575
  }
4567
4576
  return null;
4568
4577
  }
4569
- generateComponentKey() {
4578
+ generateComponentKey(currentKey = "key") {
4570
4579
  const parts = [generateId("__")];
4571
4580
  for (let i = 0; i < this.target.loopLevel; i++) {
4572
4581
  parts.push(`\${key${i + 1}}`);
4573
4582
  }
4574
- return parts.join("__");
4583
+ return `${currentKey} + \`${parts.join("__")}\``;
4575
4584
  }
4576
4585
  /**
4577
4586
  * Formats a prop name and value into a string suitable to be inserted in the
@@ -4662,7 +4671,6 @@ class CodeGenerator {
4662
4671
  this.addLine(`${propVar}.slots = markRaw(Object.assign(${slotDef}, ${propVar}.slots))`);
4663
4672
  }
4664
4673
  // cmap key
4665
- const key = this.generateComponentKey();
4666
4674
  let expr;
4667
4675
  if (ast.isDynamic) {
4668
4676
  expr = generateId("Comp");
@@ -4678,7 +4686,7 @@ class CodeGenerator {
4678
4686
  // todo: check the forcenewblock condition
4679
4687
  this.insertAnchor(block);
4680
4688
  }
4681
- let keyArg = `key + \`${key}\``;
4689
+ let keyArg = this.generateComponentKey();
4682
4690
  if (ctx.tKeyExpr) {
4683
4691
  keyArg = `${ctx.tKeyExpr} + ${keyArg}`;
4684
4692
  }
@@ -4751,7 +4759,7 @@ class CodeGenerator {
4751
4759
  }
4752
4760
  let key = this.target.loopLevel ? `key${this.target.loopLevel}` : "key";
4753
4761
  if (isMultiple) {
4754
- key = `${key} + \`${this.generateComponentKey()}\``;
4762
+ key = this.generateComponentKey(key);
4755
4763
  }
4756
4764
  const props = ast.attrs ? this.formatPropObject(ast.attrs) : [];
4757
4765
  const scope = this.getPropString(props, dynProps);
@@ -4792,7 +4800,6 @@ class CodeGenerator {
4792
4800
  }
4793
4801
  let { block } = ctx;
4794
4802
  const name = this.compileInNewTarget("slot", ast.content, ctx);
4795
- const key = this.generateComponentKey();
4796
4803
  let ctxStr = "ctx";
4797
4804
  if (this.target.loopLevel || !this.hasSafeContext) {
4798
4805
  ctxStr = generateId("ctx");
@@ -4805,7 +4812,8 @@ class CodeGenerator {
4805
4812
  expr: `app.createComponent(null, false, true, false, false)`,
4806
4813
  });
4807
4814
  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)`;
4809
4817
  if (block) {
4810
4818
  this.insertAnchor(block);
4811
4819
  }
@@ -5538,7 +5546,7 @@ function compile(template, options = {}) {
5538
5546
  }
5539
5547
 
5540
5548
  // do not modify manually. This file is generated by the release script.
5541
- const version = "2.2.10";
5549
+ const version = "2.2.11";
5542
5550
 
5543
5551
  // -----------------------------------------------------------------------------
5544
5552
  // Scheduler
@@ -5964,9 +5972,9 @@ TemplateSet.prototype._compileTemplate = function _compileTemplate(name, templat
5964
5972
  });
5965
5973
  };
5966
5974
 
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 };
5968
5976
 
5969
5977
 
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';
5972
5980
  __info__.url = 'https://github.com/odoo/owl';
package/dist/owl.iife.js CHANGED
@@ -2625,7 +2625,7 @@
2625
2625
  result.catch(() => { }),
2626
2626
  new Promise((resolve) => setTimeout(() => resolve(TIMEOUT), 3000)),
2627
2627
  ]).then((res) => {
2628
- if (res === TIMEOUT && node.fiber === fiber) {
2628
+ if (res === TIMEOUT && node.fiber === fiber && node.status <= 2) {
2629
2629
  console.warn(timeoutError);
2630
2630
  }
2631
2631
  });
@@ -3515,7 +3515,7 @@
3515
3515
  const localVars = new Set();
3516
3516
  const tokens = tokenize(expr);
3517
3517
  let i = 0;
3518
- let stack = []; // to track last opening [ or {
3518
+ let stack = []; // to track last opening (, [ or {
3519
3519
  while (i < tokens.length) {
3520
3520
  let token = tokens[i];
3521
3521
  let prevToken = tokens[i - 1];
@@ -3524,10 +3524,12 @@
3524
3524
  switch (token.type) {
3525
3525
  case "LEFT_BRACE":
3526
3526
  case "LEFT_BRACKET":
3527
+ case "LEFT_PAREN":
3527
3528
  stack.push(token.type);
3528
3529
  break;
3529
3530
  case "RIGHT_BRACE":
3530
3531
  case "RIGHT_BRACKET":
3532
+ case "RIGHT_PAREN":
3531
3533
  stack.pop();
3532
3534
  }
3533
3535
  let isVar = token.type === "SYMBOL" && !RESERVED_WORDS.includes(token.value);
@@ -3639,6 +3641,13 @@
3639
3641
  }
3640
3642
  return false;
3641
3643
  }
3644
+ /**
3645
+ * Returns a template literal that evaluates to str. You can add interpolation
3646
+ * sigils into the string if required
3647
+ */
3648
+ function toStringExpression(str) {
3649
+ return `\`${str.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/, "\\${")}\``;
3650
+ }
3642
3651
  // -----------------------------------------------------------------------------
3643
3652
  // BlockDescription
3644
3653
  // -----------------------------------------------------------------------------
@@ -3819,15 +3828,14 @@
3819
3828
  mainCode.push(``);
3820
3829
  for (let block of this.blocks) {
3821
3830
  if (block.dom) {
3822
- let xmlString = block.asXmlString();
3823
- xmlString = xmlString.replace(/\\/g, "\\\\").replace(/`/g, "\\`");
3831
+ let xmlString = toStringExpression(block.asXmlString());
3824
3832
  if (block.dynamicTagName) {
3825
- xmlString = xmlString.replace(/^<\w+/, `<\${tag || '${block.dom.nodeName}'}`);
3826
- xmlString = xmlString.replace(/\w+>$/, `\${tag || '${block.dom.nodeName}'}>`);
3827
- mainCode.push(`let ${block.blockName} = tag => createBlock(\`${xmlString}\`);`);
3833
+ xmlString = xmlString.replace(/^`<\w+/, `\`<\${tag || '${block.dom.nodeName}'}`);
3834
+ xmlString = xmlString.replace(/\w+>`$/, `\${tag || '${block.dom.nodeName}'}>\``);
3835
+ mainCode.push(`let ${block.blockName} = tag => createBlock(${xmlString});`);
3828
3836
  }
3829
3837
  else {
3830
- mainCode.push(`let ${block.blockName} = createBlock(\`${xmlString}\`);`);
3838
+ mainCode.push(`let ${block.blockName} = createBlock(${xmlString});`);
3831
3839
  }
3832
3840
  }
3833
3841
  }
@@ -4005,7 +4013,7 @@
4005
4013
  const isNewBlock = !block || forceNewBlock;
4006
4014
  if (isNewBlock) {
4007
4015
  block = this.createBlock(block, "comment", ctx);
4008
- this.insertBlock(`comment(\`${ast.value}\`)`, block, {
4016
+ this.insertBlock(`comment(${toStringExpression(ast.value)})`, block, {
4009
4017
  ...ctx,
4010
4018
  forceNewBlock: forceNewBlock && !block,
4011
4019
  });
@@ -4027,7 +4035,7 @@
4027
4035
  }
4028
4036
  if (!block || forceNewBlock) {
4029
4037
  block = this.createBlock(block, "text", ctx);
4030
- this.insertBlock(`text(\`${value}\`)`, block, {
4038
+ this.insertBlock(`text(${toStringExpression(value)})`, block, {
4031
4039
  ...ctx,
4032
4040
  forceNewBlock: forceNewBlock && !block,
4033
4041
  });
@@ -4248,7 +4256,8 @@
4248
4256
  expr = compileExpr(ast.expr);
4249
4257
  if (ast.defaultValue) {
4250
4258
  this.helpers.add("withDefault");
4251
- expr = `withDefault(${expr}, \`${ast.defaultValue}\`)`;
4259
+ // FIXME: defaultValue is not translated
4260
+ expr = `withDefault(${expr}, ${toStringExpression(ast.defaultValue)})`;
4252
4261
  }
4253
4262
  }
4254
4263
  if (!block || forceNewBlock) {
@@ -4501,7 +4510,7 @@
4501
4510
  this.addLine(`${ctxVar}[zero] = ${bl};`);
4502
4511
  }
4503
4512
  }
4504
- const key = `key + \`${this.generateComponentKey()}\``;
4513
+ const key = this.generateComponentKey();
4505
4514
  if (isDynamic) {
4506
4515
  const templateVar = generateId("template");
4507
4516
  if (!this.staticDefs.find((d) => d.id === "call")) {
@@ -4553,12 +4562,12 @@
4553
4562
  else {
4554
4563
  let value;
4555
4564
  if (ast.defaultValue) {
4556
- const defaultValue = ctx.translate ? this.translate(ast.defaultValue) : ast.defaultValue;
4565
+ const defaultValue = toStringExpression(ctx.translate ? this.translate(ast.defaultValue) : ast.defaultValue);
4557
4566
  if (ast.value) {
4558
- value = `withDefault(${expr}, \`${defaultValue}\`)`;
4567
+ value = `withDefault(${expr}, ${defaultValue})`;
4559
4568
  }
4560
4569
  else {
4561
- value = `\`${defaultValue}\``;
4570
+ value = defaultValue;
4562
4571
  }
4563
4572
  }
4564
4573
  else {
@@ -4569,12 +4578,12 @@
4569
4578
  }
4570
4579
  return null;
4571
4580
  }
4572
- generateComponentKey() {
4581
+ generateComponentKey(currentKey = "key") {
4573
4582
  const parts = [generateId("__")];
4574
4583
  for (let i = 0; i < this.target.loopLevel; i++) {
4575
4584
  parts.push(`\${key${i + 1}}`);
4576
4585
  }
4577
- return parts.join("__");
4586
+ return `${currentKey} + \`${parts.join("__")}\``;
4578
4587
  }
4579
4588
  /**
4580
4589
  * Formats a prop name and value into a string suitable to be inserted in the
@@ -4665,7 +4674,6 @@
4665
4674
  this.addLine(`${propVar}.slots = markRaw(Object.assign(${slotDef}, ${propVar}.slots))`);
4666
4675
  }
4667
4676
  // cmap key
4668
- const key = this.generateComponentKey();
4669
4677
  let expr;
4670
4678
  if (ast.isDynamic) {
4671
4679
  expr = generateId("Comp");
@@ -4681,7 +4689,7 @@
4681
4689
  // todo: check the forcenewblock condition
4682
4690
  this.insertAnchor(block);
4683
4691
  }
4684
- let keyArg = `key + \`${key}\``;
4692
+ let keyArg = this.generateComponentKey();
4685
4693
  if (ctx.tKeyExpr) {
4686
4694
  keyArg = `${ctx.tKeyExpr} + ${keyArg}`;
4687
4695
  }
@@ -4754,7 +4762,7 @@
4754
4762
  }
4755
4763
  let key = this.target.loopLevel ? `key${this.target.loopLevel}` : "key";
4756
4764
  if (isMultiple) {
4757
- key = `${key} + \`${this.generateComponentKey()}\``;
4765
+ key = this.generateComponentKey(key);
4758
4766
  }
4759
4767
  const props = ast.attrs ? this.formatPropObject(ast.attrs) : [];
4760
4768
  const scope = this.getPropString(props, dynProps);
@@ -4795,7 +4803,6 @@
4795
4803
  }
4796
4804
  let { block } = ctx;
4797
4805
  const name = this.compileInNewTarget("slot", ast.content, ctx);
4798
- const key = this.generateComponentKey();
4799
4806
  let ctxStr = "ctx";
4800
4807
  if (this.target.loopLevel || !this.hasSafeContext) {
4801
4808
  ctxStr = generateId("ctx");
@@ -4808,7 +4815,8 @@
4808
4815
  expr: `app.createComponent(null, false, true, false, false)`,
4809
4816
  });
4810
4817
  const target = compileExpr(ast.target);
4811
- const blockString = `${id}({target: ${target},slots: {'default': {__render: ${name}.bind(this), __ctx: ${ctxStr}}}}, key + \`${key}\`, node, ctx, Portal)`;
4818
+ const key = this.generateComponentKey();
4819
+ const blockString = `${id}({target: ${target},slots: {'default': {__render: ${name}.bind(this), __ctx: ${ctxStr}}}}, ${key}, node, ctx, Portal)`;
4812
4820
  if (block) {
4813
4821
  this.insertAnchor(block);
4814
4822
  }
@@ -5541,7 +5549,7 @@
5541
5549
  }
5542
5550
 
5543
5551
  // do not modify manually. This file is generated by the release script.
5544
- const version = "2.2.10";
5552
+ const version = "2.2.11";
5545
5553
 
5546
5554
  // -----------------------------------------------------------------------------
5547
5555
  // Scheduler
@@ -5972,6 +5980,7 @@ See https://github.com/odoo/owl/blob/${hash}/doc/reference/app.md#configuration
5972
5980
  exports.EventBus = EventBus;
5973
5981
  exports.OwlError = OwlError;
5974
5982
  exports.__info__ = __info__;
5983
+ exports.batched = batched;
5975
5984
  exports.blockDom = blockDom;
5976
5985
  exports.loadFile = loadFile;
5977
5986
  exports.markRaw = markRaw;
@@ -6006,8 +6015,8 @@ See https://github.com/odoo/owl/blob/${hash}/doc/reference/app.md#configuration
6006
6015
  Object.defineProperty(exports, '__esModule', { value: true });
6007
6016
 
6008
6017
 
6009
- __info__.date = '2024-04-02T10:25:32.577Z';
6010
- __info__.hash = '97b69f1';
6018
+ __info__.date = '2024-06-17T13:31:12.099Z';
6019
+ __info__.hash = 'e7f405c';
6011
6020
  __info__.url = 'https://github.com/odoo/owl';
6012
6021
 
6013
6022