@odoo/owl 2.0.0 → 2.0.2

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.es.js CHANGED
@@ -38,8 +38,11 @@ class VToggler {
38
38
  this.parentEl = parent;
39
39
  this.child.mount(parent, afterNode);
40
40
  }
41
- moveBefore(other, afterNode) {
42
- this.child.moveBefore(other ? other.child : null, afterNode);
41
+ moveBeforeDOMNode(node, parent) {
42
+ this.child.moveBeforeDOMNode(node, parent);
43
+ }
44
+ moveBeforeVNode(other, afterNode) {
45
+ this.moveBeforeDOMNode((other && other.firstNode()) || afterNode);
43
46
  }
44
47
  patch(other, withBeforeRemove) {
45
48
  if (this === other) {
@@ -415,7 +418,22 @@ class VMulti {
415
418
  this.anchors = anchors;
416
419
  this.parentEl = parent;
417
420
  }
418
- moveBefore(other, afterNode) {
421
+ moveBeforeDOMNode(node, parent = this.parentEl) {
422
+ this.parentEl = parent;
423
+ const children = this.children;
424
+ const anchors = this.anchors;
425
+ for (let i = 0, l = children.length; i < l; i++) {
426
+ let child = children[i];
427
+ if (child) {
428
+ child.moveBeforeDOMNode(node, parent);
429
+ }
430
+ else {
431
+ const anchor = anchors[i];
432
+ nodeInsertBefore$3.call(parent, anchor, node);
433
+ }
434
+ }
435
+ }
436
+ moveBeforeVNode(other, afterNode) {
419
437
  if (other) {
420
438
  const next = other.children[0];
421
439
  afterNode = (next ? next.firstNode() : other.anchors[0]) || null;
@@ -426,7 +444,7 @@ class VMulti {
426
444
  for (let i = 0, l = children.length; i < l; i++) {
427
445
  let child = children[i];
428
446
  if (child) {
429
- child.moveBefore(null, afterNode);
447
+ child.moveBeforeVNode(null, afterNode);
430
448
  }
431
449
  else {
432
450
  const anchor = anchors[i];
@@ -524,9 +542,12 @@ class VSimpleNode {
524
542
  nodeInsertBefore$2.call(parent, node, afterNode);
525
543
  this.el = node;
526
544
  }
527
- moveBefore(other, afterNode) {
528
- const target = other ? other.el : afterNode;
529
- nodeInsertBefore$2.call(this.parentEl, this.el, target);
545
+ moveBeforeDOMNode(node, parent = this.parentEl) {
546
+ this.parentEl = parent;
547
+ nodeInsertBefore$2.call(parent, this.el, node);
548
+ }
549
+ moveBeforeVNode(other, afterNode) {
550
+ nodeInsertBefore$2.call(this.parentEl, this.el, other ? other.el : afterNode);
530
551
  }
531
552
  beforeRemove() { }
532
553
  remove() {
@@ -968,9 +989,12 @@ function createBlockClass(template, ctx) {
968
989
  firstNode() {
969
990
  return this.el;
970
991
  }
971
- moveBefore(other, afterNode) {
972
- const target = other ? other.el : afterNode;
973
- nodeInsertBefore.call(this.parentEl, this.el, target);
992
+ moveBeforeDOMNode(node, parent = this.parentEl) {
993
+ this.parentEl = parent;
994
+ nodeInsertBefore.call(parent, this.el, node);
995
+ }
996
+ moveBeforeVNode(other, afterNode) {
997
+ nodeInsertBefore.call(this.parentEl, this.el, other ? other.el : afterNode);
974
998
  }
975
999
  toString() {
976
1000
  const div = document.createElement("div");
@@ -1107,14 +1131,22 @@ class VList {
1107
1131
  }
1108
1132
  this.parentEl = parent;
1109
1133
  }
1110
- moveBefore(other, afterNode) {
1134
+ moveBeforeDOMNode(node, parent = this.parentEl) {
1135
+ this.parentEl = parent;
1136
+ const children = this.children;
1137
+ for (let i = 0, l = children.length; i < l; i++) {
1138
+ children[i].moveBeforeDOMNode(node, parent);
1139
+ }
1140
+ parent.insertBefore(this.anchor, node);
1141
+ }
1142
+ moveBeforeVNode(other, afterNode) {
1111
1143
  if (other) {
1112
1144
  const next = other.children[0];
1113
1145
  afterNode = (next ? next.firstNode() : other.anchor) || null;
1114
1146
  }
1115
1147
  const children = this.children;
1116
1148
  for (let i = 0, l = children.length; i < l; i++) {
1117
- children[i].moveBefore(null, afterNode);
1149
+ children[i].moveBeforeVNode(null, afterNode);
1118
1150
  }
1119
1151
  this.parentEl.insertBefore(this.anchor, afterNode);
1120
1152
  }
@@ -1129,7 +1161,7 @@ class VList {
1129
1161
  }
1130
1162
  this.children = ch2;
1131
1163
  const proto = ch2[0] || ch1[0];
1132
- const { mount: cMount, patch: cPatch, remove: cRemove, beforeRemove, moveBefore: cMoveBefore, firstNode: cFirstNode, } = proto;
1164
+ const { mount: cMount, patch: cPatch, remove: cRemove, beforeRemove, moveBeforeVNode: cMoveBefore, firstNode: cFirstNode, } = proto;
1133
1165
  const _anchor = this.anchor;
1134
1166
  const isOnlyChild = this.isOnlyChild;
1135
1167
  const parent = this.parentEl;
@@ -1311,13 +1343,16 @@ class VHtml {
1311
1343
  nodeInsertBefore.call(parent, textNode, afterNode);
1312
1344
  }
1313
1345
  }
1314
- moveBefore(other, afterNode) {
1315
- const target = other ? other.content[0] : afterNode;
1316
- const parent = this.parentEl;
1346
+ moveBeforeDOMNode(node, parent = this.parentEl) {
1347
+ this.parentEl = parent;
1317
1348
  for (let elem of this.content) {
1318
- nodeInsertBefore.call(parent, elem, target);
1349
+ nodeInsertBefore.call(parent, elem, node);
1319
1350
  }
1320
1351
  }
1352
+ moveBeforeVNode(other, afterNode) {
1353
+ const target = other ? other.content[0] : afterNode;
1354
+ this.moveBeforeDOMNode(target);
1355
+ }
1321
1356
  patch(other) {
1322
1357
  if (this === other) {
1323
1358
  return;
@@ -1395,7 +1430,7 @@ function createCatcher(eventsSpec) {
1395
1430
  const target = ev.target;
1396
1431
  let currentNode = self.child.firstNode();
1397
1432
  const afterNode = self.afterNode;
1398
- while (currentNode !== afterNode) {
1433
+ while (currentNode && currentNode !== afterNode) {
1399
1434
  if (currentNode.contains(target)) {
1400
1435
  return origFn.call(this, ev);
1401
1436
  }
@@ -1404,8 +1439,17 @@ function createCatcher(eventsSpec) {
1404
1439
  };
1405
1440
  }
1406
1441
  }
1407
- moveBefore(other, afterNode) {
1408
- this.child.moveBefore(other ? other.child : null, afterNode);
1442
+ moveBeforeDOMNode(node, parent = this.parentEl) {
1443
+ this.parentEl = parent;
1444
+ this.child.moveBeforeDOMNode(node, parent);
1445
+ parent.insertBefore(this.afterNode, node);
1446
+ }
1447
+ moveBeforeVNode(other, afterNode) {
1448
+ if (other) {
1449
+ // check this with @ged-odoo for use in foreach
1450
+ afterNode = other.firstNode() || afterNode;
1451
+ }
1452
+ this.child.moveBeforeVNode(other ? other.child : null, afterNode);
1409
1453
  this.parentEl.insertBefore(this.afterNode, afterNode);
1410
1454
  }
1411
1455
  patch(other, withBeforeRemove) {
@@ -1696,10 +1740,6 @@ class MountFiber extends RootFiber {
1696
1740
  }
1697
1741
  }
1698
1742
 
1699
- // Allows to get the target of a Reactive (used for making a new Reactive from the underlying object)
1700
- const TARGET = Symbol("Target");
1701
- // Escape hatch to prevent reactivity system to turn something into a reactive
1702
- const SKIP = Symbol("Skip");
1703
1743
  // Special key to subscribe to, to be notified of key creation/deletion
1704
1744
  const KEYCHANGES = Symbol("Key changes");
1705
1745
  const objectToString = Object.prototype.toString;
@@ -1740,6 +1780,7 @@ function canBeMadeReactive(value) {
1740
1780
  function possiblyReactive(val, cb) {
1741
1781
  return canBeMadeReactive(val) ? reactive(val, cb) : val;
1742
1782
  }
1783
+ const skipped = new WeakSet();
1743
1784
  /**
1744
1785
  * Mark an object or array so that it is ignored by the reactivity system
1745
1786
  *
@@ -1747,7 +1788,7 @@ function possiblyReactive(val, cb) {
1747
1788
  * @returns the object itself
1748
1789
  */
1749
1790
  function markRaw(value) {
1750
- value[SKIP] = true;
1791
+ skipped.add(value);
1751
1792
  return value;
1752
1793
  }
1753
1794
  /**
@@ -1757,7 +1798,7 @@ function markRaw(value) {
1757
1798
  * @returns the underlying value
1758
1799
  */
1759
1800
  function toRaw(value) {
1760
- return value[TARGET] || value;
1801
+ return targets.has(value) ? targets.get(value) : value;
1761
1802
  }
1762
1803
  const targetToKeysToCallbacks = new WeakMap();
1763
1804
  /**
@@ -1839,6 +1880,8 @@ function getSubscriptions(callback) {
1839
1880
  };
1840
1881
  });
1841
1882
  }
1883
+ // Maps reactive objects to the underlying target
1884
+ const targets = new WeakMap();
1842
1885
  const reactiveCache = new WeakMap();
1843
1886
  /**
1844
1887
  * Creates a reactive proxy for an object. Reading data on the reactive object
@@ -1854,7 +1897,7 @@ const reactiveCache = new WeakMap();
1854
1897
  * Subscriptions:
1855
1898
  * + Reading a property on an object will subscribe you to changes in the value
1856
1899
  * of that property.
1857
- * + Accessing an object keys (eg with Object.keys or with `for..in`) will
1900
+ * + Accessing an object's keys (eg with Object.keys or with `for..in`) will
1858
1901
  * subscribe you to the creation/deletion of keys. Checking the presence of a
1859
1902
  * key on the object with 'in' has the same effect.
1860
1903
  * - getOwnPropertyDescriptor does not currently subscribe you to the property.
@@ -1871,12 +1914,12 @@ function reactive(target, callback = () => { }) {
1871
1914
  if (!canBeMadeReactive(target)) {
1872
1915
  throw new OwlError(`Cannot make the given value reactive`);
1873
1916
  }
1874
- if (SKIP in target) {
1917
+ if (skipped.has(target)) {
1875
1918
  return target;
1876
1919
  }
1877
- const originalTarget = target[TARGET];
1878
- if (originalTarget) {
1879
- return reactive(originalTarget, callback);
1920
+ if (targets.has(target)) {
1921
+ // target is reactive, create a reactive on the underlying object instead
1922
+ return reactive(targets.get(target), callback);
1880
1923
  }
1881
1924
  if (!reactiveCache.has(target)) {
1882
1925
  reactiveCache.set(target, new WeakMap());
@@ -1889,6 +1932,7 @@ function reactive(target, callback = () => { }) {
1889
1932
  : basicProxyHandler(callback);
1890
1933
  const proxy = new Proxy(target, handler);
1891
1934
  reactivesForTarget.set(callback, proxy);
1935
+ targets.set(proxy, target);
1892
1936
  }
1893
1937
  return reactivesForTarget.get(callback);
1894
1938
  }
@@ -1900,29 +1944,27 @@ function reactive(target, callback = () => { }) {
1900
1944
  */
1901
1945
  function basicProxyHandler(callback) {
1902
1946
  return {
1903
- get(target, key, proxy) {
1904
- if (key === TARGET) {
1905
- return target;
1906
- }
1947
+ get(target, key, receiver) {
1907
1948
  // non-writable non-configurable properties cannot be made reactive
1908
1949
  const desc = Object.getOwnPropertyDescriptor(target, key);
1909
1950
  if (desc && !desc.writable && !desc.configurable) {
1910
- return Reflect.get(target, key, proxy);
1951
+ return Reflect.get(target, key, receiver);
1911
1952
  }
1912
1953
  observeTargetKey(target, key, callback);
1913
- return possiblyReactive(Reflect.get(target, key, proxy), callback);
1954
+ return possiblyReactive(Reflect.get(target, key, receiver), callback);
1914
1955
  },
1915
- set(target, key, value, proxy) {
1916
- const isNewKey = !objectHasOwnProperty.call(target, key);
1917
- const originalValue = Reflect.get(target, key, proxy);
1918
- const ret = Reflect.set(target, key, value, proxy);
1919
- if (isNewKey) {
1956
+ set(target, key, value, receiver) {
1957
+ const hadKey = objectHasOwnProperty.call(target, key);
1958
+ const originalValue = Reflect.get(target, key, receiver);
1959
+ const ret = Reflect.set(target, key, value, receiver);
1960
+ if (!hadKey && objectHasOwnProperty.call(target, key)) {
1920
1961
  notifyReactives(target, KEYCHANGES);
1921
1962
  }
1922
1963
  // While Array length may trigger the set trap, it's not actually set by this
1923
1964
  // method but is updated behind the scenes, and the trap is not called with the
1924
1965
  // new value. We disable the "same-value-optimization" for it because of that.
1925
- if (originalValue !== value || (Array.isArray(target) && key === "length")) {
1966
+ if (originalValue !== Reflect.get(target, key, receiver) ||
1967
+ (key === "length" && Array.isArray(target))) {
1926
1968
  notifyReactives(target, key);
1927
1969
  }
1928
1970
  return ret;
@@ -2098,10 +2140,8 @@ function collectionsProxyHandler(target, callback, targetRawType) {
2098
2140
  // property is read.
2099
2141
  const specialHandlers = rawTypeToFuncHandlers[targetRawType](target, callback);
2100
2142
  return Object.assign(basicProxyHandler(callback), {
2143
+ // FIXME: probably broken when part of prototype chain since we ignore the receiver
2101
2144
  get(target, key) {
2102
- if (key === TARGET) {
2103
- return target;
2104
- }
2105
2145
  if (objectHasOwnProperty.call(specialHandlers, key)) {
2106
2146
  return specialHandlers[key];
2107
2147
  }
@@ -2261,7 +2301,7 @@ class ComponentNode {
2261
2301
  this.childEnv = env;
2262
2302
  for (const key in props) {
2263
2303
  const prop = props[key];
2264
- if (prop && typeof prop === "object" && prop[TARGET]) {
2304
+ if (prop && typeof prop === "object" && targets.has(prop)) {
2265
2305
  props[key] = useState(prop);
2266
2306
  }
2267
2307
  }
@@ -2379,7 +2419,7 @@ class ComponentNode {
2379
2419
  currentNode = this;
2380
2420
  for (const key in props) {
2381
2421
  const prop = props[key];
2382
- if (prop && typeof prop === "object" && prop[TARGET]) {
2422
+ if (prop && typeof prop === "object" && targets.has(prop)) {
2383
2423
  props[key] = useState(prop);
2384
2424
  }
2385
2425
  }
@@ -2441,8 +2481,11 @@ class ComponentNode {
2441
2481
  this.children = this.fiber.childrenMap;
2442
2482
  this.fiber = null;
2443
2483
  }
2444
- moveBefore(other, afterNode) {
2445
- this.bdom.moveBefore(other ? other.bdom : null, afterNode);
2484
+ moveBeforeDOMNode(node, parent) {
2485
+ this.bdom.moveBeforeDOMNode(node, parent);
2486
+ }
2487
+ moveBeforeVNode(other, afterNode) {
2488
+ this.bdom.moveBeforeVNode(other ? other.bdom : null, afterNode);
2446
2489
  }
2447
2490
  patch() {
2448
2491
  if (this.fiber && this.fiber.parent) {
@@ -2659,7 +2702,7 @@ class Portal extends Component {
2659
2702
  if (!portal.target) {
2660
2703
  const target = document.querySelector(this.props.target);
2661
2704
  if (target) {
2662
- portal.content.moveBefore(target, null);
2705
+ portal.content.moveBeforeDOMNode(target.firstChild, target);
2663
2706
  }
2664
2707
  else {
2665
2708
  throw new OwlError("invalid portal target");
@@ -2834,7 +2877,7 @@ function callSlot(ctx, parent, key, name, dynamic, extra, defaultContent) {
2834
2877
  if (__scope) {
2835
2878
  slotScope[__scope] = extra;
2836
2879
  }
2837
- const slotBDom = __render ? __render.call(__ctx.__owl__.component, slotScope, parent, key) : null;
2880
+ const slotBDom = __render ? __render(slotScope, parent, key) : null;
2838
2881
  if (defaultContent) {
2839
2882
  let child1 = undefined;
2840
2883
  let child2 = undefined;
@@ -2842,14 +2885,13 @@ function callSlot(ctx, parent, key, name, dynamic, extra, defaultContent) {
2842
2885
  child1 = dynamic ? toggler(name, slotBDom) : slotBDom;
2843
2886
  }
2844
2887
  else {
2845
- child2 = defaultContent.call(ctx.__owl__.component, ctx, parent, key);
2888
+ child2 = defaultContent(ctx, parent, key);
2846
2889
  }
2847
2890
  return multi([child1, child2]);
2848
2891
  }
2849
2892
  return slotBDom || text("");
2850
2893
  }
2851
- function capture(ctx) {
2852
- const component = ctx.__owl__.component;
2894
+ function capture(ctx, component) {
2853
2895
  const result = ObjectCreate(component);
2854
2896
  for (let k in ctx) {
2855
2897
  result[k] = ctx[k];
@@ -2905,7 +2947,7 @@ function shallowEqual(l1, l2) {
2905
2947
  class LazyValue {
2906
2948
  constructor(fn, ctx, component, node, key) {
2907
2949
  this.fn = fn;
2908
- this.ctx = capture(ctx);
2950
+ this.ctx = capture(ctx, component);
2909
2951
  this.component = component;
2910
2952
  this.node = node;
2911
2953
  this.key = key;
@@ -2959,8 +3001,7 @@ function safeOutput(value, defaultValue) {
2959
3001
  let boundFunctions = new WeakMap();
2960
3002
  const WeakMapGet = WeakMap.prototype.get;
2961
3003
  const WeakMapSet = WeakMap.prototype.set;
2962
- function bind(ctx, fn) {
2963
- let component = ctx.__owl__.component;
3004
+ function bind(component, fn) {
2964
3005
  let boundFnMap = WeakMapGet.call(boundFunctions, component);
2965
3006
  if (!boundFnMap) {
2966
3007
  boundFnMap = new WeakMap();
@@ -3574,7 +3615,7 @@ class CodeTarget {
3574
3615
  let result = [];
3575
3616
  result.push(`function ${this.name}(ctx, node, key = "") {`);
3576
3617
  if (this.hasRef) {
3577
- result.push(` const refs = ctx.__owl__.refs;`);
3618
+ result.push(` const refs = this.__owl__.refs;`);
3578
3619
  for (let name in this.refInfo) {
3579
3620
  const [id, expr] = this.refInfo[name];
3580
3621
  result.push(` const ${id} = ${expr};`);
@@ -3959,39 +4000,6 @@ class CodeGenerator {
3959
4000
  attrs[`block-attribute-${selectedId}`] = "selected";
3960
4001
  }
3961
4002
  }
3962
- // event handlers
3963
- for (let ev in ast.on) {
3964
- const name = this.generateHandlerCode(ev, ast.on[ev]);
3965
- const idx = block.insertData(name, "hdlr");
3966
- attrs[`block-handler-${idx}`] = ev;
3967
- }
3968
- // t-ref
3969
- if (ast.ref) {
3970
- this.target.hasRef = true;
3971
- const isDynamic = INTERP_REGEXP.test(ast.ref);
3972
- if (isDynamic) {
3973
- const str = replaceDynamicParts(ast.ref, (expr) => this.captureExpression(expr, true));
3974
- const idx = block.insertData(`(el) => refs[${str}] = el`, "ref");
3975
- attrs["block-ref"] = String(idx);
3976
- }
3977
- else {
3978
- let name = ast.ref;
3979
- if (name in this.target.refInfo) {
3980
- // ref has already been defined
3981
- this.helpers.add("multiRefSetter");
3982
- const info = this.target.refInfo[name];
3983
- const index = block.data.push(info[0]) - 1;
3984
- attrs["block-ref"] = String(index);
3985
- info[1] = `multiRefSetter(refs, \`${name}\`)`;
3986
- }
3987
- else {
3988
- let id = generateId("ref");
3989
- this.target.refInfo[name] = [id, `(el) => refs[\`${name}\`] = el`];
3990
- const index = block.data.push(id) - 1;
3991
- attrs["block-ref"] = String(index);
3992
- }
3993
- }
3994
- }
3995
4003
  // t-model
3996
4004
  let tModelSelectedExpr;
3997
4005
  if (ast.model) {
@@ -4025,6 +4033,39 @@ class CodeGenerator {
4025
4033
  idx = block.insertData(handler, "hdlr");
4026
4034
  attrs[`block-handler-${idx}`] = eventType;
4027
4035
  }
4036
+ // event handlers
4037
+ for (let ev in ast.on) {
4038
+ const name = this.generateHandlerCode(ev, ast.on[ev]);
4039
+ const idx = block.insertData(name, "hdlr");
4040
+ attrs[`block-handler-${idx}`] = ev;
4041
+ }
4042
+ // t-ref
4043
+ if (ast.ref) {
4044
+ this.target.hasRef = true;
4045
+ const isDynamic = INTERP_REGEXP.test(ast.ref);
4046
+ if (isDynamic) {
4047
+ const str = replaceDynamicParts(ast.ref, (expr) => this.captureExpression(expr, true));
4048
+ const idx = block.insertData(`(el) => refs[${str}] = el`, "ref");
4049
+ attrs["block-ref"] = String(idx);
4050
+ }
4051
+ else {
4052
+ let name = ast.ref;
4053
+ if (name in this.target.refInfo) {
4054
+ // ref has already been defined
4055
+ this.helpers.add("multiRefSetter");
4056
+ const info = this.target.refInfo[name];
4057
+ const index = block.data.push(info[0]) - 1;
4058
+ attrs["block-ref"] = String(index);
4059
+ info[1] = `multiRefSetter(refs, \`${name}\`)`;
4060
+ }
4061
+ else {
4062
+ let id = generateId("ref");
4063
+ this.target.refInfo[name] = [id, `(el) => refs[\`${name}\`] = el`];
4064
+ const index = block.data.push(id) - 1;
4065
+ attrs["block-ref"] = String(index);
4066
+ }
4067
+ }
4068
+ }
4028
4069
  const dom = xmlDoc.createElement(ast.tag);
4029
4070
  for (const [attr, val] of Object.entries(attrs)) {
4030
4071
  if (!(attr === "class" && val === "")) {
@@ -4215,8 +4256,8 @@ class CodeGenerator {
4215
4256
  if (this.dev) {
4216
4257
  // Throw error on duplicate keys in dev mode
4217
4258
  this.helpers.add("OwlError");
4218
- this.addLine(`if (keys${block.id}.has(key${this.target.loopLevel})) { throw new OwlError(\`Got duplicate key in t-foreach: \${key${this.target.loopLevel}}\`)}`);
4219
- this.addLine(`keys${block.id}.add(key${this.target.loopLevel});`);
4259
+ this.addLine(`if (keys${block.id}.has(String(key${this.target.loopLevel}))) { throw new OwlError(\`Got duplicate key in t-foreach: \${key${this.target.loopLevel}}\`)}`);
4260
+ this.addLine(`keys${block.id}.add(String(key${this.target.loopLevel}));`);
4220
4261
  }
4221
4262
  let id;
4222
4263
  if (ast.memo) {
@@ -4433,7 +4474,7 @@ class CodeGenerator {
4433
4474
  if (suffix === "bind") {
4434
4475
  this.helpers.add("bind");
4435
4476
  name = _name;
4436
- value = `bind(ctx, ${value || undefined})`;
4477
+ value = `bind(this, ${value || undefined})`;
4437
4478
  }
4438
4479
  else {
4439
4480
  throw new OwlError("Invalid prop suffix");
@@ -4464,7 +4505,7 @@ class CodeGenerator {
4464
4505
  if (this.target.loopLevel || !this.hasSafeContext) {
4465
4506
  ctxStr = generateId("ctx");
4466
4507
  this.helpers.add("capture");
4467
- this.define(ctxStr, `capture(ctx)`);
4508
+ this.define(ctxStr, `capture(ctx, this)`);
4468
4509
  }
4469
4510
  let slotStr = [];
4470
4511
  for (let slotName in ast.slots) {
@@ -4472,7 +4513,7 @@ class CodeGenerator {
4472
4513
  const params = [];
4473
4514
  if (slotAst.content) {
4474
4515
  const name = this.compileInNewTarget("slot", slotAst.content, ctx, slotAst.on);
4475
- params.push(`__render: ${name}, __ctx: ${ctxStr}`);
4516
+ params.push(`__render: ${name}.bind(this), __ctx: ${ctxStr}`);
4476
4517
  }
4477
4518
  const scope = ast.slots[slotName].scope;
4478
4519
  if (scope) {
@@ -4583,7 +4624,7 @@ class CodeGenerator {
4583
4624
  const scope = this.getPropString(props, dynProps);
4584
4625
  if (ast.defaultContent) {
4585
4626
  const name = this.compileInNewTarget("defaultContent", ast.defaultContent, ctx);
4586
- blockString = `callSlot(ctx, node, ${key}, ${slotName}, ${dynamic}, ${scope}, ${name})`;
4627
+ blockString = `callSlot(ctx, node, ${key}, ${slotName}, ${dynamic}, ${scope}, ${name}.bind(this))`;
4587
4628
  }
4588
4629
  else {
4589
4630
  if (dynamic) {
@@ -4623,7 +4664,7 @@ class CodeGenerator {
4623
4664
  if (this.target.loopLevel || !this.hasSafeContext) {
4624
4665
  ctxStr = generateId("ctx");
4625
4666
  this.helpers.add("capture");
4626
- this.define(ctxStr, `capture(ctx)`);
4667
+ this.define(ctxStr, `capture(ctx, this)`);
4627
4668
  }
4628
4669
  let id = generateId("comp");
4629
4670
  this.staticDefs.push({
@@ -4631,7 +4672,7 @@ class CodeGenerator {
4631
4672
  expr: `app.createComponent(null, false, true, false, false)`,
4632
4673
  });
4633
4674
  const target = compileExpr(ast.target);
4634
- const blockString = `${id}({target: ${target},slots: {'default': {__render: ${name}, __ctx: ${ctxStr}}}}, key + \`${key}\`, node, ctx, Portal)`;
4675
+ const blockString = `${id}({target: ${target},slots: {'default': {__render: ${name}.bind(this), __ctx: ${ctxStr}}}}, key + \`${key}\`, node, ctx, Portal)`;
4635
4676
  if (block) {
4636
4677
  this.insertAnchor(block);
4637
4678
  }
@@ -5164,8 +5205,9 @@ function parseComponent(node, ctx) {
5164
5205
  }
5165
5206
  // default slot
5166
5207
  const defaultContent = parseChildNodes(clone, ctx);
5167
- if (defaultContent) {
5168
- slots = slots || {};
5208
+ slots = slots || {};
5209
+ // t-set-slot="default" has priority over content
5210
+ if (defaultContent && !slots.default) {
5169
5211
  slots.default = { content: defaultContent, on, attrs: null, scope: defaultSlotScope };
5170
5212
  }
5171
5213
  }
@@ -5605,7 +5647,11 @@ class App extends TemplateSet {
5605
5647
  else {
5606
5648
  // new component
5607
5649
  if (isStatic) {
5608
- C = parent.constructor.components[name];
5650
+ const components = parent.constructor.components;
5651
+ if (!components) {
5652
+ throw new OwlError(`Cannot find the definition of component "${name}", missing static components key in parent`);
5653
+ }
5654
+ C = components[name];
5609
5655
  if (!C) {
5610
5656
  throw new OwlError(`Cannot find the definition of component "${name}"`);
5611
5657
  }
@@ -5772,7 +5818,7 @@ TemplateSet.prototype._compileTemplate = function _compileTemplate(name, templat
5772
5818
  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, whenReady, xml };
5773
5819
 
5774
5820
 
5775
- __info__.version = '2.0.0';
5776
- __info__.date = '2022-10-07T13:28:10.216Z';
5777
- __info__.hash = 'a1f2282';
5821
+ __info__.version = '2.0.2';
5822
+ __info__.date = '2022-11-29T14:11:11.260Z';
5823
+ __info__.hash = 'ef8baa2';
5778
5824
  __info__.url = 'https://github.com/odoo/owl';