mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[REL] v2.2.4
# v2.2.4 - [FIX] compiler: fix swapped key/value using t-foreach on Map - [FIX] devtools: fix crash while highlighting env - [FIX] *: move OwlError to common - [FIX] playground: todo app clear complete tasks - [IMP] compiler: improve error message when failing to compile template
This commit is contained in:
+80
-70
@@ -83,67 +83,6 @@ function toggler(key, child) {
|
|||||||
// Custom error class that wraps error that happen in the owl lifecycle
|
// Custom error class that wraps error that happen in the owl lifecycle
|
||||||
class OwlError extends Error {
|
class OwlError extends Error {
|
||||||
}
|
}
|
||||||
// Maps fibers to thrown errors
|
|
||||||
const fibersInError = new WeakMap();
|
|
||||||
const nodeErrorHandlers = new WeakMap();
|
|
||||||
function _handleError(node, error) {
|
|
||||||
if (!node) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const fiber = node.fiber;
|
|
||||||
if (fiber) {
|
|
||||||
fibersInError.set(fiber, error);
|
|
||||||
}
|
|
||||||
const errorHandlers = nodeErrorHandlers.get(node);
|
|
||||||
if (errorHandlers) {
|
|
||||||
let handled = false;
|
|
||||||
// execute in the opposite order
|
|
||||||
for (let i = errorHandlers.length - 1; i >= 0; i--) {
|
|
||||||
try {
|
|
||||||
errorHandlers[i](error);
|
|
||||||
handled = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
error = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (handled) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _handleError(node.parent, error);
|
|
||||||
}
|
|
||||||
function handleError(params) {
|
|
||||||
let { error } = params;
|
|
||||||
// Wrap error if it wasn't wrapped by wrapError (ie when not in dev mode)
|
|
||||||
if (!(error instanceof OwlError)) {
|
|
||||||
error = Object.assign(new OwlError(`An error occured in the owl lifecycle (see this Error's "cause" property)`), { cause: error });
|
|
||||||
}
|
|
||||||
const node = "node" in params ? params.node : params.fiber.node;
|
|
||||||
const fiber = "fiber" in params ? params.fiber : node.fiber;
|
|
||||||
if (fiber) {
|
|
||||||
// resets the fibers on components if possible. This is important so that
|
|
||||||
// new renderings can be properly included in the initial one, if any.
|
|
||||||
let current = fiber;
|
|
||||||
do {
|
|
||||||
current.node.fiber = current;
|
|
||||||
current = current.parent;
|
|
||||||
} while (current);
|
|
||||||
fibersInError.set(fiber.root, error);
|
|
||||||
}
|
|
||||||
const handled = _handleError(node, error);
|
|
||||||
if (!handled) {
|
|
||||||
console.warn(`[Owl] Unhandled error. Destroying the root component`);
|
|
||||||
try {
|
|
||||||
node.app.destroy();
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const { setAttribute: elemSetAttribute, removeAttribute } = Element.prototype;
|
const { setAttribute: elemSetAttribute, removeAttribute } = Element.prototype;
|
||||||
const tokenList = DOMTokenList.prototype;
|
const tokenList = DOMTokenList.prototype;
|
||||||
@@ -1603,6 +1542,68 @@ function remove(vnode, withBeforeRemove = false) {
|
|||||||
vnode.remove();
|
vnode.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Maps fibers to thrown errors
|
||||||
|
const fibersInError = new WeakMap();
|
||||||
|
const nodeErrorHandlers = new WeakMap();
|
||||||
|
function _handleError(node, error) {
|
||||||
|
if (!node) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const fiber = node.fiber;
|
||||||
|
if (fiber) {
|
||||||
|
fibersInError.set(fiber, error);
|
||||||
|
}
|
||||||
|
const errorHandlers = nodeErrorHandlers.get(node);
|
||||||
|
if (errorHandlers) {
|
||||||
|
let handled = false;
|
||||||
|
// execute in the opposite order
|
||||||
|
for (let i = errorHandlers.length - 1; i >= 0; i--) {
|
||||||
|
try {
|
||||||
|
errorHandlers[i](error);
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (handled) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _handleError(node.parent, error);
|
||||||
|
}
|
||||||
|
function handleError(params) {
|
||||||
|
let { error } = params;
|
||||||
|
// Wrap error if it wasn't wrapped by wrapError (ie when not in dev mode)
|
||||||
|
if (!(error instanceof OwlError)) {
|
||||||
|
error = Object.assign(new OwlError(`An error occured in the owl lifecycle (see this Error's "cause" property)`), { cause: error });
|
||||||
|
}
|
||||||
|
const node = "node" in params ? params.node : params.fiber.node;
|
||||||
|
const fiber = "fiber" in params ? params.fiber : node.fiber;
|
||||||
|
if (fiber) {
|
||||||
|
// resets the fibers on components if possible. This is important so that
|
||||||
|
// new renderings can be properly included in the initial one, if any.
|
||||||
|
let current = fiber;
|
||||||
|
do {
|
||||||
|
current.node.fiber = current;
|
||||||
|
current = current.parent;
|
||||||
|
} while (current);
|
||||||
|
fibersInError.set(fiber.root, error);
|
||||||
|
}
|
||||||
|
const handled = _handleError(node, error);
|
||||||
|
if (!handled) {
|
||||||
|
console.warn(`[Owl] Unhandled error. Destroying the root component`);
|
||||||
|
try {
|
||||||
|
node.app.destroy();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function makeChildFiber(node, parent) {
|
function makeChildFiber(node, parent) {
|
||||||
let current = node.fiber;
|
let current = node.fiber;
|
||||||
if (current) {
|
if (current) {
|
||||||
@@ -3007,8 +3008,8 @@ function prepareList(collection) {
|
|||||||
values = keys;
|
values = keys;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
values = Object.keys(collection);
|
values = Object.values(collection);
|
||||||
keys = Object.values(collection);
|
keys = Object.keys(collection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -4346,18 +4347,18 @@ class CodeGenerator {
|
|||||||
}
|
}
|
||||||
this.addLine(`for (let ${loopVar} = 0; ${loopVar} < ${l}; ${loopVar}++) {`);
|
this.addLine(`for (let ${loopVar} = 0; ${loopVar} < ${l}; ${loopVar}++) {`);
|
||||||
this.target.indentLevel++;
|
this.target.indentLevel++;
|
||||||
this.addLine(`ctx[\`${ast.elem}\`] = ${vals}[${loopVar}];`);
|
this.addLine(`ctx[\`${ast.elem}\`] = ${keys}[${loopVar}];`);
|
||||||
if (!ast.hasNoFirst) {
|
if (!ast.hasNoFirst) {
|
||||||
this.addLine(`ctx[\`${ast.elem}_first\`] = ${loopVar} === 0;`);
|
this.addLine(`ctx[\`${ast.elem}_first\`] = ${loopVar} === 0;`);
|
||||||
}
|
}
|
||||||
if (!ast.hasNoLast) {
|
if (!ast.hasNoLast) {
|
||||||
this.addLine(`ctx[\`${ast.elem}_last\`] = ${loopVar} === ${vals}.length - 1;`);
|
this.addLine(`ctx[\`${ast.elem}_last\`] = ${loopVar} === ${keys}.length - 1;`);
|
||||||
}
|
}
|
||||||
if (!ast.hasNoIndex) {
|
if (!ast.hasNoIndex) {
|
||||||
this.addLine(`ctx[\`${ast.elem}_index\`] = ${loopVar};`);
|
this.addLine(`ctx[\`${ast.elem}_index\`] = ${loopVar};`);
|
||||||
}
|
}
|
||||||
if (!ast.hasNoValue) {
|
if (!ast.hasNoValue) {
|
||||||
this.addLine(`ctx[\`${ast.elem}_value\`] = ${keys}[${loopVar}];`);
|
this.addLine(`ctx[\`${ast.elem}_value\`] = ${vals}[${loopVar}];`);
|
||||||
}
|
}
|
||||||
this.define(`key${this.target.loopLevel}`, ast.key ? compileExpr(ast.key) : loopVar);
|
this.define(`key${this.target.loopLevel}`, ast.key ? compileExpr(ast.key) : loopVar);
|
||||||
if (this.dev) {
|
if (this.dev) {
|
||||||
@@ -5547,11 +5548,20 @@ function compile(template, options = {}) {
|
|||||||
const codeGenerator = new CodeGenerator(ast, { ...options, hasSafeContext });
|
const codeGenerator = new CodeGenerator(ast, { ...options, hasSafeContext });
|
||||||
const code = codeGenerator.generateCode();
|
const code = codeGenerator.generateCode();
|
||||||
// template function
|
// template function
|
||||||
return new Function("app, bdom, helpers", code);
|
try {
|
||||||
|
return new Function("app, bdom, helpers", code);
|
||||||
|
}
|
||||||
|
catch (originalError) {
|
||||||
|
const { name } = options;
|
||||||
|
const nameStr = name ? `template "${name}"` : "anonymous template";
|
||||||
|
const err = new OwlError(`Failed to compile ${nameStr}: ${originalError.message}\n\ngenerated code:\nfunction(app, bdom, helpers) {\n${code}\n}`);
|
||||||
|
err.cause = originalError;
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.2.3";
|
const version = "2.2.4";
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Scheduler
|
// Scheduler
|
||||||
@@ -5984,6 +5994,6 @@ 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__, 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 = '2023-07-20T06:05:29.796Z';
|
__info__.date = '2023-08-02T06:20:03.634Z';
|
||||||
__info__.hash = 'b1a3b32';
|
__info__.hash = '8f9ad98';
|
||||||
__info__.url = 'https://github.com/odoo/owl';
|
__info__.url = 'https://github.com/odoo/owl';
|
||||||
|
|||||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@odoo/owl",
|
"name": "@odoo/owl",
|
||||||
"version": "2.2.3",
|
"version": "2.2.4",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@odoo/owl",
|
"name": "@odoo/owl",
|
||||||
"version": "2.2.3",
|
"version": "2.2.4",
|
||||||
"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
@@ -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.2.3";
|
export const version = "2.2.4";
|
||||||
|
|||||||
Reference in New Issue
Block a user