@odoo/owl 2.0.0-beta-4 → 2.0.0-beta-5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/owl.cjs.js +86 -103
- package/dist/owl.cjs.min.js +1 -1
- package/dist/owl.es.js +86 -103
- package/dist/owl.es.min.js +1 -1
- package/dist/owl.iife.js +86 -103
- package/dist/owl.iife.min.js +1 -1
- package/dist/types/compiler/parser.d.ts +1 -1
- package/dist/types/component/component_node.d.ts +2 -2
- package/dist/types/component/fibers.d.ts +1 -2
- package/dist/types/component/scheduler.d.ts +1 -1
- package/package.json +1 -1
package/dist/owl.cjs.js
CHANGED
|
@@ -1916,7 +1916,7 @@ xml.nextId = 1;
|
|
|
1916
1916
|
// Maps fibers to thrown errors
|
|
1917
1917
|
const fibersInError = new WeakMap();
|
|
1918
1918
|
const nodeErrorHandlers = new WeakMap();
|
|
1919
|
-
function _handleError(node, error
|
|
1919
|
+
function _handleError(node, error) {
|
|
1920
1920
|
if (!node) {
|
|
1921
1921
|
return false;
|
|
1922
1922
|
}
|
|
@@ -1926,23 +1926,19 @@ function _handleError(node, error, isFirstRound = false) {
|
|
|
1926
1926
|
}
|
|
1927
1927
|
const errorHandlers = nodeErrorHandlers.get(node);
|
|
1928
1928
|
if (errorHandlers) {
|
|
1929
|
-
let
|
|
1929
|
+
let handled = false;
|
|
1930
1930
|
// execute in the opposite order
|
|
1931
1931
|
for (let i = errorHandlers.length - 1; i >= 0; i--) {
|
|
1932
1932
|
try {
|
|
1933
1933
|
errorHandlers[i](error);
|
|
1934
|
-
|
|
1934
|
+
handled = true;
|
|
1935
1935
|
break;
|
|
1936
1936
|
}
|
|
1937
1937
|
catch (e) {
|
|
1938
1938
|
error = e;
|
|
1939
1939
|
}
|
|
1940
1940
|
}
|
|
1941
|
-
if (
|
|
1942
|
-
if (isFirstRound && fiber && fiber.node.fiber) {
|
|
1943
|
-
const root = fiber.root;
|
|
1944
|
-
root.setCounter(root.counter - 1);
|
|
1945
|
-
}
|
|
1941
|
+
if (handled) {
|
|
1946
1942
|
return true;
|
|
1947
1943
|
}
|
|
1948
1944
|
}
|
|
@@ -1960,7 +1956,7 @@ function handleError(params) {
|
|
|
1960
1956
|
current = current.parent;
|
|
1961
1957
|
} while (current);
|
|
1962
1958
|
fibersInError.set(fiber.root, error);
|
|
1963
|
-
const handled = _handleError(node, error
|
|
1959
|
+
const handled = _handleError(node, error);
|
|
1964
1960
|
if (!handled) {
|
|
1965
1961
|
console.warn(`[Owl] Unhandled error. Destroying the root component`);
|
|
1966
1962
|
try {
|
|
@@ -1977,10 +1973,6 @@ function makeChildFiber(node, parent) {
|
|
|
1977
1973
|
if (current) {
|
|
1978
1974
|
cancelFibers(current.children);
|
|
1979
1975
|
current.root = null;
|
|
1980
|
-
if (current instanceof RootFiber && current.delayedRenders.length) {
|
|
1981
|
-
let root = parent.root;
|
|
1982
|
-
root.delayedRenders = root.delayedRenders.concat(current.delayedRenders);
|
|
1983
|
-
}
|
|
1984
1976
|
}
|
|
1985
1977
|
return new Fiber(node, parent);
|
|
1986
1978
|
}
|
|
@@ -1988,12 +1980,15 @@ function makeRootFiber(node) {
|
|
|
1988
1980
|
let current = node.fiber;
|
|
1989
1981
|
if (current) {
|
|
1990
1982
|
let root = current.root;
|
|
1983
|
+
// lock root fiber because canceling children fibers may destroy components,
|
|
1984
|
+
// which means any arbitrary code can be run in onWillDestroy, which may
|
|
1985
|
+
// trigger new renderings
|
|
1986
|
+
root.locked = true;
|
|
1991
1987
|
root.setCounter(root.counter + 1 - cancelFibers(current.children));
|
|
1988
|
+
root.locked = false;
|
|
1992
1989
|
current.children = [];
|
|
1990
|
+
current.childrenMap = {};
|
|
1993
1991
|
current.bdom = null;
|
|
1994
|
-
if (current === root) {
|
|
1995
|
-
root.reachedChildren = new WeakSet();
|
|
1996
|
-
}
|
|
1997
1992
|
if (fibersInError.has(current)) {
|
|
1998
1993
|
fibersInError.delete(current);
|
|
1999
1994
|
fibersInError.delete(root);
|
|
@@ -2016,7 +2011,11 @@ function makeRootFiber(node) {
|
|
|
2016
2011
|
function cancelFibers(fibers) {
|
|
2017
2012
|
let result = 0;
|
|
2018
2013
|
for (let fiber of fibers) {
|
|
2019
|
-
|
|
2014
|
+
let node = fiber.node;
|
|
2015
|
+
if (node.status === 0 /* NEW */) {
|
|
2016
|
+
node.destroy();
|
|
2017
|
+
}
|
|
2018
|
+
node.fiber = null;
|
|
2020
2019
|
if (fiber.bdom) {
|
|
2021
2020
|
// if fiber has been rendered, this means that the component props have
|
|
2022
2021
|
// been updated. however, this fiber will not be patched to the dom, so
|
|
@@ -2024,7 +2023,7 @@ function cancelFibers(fibers) {
|
|
|
2024
2023
|
// the same props, and skip the render completely. With the next line,
|
|
2025
2024
|
// we kindly request the component code to force a render, so it works as
|
|
2026
2025
|
// expected.
|
|
2027
|
-
|
|
2026
|
+
node.forceNextRender = true;
|
|
2028
2027
|
}
|
|
2029
2028
|
else {
|
|
2030
2029
|
result++;
|
|
@@ -2039,6 +2038,7 @@ class Fiber {
|
|
|
2039
2038
|
this.children = [];
|
|
2040
2039
|
this.appliedToDom = false;
|
|
2041
2040
|
this.deep = false;
|
|
2041
|
+
this.childrenMap = {};
|
|
2042
2042
|
this.node = node;
|
|
2043
2043
|
this.parent = parent;
|
|
2044
2044
|
if (parent) {
|
|
@@ -2055,21 +2055,17 @@ class Fiber {
|
|
|
2055
2055
|
render() {
|
|
2056
2056
|
// if some parent has a fiber => register in followup
|
|
2057
2057
|
let prev = this.root.node;
|
|
2058
|
+
let scheduler = prev.app.scheduler;
|
|
2058
2059
|
let current = prev.parent;
|
|
2059
2060
|
while (current) {
|
|
2060
2061
|
if (current.fiber) {
|
|
2061
2062
|
let root = current.fiber.root;
|
|
2062
|
-
if (root.counter) {
|
|
2063
|
-
root.
|
|
2064
|
-
return;
|
|
2063
|
+
if (root.counter === 0 && prev.parentKey in current.fiber.childrenMap) {
|
|
2064
|
+
current = root.node;
|
|
2065
2065
|
}
|
|
2066
2066
|
else {
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
this.node.app.scheduler.shouldClear = true;
|
|
2070
|
-
return;
|
|
2071
|
-
}
|
|
2072
|
-
current = root.node;
|
|
2067
|
+
scheduler.delayedRenders.push(this);
|
|
2068
|
+
return;
|
|
2073
2069
|
}
|
|
2074
2070
|
}
|
|
2075
2071
|
prev = current;
|
|
@@ -2083,12 +2079,13 @@ class Fiber {
|
|
|
2083
2079
|
const root = this.root;
|
|
2084
2080
|
if (root) {
|
|
2085
2081
|
try {
|
|
2082
|
+
this.bdom = true;
|
|
2086
2083
|
this.bdom = node.renderFn();
|
|
2087
|
-
root.setCounter(root.counter - 1);
|
|
2088
2084
|
}
|
|
2089
2085
|
catch (e) {
|
|
2090
2086
|
handleError({ node, error: e });
|
|
2091
2087
|
}
|
|
2088
|
+
root.setCounter(root.counter - 1);
|
|
2092
2089
|
}
|
|
2093
2090
|
}
|
|
2094
2091
|
}
|
|
@@ -2103,8 +2100,6 @@ class RootFiber extends Fiber {
|
|
|
2103
2100
|
// A fiber is typically locked when it is completing and the patch has not, or is being applied.
|
|
2104
2101
|
// i.e.: render triggered in onWillUnmount or in willPatch will be delayed
|
|
2105
2102
|
this.locked = false;
|
|
2106
|
-
this.delayedRenders = [];
|
|
2107
|
-
this.reachedChildren = new WeakSet();
|
|
2108
2103
|
}
|
|
2109
2104
|
complete() {
|
|
2110
2105
|
const node = this.node;
|
|
@@ -2157,14 +2152,6 @@ class RootFiber extends Fiber {
|
|
|
2157
2152
|
setCounter(newValue) {
|
|
2158
2153
|
this.counter = newValue;
|
|
2159
2154
|
if (newValue === 0) {
|
|
2160
|
-
if (this.delayedRenders.length) {
|
|
2161
|
-
for (let f of this.delayedRenders) {
|
|
2162
|
-
if (f.root) {
|
|
2163
|
-
f.render();
|
|
2164
|
-
}
|
|
2165
|
-
}
|
|
2166
|
-
this.delayedRenders = [];
|
|
2167
|
-
}
|
|
2168
2155
|
this.node.app.scheduler.flush();
|
|
2169
2156
|
}
|
|
2170
2157
|
}
|
|
@@ -2179,6 +2166,7 @@ class MountFiber extends RootFiber {
|
|
|
2179
2166
|
let current = this;
|
|
2180
2167
|
try {
|
|
2181
2168
|
const node = this.node;
|
|
2169
|
+
node.children = this.childrenMap;
|
|
2182
2170
|
node.app.constructor.validateTarget(this.target);
|
|
2183
2171
|
if (node.bdom) {
|
|
2184
2172
|
// this is a complicated situation: if we mount a fiber with an existing
|
|
@@ -2402,14 +2390,8 @@ function arePropsDifferent(props1, props2) {
|
|
|
2402
2390
|
function component(name, props, key, ctx, parent) {
|
|
2403
2391
|
let node = ctx.children[key];
|
|
2404
2392
|
let isDynamic = typeof name !== "string";
|
|
2405
|
-
if (node) {
|
|
2406
|
-
|
|
2407
|
-
node.destroy();
|
|
2408
|
-
node = undefined;
|
|
2409
|
-
}
|
|
2410
|
-
else if (node.status === 2 /* DESTROYED */) {
|
|
2411
|
-
node = undefined;
|
|
2412
|
-
}
|
|
2393
|
+
if (node && node.status === 2 /* DESTROYED */) {
|
|
2394
|
+
node = undefined;
|
|
2413
2395
|
}
|
|
2414
2396
|
if (isDynamic && node && node.component.constructor !== name) {
|
|
2415
2397
|
node = undefined;
|
|
@@ -2440,15 +2422,15 @@ function component(name, props, key, ctx, parent) {
|
|
|
2440
2422
|
throw new Error(`Cannot find the definition of component "${name}"`);
|
|
2441
2423
|
}
|
|
2442
2424
|
}
|
|
2443
|
-
node = new ComponentNode(C, props, ctx.app, ctx);
|
|
2425
|
+
node = new ComponentNode(C, props, ctx.app, ctx, key);
|
|
2444
2426
|
ctx.children[key] = node;
|
|
2445
2427
|
node.initiateRender(new Fiber(node, parentFiber));
|
|
2446
2428
|
}
|
|
2447
|
-
parentFiber.
|
|
2429
|
+
parentFiber.childrenMap[key] = node;
|
|
2448
2430
|
return node;
|
|
2449
2431
|
}
|
|
2450
2432
|
class ComponentNode {
|
|
2451
|
-
constructor(C, props, app, parent) {
|
|
2433
|
+
constructor(C, props, app, parent, parentKey) {
|
|
2452
2434
|
this.fiber = null;
|
|
2453
2435
|
this.bdom = null;
|
|
2454
2436
|
this.status = 0 /* NEW */;
|
|
@@ -2464,7 +2446,8 @@ class ComponentNode {
|
|
|
2464
2446
|
this.willDestroy = [];
|
|
2465
2447
|
currentNode = this;
|
|
2466
2448
|
this.app = app;
|
|
2467
|
-
this.parent = parent
|
|
2449
|
+
this.parent = parent;
|
|
2450
|
+
this.parentKey = parentKey;
|
|
2468
2451
|
this.level = parent ? parent.level + 1 : 0;
|
|
2469
2452
|
applyDefaultProps(props, C);
|
|
2470
2453
|
const env = (parent && parent.childEnv) || app.env;
|
|
@@ -2499,7 +2482,7 @@ class ComponentNode {
|
|
|
2499
2482
|
}
|
|
2500
2483
|
async render(deep = false) {
|
|
2501
2484
|
let current = this.fiber;
|
|
2502
|
-
if (current && current.root.locked) {
|
|
2485
|
+
if (current && (current.root.locked || current.bdom === true)) {
|
|
2503
2486
|
await Promise.resolve();
|
|
2504
2487
|
// situation may have changed after the microtask tick
|
|
2505
2488
|
current = this.fiber;
|
|
@@ -2558,8 +2541,15 @@ class ComponentNode {
|
|
|
2558
2541
|
for (let child of Object.values(this.children)) {
|
|
2559
2542
|
child._destroy();
|
|
2560
2543
|
}
|
|
2561
|
-
|
|
2562
|
-
|
|
2544
|
+
if (this.willDestroy.length) {
|
|
2545
|
+
try {
|
|
2546
|
+
for (let cb of this.willDestroy) {
|
|
2547
|
+
cb.call(component);
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
catch (e) {
|
|
2551
|
+
handleError({ error: e, node: this });
|
|
2552
|
+
}
|
|
2563
2553
|
}
|
|
2564
2554
|
this.status = 2 /* DESTROYED */;
|
|
2565
2555
|
}
|
|
@@ -2625,6 +2615,7 @@ class ComponentNode {
|
|
|
2625
2615
|
bdom.mount(parent, anchor);
|
|
2626
2616
|
this.status = 1 /* MOUNTED */;
|
|
2627
2617
|
this.fiber.appliedToDom = true;
|
|
2618
|
+
this.children = this.fiber.childrenMap;
|
|
2628
2619
|
this.fiber = null;
|
|
2629
2620
|
}
|
|
2630
2621
|
moveBefore(other, afterNode) {
|
|
@@ -2640,10 +2631,8 @@ class ComponentNode {
|
|
|
2640
2631
|
}
|
|
2641
2632
|
_patch() {
|
|
2642
2633
|
const hasChildren = Object.keys(this.children).length > 0;
|
|
2634
|
+
this.children = this.fiber.childrenMap;
|
|
2643
2635
|
this.bdom.patch(this.fiber.bdom, hasChildren);
|
|
2644
|
-
if (hasChildren) {
|
|
2645
|
-
this.cleanOutdatedChildren();
|
|
2646
|
-
}
|
|
2647
2636
|
this.fiber.appliedToDom = true;
|
|
2648
2637
|
this.fiber = null;
|
|
2649
2638
|
}
|
|
@@ -2653,19 +2642,6 @@ class ComponentNode {
|
|
|
2653
2642
|
remove() {
|
|
2654
2643
|
this.bdom.remove();
|
|
2655
2644
|
}
|
|
2656
|
-
cleanOutdatedChildren() {
|
|
2657
|
-
const children = this.children;
|
|
2658
|
-
for (const key in children) {
|
|
2659
|
-
const node = children[key];
|
|
2660
|
-
const status = node.status;
|
|
2661
|
-
if (status !== 1 /* MOUNTED */) {
|
|
2662
|
-
delete children[key];
|
|
2663
|
-
if (status !== 2 /* DESTROYED */) {
|
|
2664
|
-
node.destroy();
|
|
2665
|
-
}
|
|
2666
|
-
}
|
|
2667
|
-
}
|
|
2668
|
-
}
|
|
2669
2645
|
// ---------------------------------------------------------------------------
|
|
2670
2646
|
// Some debug helpers
|
|
2671
2647
|
// ---------------------------------------------------------------------------
|
|
@@ -2685,7 +2661,7 @@ class Scheduler {
|
|
|
2685
2661
|
constructor() {
|
|
2686
2662
|
this.tasks = new Set();
|
|
2687
2663
|
this.frame = 0;
|
|
2688
|
-
this.
|
|
2664
|
+
this.delayedRenders = [];
|
|
2689
2665
|
this.requestAnimationFrame = Scheduler.requestAnimationFrame;
|
|
2690
2666
|
}
|
|
2691
2667
|
addFiber(fiber) {
|
|
@@ -2696,16 +2672,22 @@ class Scheduler {
|
|
|
2696
2672
|
* Other tasks are left unchanged.
|
|
2697
2673
|
*/
|
|
2698
2674
|
flush() {
|
|
2675
|
+
if (this.delayedRenders.length) {
|
|
2676
|
+
let renders = this.delayedRenders;
|
|
2677
|
+
this.delayedRenders = [];
|
|
2678
|
+
for (let f of renders) {
|
|
2679
|
+
if (f.root && f.node.status !== 2 /* DESTROYED */) {
|
|
2680
|
+
f.render();
|
|
2681
|
+
}
|
|
2682
|
+
}
|
|
2683
|
+
}
|
|
2699
2684
|
if (this.frame === 0) {
|
|
2700
2685
|
this.frame = this.requestAnimationFrame(() => {
|
|
2701
2686
|
this.frame = 0;
|
|
2702
2687
|
this.tasks.forEach((fiber) => this.processFiber(fiber));
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
if (task.node.status === 2 /* DESTROYED */) {
|
|
2707
|
-
this.tasks.delete(task);
|
|
2708
|
-
}
|
|
2688
|
+
for (let task of this.tasks) {
|
|
2689
|
+
if (task.node.status === 2 /* DESTROYED */) {
|
|
2690
|
+
this.tasks.delete(task);
|
|
2709
2691
|
}
|
|
2710
2692
|
}
|
|
2711
2693
|
});
|
|
@@ -4019,8 +4001,11 @@ class CodeGenerator {
|
|
|
4019
4001
|
let slotStr = [];
|
|
4020
4002
|
for (let slotName in ast.slots) {
|
|
4021
4003
|
const slotAst = ast.slots[slotName];
|
|
4022
|
-
const
|
|
4023
|
-
|
|
4004
|
+
const params = [];
|
|
4005
|
+
if (slotAst.content) {
|
|
4006
|
+
const name = this.compileInNewTarget("slot", slotAst.content, ctx, slotAst.on);
|
|
4007
|
+
params.push(`__render: ${name}, __ctx: ${ctxStr}`);
|
|
4008
|
+
}
|
|
4024
4009
|
const scope = ast.slots[slotName].scope;
|
|
4025
4010
|
if (scope) {
|
|
4026
4011
|
params.push(`__scope: "${scope}"`);
|
|
@@ -4122,7 +4107,7 @@ class CodeGenerator {
|
|
|
4122
4107
|
if (dynamic) {
|
|
4123
4108
|
let name = this.generateId("slot");
|
|
4124
4109
|
this.define(name, slotName);
|
|
4125
|
-
blockString = `toggler(${name}, callSlot(ctx, node, key, ${name}
|
|
4110
|
+
blockString = `toggler(${name}, callSlot(ctx, node, key, ${name}, ${dynamic}, ${scope}))`;
|
|
4126
4111
|
}
|
|
4127
4112
|
else {
|
|
4128
4113
|
blockString = `callSlot(ctx, node, key, ${slotName}, ${dynamic}, ${scope})`;
|
|
@@ -4663,28 +4648,26 @@ function parseComponent(node, ctx) {
|
|
|
4663
4648
|
slotNode.removeAttribute("t-set-slot");
|
|
4664
4649
|
slotNode.remove();
|
|
4665
4650
|
const slotAst = parseNode(slotNode, ctx);
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
attrs[attributeName] = value;
|
|
4683
|
-
}
|
|
4651
|
+
let on = null;
|
|
4652
|
+
let attrs = null;
|
|
4653
|
+
let scope = null;
|
|
4654
|
+
for (let attributeName of slotNode.getAttributeNames()) {
|
|
4655
|
+
const value = slotNode.getAttribute(attributeName);
|
|
4656
|
+
if (attributeName === "t-slot-scope") {
|
|
4657
|
+
scope = value;
|
|
4658
|
+
continue;
|
|
4659
|
+
}
|
|
4660
|
+
else if (attributeName.startsWith("t-on-")) {
|
|
4661
|
+
on = on || {};
|
|
4662
|
+
on[attributeName.slice(5)] = value;
|
|
4663
|
+
}
|
|
4664
|
+
else {
|
|
4665
|
+
attrs = attrs || {};
|
|
4666
|
+
attrs[attributeName] = value;
|
|
4684
4667
|
}
|
|
4685
|
-
slots = slots || {};
|
|
4686
|
-
slots[name] = { content: slotAst, on, attrs, scope };
|
|
4687
4668
|
}
|
|
4669
|
+
slots = slots || {};
|
|
4670
|
+
slots[name] = { content: slotAst, on, attrs, scope };
|
|
4688
4671
|
}
|
|
4689
4672
|
// default slot
|
|
4690
4673
|
const defaultContent = parseChildNodes(clone, ctx);
|
|
@@ -5412,7 +5395,7 @@ class App extends TemplateSet {
|
|
|
5412
5395
|
return prom;
|
|
5413
5396
|
}
|
|
5414
5397
|
makeNode(Component, props) {
|
|
5415
|
-
return new ComponentNode(Component, props, this);
|
|
5398
|
+
return new ComponentNode(Component, props, this, null, null);
|
|
5416
5399
|
}
|
|
5417
5400
|
mountNode(node, target, options) {
|
|
5418
5401
|
const promise = new Promise((resolve, reject) => {
|
|
@@ -5618,7 +5601,7 @@ exports.whenReady = whenReady;
|
|
|
5618
5601
|
exports.xml = xml;
|
|
5619
5602
|
|
|
5620
5603
|
|
|
5621
|
-
__info__.version = '2.0.0-beta-
|
|
5622
|
-
__info__.date = '2022-
|
|
5623
|
-
__info__.hash = '
|
|
5604
|
+
__info__.version = '2.0.0-beta-5';
|
|
5605
|
+
__info__.date = '2022-04-07T13:36:37.300Z';
|
|
5606
|
+
__info__.hash = '1179e84';
|
|
5624
5607
|
__info__.url = 'https://github.com/odoo/owl';
|