[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;
let codeIdx = this.target.code.length;
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;
if (n <= 1) {
for (let child of ast.content) {
@@ -4553,15 +4553,15 @@ class CodeGenerator {
let index = 0;
for (let i = 0, l = ast.content.length; i < l; i++) {
const child = ast.content[i];
const isTSet = child.type === 6 /* TSet */;
const forceNewBlock = !child.hasNoRepresentation;
const subCtx = createContext(ctx, {
block,
index,
forceNewBlock: !isTSet,
forceNewBlock,
isLast: ctx.isLast && i === l - 1,
});
this.compileAST(child, subCtx);
if (!isTSet) {
if (forceNewBlock) {
index++;
}
}
@@ -4979,9 +4979,9 @@ function parseNode(node, ctx) {
parseTCallBlock(node) ||
parseTTranslation(node, ctx) ||
parseTTranslationContext(node, ctx) ||
parseTKey(node, ctx) ||
parseTEscNode(node, ctx) ||
parseTOutNode(node, ctx) ||
parseTKey(node, ctx) ||
parseTSlot(node, ctx) ||
parseComponent(node, ctx) ||
parseDOMNode(node, ctx) ||
@@ -5049,19 +5049,29 @@ function parseTCustom(node, ctx) {
function parseTDebugLog(node, ctx) {
if (node.hasAttribute("t-debug")) {
node.removeAttribute("t-debug");
return {
const content = parseNode(node, ctx);
const ast = {
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")) {
const expr = node.getAttribute("t-log");
node.removeAttribute("t-log");
return {
const content = parseNode(node, ctx);
const ast = {
type: 13 /* TLog */,
expr,
content: parseNode(node, ctx),
content,
};
if (content === null || content === void 0 ? void 0 : content.hasNoRepresentation) {
ast.hasNoRepresentation = true;
}
return ast;
}
return null;
}
@@ -5291,11 +5301,19 @@ function parseTKey(node, ctx) {
}
const key = node.getAttribute("t-key");
node.removeAttribute("t-key");
const body = parseNode(node, ctx);
if (!body) {
const content = parseNode(node, ctx);
if (!content) {
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
@@ -5404,7 +5422,7 @@ function parseTSetNode(node, ctx) {
if (node.textContent !== node.innerHTML) {
body = parseChildren(node, ctx);
}
return { type: 6 /* TSet */, name, value, defaultValue, body };
return { type: 6 /* TSet */, name, value, defaultValue, body, hasNoRepresentation: true };
}
// -----------------------------------------------------------------------------
// Components
@@ -5583,30 +5601,51 @@ function parseTSlot(node, ctx) {
// -----------------------------------------------------------------------------
// 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) {
if (node.getAttribute("t-translation") !== "off") {
return null;
}
node.removeAttribute("t-translation");
return {
type: 16 /* TTranslation */,
content: parseNode(node, ctx),
};
const result = parseNode(node, ctx);
if ((result === null || result === void 0 ? void 0 : result.type) === 3 /* Multi */) {
const children = result.content.map(wrapInTTranslationAST);
return makeASTMulti(children);
}
return wrapInTTranslationAST(result);
}
// -----------------------------------------------------------------------------
// 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) {
const translationCtx = node.getAttribute("t-translation-context");
if (!translationCtx) {
return null;
}
node.removeAttribute("t-translation-context");
return {
type: 17 /* TTranslationContext */,
content: parseNode(node, ctx),
translationCtx,
};
const result = parseNode(node, ctx);
if ((result === null || result === void 0 ? void 0 : result.type) === 3 /* Multi */) {
const children = result.content.map((c) => wrapInTTranslationContextAST(c, translationCtx));
return makeASTMulti(children);
}
return wrapInTTranslationContextAST(result, translationCtx);
}
// -----------------------------------------------------------------------------
// Portal
@@ -5651,6 +5690,13 @@ function parseChildren(node, ctx) {
}
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.
* In the case there are multiple children, they are wrapped in a astmulti.
@@ -5663,7 +5709,7 @@ function parseChildNodes(node, ctx) {
case 1:
return children[0];
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.
const version = "2.8.0";
const version = "2.8.1";
// -----------------------------------------------------------------------------
// 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 };
__info__.date = '2025-06-30T12:46:06.424Z';
__info__.hash = 'b620502';
__info__.date = '2025-09-23T07:17:45.055Z';
__info__.hash = '5211116';
__info__.url = 'https://github.com/odoo/owl';
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@odoo/owl",
"version": "2.8.0",
"version": "2.8.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@odoo/owl",
"version": "2.8.0",
"version": "2.8.1",
"description": "Odoo Web Library (OWL)",
"main": "dist/owl.cjs.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.
export const version = "2.8.0";
export const version = "2.8.1";