@odoo/owl 2.5.3 → 2.6.1

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.
package/dist/owl.cjs.js CHANGED
@@ -3742,6 +3742,7 @@ function createContext(parentCtx, params) {
3742
3742
  index: 0,
3743
3743
  forceNewBlock: true,
3744
3744
  translate: parentCtx.translate,
3745
+ translationCtx: parentCtx.translationCtx,
3745
3746
  tKeyExpr: null,
3746
3747
  nameSpace: parentCtx.nameSpace,
3747
3748
  tModelSelectedExpr: parentCtx.tModelSelectedExpr,
@@ -3844,6 +3845,7 @@ class CodeGenerator {
3844
3845
  forceNewBlock: false,
3845
3846
  isLast: true,
3846
3847
  translate: true,
3848
+ translationCtx: "",
3847
3849
  tKeyExpr: null,
3848
3850
  });
3849
3851
  // define blocks and utility functions
@@ -3981,9 +3983,9 @@ class CodeGenerator {
3981
3983
  })
3982
3984
  .join("");
3983
3985
  }
3984
- translate(str) {
3986
+ translate(str, translationCtx) {
3985
3987
  const match = translationRE.exec(str);
3986
- return match[1] + this.translateFn(match[2]) + match[3];
3988
+ return match[1] + this.translateFn(match[2], translationCtx) + match[3];
3987
3989
  }
3988
3990
  /**
3989
3991
  * @returns the newly created block name, if any
@@ -4024,7 +4026,9 @@ class CodeGenerator {
4024
4026
  return this.compileTSlot(ast, ctx);
4025
4027
  case 16 /* TTranslation */:
4026
4028
  return this.compileTTranslation(ast, ctx);
4027
- case 17 /* TPortal */:
4029
+ case 17 /* TTranslationContext */:
4030
+ return this.compileTTranslationContext(ast, ctx);
4031
+ case 18 /* TPortal */:
4028
4032
  return this.compileTPortal(ast, ctx);
4029
4033
  }
4030
4034
  }
@@ -4062,7 +4066,7 @@ class CodeGenerator {
4062
4066
  let { block, forceNewBlock } = ctx;
4063
4067
  let value = ast.value;
4064
4068
  if (value && ctx.translate !== false) {
4065
- value = this.translate(value);
4069
+ value = this.translate(value, ctx.translationCtx);
4066
4070
  }
4067
4071
  if (!ctx.inPreTag) {
4068
4072
  value = value.replace(whitespaceRE, " ");
@@ -4097,6 +4101,7 @@ class CodeGenerator {
4097
4101
  return `[${modifiersCode}${this.captureExpression(handler)}, ctx]`;
4098
4102
  }
4099
4103
  compileTDomNode(ast, ctx) {
4104
+ var _a;
4100
4105
  let { block, forceNewBlock } = ctx;
4101
4106
  const isNewBlock = !block || forceNewBlock || ast.dynamicTag !== null || ast.ns;
4102
4107
  let codeIdx = this.target.code.length;
@@ -4152,7 +4157,8 @@ class CodeGenerator {
4152
4157
  }
4153
4158
  }
4154
4159
  else if (this.translatableAttributes.includes(key)) {
4155
- attrs[key] = this.translateFn(ast.attrs[key]);
4160
+ const attrTranslationCtx = ((_a = ast.attrsTranslationCtx) === null || _a === void 0 ? void 0 : _a[key]) || ctx.translationCtx;
4161
+ attrs[key] = this.translateFn(ast.attrs[key], attrTranslationCtx);
4156
4162
  }
4157
4163
  else {
4158
4164
  expr = `"${ast.attrs[key]}"`;
@@ -4596,7 +4602,7 @@ class CodeGenerator {
4596
4602
  else {
4597
4603
  let value;
4598
4604
  if (ast.defaultValue) {
4599
- const defaultValue = toStringExpression(ctx.translate ? this.translate(ast.defaultValue) : ast.defaultValue);
4605
+ const defaultValue = toStringExpression(ctx.translate ? this.translate(ast.defaultValue, ctx.translationCtx) : ast.defaultValue);
4600
4606
  if (ast.value) {
4601
4607
  value = `withDefault(${expr}, ${defaultValue})`;
4602
4608
  }
@@ -4630,9 +4636,10 @@ class CodeGenerator {
4630
4636
  * "some-prop" "state" "'some-prop': ctx['state']"
4631
4637
  * "onClick.bind" "onClick" "onClick: bind(ctx, ctx['onClick'])"
4632
4638
  */
4633
- formatProp(name, value) {
4639
+ formatProp(name, value, attrsTranslationCtx, translationCtx) {
4634
4640
  if (name.endsWith(".translate")) {
4635
- value = toStringExpression(this.translateFn(value));
4641
+ const attrTranslationCtx = (attrsTranslationCtx === null || attrsTranslationCtx === void 0 ? void 0 : attrsTranslationCtx[name]) || translationCtx;
4642
+ value = toStringExpression(this.translateFn(value, attrTranslationCtx));
4636
4643
  }
4637
4644
  else {
4638
4645
  value = this.captureExpression(value);
@@ -4654,8 +4661,8 @@ class CodeGenerator {
4654
4661
  name = /^[a-z_]+$/i.test(name) ? name : `'${name}'`;
4655
4662
  return `${name}: ${value || undefined}`;
4656
4663
  }
4657
- formatPropObject(obj) {
4658
- return Object.entries(obj).map(([k, v]) => this.formatProp(k, v));
4664
+ formatPropObject(obj, attrsTranslationCtx, translationCtx) {
4665
+ return Object.entries(obj).map(([k, v]) => this.formatProp(k, v, attrsTranslationCtx, translationCtx));
4659
4666
  }
4660
4667
  getPropString(props, dynProps) {
4661
4668
  let propString = `{${props.join(",")}}`;
@@ -4668,7 +4675,9 @@ class CodeGenerator {
4668
4675
  let { block } = ctx;
4669
4676
  // props
4670
4677
  const hasSlotsProp = "slots" in (ast.props || {});
4671
- const props = ast.props ? this.formatPropObject(ast.props) : [];
4678
+ const props = ast.props
4679
+ ? this.formatPropObject(ast.props, ast.propsTranslationCtx, ctx.translationCtx)
4680
+ : [];
4672
4681
  // slots
4673
4682
  let slotDef = "";
4674
4683
  if (ast.slots) {
@@ -4691,7 +4700,7 @@ class CodeGenerator {
4691
4700
  params.push(`__scope: "${scope}"`);
4692
4701
  }
4693
4702
  if (ast.slots[slotName].attrs) {
4694
- params.push(...this.formatPropObject(ast.slots[slotName].attrs));
4703
+ params.push(...this.formatPropObject(ast.slots[slotName].attrs, ast.slots[slotName].attrsTranslationCtx, ctx.translationCtx));
4695
4704
  }
4696
4705
  const slotInfo = `{${params.join(", ")}}`;
4697
4706
  slotStr.push(`'${slotName}': ${slotInfo}`);
@@ -4796,15 +4805,16 @@ class CodeGenerator {
4796
4805
  isMultiple = isMultiple || this.slotNames.has(ast.name);
4797
4806
  this.slotNames.add(ast.name);
4798
4807
  }
4799
- const dynProps = ast.attrs ? ast.attrs["t-props"] : null;
4800
- if (ast.attrs) {
4801
- delete ast.attrs["t-props"];
4802
- }
4808
+ const attrs = { ...ast.attrs };
4809
+ const dynProps = attrs["t-props"];
4810
+ delete attrs["t-props"];
4803
4811
  let key = this.target.loopLevel ? `key${this.target.loopLevel}` : "key";
4804
4812
  if (isMultiple) {
4805
4813
  key = this.generateComponentKey(key);
4806
4814
  }
4807
- const props = ast.attrs ? this.formatPropObject(ast.attrs) : [];
4815
+ const props = ast.attrs
4816
+ ? this.formatPropObject(attrs, ast.attrsTranslationCtx, ctx.translationCtx)
4817
+ : [];
4808
4818
  const scope = this.getPropString(props, dynProps);
4809
4819
  if (ast.defaultContent) {
4810
4820
  const name = this.compileInNewTarget("defaultContent", ast.defaultContent, ctx);
@@ -4837,6 +4847,12 @@ class CodeGenerator {
4837
4847
  }
4838
4848
  return null;
4839
4849
  }
4850
+ compileTTranslationContext(ast, ctx) {
4851
+ if (ast.content) {
4852
+ return this.compileAST(ast.content, Object.assign({}, ctx, { translationCtx: ast.translationCtx }));
4853
+ }
4854
+ return null;
4855
+ }
4840
4856
  compileTPortal(ast, ctx) {
4841
4857
  if (!this.staticDefs.find((d) => d.id === "Portal")) {
4842
4858
  this.staticDefs.push({ id: "Portal", expr: `app.Portal` });
@@ -4906,6 +4922,7 @@ function parseNode(node, ctx) {
4906
4922
  parseTOutNode(node, ctx) ||
4907
4923
  parseTKey(node, ctx) ||
4908
4924
  parseTTranslation(node, ctx) ||
4925
+ parseTTranslationContext(node, ctx) ||
4909
4926
  parseTSlot(node, ctx) ||
4910
4927
  parseComponent(node, ctx) ||
4911
4928
  parseDOMNode(node, ctx) ||
@@ -5014,6 +5031,7 @@ function parseDOMNode(node, ctx) {
5014
5031
  node.removeAttribute("t-ref");
5015
5032
  const nodeAttrsNames = node.getAttributeNames();
5016
5033
  let attrs = null;
5034
+ let attrsTranslationCtx = null;
5017
5035
  let on = null;
5018
5036
  let model = null;
5019
5037
  for (let attr of nodeAttrsNames) {
@@ -5074,6 +5092,11 @@ function parseDOMNode(node, ctx) {
5074
5092
  else if (attr === "xmlns") {
5075
5093
  ns = value;
5076
5094
  }
5095
+ else if (attr.startsWith("t-translation-context-")) {
5096
+ const attrName = attr.slice(22);
5097
+ attrsTranslationCtx = attrsTranslationCtx || {};
5098
+ attrsTranslationCtx[attrName] = value;
5099
+ }
5077
5100
  else if (attr !== "t-name") {
5078
5101
  if (attr.startsWith("t-") && !attr.startsWith("t-att")) {
5079
5102
  throw new OwlError(`Unknown QWeb directive: '${attr}'`);
@@ -5095,6 +5118,7 @@ function parseDOMNode(node, ctx) {
5095
5118
  tag: tagName,
5096
5119
  dynamicTag,
5097
5120
  attrs,
5121
+ attrsTranslationCtx,
5098
5122
  on,
5099
5123
  ref,
5100
5124
  content: children,
@@ -5235,7 +5259,15 @@ function parseTCall(node, ctx) {
5235
5259
  if (ast && ast.type === 11 /* TComponent */) {
5236
5260
  return {
5237
5261
  ...ast,
5238
- slots: { default: { content: tcall, scope: null, on: null, attrs: null } },
5262
+ slots: {
5263
+ default: {
5264
+ content: tcall,
5265
+ scope: null,
5266
+ on: null,
5267
+ attrs: null,
5268
+ attrsTranslationCtx: null,
5269
+ },
5270
+ },
5239
5271
  };
5240
5272
  }
5241
5273
  }
@@ -5350,9 +5382,15 @@ function parseComponent(node, ctx) {
5350
5382
  node.removeAttribute("t-slot-scope");
5351
5383
  let on = null;
5352
5384
  let props = null;
5385
+ let propsTranslationCtx = null;
5353
5386
  for (let name of node.getAttributeNames()) {
5354
5387
  const value = node.getAttribute(name);
5355
- if (name.startsWith("t-")) {
5388
+ if (name.startsWith("t-translation-context-")) {
5389
+ const attrName = name.slice(22);
5390
+ propsTranslationCtx = propsTranslationCtx || {};
5391
+ propsTranslationCtx[attrName] = value;
5392
+ }
5393
+ else if (name.startsWith("t-")) {
5356
5394
  if (name.startsWith("t-on-")) {
5357
5395
  on = on || {};
5358
5396
  on[name.slice(5)] = value;
@@ -5396,6 +5434,7 @@ function parseComponent(node, ctx) {
5396
5434
  const slotAst = parseNode(slotNode, ctx);
5397
5435
  let on = null;
5398
5436
  let attrs = null;
5437
+ let attrsTranslationCtx = null;
5399
5438
  let scope = null;
5400
5439
  for (let attributeName of slotNode.getAttributeNames()) {
5401
5440
  const value = slotNode.getAttribute(attributeName);
@@ -5403,6 +5442,11 @@ function parseComponent(node, ctx) {
5403
5442
  scope = value;
5404
5443
  continue;
5405
5444
  }
5445
+ else if (attributeName.startsWith("t-translation-context-")) {
5446
+ const attrName = attributeName.slice(22);
5447
+ attrsTranslationCtx = attrsTranslationCtx || {};
5448
+ attrsTranslationCtx[attrName] = value;
5449
+ }
5406
5450
  else if (attributeName.startsWith("t-on-")) {
5407
5451
  on = on || {};
5408
5452
  on[attributeName.slice(5)] = value;
@@ -5413,17 +5457,32 @@ function parseComponent(node, ctx) {
5413
5457
  }
5414
5458
  }
5415
5459
  slots = slots || {};
5416
- slots[name] = { content: slotAst, on, attrs, scope };
5460
+ slots[name] = { content: slotAst, on, attrs, attrsTranslationCtx, scope };
5417
5461
  }
5418
5462
  // default slot
5419
5463
  const defaultContent = parseChildNodes(clone, ctx);
5420
5464
  slots = slots || {};
5421
5465
  // t-set-slot="default" has priority over content
5422
5466
  if (defaultContent && !slots.default) {
5423
- slots.default = { content: defaultContent, on, attrs: null, scope: defaultSlotScope };
5467
+ slots.default = {
5468
+ content: defaultContent,
5469
+ on,
5470
+ attrs: null,
5471
+ attrsTranslationCtx: null,
5472
+ scope: defaultSlotScope,
5473
+ };
5424
5474
  }
5425
5475
  }
5426
- return { type: 11 /* TComponent */, name, isDynamic, dynamicProps, props, slots, on };
5476
+ return {
5477
+ type: 11 /* TComponent */,
5478
+ name,
5479
+ isDynamic,
5480
+ dynamicProps,
5481
+ props,
5482
+ propsTranslationCtx,
5483
+ slots,
5484
+ on,
5485
+ };
5427
5486
  }
5428
5487
  // -----------------------------------------------------------------------------
5429
5488
  // Slots
@@ -5435,6 +5494,7 @@ function parseTSlot(node, ctx) {
5435
5494
  const name = node.getAttribute("t-slot");
5436
5495
  node.removeAttribute("t-slot");
5437
5496
  let attrs = null;
5497
+ let attrsTranslationCtx = null;
5438
5498
  let on = null;
5439
5499
  for (let attributeName of node.getAttributeNames()) {
5440
5500
  const value = node.getAttribute(attributeName);
@@ -5442,6 +5502,11 @@ function parseTSlot(node, ctx) {
5442
5502
  on = on || {};
5443
5503
  on[attributeName.slice(5)] = value;
5444
5504
  }
5505
+ else if (attributeName.startsWith("t-translation-context-")) {
5506
+ const attrName = attributeName.slice(22);
5507
+ attrsTranslationCtx = attrsTranslationCtx || {};
5508
+ attrsTranslationCtx[attrName] = value;
5509
+ }
5445
5510
  else {
5446
5511
  attrs = attrs || {};
5447
5512
  attrs[attributeName] = value;
@@ -5451,10 +5516,14 @@ function parseTSlot(node, ctx) {
5451
5516
  type: 14 /* TSlot */,
5452
5517
  name,
5453
5518
  attrs,
5519
+ attrsTranslationCtx,
5454
5520
  on,
5455
5521
  defaultContent: parseChildNodes(node, ctx),
5456
5522
  };
5457
5523
  }
5524
+ // -----------------------------------------------------------------------------
5525
+ // Translation
5526
+ // -----------------------------------------------------------------------------
5458
5527
  function parseTTranslation(node, ctx) {
5459
5528
  if (node.getAttribute("t-translation") !== "off") {
5460
5529
  return null;
@@ -5466,6 +5535,21 @@ function parseTTranslation(node, ctx) {
5466
5535
  };
5467
5536
  }
5468
5537
  // -----------------------------------------------------------------------------
5538
+ // Translation Context
5539
+ // -----------------------------------------------------------------------------
5540
+ function parseTTranslationContext(node, ctx) {
5541
+ const translationCtx = node.getAttribute("t-translation-context");
5542
+ if (!translationCtx) {
5543
+ return null;
5544
+ }
5545
+ node.removeAttribute("t-translation-context");
5546
+ return {
5547
+ type: 17 /* TTranslationContext */,
5548
+ content: parseNode(node, ctx),
5549
+ translationCtx,
5550
+ };
5551
+ }
5552
+ // -----------------------------------------------------------------------------
5469
5553
  // Portal
5470
5554
  // -----------------------------------------------------------------------------
5471
5555
  function parseTPortal(node, ctx) {
@@ -5482,7 +5566,7 @@ function parseTPortal(node, ctx) {
5482
5566
  };
5483
5567
  }
5484
5568
  return {
5485
- type: 17 /* TPortal */,
5569
+ type: 18 /* TPortal */,
5486
5570
  target,
5487
5571
  content,
5488
5572
  };
@@ -5624,7 +5708,7 @@ function compile(template, options = {
5624
5708
  }
5625
5709
 
5626
5710
  // do not modify manually. This file is generated by the release script.
5627
- const version = "2.5.3";
5711
+ const version = "2.6.1";
5628
5712
 
5629
5713
  // -----------------------------------------------------------------------------
5630
5714
  // Scheduler
@@ -5719,13 +5803,6 @@ class Scheduler {
5719
5803
  Scheduler.requestAnimationFrame = window.requestAnimationFrame.bind(window);
5720
5804
 
5721
5805
  let hasBeenLogged = false;
5722
- const DEV_MSG = () => {
5723
- const hash = window.owl ? window.owl.__info__.hash : "master";
5724
- return `Owl is running in 'dev' mode.
5725
-
5726
- This is not suitable for production use.
5727
- See https://github.com/odoo/owl/blob/${hash}/doc/reference/app.md#configuration for more information.`;
5728
- };
5729
5806
  const apps = new Set();
5730
5807
  window.__OWL_DEVTOOLS__ || (window.__OWL_DEVTOOLS__ = { apps, Fiber, RootFiber, toRaw, reactive });
5731
5808
  class App extends TemplateSet {
@@ -5742,7 +5819,7 @@ class App extends TemplateSet {
5742
5819
  }
5743
5820
  this.warnIfNoStaticProps = config.warnIfNoStaticProps || false;
5744
5821
  if (this.dev && !config.test && !hasBeenLogged) {
5745
- console.info(DEV_MSG());
5822
+ console.info(`Owl is running in 'dev' mode.`);
5746
5823
  hasBeenLogged = true;
5747
5824
  }
5748
5825
  const env = config.env || {};
@@ -6137,6 +6214,6 @@ exports.whenReady = whenReady;
6137
6214
  exports.xml = xml;
6138
6215
 
6139
6216
 
6140
- __info__.date = '2025-01-10T10:10:53.709Z';
6141
- __info__.hash = 'b31fa81';
6217
+ __info__.date = '2025-03-05T08:37:58.580Z';
6218
+ __info__.hash = '2b5cea9';
6142
6219
  __info__.url = 'https://github.com/odoo/owl';