[REL] v2.8.1

# v2.8.1

 - [FIX] parser, code_generator: wrapped children recognition
 - [DOC] `slots` prop validation
This commit is contained in:
Romeo Fragomeli
2025-09-23 09:17:54 +02:00
parent 521111644c
commit 5187f01c44
4 changed files with 75 additions and 29 deletions
+72 -26
View File
@@ -4539,7 +4539,7 @@ class CodeGenerator {
const isNewBlock = !block || forceNewBlock; const isNewBlock = !block || forceNewBlock;
let codeIdx = this.target.code.length; let codeIdx = this.target.code.length;
if (isNewBlock) { if (isNewBlock) {
const n = ast.content.filter((c) => c.type !== 6 /* TSet */).length; const n = ast.content.filter((c) => !c.hasNoRepresentation).length;
let result = null; let result = null;
if (n <= 1) { if (n <= 1) {
for (let child of ast.content) { for (let child of ast.content) {
@@ -4553,15 +4553,15 @@ class CodeGenerator {
let index = 0; let index = 0;
for (let i = 0, l = ast.content.length; i < l; i++) { for (let i = 0, l = ast.content.length; i < l; i++) {
const child = ast.content[i]; const child = ast.content[i];
const isTSet = child.type === 6 /* TSet */; const forceNewBlock = !child.hasNoRepresentation;
const subCtx = createContext(ctx, { const subCtx = createContext(ctx, {
block, block,
index, index,
forceNewBlock: !isTSet, forceNewBlock,
isLast: ctx.isLast && i === l - 1, isLast: ctx.isLast && i === l - 1,
}); });
this.compileAST(child, subCtx); this.compileAST(child, subCtx);
if (!isTSet) { if (forceNewBlock) {
index++; index++;
} }
} }
@@ -4979,9 +4979,9 @@ function parseNode(node, ctx) {
parseTCallBlock(node) || parseTCallBlock(node) ||
parseTTranslation(node, ctx) || parseTTranslation(node, ctx) ||
parseTTranslationContext(node, ctx) || parseTTranslationContext(node, ctx) ||
parseTKey(node, ctx) ||
parseTEscNode(node, ctx) || parseTEscNode(node, ctx) ||
parseTOutNode(node, ctx) || parseTOutNode(node, ctx) ||
parseTKey(node, ctx) ||
parseTSlot(node, ctx) || parseTSlot(node, ctx) ||
parseComponent(node, ctx) || parseComponent(node, ctx) ||
parseDOMNode(node, ctx) || parseDOMNode(node, ctx) ||
@@ -5049,19 +5049,29 @@ function parseTCustom(node, ctx) {
function parseTDebugLog(node, ctx) { function parseTDebugLog(node, ctx) {
if (node.hasAttribute("t-debug")) { if (node.hasAttribute("t-debug")) {
node.removeAttribute("t-debug"); node.removeAttribute("t-debug");
return { const content = parseNode(node, ctx);
const ast = {
type: 12 /* TDebug */, type: 12 /* TDebug */,
content: parseNode(node, ctx), content,
}; };
if (content === null || content === void 0 ? void 0 : content.hasNoRepresentation) {
ast.hasNoRepresentation = true;
}
return ast;
} }
if (node.hasAttribute("t-log")) { if (node.hasAttribute("t-log")) {
const expr = node.getAttribute("t-log"); const expr = node.getAttribute("t-log");
node.removeAttribute("t-log"); node.removeAttribute("t-log");
return { const content = parseNode(node, ctx);
const ast = {
type: 13 /* TLog */, type: 13 /* TLog */,
expr, expr,
content: parseNode(node, ctx), content,
}; };
if (content === null || content === void 0 ? void 0 : content.hasNoRepresentation) {
ast.hasNoRepresentation = true;
}
return ast;
} }
return null; return null;
} }
@@ -5291,11 +5301,19 @@ function parseTKey(node, ctx) {
} }
const key = node.getAttribute("t-key"); const key = node.getAttribute("t-key");
node.removeAttribute("t-key"); node.removeAttribute("t-key");
const body = parseNode(node, ctx); const content = parseNode(node, ctx);
if (!body) { if (!content) {
return null; return null;
} }
return { type: 10 /* TKey */, expr: key, content: body }; const ast = {
type: 10 /* TKey */,
expr: key,
content,
};
if (content.hasNoRepresentation) {
ast.hasNoRepresentation = true;
}
return ast;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// t-call // t-call
@@ -5404,7 +5422,7 @@ function parseTSetNode(node, ctx) {
if (node.textContent !== node.innerHTML) { if (node.textContent !== node.innerHTML) {
body = parseChildren(node, ctx); body = parseChildren(node, ctx);
} }
return { type: 6 /* TSet */, name, value, defaultValue, body }; return { type: 6 /* TSet */, name, value, defaultValue, body, hasNoRepresentation: true };
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Components // Components
@@ -5583,30 +5601,51 @@ function parseTSlot(node, ctx) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Translation // Translation
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function wrapInTTranslationAST(r) {
const ast = { type: 16 /* TTranslation */, content: r };
if (r === null || r === void 0 ? void 0 : r.hasNoRepresentation) {
ast.hasNoRepresentation = true;
}
return ast;
}
function parseTTranslation(node, ctx) { function parseTTranslation(node, ctx) {
if (node.getAttribute("t-translation") !== "off") { if (node.getAttribute("t-translation") !== "off") {
return null; return null;
} }
node.removeAttribute("t-translation"); node.removeAttribute("t-translation");
return { const result = parseNode(node, ctx);
type: 16 /* TTranslation */, if ((result === null || result === void 0 ? void 0 : result.type) === 3 /* Multi */) {
content: parseNode(node, ctx), const children = result.content.map(wrapInTTranslationAST);
}; return makeASTMulti(children);
}
return wrapInTTranslationAST(result);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Translation Context // Translation Context
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function wrapInTTranslationContextAST(r, translationCtx) {
const ast = {
type: 17 /* TTranslationContext */,
content: r,
translationCtx,
};
if (r === null || r === void 0 ? void 0 : r.hasNoRepresentation) {
ast.hasNoRepresentation = true;
}
return ast;
}
function parseTTranslationContext(node, ctx) { function parseTTranslationContext(node, ctx) {
const translationCtx = node.getAttribute("t-translation-context"); const translationCtx = node.getAttribute("t-translation-context");
if (!translationCtx) { if (!translationCtx) {
return null; return null;
} }
node.removeAttribute("t-translation-context"); node.removeAttribute("t-translation-context");
return { const result = parseNode(node, ctx);
type: 17 /* TTranslationContext */, if ((result === null || result === void 0 ? void 0 : result.type) === 3 /* Multi */) {
content: parseNode(node, ctx), const children = result.content.map((c) => wrapInTTranslationContextAST(c, translationCtx));
translationCtx, return makeASTMulti(children);
}; }
return wrapInTTranslationContextAST(result, translationCtx);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Portal // Portal
@@ -5651,6 +5690,13 @@ function parseChildren(node, ctx) {
} }
return children; return children;
} }
function makeASTMulti(children) {
const ast = { type: 3 /* Multi */, content: children };
if (children.every((c) => c.hasNoRepresentation)) {
ast.hasNoRepresentation = true;
}
return ast;
}
/** /**
* Parse all the child nodes of a given node and return an ast if possible. * Parse all the child nodes of a given node and return an ast if possible.
* In the case there are multiple children, they are wrapped in a astmulti. * In the case there are multiple children, they are wrapped in a astmulti.
@@ -5663,7 +5709,7 @@ function parseChildNodes(node, ctx) {
case 1: case 1:
return children[0]; return children[0];
default: default:
return { type: 3 /* Multi */, content: children }; return makeASTMulti(children);
} }
} }
/** /**
@@ -5767,7 +5813,7 @@ function compile(template, options = {
} }
// do not modify manually. This file is generated by the release script. // do not modify manually. This file is generated by the release script.
const version = "2.8.0"; const version = "2.8.1";
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Scheduler // Scheduler
@@ -6238,6 +6284,6 @@ TemplateSet.prototype._compileTemplate = function _compileTemplate(name, templat
export { App, Component, EventBus, OwlError, __info__, batched, blockDom, htmlEscape, 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, htmlEscape, 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 = '2025-06-30T12:46:06.424Z'; __info__.date = '2025-09-23T07:17:45.055Z';
__info__.hash = 'b620502'; __info__.hash = '5211116';
__info__.url = 'https://github.com/odoo/owl'; __info__.url = 'https://github.com/odoo/owl';
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@odoo/owl", "name": "@odoo/owl",
"version": "2.8.0", "version": "2.8.1",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@odoo/owl", "name": "@odoo/owl",
"version": "2.8.0", "version": "2.8.1",
"description": "Odoo Web Library (OWL)", "description": "Odoo Web Library (OWL)",
"main": "dist/owl.cjs.js", "main": "dist/owl.cjs.js",
"module": "dist/owl.es.js", "module": "dist/owl.es.js",
+1 -1
View File
@@ -1,2 +1,2 @@
// do not modify manually. This file is generated by the release script. // do not modify manually. This file is generated by the release script.
export const version = "2.8.0"; export const version = "2.8.1";