@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/compile_templates.mjs +107 -23
- package/dist/owl-devtools.zip +0 -0
- package/dist/owl.cjs.js +111 -34
- package/dist/owl.es.js +111 -34
- package/dist/owl.iife.js +111 -34
- package/dist/owl.iife.min.js +1 -1
- package/dist/types/compiler/code_generator.d.ts +12 -6
- package/dist/types/compiler/parser.d.ts +14 -2
- package/dist/types/owl.d.ts +3 -3
- package/dist/types/runtime/app.d.ts +0 -1
- package/dist/types/runtime/template_set.d.ts +2 -2
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
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 /*
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
4800
|
-
|
|
4801
|
-
|
|
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
|
|
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: {
|
|
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 = {
|
|
5467
|
+
slots.default = {
|
|
5468
|
+
content: defaultContent,
|
|
5469
|
+
on,
|
|
5470
|
+
attrs: null,
|
|
5471
|
+
attrsTranslationCtx: null,
|
|
5472
|
+
scope: defaultSlotScope,
|
|
5473
|
+
};
|
|
5424
5474
|
}
|
|
5425
5475
|
}
|
|
5426
|
-
return {
|
|
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:
|
|
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.
|
|
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(
|
|
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-
|
|
6141
|
-
__info__.hash = '
|
|
6217
|
+
__info__.date = '2025-03-05T08:37:58.580Z';
|
|
6218
|
+
__info__.hash = '2b5cea9';
|
|
6142
6219
|
__info__.url = 'https://github.com/odoo/owl';
|