@odoo/owl 2.0.0-alpha.2 → 2.0.0-alpha.3
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 +350 -270
- package/dist/owl.cjs.min.js +1 -1
- package/dist/owl.es.js +350 -270
- package/dist/owl.es.min.js +1 -1
- package/dist/owl.iife.js +350 -270
- package/dist/owl.iife.min.js +1 -1
- package/dist/types/app/app.d.ts +3 -3
- package/dist/types/component/component.d.ts +1 -1
- package/dist/types/component/component_node.d.ts +16 -3
- package/dist/types/component/fibers.d.ts +1 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/reactivity.d.ts +8 -13
- package/package.json +1 -1
package/dist/owl.cjs.js
CHANGED
|
@@ -213,7 +213,7 @@ function updateClass(val, oldVal) {
|
|
|
213
213
|
}
|
|
214
214
|
function makePropSetter(name) {
|
|
215
215
|
return function setProp(value) {
|
|
216
|
-
this[name] = value;
|
|
216
|
+
this[name] = value || "";
|
|
217
217
|
};
|
|
218
218
|
}
|
|
219
219
|
function isProp(tag, key) {
|
|
@@ -1502,6 +1502,210 @@ function markup(value) {
|
|
|
1502
1502
|
return new Markup(value);
|
|
1503
1503
|
}
|
|
1504
1504
|
|
|
1505
|
+
// Allows to get the target of a Reactive (used for making a new Reactive from the underlying object)
|
|
1506
|
+
const TARGET = Symbol("Target");
|
|
1507
|
+
// Escape hatch to prevent reactivity system to turn something into a reactive
|
|
1508
|
+
const SKIP = Symbol("Skip");
|
|
1509
|
+
// Special key to subscribe to, to be notified of key creation/deletion
|
|
1510
|
+
const KEYCHANGES = Symbol("Key changes");
|
|
1511
|
+
const objectToString = Object.prototype.toString;
|
|
1512
|
+
/**
|
|
1513
|
+
* Checks whether a given value can be made into a reactive object.
|
|
1514
|
+
*
|
|
1515
|
+
* @param value the value to check
|
|
1516
|
+
* @returns whether the value can be made reactive
|
|
1517
|
+
*/
|
|
1518
|
+
function canBeMadeReactive(value) {
|
|
1519
|
+
if (typeof value !== "object") {
|
|
1520
|
+
return false;
|
|
1521
|
+
}
|
|
1522
|
+
// extract "RawType" from strings like "[object RawType]" => this lets us
|
|
1523
|
+
// ignore many native objects such as Promise (whose toString is [object Promise])
|
|
1524
|
+
// or Date ([object Date]).
|
|
1525
|
+
const rawType = objectToString.call(value).slice(8, -1);
|
|
1526
|
+
return rawType === "Object" || rawType === "Array";
|
|
1527
|
+
}
|
|
1528
|
+
/**
|
|
1529
|
+
* Mark an object or array so that it is ignored by the reactivity system
|
|
1530
|
+
*
|
|
1531
|
+
* @param value the value to mark
|
|
1532
|
+
* @returns the object itself
|
|
1533
|
+
*/
|
|
1534
|
+
function markRaw(value) {
|
|
1535
|
+
value[SKIP] = true;
|
|
1536
|
+
return value;
|
|
1537
|
+
}
|
|
1538
|
+
/**
|
|
1539
|
+
* Given a reactive objet, return the raw (non reactive) underlying object
|
|
1540
|
+
*
|
|
1541
|
+
* @param value a reactive value
|
|
1542
|
+
* @returns the underlying value
|
|
1543
|
+
*/
|
|
1544
|
+
function toRaw(value) {
|
|
1545
|
+
return value[TARGET] || value;
|
|
1546
|
+
}
|
|
1547
|
+
const targetToKeysToCallbacks = new WeakMap();
|
|
1548
|
+
/**
|
|
1549
|
+
* Observes a given key on a target with an callback. The callback will be
|
|
1550
|
+
* called when the given key changes on the target.
|
|
1551
|
+
*
|
|
1552
|
+
* @param target the target whose key should be observed
|
|
1553
|
+
* @param key the key to observe (or Symbol(KEYCHANGES) for key creation
|
|
1554
|
+
* or deletion)
|
|
1555
|
+
* @param callback the function to call when the key changes
|
|
1556
|
+
*/
|
|
1557
|
+
function observeTargetKey(target, key, callback) {
|
|
1558
|
+
if (!targetToKeysToCallbacks.get(target)) {
|
|
1559
|
+
targetToKeysToCallbacks.set(target, new Map());
|
|
1560
|
+
}
|
|
1561
|
+
const keyToCallbacks = targetToKeysToCallbacks.get(target);
|
|
1562
|
+
if (!keyToCallbacks.get(key)) {
|
|
1563
|
+
keyToCallbacks.set(key, new Set());
|
|
1564
|
+
}
|
|
1565
|
+
keyToCallbacks.get(key).add(callback);
|
|
1566
|
+
if (!callbacksToTargets.has(callback)) {
|
|
1567
|
+
callbacksToTargets.set(callback, new Set());
|
|
1568
|
+
}
|
|
1569
|
+
callbacksToTargets.get(callback).add(target);
|
|
1570
|
+
}
|
|
1571
|
+
/**
|
|
1572
|
+
* Notify Reactives that are observing a given target that a key has changed on
|
|
1573
|
+
* the target.
|
|
1574
|
+
*
|
|
1575
|
+
* @param target target whose Reactives should be notified that the target was
|
|
1576
|
+
* changed.
|
|
1577
|
+
* @param key the key that changed (or Symbol `KEYCHANGES` if a key was created
|
|
1578
|
+
* or deleted)
|
|
1579
|
+
*/
|
|
1580
|
+
function notifyReactives(target, key) {
|
|
1581
|
+
const keyToCallbacks = targetToKeysToCallbacks.get(target);
|
|
1582
|
+
if (!keyToCallbacks) {
|
|
1583
|
+
return;
|
|
1584
|
+
}
|
|
1585
|
+
const callbacks = keyToCallbacks.get(key);
|
|
1586
|
+
if (!callbacks) {
|
|
1587
|
+
return;
|
|
1588
|
+
}
|
|
1589
|
+
// Loop on copy because clearReactivesForCallback will modify the set in place
|
|
1590
|
+
for (const callback of [...callbacks]) {
|
|
1591
|
+
clearReactivesForCallback(callback);
|
|
1592
|
+
callback();
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
const callbacksToTargets = new WeakMap();
|
|
1596
|
+
/**
|
|
1597
|
+
* Clears all subscriptions of the Reactives associated with a given callback.
|
|
1598
|
+
*
|
|
1599
|
+
* @param callback the callback for which the reactives need to be cleared
|
|
1600
|
+
*/
|
|
1601
|
+
function clearReactivesForCallback(callback) {
|
|
1602
|
+
const targetsToClear = callbacksToTargets.get(callback);
|
|
1603
|
+
if (!targetsToClear) {
|
|
1604
|
+
return;
|
|
1605
|
+
}
|
|
1606
|
+
for (const target of targetsToClear) {
|
|
1607
|
+
const observedKeys = targetToKeysToCallbacks.get(target);
|
|
1608
|
+
if (!observedKeys) {
|
|
1609
|
+
continue;
|
|
1610
|
+
}
|
|
1611
|
+
for (const callbacks of observedKeys.values()) {
|
|
1612
|
+
callbacks.delete(callback);
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1615
|
+
targetsToClear.clear();
|
|
1616
|
+
}
|
|
1617
|
+
const reactiveCache = new WeakMap();
|
|
1618
|
+
/**
|
|
1619
|
+
* Creates a reactive proxy for an object. Reading data on the reactive object
|
|
1620
|
+
* subscribes to changes to the data. Writing data on the object will cause the
|
|
1621
|
+
* notify callback to be called if there are suscriptions to that data. Nested
|
|
1622
|
+
* objects and arrays are automatically made reactive as well.
|
|
1623
|
+
*
|
|
1624
|
+
* Whenever you are notified of a change, all subscriptions are cleared, and if
|
|
1625
|
+
* you would like to be notified of any further changes, you should go read
|
|
1626
|
+
* the underlying data again. We assume that if you don't go read it again after
|
|
1627
|
+
* being notified, it means that you are no longer interested in that data.
|
|
1628
|
+
*
|
|
1629
|
+
* Subscriptions:
|
|
1630
|
+
* + Reading a property on an object will subscribe you to changes in the value
|
|
1631
|
+
* of that property.
|
|
1632
|
+
* + Accessing an object keys (eg with Object.keys or with `for..in`) will
|
|
1633
|
+
* subscribe you to the creation/deletion of keys. Checking the presence of a
|
|
1634
|
+
* key on the object with 'in' has the same effect.
|
|
1635
|
+
* - getOwnPropertyDescriptor does not currently subscribe you to the property.
|
|
1636
|
+
* This is a choice that was made because changing a key's value will trigger
|
|
1637
|
+
* this trap and we do not want to subscribe by writes. This also means that
|
|
1638
|
+
* Object.hasOwnProperty doesn't subscribe as it goes through this trap.
|
|
1639
|
+
*
|
|
1640
|
+
* @param target the object for which to create a reactive proxy
|
|
1641
|
+
* @param callback the function to call when an observed property of the
|
|
1642
|
+
* reactive has changed
|
|
1643
|
+
* @returns a proxy that tracks changes to it
|
|
1644
|
+
*/
|
|
1645
|
+
function reactive(target, callback = () => { }) {
|
|
1646
|
+
if (!canBeMadeReactive(target)) {
|
|
1647
|
+
throw new Error(`Cannot make the given value reactive`);
|
|
1648
|
+
}
|
|
1649
|
+
if (SKIP in target) {
|
|
1650
|
+
return target;
|
|
1651
|
+
}
|
|
1652
|
+
const originalTarget = target[TARGET];
|
|
1653
|
+
if (originalTarget) {
|
|
1654
|
+
return reactive(originalTarget, callback);
|
|
1655
|
+
}
|
|
1656
|
+
if (!reactiveCache.has(target)) {
|
|
1657
|
+
reactiveCache.set(target, new Map());
|
|
1658
|
+
}
|
|
1659
|
+
const reactivesForTarget = reactiveCache.get(target);
|
|
1660
|
+
if (!reactivesForTarget.has(callback)) {
|
|
1661
|
+
const proxy = new Proxy(target, {
|
|
1662
|
+
get(target, key, proxy) {
|
|
1663
|
+
if (key === TARGET) {
|
|
1664
|
+
return target;
|
|
1665
|
+
}
|
|
1666
|
+
observeTargetKey(target, key, callback);
|
|
1667
|
+
const value = Reflect.get(target, key, proxy);
|
|
1668
|
+
if (!canBeMadeReactive(value)) {
|
|
1669
|
+
return value;
|
|
1670
|
+
}
|
|
1671
|
+
return reactive(value, callback);
|
|
1672
|
+
},
|
|
1673
|
+
set(target, key, value, proxy) {
|
|
1674
|
+
const isNewKey = !Object.hasOwnProperty.call(target, key);
|
|
1675
|
+
const originalValue = Reflect.get(target, key, proxy);
|
|
1676
|
+
const ret = Reflect.set(target, key, value, proxy);
|
|
1677
|
+
if (isNewKey) {
|
|
1678
|
+
notifyReactives(target, KEYCHANGES);
|
|
1679
|
+
}
|
|
1680
|
+
// While Array length may trigger the set trap, it's not actually set by this
|
|
1681
|
+
// method but is updated behind the scenes, and the trap is not called with the
|
|
1682
|
+
// new value. We disable the "same-value-optimization" for it because of that.
|
|
1683
|
+
if (originalValue !== value || (Array.isArray(target) && key === "length")) {
|
|
1684
|
+
notifyReactives(target, key);
|
|
1685
|
+
}
|
|
1686
|
+
return ret;
|
|
1687
|
+
},
|
|
1688
|
+
deleteProperty(target, key) {
|
|
1689
|
+
const ret = Reflect.deleteProperty(target, key);
|
|
1690
|
+
notifyReactives(target, KEYCHANGES);
|
|
1691
|
+
notifyReactives(target, key);
|
|
1692
|
+
return ret;
|
|
1693
|
+
},
|
|
1694
|
+
ownKeys(target) {
|
|
1695
|
+
observeTargetKey(target, KEYCHANGES, callback);
|
|
1696
|
+
return Reflect.ownKeys(target);
|
|
1697
|
+
},
|
|
1698
|
+
has(target, key) {
|
|
1699
|
+
// TODO: this observes all key changes instead of only the presence of the argument key
|
|
1700
|
+
observeTargetKey(target, KEYCHANGES, callback);
|
|
1701
|
+
return Reflect.has(target, key);
|
|
1702
|
+
},
|
|
1703
|
+
});
|
|
1704
|
+
reactivesForTarget.set(callback, proxy);
|
|
1705
|
+
}
|
|
1706
|
+
return reactivesForTarget.get(callback);
|
|
1707
|
+
}
|
|
1708
|
+
|
|
1505
1709
|
/**
|
|
1506
1710
|
* This file contains utility functions that will be injected in each template,
|
|
1507
1711
|
* to perform various useful tasks in the compiled code.
|
|
@@ -1511,7 +1715,7 @@ function withDefault(value, defaultValue) {
|
|
|
1511
1715
|
}
|
|
1512
1716
|
function callSlot(ctx, parent, key, name, dynamic, extra, defaultContent) {
|
|
1513
1717
|
key = key + "__slot_" + name;
|
|
1514
|
-
const slots =
|
|
1718
|
+
const slots = ctx.props[TARGET].slots || {};
|
|
1515
1719
|
const { __render, __ctx, __scope } = slots[name] || {};
|
|
1516
1720
|
const slotScope = Object.create(__ctx || {});
|
|
1517
1721
|
if (__scope) {
|
|
@@ -1779,8 +1983,7 @@ function handleError(params) {
|
|
|
1779
1983
|
function makeChildFiber(node, parent) {
|
|
1780
1984
|
let current = node.fiber;
|
|
1781
1985
|
if (current) {
|
|
1782
|
-
|
|
1783
|
-
cancelFibers(root, current.children);
|
|
1986
|
+
cancelFibers(current.children);
|
|
1784
1987
|
current.root = null;
|
|
1785
1988
|
}
|
|
1786
1989
|
return new Fiber(node, parent);
|
|
@@ -1789,9 +1992,8 @@ function makeRootFiber(node) {
|
|
|
1789
1992
|
let current = node.fiber;
|
|
1790
1993
|
if (current) {
|
|
1791
1994
|
let root = current.root;
|
|
1792
|
-
root.counter
|
|
1995
|
+
root.counter = root.counter + 1 - cancelFibers(current.children);
|
|
1793
1996
|
current.children = [];
|
|
1794
|
-
root.counter++;
|
|
1795
1997
|
current.bdom = null;
|
|
1796
1998
|
if (fibersInError.has(current)) {
|
|
1797
1999
|
fibersInError.delete(current);
|
|
@@ -1812,15 +2014,14 @@ function makeRootFiber(node) {
|
|
|
1812
2014
|
/**
|
|
1813
2015
|
* @returns number of not-yet rendered fibers cancelled
|
|
1814
2016
|
*/
|
|
1815
|
-
function cancelFibers(
|
|
2017
|
+
function cancelFibers(fibers) {
|
|
1816
2018
|
let result = 0;
|
|
1817
2019
|
for (let fiber of fibers) {
|
|
1818
2020
|
fiber.node.fiber = null;
|
|
1819
|
-
fiber.root = root;
|
|
1820
2021
|
if (!fiber.bdom) {
|
|
1821
2022
|
result++;
|
|
1822
2023
|
}
|
|
1823
|
-
result += cancelFibers(
|
|
2024
|
+
result += cancelFibers(fiber.children);
|
|
1824
2025
|
}
|
|
1825
2026
|
return result;
|
|
1826
2027
|
}
|
|
@@ -1829,9 +2030,11 @@ class Fiber {
|
|
|
1829
2030
|
this.bdom = null;
|
|
1830
2031
|
this.children = [];
|
|
1831
2032
|
this.appliedToDom = false;
|
|
2033
|
+
this.deep = false;
|
|
1832
2034
|
this.node = node;
|
|
1833
2035
|
this.parent = parent;
|
|
1834
2036
|
if (parent) {
|
|
2037
|
+
this.deep = parent.deep;
|
|
1835
2038
|
const root = parent.root;
|
|
1836
2039
|
root.counter++;
|
|
1837
2040
|
this.root = root;
|
|
@@ -1874,7 +2077,7 @@ class RootFiber extends Fiber {
|
|
|
1874
2077
|
}
|
|
1875
2078
|
current = undefined;
|
|
1876
2079
|
// Step 2: patching the dom
|
|
1877
|
-
node.
|
|
2080
|
+
node._patch();
|
|
1878
2081
|
this.locked = false;
|
|
1879
2082
|
// Step 4: calling all mounted lifecycle hooks
|
|
1880
2083
|
let mountedFibers = this.mounted;
|
|
@@ -1961,6 +2164,39 @@ function getCurrent() {
|
|
|
1961
2164
|
function useComponent() {
|
|
1962
2165
|
return currentNode.component;
|
|
1963
2166
|
}
|
|
2167
|
+
// -----------------------------------------------------------------------------
|
|
2168
|
+
// Integration with reactivity system (useState)
|
|
2169
|
+
// -----------------------------------------------------------------------------
|
|
2170
|
+
const batchedRenderFunctions = new WeakMap();
|
|
2171
|
+
/**
|
|
2172
|
+
* Creates a reactive object that will be observed by the current component.
|
|
2173
|
+
* Reading data from the returned object (eg during rendering) will cause the
|
|
2174
|
+
* component to subscribe to that data and be rerendered when it changes.
|
|
2175
|
+
*
|
|
2176
|
+
* @param state the state to observe
|
|
2177
|
+
* @returns a reactive object that will cause the component to re-render on
|
|
2178
|
+
* relevant changes
|
|
2179
|
+
* @see reactive
|
|
2180
|
+
*/
|
|
2181
|
+
function useState(state) {
|
|
2182
|
+
const node = getCurrent();
|
|
2183
|
+
let render = batchedRenderFunctions.get(node);
|
|
2184
|
+
if (!render) {
|
|
2185
|
+
render = batched(node.render.bind(node));
|
|
2186
|
+
batchedRenderFunctions.set(node, render);
|
|
2187
|
+
// manual implementation of onWillDestroy to break cyclic dependency
|
|
2188
|
+
node.willDestroy.push(clearReactivesForCallback.bind(null, render));
|
|
2189
|
+
}
|
|
2190
|
+
return reactive(state, render);
|
|
2191
|
+
}
|
|
2192
|
+
function arePropsDifferent(props1, props2) {
|
|
2193
|
+
for (let k in props1) {
|
|
2194
|
+
if (props1[k] !== props2[k]) {
|
|
2195
|
+
return true;
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
return Object.keys(props1).length !== Object.keys(props2).length;
|
|
2199
|
+
}
|
|
1964
2200
|
function component(name, props, key, ctx, parent) {
|
|
1965
2201
|
let node = ctx.children[key];
|
|
1966
2202
|
let isDynamic = typeof name !== "string";
|
|
@@ -1978,7 +2214,10 @@ function component(name, props, key, ctx, parent) {
|
|
|
1978
2214
|
}
|
|
1979
2215
|
const parentFiber = ctx.fiber;
|
|
1980
2216
|
if (node) {
|
|
1981
|
-
node.
|
|
2217
|
+
const currentProps = node.component.props[TARGET];
|
|
2218
|
+
if (parentFiber.deep || arePropsDifferent(currentProps, props)) {
|
|
2219
|
+
node.updateAndRender(props, parentFiber);
|
|
2220
|
+
}
|
|
1982
2221
|
}
|
|
1983
2222
|
else {
|
|
1984
2223
|
// new component
|
|
@@ -1994,8 +2233,7 @@ function component(name, props, key, ctx, parent) {
|
|
|
1994
2233
|
}
|
|
1995
2234
|
node = new ComponentNode(C, props, ctx.app, ctx);
|
|
1996
2235
|
ctx.children[key] = node;
|
|
1997
|
-
|
|
1998
|
-
node.initiateRender(fiber);
|
|
2236
|
+
node.initiateRender(new Fiber(node, parentFiber));
|
|
1999
2237
|
}
|
|
2000
2238
|
return node;
|
|
2001
2239
|
}
|
|
@@ -2020,6 +2258,7 @@ class ComponentNode {
|
|
|
2020
2258
|
applyDefaultProps(props, C);
|
|
2021
2259
|
const env = (parent && parent.childEnv) || app.env;
|
|
2022
2260
|
this.childEnv = env;
|
|
2261
|
+
props = useState(props);
|
|
2023
2262
|
this.component = new C(props, env, this);
|
|
2024
2263
|
this.renderFn = app.getTemplate(C.template).bind(this.component, this.component, this);
|
|
2025
2264
|
this.component.setup();
|
|
@@ -2047,20 +2286,29 @@ class ComponentNode {
|
|
|
2047
2286
|
this._render(fiber);
|
|
2048
2287
|
}
|
|
2049
2288
|
}
|
|
2050
|
-
async render() {
|
|
2289
|
+
async render(deep = false) {
|
|
2051
2290
|
let current = this.fiber;
|
|
2052
2291
|
if (current && current.root.locked) {
|
|
2053
2292
|
await Promise.resolve();
|
|
2054
2293
|
// situation may have changed after the microtask tick
|
|
2055
2294
|
current = this.fiber;
|
|
2056
2295
|
}
|
|
2057
|
-
if (current
|
|
2058
|
-
|
|
2296
|
+
if (current) {
|
|
2297
|
+
if (!current.bdom && !fibersInError.has(current)) {
|
|
2298
|
+
if (deep) {
|
|
2299
|
+
// we want the render from this point on to be with deep=true
|
|
2300
|
+
current.deep = deep;
|
|
2301
|
+
}
|
|
2302
|
+
return;
|
|
2303
|
+
}
|
|
2304
|
+
// if current rendering was with deep=true, we want this one to be the same
|
|
2305
|
+
deep = deep || current.deep;
|
|
2059
2306
|
}
|
|
2060
|
-
if (!this.bdom
|
|
2307
|
+
else if (!this.bdom) {
|
|
2061
2308
|
return;
|
|
2062
2309
|
}
|
|
2063
2310
|
const fiber = makeRootFiber(this);
|
|
2311
|
+
fiber.deep = deep;
|
|
2064
2312
|
this.fiber = fiber;
|
|
2065
2313
|
this.app.scheduler.addFiber(fiber);
|
|
2066
2314
|
await Promise.resolve();
|
|
@@ -2119,6 +2367,9 @@ class ComponentNode {
|
|
|
2119
2367
|
this.fiber = fiber;
|
|
2120
2368
|
const component = this.component;
|
|
2121
2369
|
applyDefaultProps(props, component.constructor);
|
|
2370
|
+
currentNode = this;
|
|
2371
|
+
props = useState(props);
|
|
2372
|
+
currentNode = null;
|
|
2122
2373
|
const prom = Promise.all(this.willUpdateProps.map((f) => f.call(component, props)));
|
|
2123
2374
|
await prom;
|
|
2124
2375
|
if (fiber !== this.fiber) {
|
|
@@ -2178,6 +2429,14 @@ class ComponentNode {
|
|
|
2178
2429
|
this.bdom.moveBefore(other ? other.bdom : null, afterNode);
|
|
2179
2430
|
}
|
|
2180
2431
|
patch() {
|
|
2432
|
+
if (this.fiber && this.fiber.parent) {
|
|
2433
|
+
// we only patch here renderings coming from above. renderings initiated
|
|
2434
|
+
// by the component will be patched independently in the appropriate
|
|
2435
|
+
// fiber.complete
|
|
2436
|
+
this._patch();
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2439
|
+
_patch() {
|
|
2181
2440
|
const hasChildren = Object.keys(this.children).length > 0;
|
|
2182
2441
|
this.bdom.patch(this.fiber.bdom, hasChildren);
|
|
2183
2442
|
if (hasChildren) {
|
|
@@ -2207,53 +2466,86 @@ class ComponentNode {
|
|
|
2207
2466
|
}
|
|
2208
2467
|
}
|
|
2209
2468
|
|
|
2469
|
+
function wrapError(fn, hookName) {
|
|
2470
|
+
const error = new Error(`The following error occurred in ${hookName}: `);
|
|
2471
|
+
return (...args) => {
|
|
2472
|
+
try {
|
|
2473
|
+
const result = fn(...args);
|
|
2474
|
+
if (result instanceof Promise) {
|
|
2475
|
+
return result.catch((cause) => {
|
|
2476
|
+
error.cause = cause;
|
|
2477
|
+
if (cause instanceof Error) {
|
|
2478
|
+
error.message += `"${cause.message}"`;
|
|
2479
|
+
}
|
|
2480
|
+
throw error;
|
|
2481
|
+
});
|
|
2482
|
+
}
|
|
2483
|
+
return result;
|
|
2484
|
+
}
|
|
2485
|
+
catch (cause) {
|
|
2486
|
+
if (cause instanceof Error) {
|
|
2487
|
+
error.message += `"${cause.message}"`;
|
|
2488
|
+
}
|
|
2489
|
+
throw error;
|
|
2490
|
+
}
|
|
2491
|
+
};
|
|
2492
|
+
}
|
|
2210
2493
|
// -----------------------------------------------------------------------------
|
|
2211
2494
|
// hooks
|
|
2212
2495
|
// -----------------------------------------------------------------------------
|
|
2213
2496
|
function onWillStart(fn) {
|
|
2214
2497
|
const node = getCurrent();
|
|
2215
|
-
node.
|
|
2498
|
+
const decorate = node.app.dev ? wrapError : (fn) => fn;
|
|
2499
|
+
node.willStart.push(decorate(fn.bind(node.component), "onWillStart"));
|
|
2216
2500
|
}
|
|
2217
2501
|
function onWillUpdateProps(fn) {
|
|
2218
2502
|
const node = getCurrent();
|
|
2219
|
-
node.
|
|
2503
|
+
const decorate = node.app.dev ? wrapError : (fn) => fn;
|
|
2504
|
+
node.willUpdateProps.push(decorate(fn.bind(node.component), "onWillUpdateProps"));
|
|
2220
2505
|
}
|
|
2221
2506
|
function onMounted(fn) {
|
|
2222
2507
|
const node = getCurrent();
|
|
2223
|
-
node.
|
|
2508
|
+
const decorate = node.app.dev ? wrapError : (fn) => fn;
|
|
2509
|
+
node.mounted.push(decorate(fn.bind(node.component), "onMounted"));
|
|
2224
2510
|
}
|
|
2225
2511
|
function onWillPatch(fn) {
|
|
2226
2512
|
const node = getCurrent();
|
|
2227
|
-
node.
|
|
2513
|
+
const decorate = node.app.dev ? wrapError : (fn) => fn;
|
|
2514
|
+
node.willPatch.unshift(decorate(fn.bind(node.component), "onWillPatch"));
|
|
2228
2515
|
}
|
|
2229
2516
|
function onPatched(fn) {
|
|
2230
2517
|
const node = getCurrent();
|
|
2231
|
-
node.
|
|
2518
|
+
const decorate = node.app.dev ? wrapError : (fn) => fn;
|
|
2519
|
+
node.patched.push(decorate(fn.bind(node.component), "onPatched"));
|
|
2232
2520
|
}
|
|
2233
2521
|
function onWillUnmount(fn) {
|
|
2234
2522
|
const node = getCurrent();
|
|
2235
|
-
node.
|
|
2523
|
+
const decorate = node.app.dev ? wrapError : (fn) => fn;
|
|
2524
|
+
node.willUnmount.unshift(decorate(fn.bind(node.component), "onWillUnmount"));
|
|
2236
2525
|
}
|
|
2237
2526
|
function onWillDestroy(fn) {
|
|
2238
2527
|
const node = getCurrent();
|
|
2239
|
-
node.
|
|
2528
|
+
const decorate = node.app.dev ? wrapError : (fn) => fn;
|
|
2529
|
+
node.willDestroy.push(decorate(fn.bind(node.component), "onWillDestroy"));
|
|
2240
2530
|
}
|
|
2241
2531
|
function onWillRender(fn) {
|
|
2242
2532
|
const node = getCurrent();
|
|
2243
2533
|
const renderFn = node.renderFn;
|
|
2244
|
-
node.
|
|
2534
|
+
const decorate = node.app.dev ? wrapError : (fn) => fn;
|
|
2535
|
+
node.renderFn = decorate(() => {
|
|
2245
2536
|
fn.call(node.component);
|
|
2246
2537
|
return renderFn();
|
|
2247
|
-
};
|
|
2538
|
+
}, "onWillRender");
|
|
2248
2539
|
}
|
|
2249
2540
|
function onRendered(fn) {
|
|
2250
2541
|
const node = getCurrent();
|
|
2251
2542
|
const renderFn = node.renderFn;
|
|
2252
|
-
node.
|
|
2543
|
+
const decorate = node.app.dev ? wrapError : (fn) => fn;
|
|
2544
|
+
node.renderFn = decorate(() => {
|
|
2253
2545
|
const result = renderFn();
|
|
2254
2546
|
fn.call(node.component);
|
|
2255
2547
|
return result;
|
|
2256
|
-
};
|
|
2548
|
+
}, "onRendered");
|
|
2257
2549
|
}
|
|
2258
2550
|
function onError(callback) {
|
|
2259
2551
|
const node = getCurrent();
|
|
@@ -3550,17 +3842,13 @@ class CodeGenerator {
|
|
|
3550
3842
|
slotDef = `{${slotStr.join(", ")}}`;
|
|
3551
3843
|
}
|
|
3552
3844
|
if (slotDef && !(ast.dynamicProps || hasSlotsProp)) {
|
|
3553
|
-
|
|
3845
|
+
this.helpers.add("markRaw");
|
|
3846
|
+
props.push(`slots: markRaw(${slotDef})`);
|
|
3554
3847
|
}
|
|
3555
3848
|
const propStr = `{${props.join(",")}}`;
|
|
3556
3849
|
let propString = propStr;
|
|
3557
3850
|
if (ast.dynamicProps) {
|
|
3558
|
-
|
|
3559
|
-
propString = `Object.assign({}, ${compileExpr(ast.dynamicProps)})`;
|
|
3560
|
-
}
|
|
3561
|
-
else {
|
|
3562
|
-
propString = `Object.assign({}, ${compileExpr(ast.dynamicProps)}, ${propStr})`;
|
|
3563
|
-
}
|
|
3851
|
+
propString = `Object.assign({}, ${compileExpr(ast.dynamicProps)}${props.length ? ", " + propStr : ""})`;
|
|
3564
3852
|
}
|
|
3565
3853
|
let propVar;
|
|
3566
3854
|
if ((slotDef && (ast.dynamicProps || hasSlotsProp)) || this.dev) {
|
|
@@ -3569,7 +3857,8 @@ class CodeGenerator {
|
|
|
3569
3857
|
propString = propVar;
|
|
3570
3858
|
}
|
|
3571
3859
|
if (slotDef && (ast.dynamicProps || hasSlotsProp)) {
|
|
3572
|
-
this.
|
|
3860
|
+
this.helpers.add("markRaw");
|
|
3861
|
+
this.addLine(`${propVar}.slots = markRaw(Object.assign(${slotDef}, ${propVar}.slots))`);
|
|
3573
3862
|
}
|
|
3574
3863
|
// cmap key
|
|
3575
3864
|
const key = this.generateComponentKey();
|
|
@@ -3769,6 +4058,9 @@ function parseDOMNode(node, ctx) {
|
|
|
3769
4058
|
if (tagName === "t" && !dynamicTag) {
|
|
3770
4059
|
return null;
|
|
3771
4060
|
}
|
|
4061
|
+
if (tagName.startsWith("block-")) {
|
|
4062
|
+
throw new Error(`Invalid tag name: '${tagName}'`);
|
|
4063
|
+
}
|
|
3772
4064
|
ctx = Object.assign({}, ctx);
|
|
3773
4065
|
if (tagName === "pre") {
|
|
3774
4066
|
ctx.inPreTag = true;
|
|
@@ -3834,6 +4126,9 @@ function parseDOMNode(node, ctx) {
|
|
|
3834
4126
|
ctx.tModelInfo = model;
|
|
3835
4127
|
}
|
|
3836
4128
|
}
|
|
4129
|
+
else if (attr.startsWith("block-")) {
|
|
4130
|
+
throw new Error(`Invalid attribute: '${attr}'`);
|
|
4131
|
+
}
|
|
3837
4132
|
else if (attr !== "t-name") {
|
|
3838
4133
|
if (attr.startsWith("t-") && !attr.startsWith("t-att")) {
|
|
3839
4134
|
throw new Error(`Unknown QWeb directive: '${attr}'`);
|
|
@@ -4451,7 +4746,13 @@ class TemplateSet {
|
|
|
4451
4746
|
if (!(name in this.templates)) {
|
|
4452
4747
|
const rawTemplate = this.rawTemplates[name];
|
|
4453
4748
|
if (rawTemplate === undefined) {
|
|
4454
|
-
|
|
4749
|
+
let extraInfo = "";
|
|
4750
|
+
try {
|
|
4751
|
+
const componentName = getCurrent().component.constructor.name;
|
|
4752
|
+
extraInfo = ` (for component "${componentName}")`;
|
|
4753
|
+
}
|
|
4754
|
+
catch { }
|
|
4755
|
+
throw new Error(`Missing template: "${name}"${extraInfo}`);
|
|
4455
4756
|
}
|
|
4456
4757
|
const templateFn = this._compileTemplate(name, rawTemplate);
|
|
4457
4758
|
// first add a function to lazily get the template, in case there is a
|
|
@@ -4492,8 +4793,8 @@ class Component {
|
|
|
4492
4793
|
this.__owl__ = node;
|
|
4493
4794
|
}
|
|
4494
4795
|
setup() { }
|
|
4495
|
-
render() {
|
|
4496
|
-
this.__owl__.render();
|
|
4796
|
+
render(deep = false) {
|
|
4797
|
+
this.__owl__.render(deep);
|
|
4497
4798
|
}
|
|
4498
4799
|
}
|
|
4499
4800
|
Component.template = "";
|
|
@@ -4627,10 +4928,13 @@ class Scheduler {
|
|
|
4627
4928
|
// interactions with other code, such as test frameworks that override them
|
|
4628
4929
|
Scheduler.requestAnimationFrame = window.requestAnimationFrame.bind(window);
|
|
4629
4930
|
|
|
4630
|
-
const DEV_MSG =
|
|
4931
|
+
const DEV_MSG = () => {
|
|
4932
|
+
const hash = window.owl ? window.owl.__info__.hash : "master";
|
|
4933
|
+
return `Owl is running in 'dev' mode.
|
|
4631
4934
|
|
|
4632
4935
|
This is not suitable for production use.
|
|
4633
|
-
See https://github.com/odoo/owl/blob/
|
|
4936
|
+
See https://github.com/odoo/owl/blob/${hash}/doc/reference/app.md#configuration for more information.`;
|
|
4937
|
+
};
|
|
4634
4938
|
class App extends TemplateSet {
|
|
4635
4939
|
constructor(Root, config = {}) {
|
|
4636
4940
|
super(config);
|
|
@@ -4641,7 +4945,7 @@ class App extends TemplateSet {
|
|
|
4641
4945
|
this.dev = true;
|
|
4642
4946
|
}
|
|
4643
4947
|
if (this.dev && !config.test) {
|
|
4644
|
-
console.info(DEV_MSG);
|
|
4948
|
+
console.info(DEV_MSG());
|
|
4645
4949
|
}
|
|
4646
4950
|
const descrs = Object.getOwnPropertyDescriptors(config.env || {});
|
|
4647
4951
|
this.env = Object.freeze(Object.defineProperties({}, descrs));
|
|
@@ -4746,231 +5050,6 @@ function shallowEqual(p1, p2) {
|
|
|
4746
5050
|
return true;
|
|
4747
5051
|
}
|
|
4748
5052
|
|
|
4749
|
-
// Allows to get the target of a Reactive (used for making a new Reactive from the underlying object)
|
|
4750
|
-
const TARGET = Symbol("Target");
|
|
4751
|
-
// Escape hatch to prevent reactivity system to turn something into a reactive
|
|
4752
|
-
const SKIP = Symbol("Skip");
|
|
4753
|
-
// Special key to subscribe to, to be notified of key creation/deletion
|
|
4754
|
-
const KEYCHANGES = Symbol("Key changes");
|
|
4755
|
-
const objectToString = Object.prototype.toString;
|
|
4756
|
-
/**
|
|
4757
|
-
* Checks whether a given value can be made into a reactive object.
|
|
4758
|
-
*
|
|
4759
|
-
* @param value the value to check
|
|
4760
|
-
* @returns whether the value can be made reactive
|
|
4761
|
-
*/
|
|
4762
|
-
function canBeMadeReactive(value) {
|
|
4763
|
-
if (typeof value !== "object") {
|
|
4764
|
-
return false;
|
|
4765
|
-
}
|
|
4766
|
-
// extract "RawType" from strings like "[object RawType]" => this lets us
|
|
4767
|
-
// ignore many native objects such as Promise (whose toString is [object Promise])
|
|
4768
|
-
// or Date ([object Date]).
|
|
4769
|
-
const rawType = objectToString.call(value).slice(8, -1);
|
|
4770
|
-
return rawType === "Object" || rawType === "Array";
|
|
4771
|
-
}
|
|
4772
|
-
/**
|
|
4773
|
-
* Mark an object or array so that it is ignored by the reactivity system
|
|
4774
|
-
*
|
|
4775
|
-
* @param value the value to mark
|
|
4776
|
-
* @returns the object itself
|
|
4777
|
-
*/
|
|
4778
|
-
function markRaw(value) {
|
|
4779
|
-
value[SKIP] = true;
|
|
4780
|
-
return value;
|
|
4781
|
-
}
|
|
4782
|
-
/**
|
|
4783
|
-
* Given a reactive objet, return the raw (non reactive) underlying object
|
|
4784
|
-
*
|
|
4785
|
-
* @param value a reactive value
|
|
4786
|
-
* @returns the underlying value
|
|
4787
|
-
*/
|
|
4788
|
-
function toRaw(value) {
|
|
4789
|
-
return value[TARGET];
|
|
4790
|
-
}
|
|
4791
|
-
const targetToKeysToCallbacks = new WeakMap();
|
|
4792
|
-
/**
|
|
4793
|
-
* Observes a given key on a target with an callback. The callback will be
|
|
4794
|
-
* called when the given key changes on the target.
|
|
4795
|
-
*
|
|
4796
|
-
* @param target the target whose key should be observed
|
|
4797
|
-
* @param key the key to observe (or Symbol(KEYCHANGES) for key creation
|
|
4798
|
-
* or deletion)
|
|
4799
|
-
* @param callback the function to call when the key changes
|
|
4800
|
-
*/
|
|
4801
|
-
function observeTargetKey(target, key, callback) {
|
|
4802
|
-
if (!targetToKeysToCallbacks.get(target)) {
|
|
4803
|
-
targetToKeysToCallbacks.set(target, new Map());
|
|
4804
|
-
}
|
|
4805
|
-
const keyToCallbacks = targetToKeysToCallbacks.get(target);
|
|
4806
|
-
if (!keyToCallbacks.get(key)) {
|
|
4807
|
-
keyToCallbacks.set(key, new Set());
|
|
4808
|
-
}
|
|
4809
|
-
keyToCallbacks.get(key).add(callback);
|
|
4810
|
-
if (!callbacksToTargets.has(callback)) {
|
|
4811
|
-
callbacksToTargets.set(callback, new Set());
|
|
4812
|
-
}
|
|
4813
|
-
callbacksToTargets.get(callback).add(target);
|
|
4814
|
-
}
|
|
4815
|
-
/**
|
|
4816
|
-
* Notify Reactives that are observing a given target that a key has changed on
|
|
4817
|
-
* the target.
|
|
4818
|
-
*
|
|
4819
|
-
* @param target target whose Reactives should be notified that the target was
|
|
4820
|
-
* changed.
|
|
4821
|
-
* @param key the key that changed (or Symbol `KEYCHANGES` if a key was created
|
|
4822
|
-
* or deleted)
|
|
4823
|
-
*/
|
|
4824
|
-
function notifyReactives(target, key) {
|
|
4825
|
-
const keyToCallbacks = targetToKeysToCallbacks.get(target);
|
|
4826
|
-
if (!keyToCallbacks) {
|
|
4827
|
-
return;
|
|
4828
|
-
}
|
|
4829
|
-
const callbacks = keyToCallbacks.get(key);
|
|
4830
|
-
if (!callbacks) {
|
|
4831
|
-
return;
|
|
4832
|
-
}
|
|
4833
|
-
// Loop on copy because clearReactivesForCallback will modify the set in place
|
|
4834
|
-
for (const callback of [...callbacks]) {
|
|
4835
|
-
clearReactivesForCallback(callback);
|
|
4836
|
-
callback();
|
|
4837
|
-
}
|
|
4838
|
-
}
|
|
4839
|
-
const callbacksToTargets = new WeakMap();
|
|
4840
|
-
/**
|
|
4841
|
-
* Clears all subscriptions of the Reactives associated with a given callback.
|
|
4842
|
-
*
|
|
4843
|
-
* @param callback the callback for which the reactives need to be cleared
|
|
4844
|
-
*/
|
|
4845
|
-
function clearReactivesForCallback(callback) {
|
|
4846
|
-
const targetsToClear = callbacksToTargets.get(callback);
|
|
4847
|
-
if (!targetsToClear) {
|
|
4848
|
-
return;
|
|
4849
|
-
}
|
|
4850
|
-
for (const target of targetsToClear) {
|
|
4851
|
-
const observedKeys = targetToKeysToCallbacks.get(target);
|
|
4852
|
-
if (!observedKeys) {
|
|
4853
|
-
continue;
|
|
4854
|
-
}
|
|
4855
|
-
for (const callbacks of observedKeys.values()) {
|
|
4856
|
-
callbacks.delete(callback);
|
|
4857
|
-
}
|
|
4858
|
-
}
|
|
4859
|
-
targetsToClear.clear();
|
|
4860
|
-
}
|
|
4861
|
-
const reactiveCache = new WeakMap();
|
|
4862
|
-
/**
|
|
4863
|
-
* Creates a reactive proxy for an object. Reading data on the reactive object
|
|
4864
|
-
* subscribes to changes to the data. Writing data on the object will cause the
|
|
4865
|
-
* notify callback to be called if there are suscriptions to that data. Nested
|
|
4866
|
-
* objects and arrays are automatically made reactive as well.
|
|
4867
|
-
*
|
|
4868
|
-
* Whenever you are notified of a change, all subscriptions are cleared, and if
|
|
4869
|
-
* you would like to be notified of any further changes, you should go read
|
|
4870
|
-
* the underlying data again. We assume that if you don't go read it again after
|
|
4871
|
-
* being notified, it means that you are no longer interested in that data.
|
|
4872
|
-
*
|
|
4873
|
-
* Subscriptions:
|
|
4874
|
-
* + Reading a property on an object will subscribe you to changes in the value
|
|
4875
|
-
* of that property.
|
|
4876
|
-
* + Accessing an object keys (eg with Object.keys or with `for..in`) will
|
|
4877
|
-
* subscribe you to the creation/deletion of keys. Checking the presence of a
|
|
4878
|
-
* key on the object with 'in' has the same effect.
|
|
4879
|
-
* - getOwnPropertyDescriptor does not currently subscribe you to the property.
|
|
4880
|
-
* This is a choice that was made because changing a key's value will trigger
|
|
4881
|
-
* this trap and we do not want to subscribe by writes. This also means that
|
|
4882
|
-
* Object.hasOwnProperty doesn't subscribe as it goes through this trap.
|
|
4883
|
-
*
|
|
4884
|
-
* @param target the object for which to create a reactive proxy
|
|
4885
|
-
* @param callback the function to call when an observed property of the
|
|
4886
|
-
* reactive has changed
|
|
4887
|
-
* @returns a proxy that tracks changes to it
|
|
4888
|
-
*/
|
|
4889
|
-
function reactive(target, callback = () => { }) {
|
|
4890
|
-
if (!canBeMadeReactive(target)) {
|
|
4891
|
-
throw new Error(`Cannot make the given value reactive`);
|
|
4892
|
-
}
|
|
4893
|
-
if (SKIP in target) {
|
|
4894
|
-
return target;
|
|
4895
|
-
}
|
|
4896
|
-
const originalTarget = target[TARGET];
|
|
4897
|
-
if (originalTarget) {
|
|
4898
|
-
return reactive(originalTarget, callback);
|
|
4899
|
-
}
|
|
4900
|
-
if (!reactiveCache.has(target)) {
|
|
4901
|
-
reactiveCache.set(target, new Map());
|
|
4902
|
-
}
|
|
4903
|
-
const reactivesForTarget = reactiveCache.get(target);
|
|
4904
|
-
if (!reactivesForTarget.has(callback)) {
|
|
4905
|
-
const proxy = new Proxy(target, {
|
|
4906
|
-
get(target, key, proxy) {
|
|
4907
|
-
if (key === TARGET) {
|
|
4908
|
-
return target;
|
|
4909
|
-
}
|
|
4910
|
-
observeTargetKey(target, key, callback);
|
|
4911
|
-
const value = Reflect.get(target, key, proxy);
|
|
4912
|
-
if (!canBeMadeReactive(value)) {
|
|
4913
|
-
return value;
|
|
4914
|
-
}
|
|
4915
|
-
return reactive(value, callback);
|
|
4916
|
-
},
|
|
4917
|
-
set(target, key, value, proxy) {
|
|
4918
|
-
const isNewKey = !Object.hasOwnProperty.call(target, key);
|
|
4919
|
-
const originalValue = Reflect.get(target, key, proxy);
|
|
4920
|
-
const ret = Reflect.set(target, key, value, proxy);
|
|
4921
|
-
if (isNewKey) {
|
|
4922
|
-
notifyReactives(target, KEYCHANGES);
|
|
4923
|
-
}
|
|
4924
|
-
// While Array length may trigger the set trap, it's not actually set by this
|
|
4925
|
-
// method but is updated behind the scenes, and the trap is not called with the
|
|
4926
|
-
// new value. We disable the "same-value-optimization" for it because of that.
|
|
4927
|
-
if (originalValue !== value || (Array.isArray(target) && key === "length")) {
|
|
4928
|
-
notifyReactives(target, key);
|
|
4929
|
-
}
|
|
4930
|
-
return ret;
|
|
4931
|
-
},
|
|
4932
|
-
deleteProperty(target, key) {
|
|
4933
|
-
const ret = Reflect.deleteProperty(target, key);
|
|
4934
|
-
notifyReactives(target, KEYCHANGES);
|
|
4935
|
-
notifyReactives(target, key);
|
|
4936
|
-
return ret;
|
|
4937
|
-
},
|
|
4938
|
-
ownKeys(target) {
|
|
4939
|
-
observeTargetKey(target, KEYCHANGES, callback);
|
|
4940
|
-
return Reflect.ownKeys(target);
|
|
4941
|
-
},
|
|
4942
|
-
has(target, key) {
|
|
4943
|
-
// TODO: this observes all key changes instead of only the presence of the argument key
|
|
4944
|
-
observeTargetKey(target, KEYCHANGES, callback);
|
|
4945
|
-
return Reflect.has(target, key);
|
|
4946
|
-
},
|
|
4947
|
-
});
|
|
4948
|
-
reactivesForTarget.set(callback, proxy);
|
|
4949
|
-
}
|
|
4950
|
-
return reactivesForTarget.get(callback);
|
|
4951
|
-
}
|
|
4952
|
-
const batchedRenderFunctions = new WeakMap();
|
|
4953
|
-
/**
|
|
4954
|
-
* Creates a reactive object that will be observed by the current component.
|
|
4955
|
-
* Reading data from the returned object (eg during rendering) will cause the
|
|
4956
|
-
* component to subscribe to that data and be rerendered when it changes.
|
|
4957
|
-
*
|
|
4958
|
-
* @param state the state to observe
|
|
4959
|
-
* @returns a reactive object that will cause the component to re-render on
|
|
4960
|
-
* relevant changes
|
|
4961
|
-
* @see reactive
|
|
4962
|
-
*/
|
|
4963
|
-
function useState(state) {
|
|
4964
|
-
const node = getCurrent();
|
|
4965
|
-
if (!batchedRenderFunctions.has(node)) {
|
|
4966
|
-
batchedRenderFunctions.set(node, batched(() => node.render()));
|
|
4967
|
-
onWillDestroy(() => clearReactivesForCallback(render));
|
|
4968
|
-
}
|
|
4969
|
-
const render = batchedRenderFunctions.get(node);
|
|
4970
|
-
const reactiveState = reactive(state, render);
|
|
4971
|
-
return reactiveState;
|
|
4972
|
-
}
|
|
4973
|
-
|
|
4974
5053
|
// -----------------------------------------------------------------------------
|
|
4975
5054
|
// useRef
|
|
4976
5055
|
// -----------------------------------------------------------------------------
|
|
@@ -5076,6 +5155,7 @@ function useExternalListener(target, eventName, handler, eventParams) {
|
|
|
5076
5155
|
config.shouldNormalizeDom = false;
|
|
5077
5156
|
config.mainEventHandler = mainEventHandler;
|
|
5078
5157
|
UTILS.Portal = Portal;
|
|
5158
|
+
UTILS.markRaw = markRaw;
|
|
5079
5159
|
const blockDom = {
|
|
5080
5160
|
config,
|
|
5081
5161
|
// bdom entry points
|
|
@@ -5128,7 +5208,7 @@ exports.whenReady = whenReady;
|
|
|
5128
5208
|
exports.xml = xml;
|
|
5129
5209
|
|
|
5130
5210
|
|
|
5131
|
-
__info__.version = '2.0.0-alpha.
|
|
5132
|
-
__info__.date = '2022-02-
|
|
5133
|
-
__info__.hash = '
|
|
5211
|
+
__info__.version = '2.0.0-alpha.3';
|
|
5212
|
+
__info__.date = '2022-02-25T09:57:37.893Z';
|
|
5213
|
+
__info__.hash = '076b0d7';
|
|
5134
5214
|
__info__.url = 'https://github.com/odoo/owl';
|