mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[REL] v2.4.0
# v2.4.0 - [IMP] owl: add basic support for sub roots - [IMP] make set of timeout-able hooks (and their timeouts) clearer by using a const map - [IMP] devtools: add support for file urls on chrome
This commit is contained in:
+71
-34
@@ -2598,42 +2598,47 @@ class ComponentNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const TIMEOUT = Symbol("timeout");
|
const TIMEOUT = Symbol("timeout");
|
||||||
|
const HOOK_TIMEOUT = {
|
||||||
|
onWillStart: 3000,
|
||||||
|
onWillUpdateProps: 3000,
|
||||||
|
};
|
||||||
function wrapError(fn, hookName) {
|
function wrapError(fn, hookName) {
|
||||||
const error = new OwlError(`The following error occurred in ${hookName}: `);
|
const error = new OwlError();
|
||||||
const timeoutError = new OwlError(`${hookName}'s promise hasn't resolved after 3 seconds`);
|
const timeoutError = new OwlError();
|
||||||
const node = getCurrent();
|
const node = getCurrent();
|
||||||
return (...args) => {
|
return (...args) => {
|
||||||
const onError = (cause) => {
|
const onError = (cause) => {
|
||||||
error.cause = cause;
|
error.cause = cause;
|
||||||
if (cause instanceof Error) {
|
error.message =
|
||||||
error.message += `"${cause.message}"`;
|
cause instanceof Error
|
||||||
}
|
? `The following error occurred in ${hookName}: "${cause.message}"`
|
||||||
else {
|
: `Something that is not an Error was thrown in ${hookName} (see this Error's "cause" property)`;
|
||||||
error.message = `Something that is not an Error was thrown in ${hookName} (see this Error's "cause" property)`;
|
|
||||||
}
|
|
||||||
throw error;
|
throw error;
|
||||||
};
|
};
|
||||||
|
let result;
|
||||||
try {
|
try {
|
||||||
const result = fn(...args);
|
result = fn(...args);
|
||||||
if (result instanceof Promise) {
|
|
||||||
if (hookName === "onWillStart" || hookName === "onWillUpdateProps") {
|
|
||||||
const fiber = node.fiber;
|
|
||||||
Promise.race([
|
|
||||||
result.catch(() => { }),
|
|
||||||
new Promise((resolve) => setTimeout(() => resolve(TIMEOUT), 3000)),
|
|
||||||
]).then((res) => {
|
|
||||||
if (res === TIMEOUT && node.fiber === fiber && node.status <= 2) {
|
|
||||||
console.log(timeoutError);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return result.catch(onError);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
catch (cause) {
|
catch (cause) {
|
||||||
onError(cause);
|
onError(cause);
|
||||||
}
|
}
|
||||||
|
if (!(result instanceof Promise)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
const timeout = HOOK_TIMEOUT[hookName];
|
||||||
|
if (timeout) {
|
||||||
|
const fiber = node.fiber;
|
||||||
|
Promise.race([
|
||||||
|
result.catch(() => { }),
|
||||||
|
new Promise((resolve) => setTimeout(() => resolve(TIMEOUT), timeout)),
|
||||||
|
]).then((res) => {
|
||||||
|
if (res === TIMEOUT && node.fiber === fiber && node.status <= 2) {
|
||||||
|
timeoutError.message = `${hookName}'s promise hasn't resolved after ${timeout / 1000} seconds`;
|
||||||
|
console.log(timeoutError);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result.catch(onError);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@@ -5552,7 +5557,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.3.1";
|
const version = "2.4.0";
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Scheduler
|
// Scheduler
|
||||||
@@ -5647,6 +5652,7 @@ class App extends TemplateSet {
|
|||||||
constructor(Root, config = {}) {
|
constructor(Root, config = {}) {
|
||||||
super(config);
|
super(config);
|
||||||
this.scheduler = new Scheduler();
|
this.scheduler = new Scheduler();
|
||||||
|
this.subRoots = new Set();
|
||||||
this.root = null;
|
this.root = null;
|
||||||
this.name = config.name || "";
|
this.name = config.name || "";
|
||||||
this.Root = Root;
|
this.Root = Root;
|
||||||
@@ -5665,14 +5671,42 @@ class App extends TemplateSet {
|
|||||||
this.props = config.props || {};
|
this.props = config.props || {};
|
||||||
}
|
}
|
||||||
mount(target, options) {
|
mount(target, options) {
|
||||||
App.validateTarget(target);
|
const root = this.createRoot(this.Root, { props: this.props });
|
||||||
if (this.dev) {
|
this.root = root.node;
|
||||||
validateProps(this.Root, this.props, { __owl__: { app: this } });
|
this.subRoots.delete(root.node);
|
||||||
|
return root.mount(target, options);
|
||||||
|
}
|
||||||
|
createRoot(Root, config = {}) {
|
||||||
|
const props = config.props || {};
|
||||||
|
// hack to make sure the sub root get the sub env if necessary. for owl 3,
|
||||||
|
// would be nice to rethink the initialization process to make sure that
|
||||||
|
// we can create a ComponentNode and give it explicitely the env, instead
|
||||||
|
// of looking it up in the app
|
||||||
|
const env = this.env;
|
||||||
|
if (config.env) {
|
||||||
|
this.env = config.env;
|
||||||
}
|
}
|
||||||
const node = this.makeNode(this.Root, this.props);
|
const node = this.makeNode(Root, props);
|
||||||
const prom = this.mountNode(node, target, options);
|
if (config.env) {
|
||||||
this.root = node;
|
this.env = env;
|
||||||
return prom;
|
}
|
||||||
|
this.subRoots.add(node);
|
||||||
|
return {
|
||||||
|
node,
|
||||||
|
mount: (target, options) => {
|
||||||
|
App.validateTarget(target);
|
||||||
|
if (this.dev) {
|
||||||
|
validateProps(Root, props, { __owl__: { app: this } });
|
||||||
|
}
|
||||||
|
const prom = this.mountNode(node, target, options);
|
||||||
|
return prom;
|
||||||
|
},
|
||||||
|
destroy: () => {
|
||||||
|
this.subRoots.delete(node);
|
||||||
|
node.destroy();
|
||||||
|
this.scheduler.processTasks();
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
makeNode(Component, props) {
|
makeNode(Component, props) {
|
||||||
return new ComponentNode(Component, props, this, null, null);
|
return new ComponentNode(Component, props, this, null, null);
|
||||||
@@ -5704,6 +5738,9 @@ class App extends TemplateSet {
|
|||||||
}
|
}
|
||||||
destroy() {
|
destroy() {
|
||||||
if (this.root) {
|
if (this.root) {
|
||||||
|
for (let subroot of this.subRoots) {
|
||||||
|
subroot.destroy();
|
||||||
|
}
|
||||||
this.root.destroy();
|
this.root.destroy();
|
||||||
this.scheduler.processTasks();
|
this.scheduler.processTasks();
|
||||||
}
|
}
|
||||||
@@ -5981,6 +6018,6 @@ TemplateSet.prototype._compileTemplate = function _compileTemplate(name, templat
|
|||||||
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 };
|
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-08-14T14:25:23.038Z';
|
__info__.date = '2024-09-30T08:49:29.420Z';
|
||||||
__info__.hash = '9c2d957';
|
__info__.hash = 'eb2b32a';
|
||||||
__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.3.1",
|
"version": "2.4.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@odoo/owl",
|
"name": "@odoo/owl",
|
||||||
"version": "2.3.1",
|
"version": "2.4.0",
|
||||||
"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.3.1";
|
export const version = "2.4.0";
|
||||||
|
|||||||
Reference in New Issue
Block a user