@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.
@@ -428,6 +428,7 @@ function createContext(parentCtx, params) {
428
428
  index: 0,
429
429
  forceNewBlock: true,
430
430
  translate: parentCtx.translate,
431
+ translationCtx: parentCtx.translationCtx,
431
432
  tKeyExpr: null,
432
433
  nameSpace: parentCtx.nameSpace,
433
434
  tModelSelectedExpr: parentCtx.tModelSelectedExpr,
@@ -530,6 +531,7 @@ class CodeGenerator {
530
531
  forceNewBlock: false,
531
532
  isLast: true,
532
533
  translate: true,
534
+ translationCtx: "",
533
535
  tKeyExpr: null,
534
536
  });
535
537
  // define blocks and utility functions
@@ -667,9 +669,9 @@ class CodeGenerator {
667
669
  })
668
670
  .join("");
669
671
  }
670
- translate(str) {
672
+ translate(str, translationCtx) {
671
673
  const match = translationRE.exec(str);
672
- return match[1] + this.translateFn(match[2]) + match[3];
674
+ return match[1] + this.translateFn(match[2], translationCtx) + match[3];
673
675
  }
674
676
  /**
675
677
  * @returns the newly created block name, if any
@@ -710,7 +712,9 @@ class CodeGenerator {
710
712
  return this.compileTSlot(ast, ctx);
711
713
  case 16 /* TTranslation */:
712
714
  return this.compileTTranslation(ast, ctx);
713
- case 17 /* TPortal */:
715
+ case 17 /* TTranslationContext */:
716
+ return this.compileTTranslationContext(ast, ctx);
717
+ case 18 /* TPortal */:
714
718
  return this.compileTPortal(ast, ctx);
715
719
  }
716
720
  }
@@ -748,7 +752,7 @@ class CodeGenerator {
748
752
  let { block, forceNewBlock } = ctx;
749
753
  let value = ast.value;
750
754
  if (value && ctx.translate !== false) {
751
- value = this.translate(value);
755
+ value = this.translate(value, ctx.translationCtx);
752
756
  }
753
757
  if (!ctx.inPreTag) {
754
758
  value = value.replace(whitespaceRE, " ");
@@ -783,6 +787,7 @@ class CodeGenerator {
783
787
  return `[${modifiersCode}${this.captureExpression(handler)}, ctx]`;
784
788
  }
785
789
  compileTDomNode(ast, ctx) {
790
+ var _a;
786
791
  let { block, forceNewBlock } = ctx;
787
792
  const isNewBlock = !block || forceNewBlock || ast.dynamicTag !== null || ast.ns;
788
793
  let codeIdx = this.target.code.length;
@@ -838,7 +843,8 @@ class CodeGenerator {
838
843
  }
839
844
  }
840
845
  else if (this.translatableAttributes.includes(key)) {
841
- attrs[key] = this.translateFn(ast.attrs[key]);
846
+ const attrTranslationCtx = ((_a = ast.attrsTranslationCtx) === null || _a === void 0 ? void 0 : _a[key]) || ctx.translationCtx;
847
+ attrs[key] = this.translateFn(ast.attrs[key], attrTranslationCtx);
842
848
  }
843
849
  else {
844
850
  expr = `"${ast.attrs[key]}"`;
@@ -1282,7 +1288,7 @@ class CodeGenerator {
1282
1288
  else {
1283
1289
  let value;
1284
1290
  if (ast.defaultValue) {
1285
- const defaultValue = toStringExpression(ctx.translate ? this.translate(ast.defaultValue) : ast.defaultValue);
1291
+ const defaultValue = toStringExpression(ctx.translate ? this.translate(ast.defaultValue, ctx.translationCtx) : ast.defaultValue);
1286
1292
  if (ast.value) {
1287
1293
  value = `withDefault(${expr}, ${defaultValue})`;
1288
1294
  }
@@ -1316,9 +1322,10 @@ class CodeGenerator {
1316
1322
  * "some-prop" "state" "'some-prop': ctx['state']"
1317
1323
  * "onClick.bind" "onClick" "onClick: bind(ctx, ctx['onClick'])"
1318
1324
  */
1319
- formatProp(name, value) {
1325
+ formatProp(name, value, attrsTranslationCtx, translationCtx) {
1320
1326
  if (name.endsWith(".translate")) {
1321
- value = toStringExpression(this.translateFn(value));
1327
+ const attrTranslationCtx = (attrsTranslationCtx === null || attrsTranslationCtx === void 0 ? void 0 : attrsTranslationCtx[name]) || translationCtx;
1328
+ value = toStringExpression(this.translateFn(value, attrTranslationCtx));
1322
1329
  }
1323
1330
  else {
1324
1331
  value = this.captureExpression(value);
@@ -1340,8 +1347,8 @@ class CodeGenerator {
1340
1347
  name = /^[a-z_]+$/i.test(name) ? name : `'${name}'`;
1341
1348
  return `${name}: ${value || undefined}`;
1342
1349
  }
1343
- formatPropObject(obj) {
1344
- return Object.entries(obj).map(([k, v]) => this.formatProp(k, v));
1350
+ formatPropObject(obj, attrsTranslationCtx, translationCtx) {
1351
+ return Object.entries(obj).map(([k, v]) => this.formatProp(k, v, attrsTranslationCtx, translationCtx));
1345
1352
  }
1346
1353
  getPropString(props, dynProps) {
1347
1354
  let propString = `{${props.join(",")}}`;
@@ -1354,7 +1361,9 @@ class CodeGenerator {
1354
1361
  let { block } = ctx;
1355
1362
  // props
1356
1363
  const hasSlotsProp = "slots" in (ast.props || {});
1357
- const props = ast.props ? this.formatPropObject(ast.props) : [];
1364
+ const props = ast.props
1365
+ ? this.formatPropObject(ast.props, ast.propsTranslationCtx, ctx.translationCtx)
1366
+ : [];
1358
1367
  // slots
1359
1368
  let slotDef = "";
1360
1369
  if (ast.slots) {
@@ -1377,7 +1386,7 @@ class CodeGenerator {
1377
1386
  params.push(`__scope: "${scope}"`);
1378
1387
  }
1379
1388
  if (ast.slots[slotName].attrs) {
1380
- params.push(...this.formatPropObject(ast.slots[slotName].attrs));
1389
+ params.push(...this.formatPropObject(ast.slots[slotName].attrs, ast.slots[slotName].attrsTranslationCtx, ctx.translationCtx));
1381
1390
  }
1382
1391
  const slotInfo = `{${params.join(", ")}}`;
1383
1392
  slotStr.push(`'${slotName}': ${slotInfo}`);
@@ -1482,15 +1491,16 @@ class CodeGenerator {
1482
1491
  isMultiple = isMultiple || this.slotNames.has(ast.name);
1483
1492
  this.slotNames.add(ast.name);
1484
1493
  }
1485
- const dynProps = ast.attrs ? ast.attrs["t-props"] : null;
1486
- if (ast.attrs) {
1487
- delete ast.attrs["t-props"];
1488
- }
1494
+ const attrs = { ...ast.attrs };
1495
+ const dynProps = attrs["t-props"];
1496
+ delete attrs["t-props"];
1489
1497
  let key = this.target.loopLevel ? `key${this.target.loopLevel}` : "key";
1490
1498
  if (isMultiple) {
1491
1499
  key = this.generateComponentKey(key);
1492
1500
  }
1493
- const props = ast.attrs ? this.formatPropObject(ast.attrs) : [];
1501
+ const props = ast.attrs
1502
+ ? this.formatPropObject(attrs, ast.attrsTranslationCtx, ctx.translationCtx)
1503
+ : [];
1494
1504
  const scope = this.getPropString(props, dynProps);
1495
1505
  if (ast.defaultContent) {
1496
1506
  const name = this.compileInNewTarget("defaultContent", ast.defaultContent, ctx);
@@ -1523,6 +1533,12 @@ class CodeGenerator {
1523
1533
  }
1524
1534
  return null;
1525
1535
  }
1536
+ compileTTranslationContext(ast, ctx) {
1537
+ if (ast.content) {
1538
+ return this.compileAST(ast.content, Object.assign({}, ctx, { translationCtx: ast.translationCtx }));
1539
+ }
1540
+ return null;
1541
+ }
1526
1542
  compileTPortal(ast, ctx) {
1527
1543
  if (!this.staticDefs.find((d) => d.id === "Portal")) {
1528
1544
  this.staticDefs.push({ id: "Portal", expr: `app.Portal` });
@@ -1628,6 +1644,7 @@ function parseNode(node, ctx) {
1628
1644
  parseTOutNode(node, ctx) ||
1629
1645
  parseTKey(node, ctx) ||
1630
1646
  parseTTranslation(node, ctx) ||
1647
+ parseTTranslationContext(node, ctx) ||
1631
1648
  parseTSlot(node, ctx) ||
1632
1649
  parseComponent(node, ctx) ||
1633
1650
  parseDOMNode(node, ctx) ||
@@ -1736,6 +1753,7 @@ function parseDOMNode(node, ctx) {
1736
1753
  node.removeAttribute("t-ref");
1737
1754
  const nodeAttrsNames = node.getAttributeNames();
1738
1755
  let attrs = null;
1756
+ let attrsTranslationCtx = null;
1739
1757
  let on = null;
1740
1758
  let model = null;
1741
1759
  for (let attr of nodeAttrsNames) {
@@ -1796,6 +1814,11 @@ function parseDOMNode(node, ctx) {
1796
1814
  else if (attr === "xmlns") {
1797
1815
  ns = value;
1798
1816
  }
1817
+ else if (attr.startsWith("t-translation-context-")) {
1818
+ const attrName = attr.slice(22);
1819
+ attrsTranslationCtx = attrsTranslationCtx || {};
1820
+ attrsTranslationCtx[attrName] = value;
1821
+ }
1799
1822
  else if (attr !== "t-name") {
1800
1823
  if (attr.startsWith("t-") && !attr.startsWith("t-att")) {
1801
1824
  throw new OwlError(`Unknown QWeb directive: '${attr}'`);
@@ -1817,6 +1840,7 @@ function parseDOMNode(node, ctx) {
1817
1840
  tag: tagName,
1818
1841
  dynamicTag,
1819
1842
  attrs,
1843
+ attrsTranslationCtx,
1820
1844
  on,
1821
1845
  ref,
1822
1846
  content: children,
@@ -1957,7 +1981,15 @@ function parseTCall(node, ctx) {
1957
1981
  if (ast && ast.type === 11 /* TComponent */) {
1958
1982
  return {
1959
1983
  ...ast,
1960
- slots: { default: { content: tcall, scope: null, on: null, attrs: null } },
1984
+ slots: {
1985
+ default: {
1986
+ content: tcall,
1987
+ scope: null,
1988
+ on: null,
1989
+ attrs: null,
1990
+ attrsTranslationCtx: null,
1991
+ },
1992
+ },
1961
1993
  };
1962
1994
  }
1963
1995
  }
@@ -2072,9 +2104,15 @@ function parseComponent(node, ctx) {
2072
2104
  node.removeAttribute("t-slot-scope");
2073
2105
  let on = null;
2074
2106
  let props = null;
2107
+ let propsTranslationCtx = null;
2075
2108
  for (let name of node.getAttributeNames()) {
2076
2109
  const value = node.getAttribute(name);
2077
- if (name.startsWith("t-")) {
2110
+ if (name.startsWith("t-translation-context-")) {
2111
+ const attrName = name.slice(22);
2112
+ propsTranslationCtx = propsTranslationCtx || {};
2113
+ propsTranslationCtx[attrName] = value;
2114
+ }
2115
+ else if (name.startsWith("t-")) {
2078
2116
  if (name.startsWith("t-on-")) {
2079
2117
  on = on || {};
2080
2118
  on[name.slice(5)] = value;
@@ -2118,6 +2156,7 @@ function parseComponent(node, ctx) {
2118
2156
  const slotAst = parseNode(slotNode, ctx);
2119
2157
  let on = null;
2120
2158
  let attrs = null;
2159
+ let attrsTranslationCtx = null;
2121
2160
  let scope = null;
2122
2161
  for (let attributeName of slotNode.getAttributeNames()) {
2123
2162
  const value = slotNode.getAttribute(attributeName);
@@ -2125,6 +2164,11 @@ function parseComponent(node, ctx) {
2125
2164
  scope = value;
2126
2165
  continue;
2127
2166
  }
2167
+ else if (attributeName.startsWith("t-translation-context-")) {
2168
+ const attrName = attributeName.slice(22);
2169
+ attrsTranslationCtx = attrsTranslationCtx || {};
2170
+ attrsTranslationCtx[attrName] = value;
2171
+ }
2128
2172
  else if (attributeName.startsWith("t-on-")) {
2129
2173
  on = on || {};
2130
2174
  on[attributeName.slice(5)] = value;
@@ -2135,17 +2179,32 @@ function parseComponent(node, ctx) {
2135
2179
  }
2136
2180
  }
2137
2181
  slots = slots || {};
2138
- slots[name] = { content: slotAst, on, attrs, scope };
2182
+ slots[name] = { content: slotAst, on, attrs, attrsTranslationCtx, scope };
2139
2183
  }
2140
2184
  // default slot
2141
2185
  const defaultContent = parseChildNodes(clone, ctx);
2142
2186
  slots = slots || {};
2143
2187
  // t-set-slot="default" has priority over content
2144
2188
  if (defaultContent && !slots.default) {
2145
- slots.default = { content: defaultContent, on, attrs: null, scope: defaultSlotScope };
2189
+ slots.default = {
2190
+ content: defaultContent,
2191
+ on,
2192
+ attrs: null,
2193
+ attrsTranslationCtx: null,
2194
+ scope: defaultSlotScope,
2195
+ };
2146
2196
  }
2147
2197
  }
2148
- return { type: 11 /* TComponent */, name, isDynamic, dynamicProps, props, slots, on };
2198
+ return {
2199
+ type: 11 /* TComponent */,
2200
+ name,
2201
+ isDynamic,
2202
+ dynamicProps,
2203
+ props,
2204
+ propsTranslationCtx,
2205
+ slots,
2206
+ on,
2207
+ };
2149
2208
  }
2150
2209
  // -----------------------------------------------------------------------------
2151
2210
  // Slots
@@ -2157,6 +2216,7 @@ function parseTSlot(node, ctx) {
2157
2216
  const name = node.getAttribute("t-slot");
2158
2217
  node.removeAttribute("t-slot");
2159
2218
  let attrs = null;
2219
+ let attrsTranslationCtx = null;
2160
2220
  let on = null;
2161
2221
  for (let attributeName of node.getAttributeNames()) {
2162
2222
  const value = node.getAttribute(attributeName);
@@ -2164,6 +2224,11 @@ function parseTSlot(node, ctx) {
2164
2224
  on = on || {};
2165
2225
  on[attributeName.slice(5)] = value;
2166
2226
  }
2227
+ else if (attributeName.startsWith("t-translation-context-")) {
2228
+ const attrName = attributeName.slice(22);
2229
+ attrsTranslationCtx = attrsTranslationCtx || {};
2230
+ attrsTranslationCtx[attrName] = value;
2231
+ }
2167
2232
  else {
2168
2233
  attrs = attrs || {};
2169
2234
  attrs[attributeName] = value;
@@ -2173,10 +2238,14 @@ function parseTSlot(node, ctx) {
2173
2238
  type: 14 /* TSlot */,
2174
2239
  name,
2175
2240
  attrs,
2241
+ attrsTranslationCtx,
2176
2242
  on,
2177
2243
  defaultContent: parseChildNodes(node, ctx),
2178
2244
  };
2179
2245
  }
2246
+ // -----------------------------------------------------------------------------
2247
+ // Translation
2248
+ // -----------------------------------------------------------------------------
2180
2249
  function parseTTranslation(node, ctx) {
2181
2250
  if (node.getAttribute("t-translation") !== "off") {
2182
2251
  return null;
@@ -2188,6 +2257,21 @@ function parseTTranslation(node, ctx) {
2188
2257
  };
2189
2258
  }
2190
2259
  // -----------------------------------------------------------------------------
2260
+ // Translation Context
2261
+ // -----------------------------------------------------------------------------
2262
+ function parseTTranslationContext(node, ctx) {
2263
+ const translationCtx = node.getAttribute("t-translation-context");
2264
+ if (!translationCtx) {
2265
+ return null;
2266
+ }
2267
+ node.removeAttribute("t-translation-context");
2268
+ return {
2269
+ type: 17 /* TTranslationContext */,
2270
+ content: parseNode(node, ctx),
2271
+ translationCtx,
2272
+ };
2273
+ }
2274
+ // -----------------------------------------------------------------------------
2191
2275
  // Portal
2192
2276
  // -----------------------------------------------------------------------------
2193
2277
  function parseTPortal(node, ctx) {
@@ -2204,7 +2288,7 @@ function parseTPortal(node, ctx) {
2204
2288
  };
2205
2289
  }
2206
2290
  return {
2207
- type: 17 /* TPortal */,
2291
+ type: 18 /* TPortal */,
2208
2292
  target,
2209
2293
  content,
2210
2294
  };
Binary file