Skip to content

Commit 66a8013

Browse files
committed
[REL] v2.2.11
# v2.2.11 - [FIX] compiler: better support for arrow function and function call - [IMP] owl-vision: Autocomplete and added missing owl directives - [IMP] index: export batched utility function - [FIX] playground: correctly escape backslashes and interpolation sigils - [FIX] compiler: correctly escape special characters in template literals - [FIX] Typo docs - [FIX] runtime: don't emit async hook warnings when cancelled/destroyed
1 parent e7f405c commit 66a8013

File tree

4 files changed

+37
-29
lines changed

4 files changed

+37
-29
lines changed

docs/owl.js

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2622,7 +2622,7 @@ function wrapError(fn, hookName) {
26222622
result.catch(() => { }),
26232623
new Promise((resolve) => setTimeout(() => resolve(TIMEOUT), 3000)),
26242624
]).then((res) => {
2625-
if (res === TIMEOUT && node.fiber === fiber) {
2625+
if (res === TIMEOUT && node.fiber === fiber && node.status <= 2) {
26262626
console.warn(timeoutError);
26272627
}
26282628
});
@@ -3512,7 +3512,7 @@ function compileExprToArray(expr) {
35123512
const localVars = new Set();
35133513
const tokens = tokenize(expr);
35143514
let i = 0;
3515-
let stack = []; // to track last opening [ or {
3515+
let stack = []; // to track last opening (, [ or {
35163516
while (i < tokens.length) {
35173517
let token = tokens[i];
35183518
let prevToken = tokens[i - 1];
@@ -3521,10 +3521,12 @@ function compileExprToArray(expr) {
35213521
switch (token.type) {
35223522
case "LEFT_BRACE":
35233523
case "LEFT_BRACKET":
3524+
case "LEFT_PAREN":
35243525
stack.push(token.type);
35253526
break;
35263527
case "RIGHT_BRACE":
35273528
case "RIGHT_BRACKET":
3529+
case "RIGHT_PAREN":
35283530
stack.pop();
35293531
}
35303532
let isVar = token.type === "SYMBOL" && !RESERVED_WORDS.includes(token.value);
@@ -3636,6 +3638,13 @@ function isProp(tag, key) {
36363638
}
36373639
return false;
36383640
}
3641+
/**
3642+
* Returns a template literal that evaluates to str. You can add interpolation
3643+
* sigils into the string if required
3644+
*/
3645+
function toStringExpression(str) {
3646+
return `\`${str.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/, "\\${")}\``;
3647+
}
36393648
// -----------------------------------------------------------------------------
36403649
// BlockDescription
36413650
// -----------------------------------------------------------------------------
@@ -3816,15 +3825,14 @@ class CodeGenerator {
38163825
mainCode.push(``);
38173826
for (let block of this.blocks) {
38183827
if (block.dom) {
3819-
let xmlString = block.asXmlString();
3820-
xmlString = xmlString.replace(/\\/g, "\\\\").replace(/`/g, "\\`");
3828+
let xmlString = toStringExpression(block.asXmlString());
38213829
if (block.dynamicTagName) {
3822-
xmlString = xmlString.replace(/^<\w+/, `<\${tag || '${block.dom.nodeName}'}`);
3823-
xmlString = xmlString.replace(/\w+>$/, `\${tag || '${block.dom.nodeName}'}>`);
3824-
mainCode.push(`let ${block.blockName} = tag => createBlock(\`${xmlString}\`);`);
3830+
xmlString = xmlString.replace(/^`<\w+/, `\`<\${tag || '${block.dom.nodeName}'}`);
3831+
xmlString = xmlString.replace(/\w+>`$/, `\${tag || '${block.dom.nodeName}'}>\``);
3832+
mainCode.push(`let ${block.blockName} = tag => createBlock(${xmlString});`);
38253833
}
38263834
else {
3827-
mainCode.push(`let ${block.blockName} = createBlock(\`${xmlString}\`);`);
3835+
mainCode.push(`let ${block.blockName} = createBlock(${xmlString});`);
38283836
}
38293837
}
38303838
}
@@ -4002,7 +4010,7 @@ class CodeGenerator {
40024010
const isNewBlock = !block || forceNewBlock;
40034011
if (isNewBlock) {
40044012
block = this.createBlock(block, "comment", ctx);
4005-
this.insertBlock(`comment(\`${ast.value}\`)`, block, {
4013+
this.insertBlock(`comment(${toStringExpression(ast.value)})`, block, {
40064014
...ctx,
40074015
forceNewBlock: forceNewBlock && !block,
40084016
});
@@ -4024,7 +4032,7 @@ class CodeGenerator {
40244032
}
40254033
if (!block || forceNewBlock) {
40264034
block = this.createBlock(block, "text", ctx);
4027-
this.insertBlock(`text(\`${value}\`)`, block, {
4035+
this.insertBlock(`text(${toStringExpression(value)})`, block, {
40284036
...ctx,
40294037
forceNewBlock: forceNewBlock && !block,
40304038
});
@@ -4245,7 +4253,8 @@ class CodeGenerator {
42454253
expr = compileExpr(ast.expr);
42464254
if (ast.defaultValue) {
42474255
this.helpers.add("withDefault");
4248-
expr = `withDefault(${expr}, \`${ast.defaultValue}\`)`;
4256+
// FIXME: defaultValue is not translated
4257+
expr = `withDefault(${expr}, ${toStringExpression(ast.defaultValue)})`;
42494258
}
42504259
}
42514260
if (!block || forceNewBlock) {
@@ -4498,7 +4507,7 @@ class CodeGenerator {
44984507
this.addLine(`${ctxVar}[zero] = ${bl};`);
44994508
}
45004509
}
4501-
const key = `key + \`${this.generateComponentKey()}\``;
4510+
const key = this.generateComponentKey();
45024511
if (isDynamic) {
45034512
const templateVar = generateId("template");
45044513
if (!this.staticDefs.find((d) => d.id === "call")) {
@@ -4550,12 +4559,12 @@ class CodeGenerator {
45504559
else {
45514560
let value;
45524561
if (ast.defaultValue) {
4553-
const defaultValue = ctx.translate ? this.translate(ast.defaultValue) : ast.defaultValue;
4562+
const defaultValue = toStringExpression(ctx.translate ? this.translate(ast.defaultValue) : ast.defaultValue);
45544563
if (ast.value) {
4555-
value = `withDefault(${expr}, \`${defaultValue}\`)`;
4564+
value = `withDefault(${expr}, ${defaultValue})`;
45564565
}
45574566
else {
4558-
value = `\`${defaultValue}\``;
4567+
value = defaultValue;
45594568
}
45604569
}
45614570
else {
@@ -4566,12 +4575,12 @@ class CodeGenerator {
45664575
}
45674576
return null;
45684577
}
4569-
generateComponentKey() {
4578+
generateComponentKey(currentKey = "key") {
45704579
const parts = [generateId("__")];
45714580
for (let i = 0; i < this.target.loopLevel; i++) {
45724581
parts.push(`\${key${i + 1}}`);
45734582
}
4574-
return parts.join("__");
4583+
return `${currentKey} + \`${parts.join("__")}\``;
45754584
}
45764585
/**
45774586
* Formats a prop name and value into a string suitable to be inserted in the
@@ -4662,7 +4671,6 @@ class CodeGenerator {
46624671
this.addLine(`${propVar}.slots = markRaw(Object.assign(${slotDef}, ${propVar}.slots))`);
46634672
}
46644673
// cmap key
4665-
const key = this.generateComponentKey();
46664674
let expr;
46674675
if (ast.isDynamic) {
46684676
expr = generateId("Comp");
@@ -4678,7 +4686,7 @@ class CodeGenerator {
46784686
// todo: check the forcenewblock condition
46794687
this.insertAnchor(block);
46804688
}
4681-
let keyArg = `key + \`${key}\``;
4689+
let keyArg = this.generateComponentKey();
46824690
if (ctx.tKeyExpr) {
46834691
keyArg = `${ctx.tKeyExpr} + ${keyArg}`;
46844692
}
@@ -4751,7 +4759,7 @@ class CodeGenerator {
47514759
}
47524760
let key = this.target.loopLevel ? `key${this.target.loopLevel}` : "key";
47534761
if (isMultiple) {
4754-
key = `${key} + \`${this.generateComponentKey()}\``;
4762+
key = this.generateComponentKey(key);
47554763
}
47564764
const props = ast.attrs ? this.formatPropObject(ast.attrs) : [];
47574765
const scope = this.getPropString(props, dynProps);
@@ -4792,7 +4800,6 @@ class CodeGenerator {
47924800
}
47934801
let { block } = ctx;
47944802
const name = this.compileInNewTarget("slot", ast.content, ctx);
4795-
const key = this.generateComponentKey();
47964803
let ctxStr = "ctx";
47974804
if (this.target.loopLevel || !this.hasSafeContext) {
47984805
ctxStr = generateId("ctx");
@@ -4805,7 +4812,8 @@ class CodeGenerator {
48054812
expr: `app.createComponent(null, false, true, false, false)`,
48064813
});
48074814
const target = compileExpr(ast.target);
4808-
const blockString = `${id}({target: ${target},slots: {'default': {__render: ${name}.bind(this), __ctx: ${ctxStr}}}}, key + \`${key}\`, node, ctx, Portal)`;
4815+
const key = this.generateComponentKey();
4816+
const blockString = `${id}({target: ${target},slots: {'default': {__render: ${name}.bind(this), __ctx: ${ctxStr}}}}, ${key}, node, ctx, Portal)`;
48094817
if (block) {
48104818
this.insertAnchor(block);
48114819
}
@@ -5538,7 +5546,7 @@ function compile(template, options = {}) {
55385546
}
55395547

55405548
// do not modify manually. This file is generated by the release script.
5541-
const version = "2.2.10";
5549+
const version = "2.2.11";
55425550

55435551
// -----------------------------------------------------------------------------
55445552
// Scheduler
@@ -5964,9 +5972,9 @@ TemplateSet.prototype._compileTemplate = function _compileTemplate(name, templat
59645972
});
59655973
};
59665974

5967-
export { App, Component, EventBus, OwlError, __info__, 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 };
5975+
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 };
59685976

59695977

5970-
__info__.date = '2024-04-02T10:25:32.577Z';
5971-
__info__.hash = '97b69f1';
5978+
__info__.date = '2024-06-17T13:31:12.099Z';
5979+
__info__.hash = 'e7f405c';
59725980
__info__.url = 'https://github.com/odoo/owl';

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@odoo/owl",
3-
"version": "2.2.10",
3+
"version": "2.2.11",
44
"description": "Odoo Web Library (OWL)",
55
"main": "dist/owl.cjs.js",
66
"module": "dist/owl.es.js",

src/version.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
// do not modify manually. This file is generated by the release script.
2-
export const version = "2.2.10";
2+
export const version = "2.2.11";

0 commit comments

Comments
 (0)