@odoo/owl 2.0.1 → 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
@@ -1740,10 +1740,6 @@ class MountFiber extends RootFiber {
1740
1740
  }
1741
1741
  }
1742
1742
 
1743
- // Allows to get the target of a Reactive (used for making a new Reactive from the underlying object)
1744
- const TARGET = Symbol("Target");
1745
- // Escape hatch to prevent reactivity system to turn something into a reactive
1746
- const SKIP = Symbol("Skip");
1747
1743
  // Special key to subscribe to, to be notified of key creation/deletion
1748
1744
  const KEYCHANGES = Symbol("Key changes");
1749
1745
  const objectToString = Object.prototype.toString;
@@ -1784,6 +1780,7 @@ function canBeMadeReactive(value) {
1784
1780
  function possiblyReactive(val, cb) {
1785
1781
  return canBeMadeReactive(val) ? reactive(val, cb) : val;
1786
1782
  }
1783
+ const skipped = new WeakSet();
1787
1784
  /**
1788
1785
  * Mark an object or array so that it is ignored by the reactivity system
1789
1786
  *
@@ -1791,7 +1788,7 @@ function possiblyReactive(val, cb) {
1791
1788
  * @returns the object itself
1792
1789
  */
1793
1790
  function markRaw(value) {
1794
- value[SKIP] = true;
1791
+ skipped.add(value);
1795
1792
  return value;
1796
1793
  }
1797
1794
  /**
@@ -1801,7 +1798,7 @@ function markRaw(value) {
1801
1798
  * @returns the underlying value
1802
1799
  */
1803
1800
  function toRaw(value) {
1804
- return value[TARGET] || value;
1801
+ return targets.has(value) ? targets.get(value) : value;
1805
1802
  }
1806
1803
  const targetToKeysToCallbacks = new WeakMap();
1807
1804
  /**
@@ -1883,6 +1880,8 @@ function getSubscriptions(callback) {
1883
1880
  };
1884
1881
  });
1885
1882
  }
1883
+ // Maps reactive objects to the underlying target
1884
+ const targets = new WeakMap();
1886
1885
  const reactiveCache = new WeakMap();
1887
1886
  /**
1888
1887
  * Creates a reactive proxy for an object. Reading data on the reactive object
@@ -1898,7 +1897,7 @@ const reactiveCache = new WeakMap();
1898
1897
  * Subscriptions:
1899
1898
  * + Reading a property on an object will subscribe you to changes in the value
1900
1899
  * of that property.
1901
- * + 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
1902
1901
  * subscribe you to the creation/deletion of keys. Checking the presence of a
1903
1902
  * key on the object with 'in' has the same effect.
1904
1903
  * - getOwnPropertyDescriptor does not currently subscribe you to the property.
@@ -1915,12 +1914,12 @@ function reactive(target, callback = () => { }) {
1915
1914
  if (!canBeMadeReactive(target)) {
1916
1915
  throw new OwlError(`Cannot make the given value reactive`);
1917
1916
  }
1918
- if (SKIP in target) {
1917
+ if (skipped.has(target)) {
1919
1918
  return target;
1920
1919
  }
1921
- const originalTarget = target[TARGET];
1922
- if (originalTarget) {
1923
- 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);
1924
1923
  }
1925
1924
  if (!reactiveCache.has(target)) {
1926
1925
  reactiveCache.set(target, new WeakMap());
@@ -1933,6 +1932,7 @@ function reactive(target, callback = () => { }) {
1933
1932
  : basicProxyHandler(callback);
1934
1933
  const proxy = new Proxy(target, handler);
1935
1934
  reactivesForTarget.set(callback, proxy);
1935
+ targets.set(proxy, target);
1936
1936
  }
1937
1937
  return reactivesForTarget.get(callback);
1938
1938
  }
@@ -1944,29 +1944,27 @@ function reactive(target, callback = () => { }) {
1944
1944
  */
1945
1945
  function basicProxyHandler(callback) {
1946
1946
  return {
1947
- get(target, key, proxy) {
1948
- if (key === TARGET) {
1949
- return target;
1950
- }
1947
+ get(target, key, receiver) {
1951
1948
  // non-writable non-configurable properties cannot be made reactive
1952
1949
  const desc = Object.getOwnPropertyDescriptor(target, key);
1953
1950
  if (desc && !desc.writable && !desc.configurable) {
1954
- return Reflect.get(target, key, proxy);
1951
+ return Reflect.get(target, key, receiver);
1955
1952
  }
1956
1953
  observeTargetKey(target, key, callback);
1957
- return possiblyReactive(Reflect.get(target, key, proxy), callback);
1954
+ return possiblyReactive(Reflect.get(target, key, receiver), callback);
1958
1955
  },
1959
- set(target, key, value, proxy) {
1960
- const isNewKey = !objectHasOwnProperty.call(target, key);
1961
- const originalValue = Reflect.get(target, key, proxy);
1962
- const ret = Reflect.set(target, key, value, proxy);
1963
- 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)) {
1964
1961
  notifyReactives(target, KEYCHANGES);
1965
1962
  }
1966
1963
  // While Array length may trigger the set trap, it's not actually set by this
1967
1964
  // method but is updated behind the scenes, and the trap is not called with the
1968
1965
  // new value. We disable the "same-value-optimization" for it because of that.
1969
- if (originalValue !== value || (Array.isArray(target) && key === "length")) {
1966
+ if (originalValue !== Reflect.get(target, key, receiver) ||
1967
+ (key === "length" && Array.isArray(target))) {
1970
1968
  notifyReactives(target, key);
1971
1969
  }
1972
1970
  return ret;
@@ -2142,10 +2140,8 @@ function collectionsProxyHandler(target, callback, targetRawType) {
2142
2140
  // property is read.
2143
2141
  const specialHandlers = rawTypeToFuncHandlers[targetRawType](target, callback);
2144
2142
  return Object.assign(basicProxyHandler(callback), {
2143
+ // FIXME: probably broken when part of prototype chain since we ignore the receiver
2145
2144
  get(target, key) {
2146
- if (key === TARGET) {
2147
- return target;
2148
- }
2149
2145
  if (objectHasOwnProperty.call(specialHandlers, key)) {
2150
2146
  return specialHandlers[key];
2151
2147
  }
@@ -2305,7 +2301,7 @@ class ComponentNode {
2305
2301
  this.childEnv = env;
2306
2302
  for (const key in props) {
2307
2303
  const prop = props[key];
2308
- if (prop && typeof prop === "object" && prop[TARGET]) {
2304
+ if (prop && typeof prop === "object" && targets.has(prop)) {
2309
2305
  props[key] = useState(prop);
2310
2306
  }
2311
2307
  }
@@ -2423,7 +2419,7 @@ class ComponentNode {
2423
2419
  currentNode = this;
2424
2420
  for (const key in props) {
2425
2421
  const prop = props[key];
2426
- if (prop && typeof prop === "object" && prop[TARGET]) {
2422
+ if (prop && typeof prop === "object" && targets.has(prop)) {
2427
2423
  props[key] = useState(prop);
2428
2424
  }
2429
2425
  }
@@ -2881,7 +2877,7 @@ function callSlot(ctx, parent, key, name, dynamic, extra, defaultContent) {
2881
2877
  if (__scope) {
2882
2878
  slotScope[__scope] = extra;
2883
2879
  }
2884
- const slotBDom = __render ? __render.call(__ctx.__owl__.component, slotScope, parent, key) : null;
2880
+ const slotBDom = __render ? __render(slotScope, parent, key) : null;
2885
2881
  if (defaultContent) {
2886
2882
  let child1 = undefined;
2887
2883
  let child2 = undefined;
@@ -2889,14 +2885,13 @@ function callSlot(ctx, parent, key, name, dynamic, extra, defaultContent) {
2889
2885
  child1 = dynamic ? toggler(name, slotBDom) : slotBDom;
2890
2886
  }
2891
2887
  else {
2892
- child2 = defaultContent.call(ctx.__owl__.component, ctx, parent, key);
2888
+ child2 = defaultContent(ctx, parent, key);
2893
2889
  }
2894
2890
  return multi([child1, child2]);
2895
2891
  }
2896
2892
  return slotBDom || text("");
2897
2893
  }
2898
- function capture(ctx) {
2899
- const component = ctx.__owl__.component;
2894
+ function capture(ctx, component) {
2900
2895
  const result = ObjectCreate(component);
2901
2896
  for (let k in ctx) {
2902
2897
  result[k] = ctx[k];
@@ -2952,7 +2947,7 @@ function shallowEqual(l1, l2) {
2952
2947
  class LazyValue {
2953
2948
  constructor(fn, ctx, component, node, key) {
2954
2949
  this.fn = fn;
2955
- this.ctx = capture(ctx);
2950
+ this.ctx = capture(ctx, component);
2956
2951
  this.component = component;
2957
2952
  this.node = node;
2958
2953
  this.key = key;
@@ -3006,8 +3001,7 @@ function safeOutput(value, defaultValue) {
3006
3001
  let boundFunctions = new WeakMap();
3007
3002
  const WeakMapGet = WeakMap.prototype.get;
3008
3003
  const WeakMapSet = WeakMap.prototype.set;
3009
- function bind(ctx, fn) {
3010
- let component = ctx.__owl__.component;
3004
+ function bind(component, fn) {
3011
3005
  let boundFnMap = WeakMapGet.call(boundFunctions, component);
3012
3006
  if (!boundFnMap) {
3013
3007
  boundFnMap = new WeakMap();
@@ -3621,7 +3615,7 @@ class CodeTarget {
3621
3615
  let result = [];
3622
3616
  result.push(`function ${this.name}(ctx, node, key = "") {`);
3623
3617
  if (this.hasRef) {
3624
- result.push(` const refs = ctx.__owl__.refs;`);
3618
+ result.push(` const refs = this.__owl__.refs;`);
3625
3619
  for (let name in this.refInfo) {
3626
3620
  const [id, expr] = this.refInfo[name];
3627
3621
  result.push(` const ${id} = ${expr};`);
@@ -4006,39 +4000,6 @@ class CodeGenerator {
4006
4000
  attrs[`block-attribute-${selectedId}`] = "selected";
4007
4001
  }
4008
4002
  }
4009
- // event handlers
4010
- for (let ev in ast.on) {
4011
- const name = this.generateHandlerCode(ev, ast.on[ev]);
4012
- const idx = block.insertData(name, "hdlr");
4013
- attrs[`block-handler-${idx}`] = ev;
4014
- }
4015
- // t-ref
4016
- if (ast.ref) {
4017
- this.target.hasRef = true;
4018
- const isDynamic = INTERP_REGEXP.test(ast.ref);
4019
- if (isDynamic) {
4020
- const str = replaceDynamicParts(ast.ref, (expr) => this.captureExpression(expr, true));
4021
- const idx = block.insertData(`(el) => refs[${str}] = el`, "ref");
4022
- attrs["block-ref"] = String(idx);
4023
- }
4024
- else {
4025
- let name = ast.ref;
4026
- if (name in this.target.refInfo) {
4027
- // ref has already been defined
4028
- this.helpers.add("multiRefSetter");
4029
- const info = this.target.refInfo[name];
4030
- const index = block.data.push(info[0]) - 1;
4031
- attrs["block-ref"] = String(index);
4032
- info[1] = `multiRefSetter(refs, \`${name}\`)`;
4033
- }
4034
- else {
4035
- let id = generateId("ref");
4036
- this.target.refInfo[name] = [id, `(el) => refs[\`${name}\`] = el`];
4037
- const index = block.data.push(id) - 1;
4038
- attrs["block-ref"] = String(index);
4039
- }
4040
- }
4041
- }
4042
4003
  // t-model
4043
4004
  let tModelSelectedExpr;
4044
4005
  if (ast.model) {
@@ -4072,6 +4033,39 @@ class CodeGenerator {
4072
4033
  idx = block.insertData(handler, "hdlr");
4073
4034
  attrs[`block-handler-${idx}`] = eventType;
4074
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
+ }
4075
4069
  const dom = xmlDoc.createElement(ast.tag);
4076
4070
  for (const [attr, val] of Object.entries(attrs)) {
4077
4071
  if (!(attr === "class" && val === "")) {
@@ -4480,7 +4474,7 @@ class CodeGenerator {
4480
4474
  if (suffix === "bind") {
4481
4475
  this.helpers.add("bind");
4482
4476
  name = _name;
4483
- value = `bind(ctx, ${value || undefined})`;
4477
+ value = `bind(this, ${value || undefined})`;
4484
4478
  }
4485
4479
  else {
4486
4480
  throw new OwlError("Invalid prop suffix");
@@ -4511,7 +4505,7 @@ class CodeGenerator {
4511
4505
  if (this.target.loopLevel || !this.hasSafeContext) {
4512
4506
  ctxStr = generateId("ctx");
4513
4507
  this.helpers.add("capture");
4514
- this.define(ctxStr, `capture(ctx)`);
4508
+ this.define(ctxStr, `capture(ctx, this)`);
4515
4509
  }
4516
4510
  let slotStr = [];
4517
4511
  for (let slotName in ast.slots) {
@@ -4519,7 +4513,7 @@ class CodeGenerator {
4519
4513
  const params = [];
4520
4514
  if (slotAst.content) {
4521
4515
  const name = this.compileInNewTarget("slot", slotAst.content, ctx, slotAst.on);
4522
- params.push(`__render: ${name}, __ctx: ${ctxStr}`);
4516
+ params.push(`__render: ${name}.bind(this), __ctx: ${ctxStr}`);
4523
4517
  }
4524
4518
  const scope = ast.slots[slotName].scope;
4525
4519
  if (scope) {
@@ -4630,7 +4624,7 @@ class CodeGenerator {
4630
4624
  const scope = this.getPropString(props, dynProps);
4631
4625
  if (ast.defaultContent) {
4632
4626
  const name = this.compileInNewTarget("defaultContent", ast.defaultContent, ctx);
4633
- blockString = `callSlot(ctx, node, ${key}, ${slotName}, ${dynamic}, ${scope}, ${name})`;
4627
+ blockString = `callSlot(ctx, node, ${key}, ${slotName}, ${dynamic}, ${scope}, ${name}.bind(this))`;
4634
4628
  }
4635
4629
  else {
4636
4630
  if (dynamic) {
@@ -4670,7 +4664,7 @@ class CodeGenerator {
4670
4664
  if (this.target.loopLevel || !this.hasSafeContext) {
4671
4665
  ctxStr = generateId("ctx");
4672
4666
  this.helpers.add("capture");
4673
- this.define(ctxStr, `capture(ctx)`);
4667
+ this.define(ctxStr, `capture(ctx, this)`);
4674
4668
  }
4675
4669
  let id = generateId("comp");
4676
4670
  this.staticDefs.push({
@@ -4678,7 +4672,7 @@ class CodeGenerator {
4678
4672
  expr: `app.createComponent(null, false, true, false, false)`,
4679
4673
  });
4680
4674
  const target = compileExpr(ast.target);
4681
- 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)`;
4682
4676
  if (block) {
4683
4677
  this.insertAnchor(block);
4684
4678
  }
@@ -5653,7 +5647,11 @@ class App extends TemplateSet {
5653
5647
  else {
5654
5648
  // new component
5655
5649
  if (isStatic) {
5656
- 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];
5657
5655
  if (!C) {
5658
5656
  throw new OwlError(`Cannot find the definition of component "${name}"`);
5659
5657
  }
@@ -5820,7 +5818,7 @@ TemplateSet.prototype._compileTemplate = function _compileTemplate(name, templat
5820
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 };
5821
5819
 
5822
5820
 
5823
- __info__.version = '2.0.1';
5824
- __info__.date = '2022-10-21T08:41:01.873Z';
5825
- __info__.hash = '9fe8e93';
5821
+ __info__.version = '2.0.2';
5822
+ __info__.date = '2022-11-29T14:11:11.260Z';
5823
+ __info__.hash = 'ef8baa2';
5826
5824
  __info__.url = 'https://github.com/odoo/owl';