Skip to content

Commit

Permalink
[REL] v2.2.11
Browse files Browse the repository at this point in the history
# 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
  • Loading branch information
rfr-odoo committed Jun 17, 2024
1 parent e7f405c commit 66a8013
Showing 4 changed files with 37 additions and 29 deletions.
60 changes: 34 additions & 26 deletions docs/owl.js
Original file line number Diff line number Diff line change
@@ -2622,7 +2622,7 @@ function wrapError(fn, hookName) {
result.catch(() => { }),
new Promise((resolve) => setTimeout(() => resolve(TIMEOUT), 3000)),
]).then((res) => {
if (res === TIMEOUT && node.fiber === fiber) {
if (res === TIMEOUT && node.fiber === fiber && node.status <= 2) {
console.warn(timeoutError);
}
});
@@ -3512,7 +3512,7 @@ function compileExprToArray(expr) {
const localVars = new Set();
const tokens = tokenize(expr);
let i = 0;
let stack = []; // to track last opening [ or {
let stack = []; // to track last opening (, [ or {
while (i < tokens.length) {
let token = tokens[i];
let prevToken = tokens[i - 1];
@@ -3521,10 +3521,12 @@ function compileExprToArray(expr) {
switch (token.type) {
case "LEFT_BRACE":
case "LEFT_BRACKET":
case "LEFT_PAREN":
stack.push(token.type);
break;
case "RIGHT_BRACE":
case "RIGHT_BRACKET":
case "RIGHT_PAREN":
stack.pop();
}
let isVar = token.type === "SYMBOL" && !RESERVED_WORDS.includes(token.value);
@@ -3636,6 +3638,13 @@ function isProp(tag, key) {
}
return false;
}
/**
* Returns a template literal that evaluates to str. You can add interpolation
* sigils into the string if required
*/
function toStringExpression(str) {
return `\`${str.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/, "\\${")}\``;
}
// -----------------------------------------------------------------------------
// BlockDescription
// -----------------------------------------------------------------------------
@@ -3816,15 +3825,14 @@ class CodeGenerator {
mainCode.push(``);
for (let block of this.blocks) {
if (block.dom) {
let xmlString = block.asXmlString();
xmlString = xmlString.replace(/\\/g, "\\\\").replace(/`/g, "\\`");
let xmlString = toStringExpression(block.asXmlString());
if (block.dynamicTagName) {
xmlString = xmlString.replace(/^<\w+/, `<\${tag || '${block.dom.nodeName}'}`);
xmlString = xmlString.replace(/\w+>$/, `\${tag || '${block.dom.nodeName}'}>`);
mainCode.push(`let ${block.blockName} = tag => createBlock(\`${xmlString}\`);`);
xmlString = xmlString.replace(/^`<\w+/, `\`<\${tag || '${block.dom.nodeName}'}`);
xmlString = xmlString.replace(/\w+>`$/, `\${tag || '${block.dom.nodeName}'}>\``);
mainCode.push(`let ${block.blockName} = tag => createBlock(${xmlString});`);
}
else {
mainCode.push(`let ${block.blockName} = createBlock(\`${xmlString}\`);`);
mainCode.push(`let ${block.blockName} = createBlock(${xmlString});`);
}
}
}
@@ -4002,7 +4010,7 @@ class CodeGenerator {
const isNewBlock = !block || forceNewBlock;
if (isNewBlock) {
block = this.createBlock(block, "comment", ctx);
this.insertBlock(`comment(\`${ast.value}\`)`, block, {
this.insertBlock(`comment(${toStringExpression(ast.value)})`, block, {
...ctx,
forceNewBlock: forceNewBlock && !block,
});
@@ -4024,7 +4032,7 @@ class CodeGenerator {
}
if (!block || forceNewBlock) {
block = this.createBlock(block, "text", ctx);
this.insertBlock(`text(\`${value}\`)`, block, {
this.insertBlock(`text(${toStringExpression(value)})`, block, {
...ctx,
forceNewBlock: forceNewBlock && !block,
});
@@ -4245,7 +4253,8 @@ class CodeGenerator {
expr = compileExpr(ast.expr);
if (ast.defaultValue) {
this.helpers.add("withDefault");
expr = `withDefault(${expr}, \`${ast.defaultValue}\`)`;
// FIXME: defaultValue is not translated
expr = `withDefault(${expr}, ${toStringExpression(ast.defaultValue)})`;
}
}
if (!block || forceNewBlock) {
@@ -4498,7 +4507,7 @@ class CodeGenerator {
this.addLine(`${ctxVar}[zero] = ${bl};`);
}
}
const key = `key + \`${this.generateComponentKey()}\``;
const key = this.generateComponentKey();
if (isDynamic) {
const templateVar = generateId("template");
if (!this.staticDefs.find((d) => d.id === "call")) {
@@ -4550,12 +4559,12 @@ class CodeGenerator {
else {
let value;
if (ast.defaultValue) {
const defaultValue = ctx.translate ? this.translate(ast.defaultValue) : ast.defaultValue;
const defaultValue = toStringExpression(ctx.translate ? this.translate(ast.defaultValue) : ast.defaultValue);
if (ast.value) {
value = `withDefault(${expr}, \`${defaultValue}\`)`;
value = `withDefault(${expr}, ${defaultValue})`;
}
else {
value = `\`${defaultValue}\``;
value = defaultValue;
}
}
else {
@@ -4566,12 +4575,12 @@ class CodeGenerator {
}
return null;
}
generateComponentKey() {
generateComponentKey(currentKey = "key") {
const parts = [generateId("__")];
for (let i = 0; i < this.target.loopLevel; i++) {
parts.push(`\${key${i + 1}}`);
}
return parts.join("__");
return `${currentKey} + \`${parts.join("__")}\``;
}
/**
* Formats a prop name and value into a string suitable to be inserted in the
@@ -4662,7 +4671,6 @@ class CodeGenerator {
this.addLine(`${propVar}.slots = markRaw(Object.assign(${slotDef}, ${propVar}.slots))`);
}
// cmap key
const key = this.generateComponentKey();
let expr;
if (ast.isDynamic) {
expr = generateId("Comp");
@@ -4678,7 +4686,7 @@ class CodeGenerator {
// todo: check the forcenewblock condition
this.insertAnchor(block);
}
let keyArg = `key + \`${key}\``;
let keyArg = this.generateComponentKey();
if (ctx.tKeyExpr) {
keyArg = `${ctx.tKeyExpr} + ${keyArg}`;
}
@@ -4751,7 +4759,7 @@ class CodeGenerator {
}
let key = this.target.loopLevel ? `key${this.target.loopLevel}` : "key";
if (isMultiple) {
key = `${key} + \`${this.generateComponentKey()}\``;
key = this.generateComponentKey(key);
}
const props = ast.attrs ? this.formatPropObject(ast.attrs) : [];
const scope = this.getPropString(props, dynProps);
@@ -4792,7 +4800,6 @@ class CodeGenerator {
}
let { block } = ctx;
const name = this.compileInNewTarget("slot", ast.content, ctx);
const key = this.generateComponentKey();
let ctxStr = "ctx";
if (this.target.loopLevel || !this.hasSafeContext) {
ctxStr = generateId("ctx");
@@ -4805,7 +4812,8 @@ class CodeGenerator {
expr: `app.createComponent(null, false, true, false, false)`,
});
const target = compileExpr(ast.target);
const blockString = `${id}({target: ${target},slots: {'default': {__render: ${name}.bind(this), __ctx: ${ctxStr}}}}, key + \`${key}\`, node, ctx, Portal)`;
const key = this.generateComponentKey();
const blockString = `${id}({target: ${target},slots: {'default': {__render: ${name}.bind(this), __ctx: ${ctxStr}}}}, ${key}, node, ctx, Portal)`;
if (block) {
this.insertAnchor(block);
}
@@ -5538,7 +5546,7 @@ function compile(template, options = {}) {
}

// do not modify manually. This file is generated by the release script.
const version = "2.2.10";
const version = "2.2.11";

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

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 };
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 };


__info__.date = '2024-04-02T10:25:32.577Z';
__info__.hash = '97b69f1';
__info__.date = '2024-06-17T13:31:12.099Z';
__info__.hash = 'e7f405c';
__info__.url = 'https://github.com/odoo/owl';
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@odoo/owl",
"version": "2.2.10",
"version": "2.2.11",
"description": "Odoo Web Library (OWL)",
"main": "dist/owl.cjs.js",
"module": "dist/owl.es.js",
2 changes: 1 addition & 1 deletion src/version.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// do not modify manually. This file is generated by the release script.
export const version = "2.2.10";
export const version = "2.2.11";

0 comments on commit 66a8013

Please sign in to comment.