@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.iife.js CHANGED
@@ -1743,10 +1743,6 @@
1743
1743
  }
1744
1744
  }
1745
1745
 
1746
- // Allows to get the target of a Reactive (used for making a new Reactive from the underlying object)
1747
- const TARGET = Symbol("Target");
1748
- // Escape hatch to prevent reactivity system to turn something into a reactive
1749
- const SKIP = Symbol("Skip");
1750
1746
  // Special key to subscribe to, to be notified of key creation/deletion
1751
1747
  const KEYCHANGES = Symbol("Key changes");
1752
1748
  const objectToString = Object.prototype.toString;
@@ -1787,6 +1783,7 @@
1787
1783
  function possiblyReactive(val, cb) {
1788
1784
  return canBeMadeReactive(val) ? reactive(val, cb) : val;
1789
1785
  }
1786
+ const skipped = new WeakSet();
1790
1787
  /**
1791
1788
  * Mark an object or array so that it is ignored by the reactivity system
1792
1789
  *
@@ -1794,7 +1791,7 @@
1794
1791
  * @returns the object itself
1795
1792
  */
1796
1793
  function markRaw(value) {
1797
- value[SKIP] = true;
1794
+ skipped.add(value);
1798
1795
  return value;
1799
1796
  }
1800
1797
  /**
@@ -1804,7 +1801,7 @@
1804
1801
  * @returns the underlying value
1805
1802
  */
1806
1803
  function toRaw(value) {
1807
- return value[TARGET] || value;
1804
+ return targets.has(value) ? targets.get(value) : value;
1808
1805
  }
1809
1806
  const targetToKeysToCallbacks = new WeakMap();
1810
1807
  /**
@@ -1886,6 +1883,8 @@
1886
1883
  };
1887
1884
  });
1888
1885
  }
1886
+ // Maps reactive objects to the underlying target
1887
+ const targets = new WeakMap();
1889
1888
  const reactiveCache = new WeakMap();
1890
1889
  /**
1891
1890
  * Creates a reactive proxy for an object. Reading data on the reactive object
@@ -1901,7 +1900,7 @@
1901
1900
  * Subscriptions:
1902
1901
  * + Reading a property on an object will subscribe you to changes in the value
1903
1902
  * of that property.
1904
- * + Accessing an object keys (eg with Object.keys or with `for..in`) will
1903
+ * + Accessing an object's keys (eg with Object.keys or with `for..in`) will
1905
1904
  * subscribe you to the creation/deletion of keys. Checking the presence of a
1906
1905
  * key on the object with 'in' has the same effect.
1907
1906
  * - getOwnPropertyDescriptor does not currently subscribe you to the property.
@@ -1918,12 +1917,12 @@
1918
1917
  if (!canBeMadeReactive(target)) {
1919
1918
  throw new OwlError(`Cannot make the given value reactive`);
1920
1919
  }
1921
- if (SKIP in target) {
1920
+ if (skipped.has(target)) {
1922
1921
  return target;
1923
1922
  }
1924
- const originalTarget = target[TARGET];
1925
- if (originalTarget) {
1926
- return reactive(originalTarget, callback);
1923
+ if (targets.has(target)) {
1924
+ // target is reactive, create a reactive on the underlying object instead
1925
+ return reactive(targets.get(target), callback);
1927
1926
  }
1928
1927
  if (!reactiveCache.has(target)) {
1929
1928
  reactiveCache.set(target, new WeakMap());
@@ -1936,6 +1935,7 @@
1936
1935
  : basicProxyHandler(callback);
1937
1936
  const proxy = new Proxy(target, handler);
1938
1937
  reactivesForTarget.set(callback, proxy);
1938
+ targets.set(proxy, target);
1939
1939
  }
1940
1940
  return reactivesForTarget.get(callback);
1941
1941
  }
@@ -1947,29 +1947,27 @@
1947
1947
  */
1948
1948
  function basicProxyHandler(callback) {
1949
1949
  return {
1950
- get(target, key, proxy) {
1951
- if (key === TARGET) {
1952
- return target;
1953
- }
1950
+ get(target, key, receiver) {
1954
1951
  // non-writable non-configurable properties cannot be made reactive
1955
1952
  const desc = Object.getOwnPropertyDescriptor(target, key);
1956
1953
  if (desc && !desc.writable && !desc.configurable) {
1957
- return Reflect.get(target, key, proxy);
1954
+ return Reflect.get(target, key, receiver);
1958
1955
  }
1959
1956
  observeTargetKey(target, key, callback);
1960
- return possiblyReactive(Reflect.get(target, key, proxy), callback);
1957
+ return possiblyReactive(Reflect.get(target, key, receiver), callback);
1961
1958
  },
1962
- set(target, key, value, proxy) {
1963
- const isNewKey = !objectHasOwnProperty.call(target, key);
1964
- const originalValue = Reflect.get(target, key, proxy);
1965
- const ret = Reflect.set(target, key, value, proxy);
1966
- if (isNewKey) {
1959
+ set(target, key, value, receiver) {
1960
+ const hadKey = objectHasOwnProperty.call(target, key);
1961
+ const originalValue = Reflect.get(target, key, receiver);
1962
+ const ret = Reflect.set(target, key, value, receiver);
1963
+ if (!hadKey && objectHasOwnProperty.call(target, key)) {
1967
1964
  notifyReactives(target, KEYCHANGES);
1968
1965
  }
1969
1966
  // While Array length may trigger the set trap, it's not actually set by this
1970
1967
  // method but is updated behind the scenes, and the trap is not called with the
1971
1968
  // new value. We disable the "same-value-optimization" for it because of that.
1972
- if (originalValue !== value || (Array.isArray(target) && key === "length")) {
1969
+ if (originalValue !== Reflect.get(target, key, receiver) ||
1970
+ (key === "length" && Array.isArray(target))) {
1973
1971
  notifyReactives(target, key);
1974
1972
  }
1975
1973
  return ret;
@@ -2145,10 +2143,8 @@
2145
2143
  // property is read.
2146
2144
  const specialHandlers = rawTypeToFuncHandlers[targetRawType](target, callback);
2147
2145
  return Object.assign(basicProxyHandler(callback), {
2146
+ // FIXME: probably broken when part of prototype chain since we ignore the receiver
2148
2147
  get(target, key) {
2149
- if (key === TARGET) {
2150
- return target;
2151
- }
2152
2148
  if (objectHasOwnProperty.call(specialHandlers, key)) {
2153
2149
  return specialHandlers[key];
2154
2150
  }
@@ -2308,7 +2304,7 @@
2308
2304
  this.childEnv = env;
2309
2305
  for (const key in props) {
2310
2306
  const prop = props[key];
2311
- if (prop && typeof prop === "object" && prop[TARGET]) {
2307
+ if (prop && typeof prop === "object" && targets.has(prop)) {
2312
2308
  props[key] = useState(prop);
2313
2309
  }
2314
2310
  }
@@ -2426,7 +2422,7 @@
2426
2422
  currentNode = this;
2427
2423
  for (const key in props) {
2428
2424
  const prop = props[key];
2429
- if (prop && typeof prop === "object" && prop[TARGET]) {
2425
+ if (prop && typeof prop === "object" && targets.has(prop)) {
2430
2426
  props[key] = useState(prop);
2431
2427
  }
2432
2428
  }
@@ -2884,7 +2880,7 @@
2884
2880
  if (__scope) {
2885
2881
  slotScope[__scope] = extra;
2886
2882
  }
2887
- const slotBDom = __render ? __render.call(__ctx.__owl__.component, slotScope, parent, key) : null;
2883
+ const slotBDom = __render ? __render(slotScope, parent, key) : null;
2888
2884
  if (defaultContent) {
2889
2885
  let child1 = undefined;
2890
2886
  let child2 = undefined;
@@ -2892,14 +2888,13 @@
2892
2888
  child1 = dynamic ? toggler(name, slotBDom) : slotBDom;
2893
2889
  }
2894
2890
  else {
2895
- child2 = defaultContent.call(ctx.__owl__.component, ctx, parent, key);
2891
+ child2 = defaultContent(ctx, parent, key);
2896
2892
  }
2897
2893
  return multi([child1, child2]);
2898
2894
  }
2899
2895
  return slotBDom || text("");
2900
2896
  }
2901
- function capture(ctx) {
2902
- const component = ctx.__owl__.component;
2897
+ function capture(ctx, component) {
2903
2898
  const result = ObjectCreate(component);
2904
2899
  for (let k in ctx) {
2905
2900
  result[k] = ctx[k];
@@ -2955,7 +2950,7 @@
2955
2950
  class LazyValue {
2956
2951
  constructor(fn, ctx, component, node, key) {
2957
2952
  this.fn = fn;
2958
- this.ctx = capture(ctx);
2953
+ this.ctx = capture(ctx, component);
2959
2954
  this.component = component;
2960
2955
  this.node = node;
2961
2956
  this.key = key;
@@ -3009,8 +3004,7 @@
3009
3004
  let boundFunctions = new WeakMap();
3010
3005
  const WeakMapGet = WeakMap.prototype.get;
3011
3006
  const WeakMapSet = WeakMap.prototype.set;
3012
- function bind(ctx, fn) {
3013
- let component = ctx.__owl__.component;
3007
+ function bind(component, fn) {
3014
3008
  let boundFnMap = WeakMapGet.call(boundFunctions, component);
3015
3009
  if (!boundFnMap) {
3016
3010
  boundFnMap = new WeakMap();
@@ -3624,7 +3618,7 @@
3624
3618
  let result = [];
3625
3619
  result.push(`function ${this.name}(ctx, node, key = "") {`);
3626
3620
  if (this.hasRef) {
3627
- result.push(` const refs = ctx.__owl__.refs;`);
3621
+ result.push(` const refs = this.__owl__.refs;`);
3628
3622
  for (let name in this.refInfo) {
3629
3623
  const [id, expr] = this.refInfo[name];
3630
3624
  result.push(` const ${id} = ${expr};`);
@@ -4009,39 +4003,6 @@
4009
4003
  attrs[`block-attribute-${selectedId}`] = "selected";
4010
4004
  }
4011
4005
  }
4012
- // event handlers
4013
- for (let ev in ast.on) {
4014
- const name = this.generateHandlerCode(ev, ast.on[ev]);
4015
- const idx = block.insertData(name, "hdlr");
4016
- attrs[`block-handler-${idx}`] = ev;
4017
- }
4018
- // t-ref
4019
- if (ast.ref) {
4020
- this.target.hasRef = true;
4021
- const isDynamic = INTERP_REGEXP.test(ast.ref);
4022
- if (isDynamic) {
4023
- const str = replaceDynamicParts(ast.ref, (expr) => this.captureExpression(expr, true));
4024
- const idx = block.insertData(`(el) => refs[${str}] = el`, "ref");
4025
- attrs["block-ref"] = String(idx);
4026
- }
4027
- else {
4028
- let name = ast.ref;
4029
- if (name in this.target.refInfo) {
4030
- // ref has already been defined
4031
- this.helpers.add("multiRefSetter");
4032
- const info = this.target.refInfo[name];
4033
- const index = block.data.push(info[0]) - 1;
4034
- attrs["block-ref"] = String(index);
4035
- info[1] = `multiRefSetter(refs, \`${name}\`)`;
4036
- }
4037
- else {
4038
- let id = generateId("ref");
4039
- this.target.refInfo[name] = [id, `(el) => refs[\`${name}\`] = el`];
4040
- const index = block.data.push(id) - 1;
4041
- attrs["block-ref"] = String(index);
4042
- }
4043
- }
4044
- }
4045
4006
  // t-model
4046
4007
  let tModelSelectedExpr;
4047
4008
  if (ast.model) {
@@ -4075,6 +4036,39 @@
4075
4036
  idx = block.insertData(handler, "hdlr");
4076
4037
  attrs[`block-handler-${idx}`] = eventType;
4077
4038
  }
4039
+ // event handlers
4040
+ for (let ev in ast.on) {
4041
+ const name = this.generateHandlerCode(ev, ast.on[ev]);
4042
+ const idx = block.insertData(name, "hdlr");
4043
+ attrs[`block-handler-${idx}`] = ev;
4044
+ }
4045
+ // t-ref
4046
+ if (ast.ref) {
4047
+ this.target.hasRef = true;
4048
+ const isDynamic = INTERP_REGEXP.test(ast.ref);
4049
+ if (isDynamic) {
4050
+ const str = replaceDynamicParts(ast.ref, (expr) => this.captureExpression(expr, true));
4051
+ const idx = block.insertData(`(el) => refs[${str}] = el`, "ref");
4052
+ attrs["block-ref"] = String(idx);
4053
+ }
4054
+ else {
4055
+ let name = ast.ref;
4056
+ if (name in this.target.refInfo) {
4057
+ // ref has already been defined
4058
+ this.helpers.add("multiRefSetter");
4059
+ const info = this.target.refInfo[name];
4060
+ const index = block.data.push(info[0]) - 1;
4061
+ attrs["block-ref"] = String(index);
4062
+ info[1] = `multiRefSetter(refs, \`${name}\`)`;
4063
+ }
4064
+ else {
4065
+ let id = generateId("ref");
4066
+ this.target.refInfo[name] = [id, `(el) => refs[\`${name}\`] = el`];
4067
+ const index = block.data.push(id) - 1;
4068
+ attrs["block-ref"] = String(index);
4069
+ }
4070
+ }
4071
+ }
4078
4072
  const dom = xmlDoc.createElement(ast.tag);
4079
4073
  for (const [attr, val] of Object.entries(attrs)) {
4080
4074
  if (!(attr === "class" && val === "")) {
@@ -4483,7 +4477,7 @@
4483
4477
  if (suffix === "bind") {
4484
4478
  this.helpers.add("bind");
4485
4479
  name = _name;
4486
- value = `bind(ctx, ${value || undefined})`;
4480
+ value = `bind(this, ${value || undefined})`;
4487
4481
  }
4488
4482
  else {
4489
4483
  throw new OwlError("Invalid prop suffix");
@@ -4514,7 +4508,7 @@
4514
4508
  if (this.target.loopLevel || !this.hasSafeContext) {
4515
4509
  ctxStr = generateId("ctx");
4516
4510
  this.helpers.add("capture");
4517
- this.define(ctxStr, `capture(ctx)`);
4511
+ this.define(ctxStr, `capture(ctx, this)`);
4518
4512
  }
4519
4513
  let slotStr = [];
4520
4514
  for (let slotName in ast.slots) {
@@ -4522,7 +4516,7 @@
4522
4516
  const params = [];
4523
4517
  if (slotAst.content) {
4524
4518
  const name = this.compileInNewTarget("slot", slotAst.content, ctx, slotAst.on);
4525
- params.push(`__render: ${name}, __ctx: ${ctxStr}`);
4519
+ params.push(`__render: ${name}.bind(this), __ctx: ${ctxStr}`);
4526
4520
  }
4527
4521
  const scope = ast.slots[slotName].scope;
4528
4522
  if (scope) {
@@ -4633,7 +4627,7 @@
4633
4627
  const scope = this.getPropString(props, dynProps);
4634
4628
  if (ast.defaultContent) {
4635
4629
  const name = this.compileInNewTarget("defaultContent", ast.defaultContent, ctx);
4636
- blockString = `callSlot(ctx, node, ${key}, ${slotName}, ${dynamic}, ${scope}, ${name})`;
4630
+ blockString = `callSlot(ctx, node, ${key}, ${slotName}, ${dynamic}, ${scope}, ${name}.bind(this))`;
4637
4631
  }
4638
4632
  else {
4639
4633
  if (dynamic) {
@@ -4673,7 +4667,7 @@
4673
4667
  if (this.target.loopLevel || !this.hasSafeContext) {
4674
4668
  ctxStr = generateId("ctx");
4675
4669
  this.helpers.add("capture");
4676
- this.define(ctxStr, `capture(ctx)`);
4670
+ this.define(ctxStr, `capture(ctx, this)`);
4677
4671
  }
4678
4672
  let id = generateId("comp");
4679
4673
  this.staticDefs.push({
@@ -4681,7 +4675,7 @@
4681
4675
  expr: `app.createComponent(null, false, true, false, false)`,
4682
4676
  });
4683
4677
  const target = compileExpr(ast.target);
4684
- const blockString = `${id}({target: ${target},slots: {'default': {__render: ${name}, __ctx: ${ctxStr}}}}, key + \`${key}\`, node, ctx, Portal)`;
4678
+ const blockString = `${id}({target: ${target},slots: {'default': {__render: ${name}.bind(this), __ctx: ${ctxStr}}}}, key + \`${key}\`, node, ctx, Portal)`;
4685
4679
  if (block) {
4686
4680
  this.insertAnchor(block);
4687
4681
  }
@@ -5656,7 +5650,11 @@ See https://github.com/odoo/owl/blob/${hash}/doc/reference/app.md#configuration
5656
5650
  else {
5657
5651
  // new component
5658
5652
  if (isStatic) {
5659
- C = parent.constructor.components[name];
5653
+ const components = parent.constructor.components;
5654
+ if (!components) {
5655
+ throw new OwlError(`Cannot find the definition of component "${name}", missing static components key in parent`);
5656
+ }
5657
+ C = components[name];
5660
5658
  if (!C) {
5661
5659
  throw new OwlError(`Cannot find the definition of component "${name}"`);
5662
5660
  }
@@ -5858,9 +5856,9 @@ See https://github.com/odoo/owl/blob/${hash}/doc/reference/app.md#configuration
5858
5856
  Object.defineProperty(exports, '__esModule', { value: true });
5859
5857
 
5860
5858
 
5861
- __info__.version = '2.0.1';
5862
- __info__.date = '2022-10-21T08:41:01.873Z';
5863
- __info__.hash = '9fe8e93';
5859
+ __info__.version = '2.0.2';
5860
+ __info__.date = '2022-11-29T14:11:11.260Z';
5861
+ __info__.hash = 'ef8baa2';
5864
5862
  __info__.url = 'https://github.com/odoo/owl';
5865
5863
 
5866
5864