@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
|
@@ -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 /*
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
1486
|
-
|
|
1487
|
-
|
|
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
|
|
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: {
|
|
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 = {
|
|
2189
|
+
slots.default = {
|
|
2190
|
+
content: defaultContent,
|
|
2191
|
+
on,
|
|
2192
|
+
attrs: null,
|
|
2193
|
+
attrsTranslationCtx: null,
|
|
2194
|
+
scope: defaultSlotScope,
|
|
2195
|
+
};
|
|
2146
2196
|
}
|
|
2147
2197
|
}
|
|
2148
|
-
return {
|
|
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:
|
|
2291
|
+
type: 18 /* TPortal */,
|
|
2208
2292
|
target,
|
|
2209
2293
|
content,
|
|
2210
2294
|
};
|
package/dist/owl-devtools.zip
CHANGED
|
Binary file
|