@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.es.js
CHANGED
|
@@ -1912,7 +1912,7 @@ xml.nextId = 1;
|
|
|
1912
1912
|
// Maps fibers to thrown errors
|
|
1913
1913
|
const fibersInError = new WeakMap();
|
|
1914
1914
|
const nodeErrorHandlers = new WeakMap();
|
|
1915
|
-
function _handleError(node, error
|
|
1915
|
+
function _handleError(node, error) {
|
|
1916
1916
|
if (!node) {
|
|
1917
1917
|
return false;
|
|
1918
1918
|
}
|
|
@@ -1922,23 +1922,19 @@ function _handleError(node, error, isFirstRound = false) {
|
|
|
1922
1922
|
}
|
|
1923
1923
|
const errorHandlers = nodeErrorHandlers.get(node);
|
|
1924
1924
|
if (errorHandlers) {
|
|
1925
|
-
let
|
|
1925
|
+
let handled = false;
|
|
1926
1926
|
// execute in the opposite order
|
|
1927
1927
|
for (let i = errorHandlers.length - 1; i >= 0; i--) {
|
|
1928
1928
|
try {
|
|
1929
1929
|
errorHandlers[i](error);
|
|
1930
|
-
|
|
1930
|
+
handled = true;
|
|
1931
1931
|
break;
|
|
1932
1932
|
}
|
|
1933
1933
|
catch (e) {
|
|
1934
1934
|
error = e;
|
|
1935
1935
|
}
|
|
1936
1936
|
}
|
|
1937
|
-
if (
|
|
1938
|
-
if (isFirstRound && fiber && fiber.node.fiber) {
|
|
1939
|
-
const root = fiber.root;
|
|
1940
|
-
root.setCounter(root.counter - 1);
|
|
1941
|
-
}
|
|
1937
|
+
if (handled) {
|
|
1942
1938
|
return true;
|
|
1943
1939
|
}
|
|
1944
1940
|
}
|
|
@@ -1956,7 +1952,7 @@ function handleError(params) {
|
|
|
1956
1952
|
current = current.parent;
|
|
1957
1953
|
} while (current);
|
|
1958
1954
|
fibersInError.set(fiber.root, error);
|
|
1959
|
-
const handled = _handleError(node, error
|
|
1955
|
+
const handled = _handleError(node, error);
|
|
1960
1956
|
if (!handled) {
|
|
1961
1957
|
console.warn(`[Owl] Unhandled error. Destroying the root component`);
|
|
1962
1958
|
try {
|
|
@@ -1973,10 +1969,6 @@ function makeChildFiber(node, parent) {
|
|
|
1973
1969
|
if (current) {
|
|
1974
1970
|
cancelFibers(current.children);
|
|
1975
1971
|
current.root = null;
|
|
1976
|
-
if (current instanceof RootFiber && current.delayedRenders.length) {
|
|
1977
|
-
let root = parent.root;
|
|
1978
|
-
root.delayedRenders = root.delayedRenders.concat(current.delayedRenders);
|
|
1979
|
-
}
|
|
1980
1972
|
}
|
|
1981
1973
|
return new Fiber(node, parent);
|
|
1982
1974
|
}
|
|
@@ -1984,12 +1976,15 @@ function makeRootFiber(node) {
|
|
|
1984
1976
|
let current = node.fiber;
|
|
1985
1977
|
if (current) {
|
|
1986
1978
|
let root = current.root;
|
|
1979
|
+
// lock root fiber because canceling children fibers may destroy components,
|
|
1980
|
+
// which means any arbitrary code can be run in onWillDestroy, which may
|
|
1981
|
+
// trigger new renderings
|
|
1982
|
+
root.locked = true;
|
|
1987
1983
|
root.setCounter(root.counter + 1 - cancelFibers(current.children));
|
|
1984
|
+
root.locked = false;
|
|
1988
1985
|
current.children = [];
|
|
1986
|
+
current.childrenMap = {};
|
|
1989
1987
|
current.bdom = null;
|
|
1990
|
-
if (current === root) {
|
|
1991
|
-
root.reachedChildren = new WeakSet();
|
|
1992
|
-
}
|
|
1993
1988
|
if (fibersInError.has(current)) {
|
|
1994
1989
|
fibersInError.delete(current);
|
|
1995
1990
|
fibersInError.delete(root);
|
|
@@ -2012,7 +2007,11 @@ function makeRootFiber(node) {
|
|
|
2012
2007
|
function cancelFibers(fibers) {
|
|
2013
2008
|
let result = 0;
|
|
2014
2009
|
for (let fiber of fibers) {
|
|
2015
|
-
|
|
2010
|
+
let node = fiber.node;
|
|
2011
|
+
if (node.status === 0 /* NEW */) {
|
|
2012
|
+
node.destroy();
|
|
2013
|
+
}
|
|
2014
|
+
node.fiber = null;
|
|
2016
2015
|
if (fiber.bdom) {
|
|
2017
2016
|
// if fiber has been rendered, this means that the component props have
|
|
2018
2017
|
// been updated. however, this fiber will not be patched to the dom, so
|
|
@@ -2020,7 +2019,7 @@ function cancelFibers(fibers) {
|
|
|
2020
2019
|
// the same props, and skip the render completely. With the next line,
|
|
2021
2020
|
// we kindly request the component code to force a render, so it works as
|
|
2022
2021
|
// expected.
|
|
2023
|
-
|
|
2022
|
+
node.forceNextRender = true;
|
|
2024
2023
|
}
|
|
2025
2024
|
else {
|
|
2026
2025
|
result++;
|
|
@@ -2035,6 +2034,7 @@ class Fiber {
|
|
|
2035
2034
|
this.children = [];
|
|
2036
2035
|
this.appliedToDom = false;
|
|
2037
2036
|
this.deep = false;
|
|
2037
|
+
this.childrenMap = {};
|
|
2038
2038
|
this.node = node;
|
|
2039
2039
|
this.parent = parent;
|
|
2040
2040
|
if (parent) {
|
|
@@ -2051,21 +2051,17 @@ class Fiber {
|
|
|
2051
2051
|
render() {
|
|
2052
2052
|
// if some parent has a fiber => register in followup
|
|
2053
2053
|
let prev = this.root.node;
|
|
2054
|
+
let scheduler = prev.app.scheduler;
|
|
2054
2055
|
let current = prev.parent;
|
|
2055
2056
|
while (current) {
|
|
2056
2057
|
if (current.fiber) {
|
|
2057
2058
|
let root = current.fiber.root;
|
|
2058
|
-
if (root.counter) {
|
|
2059
|
-
root.
|
|
2060
|
-
return;
|
|
2059
|
+
if (root.counter === 0 && prev.parentKey in current.fiber.childrenMap) {
|
|
2060
|
+
current = root.node;
|
|
2061
2061
|
}
|
|
2062
2062
|
else {
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
this.node.app.scheduler.shouldClear = true;
|
|
2066
|
-
return;
|
|
2067
|
-
}
|
|
2068
|
-
current = root.node;
|
|
2063
|
+
scheduler.delayedRenders.push(this);
|
|
2064
|
+
return;
|
|
2069
2065
|
}
|
|
2070
2066
|
}
|
|
2071
2067
|
prev = current;
|
|
@@ -2079,12 +2075,13 @@ class Fiber {
|
|
|
2079
2075
|
const root = this.root;
|
|
2080
2076
|
if (root) {
|
|
2081
2077
|
try {
|
|
2078
|
+
this.bdom = true;
|
|
2082
2079
|
this.bdom = node.renderFn();
|
|
2083
|
-
root.setCounter(root.counter - 1);
|
|
2084
2080
|
}
|
|
2085
2081
|
catch (e) {
|
|
2086
2082
|
handleError({ node, error: e });
|
|
2087
2083
|
}
|
|
2084
|
+
root.setCounter(root.counter - 1);
|
|
2088
2085
|
}
|
|
2089
2086
|
}
|
|
2090
2087
|
}
|
|
@@ -2099,8 +2096,6 @@ class RootFiber extends Fiber {
|
|
|
2099
2096
|
// A fiber is typically locked when it is completing and the patch has not, or is being applied.
|
|
2100
2097
|
// i.e.: render triggered in onWillUnmount or in willPatch will be delayed
|
|
2101
2098
|
this.locked = false;
|
|
2102
|
-
this.delayedRenders = [];
|
|
2103
|
-
this.reachedChildren = new WeakSet();
|
|
2104
2099
|
}
|
|
2105
2100
|
complete() {
|
|
2106
2101
|
const node = this.node;
|
|
@@ -2153,14 +2148,6 @@ class RootFiber extends Fiber {
|
|
|
2153
2148
|
setCounter(newValue) {
|
|
2154
2149
|
this.counter = newValue;
|
|
2155
2150
|
if (newValue === 0) {
|
|
2156
|
-
if (this.delayedRenders.length) {
|
|
2157
|
-
for (let f of this.delayedRenders) {
|
|
2158
|
-
if (f.root) {
|
|
2159
|
-
f.render();
|
|
2160
|
-
}
|
|
2161
|
-
}
|
|
2162
|
-
this.delayedRenders = [];
|
|
2163
|
-
}
|
|
2164
2151
|
this.node.app.scheduler.flush();
|
|
2165
2152
|
}
|
|
2166
2153
|
}
|
|
@@ -2175,6 +2162,7 @@ class MountFiber extends RootFiber {
|
|
|
2175
2162
|
let current = this;
|
|
2176
2163
|
try {
|
|
2177
2164
|
const node = this.node;
|
|
2165
|
+
node.children = this.childrenMap;
|
|
2178
2166
|
node.app.constructor.validateTarget(this.target);
|
|
2179
2167
|
if (node.bdom) {
|
|
2180
2168
|
// this is a complicated situation: if we mount a fiber with an existing
|
|
@@ -2398,14 +2386,8 @@ function arePropsDifferent(props1, props2) {
|
|
|
2398
2386
|
function component(name, props, key, ctx, parent) {
|
|
2399
2387
|
let node = ctx.children[key];
|
|
2400
2388
|
let isDynamic = typeof name !== "string";
|
|
2401
|
-
if (node) {
|
|
2402
|
-
|
|
2403
|
-
node.destroy();
|
|
2404
|
-
node = undefined;
|
|
2405
|
-
}
|
|
2406
|
-
else if (node.status === 2 /* DESTROYED */) {
|
|
2407
|
-
node = undefined;
|
|
2408
|
-
}
|
|
2389
|
+
if (node && node.status === 2 /* DESTROYED */) {
|
|
2390
|
+
node = undefined;
|
|
2409
2391
|
}
|
|
2410
2392
|
if (isDynamic && node && node.component.constructor !== name) {
|
|
2411
2393
|
node = undefined;
|
|
@@ -2436,15 +2418,15 @@ function component(name, props, key, ctx, parent) {
|
|
|
2436
2418
|
throw new Error(`Cannot find the definition of component "${name}"`);
|
|
2437
2419
|
}
|
|
2438
2420
|
}
|
|
2439
|
-
node = new ComponentNode(C, props, ctx.app, ctx);
|
|
2421
|
+
node = new ComponentNode(C, props, ctx.app, ctx, key);
|
|
2440
2422
|
ctx.children[key] = node;
|
|
2441
2423
|
node.initiateRender(new Fiber(node, parentFiber));
|
|
2442
2424
|
}
|
|
2443
|
-
parentFiber.
|
|
2425
|
+
parentFiber.childrenMap[key] = node;
|
|
2444
2426
|
return node;
|
|
2445
2427
|
}
|
|
2446
2428
|
class ComponentNode {
|
|
2447
|
-
constructor(C, props, app, parent) {
|
|
2429
|
+
constructor(C, props, app, parent, parentKey) {
|
|
2448
2430
|
this.fiber = null;
|
|
2449
2431
|
this.bdom = null;
|
|
2450
2432
|
this.status = 0 /* NEW */;
|
|
@@ -2460,7 +2442,8 @@ class ComponentNode {
|
|
|
2460
2442
|
this.willDestroy = [];
|
|
2461
2443
|
currentNode = this;
|
|
2462
2444
|
this.app = app;
|
|
2463
|
-
this.parent = parent
|
|
2445
|
+
this.parent = parent;
|
|
2446
|
+
this.parentKey = parentKey;
|
|
2464
2447
|
this.level = parent ? parent.level + 1 : 0;
|
|
2465
2448
|
applyDefaultProps(props, C);
|
|
2466
2449
|
const env = (parent && parent.childEnv) || app.env;
|
|
@@ -2495,7 +2478,7 @@ class ComponentNode {
|
|
|
2495
2478
|
}
|
|
2496
2479
|
async render(deep = false) {
|
|
2497
2480
|
let current = this.fiber;
|
|
2498
|
-
if (current && current.root.locked) {
|
|
2481
|
+
if (current && (current.root.locked || current.bdom === true)) {
|
|
2499
2482
|
await Promise.resolve();
|
|
2500
2483
|
// situation may have changed after the microtask tick
|
|
2501
2484
|
current = this.fiber;
|
|
@@ -2554,8 +2537,15 @@ class ComponentNode {
|
|
|
2554
2537
|
for (let child of Object.values(this.children)) {
|
|
2555
2538
|
child._destroy();
|
|
2556
2539
|
}
|
|
2557
|
-
|
|
2558
|
-
|
|
2540
|
+
if (this.willDestroy.length) {
|
|
2541
|
+
try {
|
|
2542
|
+
for (let cb of this.willDestroy) {
|
|
2543
|
+
cb.call(component);
|
|
2544
|
+
}
|
|
2545
|
+
}
|
|
2546
|
+
catch (e) {
|
|
2547
|
+
handleError({ error: e, node: this });
|
|
2548
|
+
}
|
|
2559
2549
|
}
|
|
2560
2550
|
this.status = 2 /* DESTROYED */;
|
|
2561
2551
|
}
|
|
@@ -2621,6 +2611,7 @@ class ComponentNode {
|
|
|
2621
2611
|
bdom.mount(parent, anchor);
|
|
2622
2612
|
this.status = 1 /* MOUNTED */;
|
|
2623
2613
|
this.fiber.appliedToDom = true;
|
|
2614
|
+
this.children = this.fiber.childrenMap;
|
|
2624
2615
|
this.fiber = null;
|
|
2625
2616
|
}
|
|
2626
2617
|
moveBefore(other, afterNode) {
|
|
@@ -2636,10 +2627,8 @@ class ComponentNode {
|
|
|
2636
2627
|
}
|
|
2637
2628
|
_patch() {
|
|
2638
2629
|
const hasChildren = Object.keys(this.children).length > 0;
|
|
2630
|
+
this.children = this.fiber.childrenMap;
|
|
2639
2631
|
this.bdom.patch(this.fiber.bdom, hasChildren);
|
|
2640
|
-
if (hasChildren) {
|
|
2641
|
-
this.cleanOutdatedChildren();
|
|
2642
|
-
}
|
|
2643
2632
|
this.fiber.appliedToDom = true;
|
|
2644
2633
|
this.fiber = null;
|
|
2645
2634
|
}
|
|
@@ -2649,19 +2638,6 @@ class ComponentNode {
|
|
|
2649
2638
|
remove() {
|
|
2650
2639
|
this.bdom.remove();
|
|
2651
2640
|
}
|
|
2652
|
-
cleanOutdatedChildren() {
|
|
2653
|
-
const children = this.children;
|
|
2654
|
-
for (const key in children) {
|
|
2655
|
-
const node = children[key];
|
|
2656
|
-
const status = node.status;
|
|
2657
|
-
if (status !== 1 /* MOUNTED */) {
|
|
2658
|
-
delete children[key];
|
|
2659
|
-
if (status !== 2 /* DESTROYED */) {
|
|
2660
|
-
node.destroy();
|
|
2661
|
-
}
|
|
2662
|
-
}
|
|
2663
|
-
}
|
|
2664
|
-
}
|
|
2665
2641
|
// ---------------------------------------------------------------------------
|
|
2666
2642
|
// Some debug helpers
|
|
2667
2643
|
// ---------------------------------------------------------------------------
|
|
@@ -2681,7 +2657,7 @@ class Scheduler {
|
|
|
2681
2657
|
constructor() {
|
|
2682
2658
|
this.tasks = new Set();
|
|
2683
2659
|
this.frame = 0;
|
|
2684
|
-
this.
|
|
2660
|
+
this.delayedRenders = [];
|
|
2685
2661
|
this.requestAnimationFrame = Scheduler.requestAnimationFrame;
|
|
2686
2662
|
}
|
|
2687
2663
|
addFiber(fiber) {
|
|
@@ -2692,16 +2668,22 @@ class Scheduler {
|
|
|
2692
2668
|
* Other tasks are left unchanged.
|
|
2693
2669
|
*/
|
|
2694
2670
|
flush() {
|
|
2671
|
+
if (this.delayedRenders.length) {
|
|
2672
|
+
let renders = this.delayedRenders;
|
|
2673
|
+
this.delayedRenders = [];
|
|
2674
|
+
for (let f of renders) {
|
|
2675
|
+
if (f.root && f.node.status !== 2 /* DESTROYED */) {
|
|
2676
|
+
f.render();
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
}
|
|
2695
2680
|
if (this.frame === 0) {
|
|
2696
2681
|
this.frame = this.requestAnimationFrame(() => {
|
|
2697
2682
|
this.frame = 0;
|
|
2698
2683
|
this.tasks.forEach((fiber) => this.processFiber(fiber));
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
if (task.node.status === 2 /* DESTROYED */) {
|
|
2703
|
-
this.tasks.delete(task);
|
|
2704
|
-
}
|
|
2684
|
+
for (let task of this.tasks) {
|
|
2685
|
+
if (task.node.status === 2 /* DESTROYED */) {
|
|
2686
|
+
this.tasks.delete(task);
|
|
2705
2687
|
}
|
|
2706
2688
|
}
|
|
2707
2689
|
});
|
|
@@ -4015,8 +3997,11 @@ class CodeGenerator {
|
|
|
4015
3997
|
let slotStr = [];
|
|
4016
3998
|
for (let slotName in ast.slots) {
|
|
4017
3999
|
const slotAst = ast.slots[slotName];
|
|
4018
|
-
const
|
|
4019
|
-
|
|
4000
|
+
const params = [];
|
|
4001
|
+
if (slotAst.content) {
|
|
4002
|
+
const name = this.compileInNewTarget("slot", slotAst.content, ctx, slotAst.on);
|
|
4003
|
+
params.push(`__render: ${name}, __ctx: ${ctxStr}`);
|
|
4004
|
+
}
|
|
4020
4005
|
const scope = ast.slots[slotName].scope;
|
|
4021
4006
|
if (scope) {
|
|
4022
4007
|
params.push(`__scope: "${scope}"`);
|
|
@@ -4118,7 +4103,7 @@ class CodeGenerator {
|
|
|
4118
4103
|
if (dynamic) {
|
|
4119
4104
|
let name = this.generateId("slot");
|
|
4120
4105
|
this.define(name, slotName);
|
|
4121
|
-
blockString = `toggler(${name}, callSlot(ctx, node, key, ${name}
|
|
4106
|
+
blockString = `toggler(${name}, callSlot(ctx, node, key, ${name}, ${dynamic}, ${scope}))`;
|
|
4122
4107
|
}
|
|
4123
4108
|
else {
|
|
4124
4109
|
blockString = `callSlot(ctx, node, key, ${slotName}, ${dynamic}, ${scope})`;
|
|
@@ -4659,28 +4644,26 @@ function parseComponent(node, ctx) {
|
|
|
4659
4644
|
slotNode.removeAttribute("t-set-slot");
|
|
4660
4645
|
slotNode.remove();
|
|
4661
4646
|
const slotAst = parseNode(slotNode, ctx);
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
attrs[attributeName] = value;
|
|
4679
|
-
}
|
|
4647
|
+
let on = null;
|
|
4648
|
+
let attrs = null;
|
|
4649
|
+
let scope = null;
|
|
4650
|
+
for (let attributeName of slotNode.getAttributeNames()) {
|
|
4651
|
+
const value = slotNode.getAttribute(attributeName);
|
|
4652
|
+
if (attributeName === "t-slot-scope") {
|
|
4653
|
+
scope = value;
|
|
4654
|
+
continue;
|
|
4655
|
+
}
|
|
4656
|
+
else if (attributeName.startsWith("t-on-")) {
|
|
4657
|
+
on = on || {};
|
|
4658
|
+
on[attributeName.slice(5)] = value;
|
|
4659
|
+
}
|
|
4660
|
+
else {
|
|
4661
|
+
attrs = attrs || {};
|
|
4662
|
+
attrs[attributeName] = value;
|
|
4680
4663
|
}
|
|
4681
|
-
slots = slots || {};
|
|
4682
|
-
slots[name] = { content: slotAst, on, attrs, scope };
|
|
4683
4664
|
}
|
|
4665
|
+
slots = slots || {};
|
|
4666
|
+
slots[name] = { content: slotAst, on, attrs, scope };
|
|
4684
4667
|
}
|
|
4685
4668
|
// default slot
|
|
4686
4669
|
const defaultContent = parseChildNodes(clone, ctx);
|
|
@@ -5408,7 +5391,7 @@ class App extends TemplateSet {
|
|
|
5408
5391
|
return prom;
|
|
5409
5392
|
}
|
|
5410
5393
|
makeNode(Component, props) {
|
|
5411
|
-
return new ComponentNode(Component, props, this);
|
|
5394
|
+
return new ComponentNode(Component, props, this, null, null);
|
|
5412
5395
|
}
|
|
5413
5396
|
mountNode(node, target, options) {
|
|
5414
5397
|
const promise = new Promise((resolve, reject) => {
|
|
@@ -5583,7 +5566,7 @@ const __info__ = {};
|
|
|
5583
5566
|
export { App, Component, EventBus, __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, whenReady, xml };
|
|
5584
5567
|
|
|
5585
5568
|
|
|
5586
|
-
__info__.version = '2.0.0-beta-
|
|
5587
|
-
__info__.date = '2022-
|
|
5588
|
-
__info__.hash = '
|
|
5569
|
+
__info__.version = '2.0.0-beta-5';
|
|
5570
|
+
__info__.date = '2022-04-07T13:36:37.300Z';
|
|
5571
|
+
__info__.hash = '1179e84';
|
|
5589
5572
|
__info__.url = 'https://github.com/odoo/owl';
|