@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.es.js CHANGED
@@ -3738,6 +3738,7 @@ function createContext(parentCtx, params) {
3738
3738
  index: 0,
3739
3739
  forceNewBlock: true,
3740
3740
  translate: parentCtx.translate,
3741
+ translationCtx: parentCtx.translationCtx,
3741
3742
  tKeyExpr: null,
3742
3743
  nameSpace: parentCtx.nameSpace,
3743
3744
  tModelSelectedExpr: parentCtx.tModelSelectedExpr,
@@ -3840,6 +3841,7 @@ class CodeGenerator {
3840
3841
  forceNewBlock: false,
3841
3842
  isLast: true,
3842
3843
  translate: true,
3844
+ translationCtx: "",
3843
3845
  tKeyExpr: null,
3844
3846
  });
3845
3847
  // define blocks and utility functions
@@ -3977,9 +3979,9 @@ class CodeGenerator {
3977
3979
  })
3978
3980
  .join("");
3979
3981
  }
3980
- translate(str) {
3982
+ translate(str, translationCtx) {
3981
3983
  const match = translationRE.exec(str);
3982
- return match[1] + this.translateFn(match[2]) + match[3];
3984
+ return match[1] + this.translateFn(match[2], translationCtx) + match[3];
3983
3985
  }
3984
3986
  /**
3985
3987
  * @returns the newly created block name, if any
@@ -4020,7 +4022,9 @@ class CodeGenerator {
4020
4022
  return this.compileTSlot(ast, ctx);
4021
4023
  case 16 /* TTranslation */:
4022
4024
  return this.compileTTranslation(ast, ctx);
4023
- case 17 /* TPortal */:
4025
+ case 17 /* TTranslationContext */:
4026
+ return this.compileTTranslationContext(ast, ctx);
4027
+ case 18 /* TPortal */:
4024
4028
  return this.compileTPortal(ast, ctx);
4025
4029
  }
4026
4030
  }
@@ -4058,7 +4062,7 @@ class CodeGenerator {
4058
4062
  let { block, forceNewBlock } = ctx;
4059
4063
  let value = ast.value;
4060
4064
  if (value && ctx.translate !== false) {
4061
- value = this.translate(value);
4065
+ value = this.translate(value, ctx.translationCtx);
4062
4066
  }
4063
4067
  if (!ctx.inPreTag) {
4064
4068
  value = value.replace(whitespaceRE, " ");
@@ -4093,6 +4097,7 @@ class CodeGenerator {
4093
4097
  return `[${modifiersCode}${this.captureExpression(handler)}, ctx]`;
4094
4098
  }
4095
4099
  compileTDomNode(ast, ctx) {
4100
+ var _a;
4096
4101
  let { block, forceNewBlock } = ctx;
4097
4102
  const isNewBlock = !block || forceNewBlock || ast.dynamicTag !== null || ast.ns;
4098
4103
  let codeIdx = this.target.code.length;
@@ -4148,7 +4153,8 @@ class CodeGenerator {
4148
4153
  }
4149
4154
  }
4150
4155
  else if (this.translatableAttributes.includes(key)) {
4151
- attrs[key] = this.translateFn(ast.attrs[key]);
4156
+ const attrTranslationCtx = ((_a = ast.attrsTranslationCtx) === null || _a === void 0 ? void 0 : _a[key]) || ctx.translationCtx;
4157
+ attrs[key] = this.translateFn(ast.attrs[key], attrTranslationCtx);
4152
4158
  }
4153
4159
  else {
4154
4160
  expr = `"${ast.attrs[key]}"`;
@@ -4592,7 +4598,7 @@ class CodeGenerator {
4592
4598
  else {
4593
4599
  let value;
4594
4600
  if (ast.defaultValue) {
4595
- const defaultValue = toStringExpression(ctx.translate ? this.translate(ast.defaultValue) : ast.defaultValue);
4601
+ const defaultValue = toStringExpression(ctx.translate ? this.translate(ast.defaultValue, ctx.translationCtx) : ast.defaultValue);
4596
4602
  if (ast.value) {
4597
4603
  value = `withDefault(${expr}, ${defaultValue})`;
4598
4604
  }
@@ -4626,9 +4632,10 @@ class CodeGenerator {
4626
4632
  * "some-prop" "state" "'some-prop': ctx['state']"
4627
4633
  * "onClick.bind" "onClick" "onClick: bind(ctx, ctx['onClick'])"
4628
4634
  */
4629
- formatProp(name, value) {
4635
+ formatProp(name, value, attrsTranslationCtx, translationCtx) {
4630
4636
  if (name.endsWith(".translate")) {
4631
- value = toStringExpression(this.translateFn(value));
4637
+ const attrTranslationCtx = (attrsTranslationCtx === null || attrsTranslationCtx === void 0 ? void 0 : attrsTranslationCtx[name]) || translationCtx;
4638
+ value = toStringExpression(this.translateFn(value, attrTranslationCtx));
4632
4639
  }
4633
4640
  else {
4634
4641
  value = this.captureExpression(value);
@@ -4650,8 +4657,8 @@ class CodeGenerator {
4650
4657
  name = /^[a-z_]+$/i.test(name) ? name : `'${name}'`;
4651
4658
  return `${name}: ${value || undefined}`;
4652
4659
  }
4653
- formatPropObject(obj) {
4654
- return Object.entries(obj).map(([k, v]) => this.formatProp(k, v));
4660
+ formatPropObject(obj, attrsTranslationCtx, translationCtx) {
4661
+ return Object.entries(obj).map(([k, v]) => this.formatProp(k, v, attrsTranslationCtx, translationCtx));
4655
4662
  }
4656
4663
  getPropString(props, dynProps) {
4657
4664
  let propString = `{${props.join(",")}}`;
@@ -4664,7 +4671,9 @@ class CodeGenerator {
4664
4671
  let { block } = ctx;
4665
4672
  // props
4666
4673
  const hasSlotsProp = "slots" in (ast.props || {});
4667
- const props = ast.props ? this.formatPropObject(ast.props) : [];
4674
+ const props = ast.props
4675
+ ? this.formatPropObject(ast.props, ast.propsTranslationCtx, ctx.translationCtx)
4676
+ : [];
4668
4677
  // slots
4669
4678
  let slotDef = "";
4670
4679
  if (ast.slots) {
@@ -4687,7 +4696,7 @@ class CodeGenerator {
4687
4696
  params.push(`__scope: "${scope}"`);
4688
4697
  }
4689
4698
  if (ast.slots[slotName].attrs) {
4690
- params.push(...this.formatPropObject(ast.slots[slotName].attrs));
4699
+ params.push(...this.formatPropObject(ast.slots[slotName].attrs, ast.slots[slotName].attrsTranslationCtx, ctx.translationCtx));
4691
4700
  }
4692
4701
  const slotInfo = `{${params.join(", ")}}`;
4693
4702
  slotStr.push(`'${slotName}': ${slotInfo}`);
@@ -4792,15 +4801,16 @@ class CodeGenerator {
4792
4801
  isMultiple = isMultiple || this.slotNames.has(ast.name);
4793
4802
  this.slotNames.add(ast.name);
4794
4803
  }
4795
- const dynProps = ast.attrs ? ast.attrs["t-props"] : null;
4796
- if (ast.attrs) {
4797
- delete ast.attrs["t-props"];
4798
- }
4804
+ const attrs = { ...ast.attrs };
4805
+ const dynProps = attrs["t-props"];
4806
+ delete attrs["t-props"];
4799
4807
  let key = this.target.loopLevel ? `key${this.target.loopLevel}` : "key";
4800
4808
  if (isMultiple) {
4801
4809
  key = this.generateComponentKey(key);
4802
4810
  }
4803
- const props = ast.attrs ? this.formatPropObject(ast.attrs) : [];
4811
+ const props = ast.attrs
4812
+ ? this.formatPropObject(attrs, ast.attrsTranslationCtx, ctx.translationCtx)
4813
+ : [];
4804
4814
  const scope = this.getPropString(props, dynProps);
4805
4815
  if (ast.defaultContent) {
4806
4816
  const name = this.compileInNewTarget("defaultContent", ast.defaultContent, ctx);
@@ -4833,6 +4843,12 @@ class CodeGenerator {
4833
4843
  }
4834
4844
  return null;
4835
4845
  }
4846
+ compileTTranslationContext(ast, ctx) {
4847
+ if (ast.content) {
4848
+ return this.compileAST(ast.content, Object.assign({}, ctx, { translationCtx: ast.translationCtx }));
4849
+ }
4850
+ return null;
4851
+ }
4836
4852
  compileTPortal(ast, ctx) {
4837
4853
  if (!this.staticDefs.find((d) => d.id === "Portal")) {
4838
4854
  this.staticDefs.push({ id: "Portal", expr: `app.Portal` });
@@ -4902,6 +4918,7 @@ function parseNode(node, ctx) {
4902
4918
  parseTOutNode(node, ctx) ||
4903
4919
  parseTKey(node, ctx) ||
4904
4920
  parseTTranslation(node, ctx) ||
4921
+ parseTTranslationContext(node, ctx) ||
4905
4922
  parseTSlot(node, ctx) ||
4906
4923
  parseComponent(node, ctx) ||
4907
4924
  parseDOMNode(node, ctx) ||
@@ -5010,6 +5027,7 @@ function parseDOMNode(node, ctx) {
5010
5027
  node.removeAttribute("t-ref");
5011
5028
  const nodeAttrsNames = node.getAttributeNames();
5012
5029
  let attrs = null;
5030
+ let attrsTranslationCtx = null;
5013
5031
  let on = null;
5014
5032
  let model = null;
5015
5033
  for (let attr of nodeAttrsNames) {
@@ -5070,6 +5088,11 @@ function parseDOMNode(node, ctx) {
5070
5088
  else if (attr === "xmlns") {
5071
5089
  ns = value;
5072
5090
  }
5091
+ else if (attr.startsWith("t-translation-context-")) {
5092
+ const attrName = attr.slice(22);
5093
+ attrsTranslationCtx = attrsTranslationCtx || {};
5094
+ attrsTranslationCtx[attrName] = value;
5095
+ }
5073
5096
  else if (attr !== "t-name") {
5074
5097
  if (attr.startsWith("t-") && !attr.startsWith("t-att")) {
5075
5098
  throw new OwlError(`Unknown QWeb directive: '${attr}'`);
@@ -5091,6 +5114,7 @@ function parseDOMNode(node, ctx) {
5091
5114
  tag: tagName,
5092
5115
  dynamicTag,
5093
5116
  attrs,
5117
+ attrsTranslationCtx,
5094
5118
  on,
5095
5119
  ref,
5096
5120
  content: children,
@@ -5231,7 +5255,15 @@ function parseTCall(node, ctx) {
5231
5255
  if (ast && ast.type === 11 /* TComponent */) {
5232
5256
  return {
5233
5257
  ...ast,
5234
- slots: { default: { content: tcall, scope: null, on: null, attrs: null } },
5258
+ slots: {
5259
+ default: {
5260
+ content: tcall,
5261
+ scope: null,
5262
+ on: null,
5263
+ attrs: null,
5264
+ attrsTranslationCtx: null,
5265
+ },
5266
+ },
5235
5267
  };
5236
5268
  }
5237
5269
  }
@@ -5346,9 +5378,15 @@ function parseComponent(node, ctx) {
5346
5378
  node.removeAttribute("t-slot-scope");
5347
5379
  let on = null;
5348
5380
  let props = null;
5381
+ let propsTranslationCtx = null;
5349
5382
  for (let name of node.getAttributeNames()) {
5350
5383
  const value = node.getAttribute(name);
5351
- if (name.startsWith("t-")) {
5384
+ if (name.startsWith("t-translation-context-")) {
5385
+ const attrName = name.slice(22);
5386
+ propsTranslationCtx = propsTranslationCtx || {};
5387
+ propsTranslationCtx[attrName] = value;
5388
+ }
5389
+ else if (name.startsWith("t-")) {
5352
5390
  if (name.startsWith("t-on-")) {
5353
5391
  on = on || {};
5354
5392
  on[name.slice(5)] = value;
@@ -5392,6 +5430,7 @@ function parseComponent(node, ctx) {
5392
5430
  const slotAst = parseNode(slotNode, ctx);
5393
5431
  let on = null;
5394
5432
  let attrs = null;
5433
+ let attrsTranslationCtx = null;
5395
5434
  let scope = null;
5396
5435
  for (let attributeName of slotNode.getAttributeNames()) {
5397
5436
  const value = slotNode.getAttribute(attributeName);
@@ -5399,6 +5438,11 @@ function parseComponent(node, ctx) {
5399
5438
  scope = value;
5400
5439
  continue;
5401
5440
  }
5441
+ else if (attributeName.startsWith("t-translation-context-")) {
5442
+ const attrName = attributeName.slice(22);
5443
+ attrsTranslationCtx = attrsTranslationCtx || {};
5444
+ attrsTranslationCtx[attrName] = value;
5445
+ }
5402
5446
  else if (attributeName.startsWith("t-on-")) {
5403
5447
  on = on || {};
5404
5448
  on[attributeName.slice(5)] = value;
@@ -5409,17 +5453,32 @@ function parseComponent(node, ctx) {
5409
5453
  }
5410
5454
  }
5411
5455
  slots = slots || {};
5412
- slots[name] = { content: slotAst, on, attrs, scope };
5456
+ slots[name] = { content: slotAst, on, attrs, attrsTranslationCtx, scope };
5413
5457
  }
5414
5458
  // default slot
5415
5459
  const defaultContent = parseChildNodes(clone, ctx);
5416
5460
  slots = slots || {};
5417
5461
  // t-set-slot="default" has priority over content
5418
5462
  if (defaultContent && !slots.default) {
5419
- slots.default = { content: defaultContent, on, attrs: null, scope: defaultSlotScope };
5463
+ slots.default = {
5464
+ content: defaultContent,
5465
+ on,
5466
+ attrs: null,
5467
+ attrsTranslationCtx: null,
5468
+ scope: defaultSlotScope,
5469
+ };
5420
5470
  }
5421
5471
  }
5422
- return { type: 11 /* TComponent */, name, isDynamic, dynamicProps, props, slots, on };
5472
+ return {
5473
+ type: 11 /* TComponent */,
5474
+ name,
5475
+ isDynamic,
5476
+ dynamicProps,
5477
+ props,
5478
+ propsTranslationCtx,
5479
+ slots,
5480
+ on,
5481
+ };
5423
5482
  }
5424
5483
  // -----------------------------------------------------------------------------
5425
5484
  // Slots
@@ -5431,6 +5490,7 @@ function parseTSlot(node, ctx) {
5431
5490
  const name = node.getAttribute("t-slot");
5432
5491
  node.removeAttribute("t-slot");
5433
5492
  let attrs = null;
5493
+ let attrsTranslationCtx = null;
5434
5494
  let on = null;
5435
5495
  for (let attributeName of node.getAttributeNames()) {
5436
5496
  const value = node.getAttribute(attributeName);
@@ -5438,6 +5498,11 @@ function parseTSlot(node, ctx) {
5438
5498
  on = on || {};
5439
5499
  on[attributeName.slice(5)] = value;
5440
5500
  }
5501
+ else if (attributeName.startsWith("t-translation-context-")) {
5502
+ const attrName = attributeName.slice(22);
5503
+ attrsTranslationCtx = attrsTranslationCtx || {};
5504
+ attrsTranslationCtx[attrName] = value;
5505
+ }
5441
5506
  else {
5442
5507
  attrs = attrs || {};
5443
5508
  attrs[attributeName] = value;
@@ -5447,10 +5512,14 @@ function parseTSlot(node, ctx) {
5447
5512
  type: 14 /* TSlot */,
5448
5513
  name,
5449
5514
  attrs,
5515
+ attrsTranslationCtx,
5450
5516
  on,
5451
5517
  defaultContent: parseChildNodes(node, ctx),
5452
5518
  };
5453
5519
  }
5520
+ // -----------------------------------------------------------------------------
5521
+ // Translation
5522
+ // -----------------------------------------------------------------------------
5454
5523
  function parseTTranslation(node, ctx) {
5455
5524
  if (node.getAttribute("t-translation") !== "off") {
5456
5525
  return null;
@@ -5462,6 +5531,21 @@ function parseTTranslation(node, ctx) {
5462
5531
  };
5463
5532
  }
5464
5533
  // -----------------------------------------------------------------------------
5534
+ // Translation Context
5535
+ // -----------------------------------------------------------------------------
5536
+ function parseTTranslationContext(node, ctx) {
5537
+ const translationCtx = node.getAttribute("t-translation-context");
5538
+ if (!translationCtx) {
5539
+ return null;
5540
+ }
5541
+ node.removeAttribute("t-translation-context");
5542
+ return {
5543
+ type: 17 /* TTranslationContext */,
5544
+ content: parseNode(node, ctx),
5545
+ translationCtx,
5546
+ };
5547
+ }
5548
+ // -----------------------------------------------------------------------------
5465
5549
  // Portal
5466
5550
  // -----------------------------------------------------------------------------
5467
5551
  function parseTPortal(node, ctx) {
@@ -5478,7 +5562,7 @@ function parseTPortal(node, ctx) {
5478
5562
  };
5479
5563
  }
5480
5564
  return {
5481
- type: 17 /* TPortal */,
5565
+ type: 18 /* TPortal */,
5482
5566
  target,
5483
5567
  content,
5484
5568
  };
@@ -5620,7 +5704,7 @@ function compile(template, options = {
5620
5704
  }
5621
5705
 
5622
5706
  // do not modify manually. This file is generated by the release script.
5623
- const version = "2.5.3";
5707
+ const version = "2.6.1";
5624
5708
 
5625
5709
  // -----------------------------------------------------------------------------
5626
5710
  // Scheduler
@@ -5715,13 +5799,6 @@ class Scheduler {
5715
5799
  Scheduler.requestAnimationFrame = window.requestAnimationFrame.bind(window);
5716
5800
 
5717
5801
  let hasBeenLogged = false;
5718
- const DEV_MSG = () => {
5719
- const hash = window.owl ? window.owl.__info__.hash : "master";
5720
- return `Owl is running in 'dev' mode.
5721
-
5722
- This is not suitable for production use.
5723
- See https://github.com/odoo/owl/blob/${hash}/doc/reference/app.md#configuration for more information.`;
5724
- };
5725
5802
  const apps = new Set();
5726
5803
  window.__OWL_DEVTOOLS__ || (window.__OWL_DEVTOOLS__ = { apps, Fiber, RootFiber, toRaw, reactive });
5727
5804
  class App extends TemplateSet {
@@ -5738,7 +5815,7 @@ class App extends TemplateSet {
5738
5815
  }
5739
5816
  this.warnIfNoStaticProps = config.warnIfNoStaticProps || false;
5740
5817
  if (this.dev && !config.test && !hasBeenLogged) {
5741
- console.info(DEV_MSG());
5818
+ console.info(`Owl is running in 'dev' mode.`);
5742
5819
  hasBeenLogged = true;
5743
5820
  }
5744
5821
  const env = config.env || {};
@@ -6098,6 +6175,6 @@ TemplateSet.prototype._compileTemplate = function _compileTemplate(name, templat
6098
6175
  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 };
6099
6176
 
6100
6177
 
6101
- __info__.date = '2025-01-10T10:10:53.709Z';
6102
- __info__.hash = 'b31fa81';
6178
+ __info__.date = '2025-03-05T08:37:58.580Z';
6179
+ __info__.hash = '2b5cea9';
6103
6180
  __info__.url = 'https://github.com/odoo/owl';