@odoo/owl 3.0.0-alpha.21 → 3.0.0-alpha.23

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
@@ -285,31 +285,6 @@
285
285
  return { [expr]: true };
286
286
  }
287
287
  }
288
- function setClass(val) {
289
- val = val === "" ? {} : toClassObj(val);
290
- // add classes
291
- const cl = this.classList;
292
- for (let c in val) {
293
- tokenListAdd.call(cl, c);
294
- }
295
- }
296
- function updateClass(val, oldVal) {
297
- oldVal = oldVal === "" ? {} : toClassObj(oldVal);
298
- val = val === "" ? {} : toClassObj(val);
299
- const cl = this.classList;
300
- // remove classes
301
- for (let c in oldVal) {
302
- if (!(c in val)) {
303
- tokenListRemove.call(cl, c);
304
- }
305
- }
306
- // add classes
307
- for (let c in val) {
308
- if (!(c in oldVal)) {
309
- tokenListAdd.call(cl, c);
310
- }
311
- }
312
- }
313
288
  // ---------------------------------------------------------------------------
314
289
  // Style
315
290
  // ---------------------------------------------------------------------------
@@ -342,7 +317,7 @@
342
317
  }
343
318
  const prop = trim.call(part.slice(0, colonIdx));
344
319
  const value = trim.call(part.slice(colonIdx + 1));
345
- if (prop && value) {
320
+ if (prop && value && value !== "undefined") {
346
321
  result[prop] = value;
347
322
  }
348
323
  }
@@ -360,6 +335,32 @@
360
335
  return {};
361
336
  }
362
337
  }
338
+ // ---------------------------------------------------------------------------
339
+ // Class
340
+ // ---------------------------------------------------------------------------
341
+ function setClass(val) {
342
+ val = val === "" ? {} : toClassObj(val);
343
+ for (let k in val) {
344
+ tokenListAdd.call(this.classList, k);
345
+ }
346
+ }
347
+ function updateClass(val, oldVal) {
348
+ oldVal = oldVal === "" ? {} : toClassObj(oldVal);
349
+ val = val === "" ? {} : toClassObj(val);
350
+ for (let k in oldVal) {
351
+ if (!(k in val)) {
352
+ tokenListRemove.call(this.classList, k);
353
+ }
354
+ }
355
+ for (let k in val) {
356
+ if (val[k] !== oldVal[k]) {
357
+ tokenListAdd.call(this.classList, k);
358
+ }
359
+ }
360
+ }
361
+ // ---------------------------------------------------------------------------
362
+ // Style setters
363
+ // ---------------------------------------------------------------------------
363
364
  function setStyle(val) {
364
365
  val = val === "" ? {} : toStyleObj(val);
365
366
  const style = this.style;
@@ -371,18 +372,19 @@
371
372
  oldVal = oldVal === "" ? {} : toStyleObj(oldVal);
372
373
  val = val === "" ? {} : toStyleObj(val);
373
374
  const style = this.style;
374
- // remove old styles
375
375
  for (let prop in oldVal) {
376
376
  if (!(prop in val)) {
377
377
  style.removeProperty(prop);
378
378
  }
379
379
  }
380
- // set new/changed styles
381
380
  for (let prop in val) {
382
381
  if (val[prop] !== oldVal[prop]) {
383
382
  style.setProperty(prop, val[prop]);
384
383
  }
385
384
  }
385
+ if (!style.cssText) {
386
+ removeAttribute.call(this, "style");
387
+ }
386
388
  }
387
389
 
388
390
  /**
@@ -2001,51 +2003,11 @@
2001
2003
  // Maps fibers to thrown errors
2002
2004
  const fibersInError = new WeakMap();
2003
2005
  const nodeErrorHandlers = new WeakMap();
2004
- function destroyApp(app, error) {
2005
- try {
2006
- app.destroy();
2007
- }
2008
- catch (e) {
2009
- // mute all errors here because we are in a corrupted state anyway
2010
- }
2011
- const e = Object.assign(new OwlError(`[Owl] Unhandled error. Destroying the root component`), {
2012
- cause: error,
2013
- });
2014
- return e;
2015
- }
2016
- function _handleError(node, error) {
2017
- if (!node) {
2018
- return false;
2019
- }
2020
- const fiber = node.fiber;
2021
- if (fiber) {
2022
- fibersInError.set(fiber, error);
2023
- }
2024
- const errorHandlers = nodeErrorHandlers.get(node);
2025
- if (errorHandlers) {
2026
- let handled = false;
2027
- // execute in the opposite order
2028
- const finalize = () => destroyApp(node.app, error);
2029
- for (let i = errorHandlers.length - 1; i >= 0; i--) {
2030
- try {
2031
- errorHandlers[i](error, finalize);
2032
- handled = true;
2033
- break;
2034
- }
2035
- catch (e) {
2036
- error = e;
2037
- }
2038
- }
2039
- if (handled) {
2040
- return true;
2041
- }
2042
- }
2043
- return _handleError(node.parent, error);
2044
- }
2045
2006
  function handleError(params) {
2046
2007
  let { error } = params;
2047
- const node = "node" in params ? params.node : params.fiber.node;
2008
+ let node = "node" in params ? params.node : params.fiber.node;
2048
2009
  const fiber = "fiber" in params ? params.fiber : node.fiber;
2010
+ const app = node.app;
2049
2011
  if (fiber) {
2050
2012
  // resets the fibers on components if possible. This is important so that
2051
2013
  // new renderings can be properly included in the initial one, if any.
@@ -2057,10 +2019,43 @@
2057
2019
  } while (current);
2058
2020
  fibersInError.set(fiber.root, error);
2059
2021
  }
2060
- const handled = _handleError(node, error);
2061
- if (!handled) {
2062
- throw destroyApp(node.app, error);
2022
+ const finalize = () => {
2023
+ try {
2024
+ app.destroy();
2025
+ }
2026
+ catch (e) {
2027
+ // mute all errors here because we are in a corrupted state anyway
2028
+ }
2029
+ return Object.assign(new OwlError(`[Owl] Unhandled error. Destroying the root component`), {
2030
+ cause: error,
2031
+ });
2032
+ };
2033
+ // Walk up the component tree looking for error handlers
2034
+ while (node) {
2035
+ const nodeFiber = node.fiber;
2036
+ if (nodeFiber) {
2037
+ fibersInError.set(nodeFiber, error);
2038
+ }
2039
+ const errorHandlers = nodeErrorHandlers.get(node);
2040
+ if (errorHandlers) {
2041
+ // execute in the opposite order
2042
+ for (let i = errorHandlers.length - 1; i >= 0; i--) {
2043
+ try {
2044
+ errorHandlers[i](error, finalize);
2045
+ return; // handled
2046
+ }
2047
+ catch (e) {
2048
+ error = e;
2049
+ }
2050
+ }
2051
+ }
2052
+ node = node.parent;
2063
2053
  }
2054
+ // No handler found — create the OwlError, then let the app handle it.
2055
+ // app._handleError is called after error creation, so it doesn't appear
2056
+ // in the error's .stack property.
2057
+ const owlError = finalize();
2058
+ app._handleError(owlError);
2064
2059
  }
2065
2060
 
2066
2061
  function makeChildFiber(node, parent) {
@@ -2196,7 +2191,7 @@
2196
2191
  this.bdom = node.renderFn();
2197
2192
  }
2198
2193
  catch (e) {
2199
- node.app.handleError({ node, error: e });
2194
+ handleError({ node, error: e });
2200
2195
  }
2201
2196
  setComputation(c);
2202
2197
  root.setCounter(root.counter - 1);
@@ -2266,7 +2261,7 @@
2266
2261
  fiber.node.willUnmount = [];
2267
2262
  }
2268
2263
  this.locked = false;
2269
- node.app.handleError({ fiber: current || this, error: e });
2264
+ handleError({ fiber: current || this, error: e });
2270
2265
  }
2271
2266
  }
2272
2267
  setCounter(newValue) {
@@ -2322,7 +2317,7 @@
2322
2317
  }
2323
2318
  }
2324
2319
  catch (e) {
2325
- this.node.app.handleError({ fiber: current, error: e });
2320
+ handleError({ fiber: current, error: e });
2326
2321
  }
2327
2322
  }
2328
2323
  }
@@ -2400,7 +2395,7 @@
2400
2395
  await Promise.all(promises);
2401
2396
  }
2402
2397
  catch (e) {
2403
- this.app.handleError({ node: this, error: e });
2398
+ handleError({ node: this, error: e });
2404
2399
  return;
2405
2400
  }
2406
2401
  if (this.status === 0 /* STATUS.NEW */ && this.fiber === fiber) {
@@ -2490,7 +2485,7 @@
2490
2485
  }
2491
2486
  }
2492
2487
  catch (e) {
2493
- this.app.handleError({ error: e, node: this });
2488
+ handleError({ error: e, node: this });
2494
2489
  }
2495
2490
  }
2496
2491
  for (const computation of this.computations) {
@@ -5673,7 +5668,7 @@
5673
5668
  }
5674
5669
 
5675
5670
  // do not modify manually. This file is generated by the release script.
5676
- const version = "3.0.0-alpha.21";
5671
+ const version = "3.0.0-alpha.23";
5677
5672
 
5678
5673
  function effect(fn) {
5679
5674
  const computation = createComputation(() => {
@@ -5871,8 +5866,33 @@
5871
5866
  node._destroy();
5872
5867
  }
5873
5868
  this.cancelledNodes.clear();
5874
- for (let task of this.tasks) {
5875
- this.processFiber(task);
5869
+ for (let fiber of this.tasks) {
5870
+ if (fiber.root !== fiber) {
5871
+ this.tasks.delete(fiber);
5872
+ continue;
5873
+ }
5874
+ const hasError = fibersInError.has(fiber);
5875
+ if (hasError && fiber.counter !== 0) {
5876
+ this.tasks.delete(fiber);
5877
+ continue;
5878
+ }
5879
+ if (fiber.node.status === 3 /* STATUS.DESTROYED */) {
5880
+ this.tasks.delete(fiber);
5881
+ continue;
5882
+ }
5883
+ if (fiber.counter === 0) {
5884
+ if (!hasError) {
5885
+ fiber.complete();
5886
+ }
5887
+ // at this point, the fiber should have been applied to the DOM, so we can
5888
+ // remove it from the task list. If it is not the case, it means that there
5889
+ // was an error and an error handler triggered a new rendering that recycled
5890
+ // the fiber, so in that case, we actually want to keep the fiber around,
5891
+ // otherwise it will just be ignored.
5892
+ if (fiber.appliedToDom) {
5893
+ this.tasks.delete(fiber);
5894
+ }
5895
+ }
5876
5896
  }
5877
5897
  for (let task of this.tasks) {
5878
5898
  if (task.node.status === 3 /* STATUS.DESTROYED */) {
@@ -5881,34 +5901,6 @@
5881
5901
  }
5882
5902
  this.processing = false;
5883
5903
  }
5884
- processFiber(fiber) {
5885
- if (fiber.root !== fiber) {
5886
- this.tasks.delete(fiber);
5887
- return;
5888
- }
5889
- const hasError = fibersInError.has(fiber);
5890
- if (hasError && fiber.counter !== 0) {
5891
- this.tasks.delete(fiber);
5892
- return;
5893
- }
5894
- if (fiber.node.status === 3 /* STATUS.DESTROYED */) {
5895
- this.tasks.delete(fiber);
5896
- return;
5897
- }
5898
- if (fiber.counter === 0) {
5899
- if (!hasError) {
5900
- fiber.complete();
5901
- }
5902
- // at this point, the fiber should have been applied to the DOM, so we can
5903
- // remove it from the task list. If it is not the case, it means that there
5904
- // was an error and an error handler triggered a new rendering that recycled
5905
- // the fiber, so in that case, we actually want to keep the fiber around,
5906
- // otherwise it will just be ignored.
5907
- if (fiber.appliedToDom) {
5908
- this.tasks.delete(fiber);
5909
- }
5910
- }
5911
- }
5912
5904
  }
5913
5905
 
5914
5906
  let hasBeenLogged = false;
@@ -6008,8 +6000,8 @@
6008
6000
  this.scheduler.processTasks();
6009
6001
  apps.delete(this);
6010
6002
  }
6011
- handleError(...args) {
6012
- return handleError(...args);
6003
+ _handleError(error) {
6004
+ throw error;
6013
6005
  }
6014
6006
  }
6015
6007
  async function mount(C, target, config = {}) {
@@ -6067,14 +6059,20 @@
6067
6059
  // hooks
6068
6060
  // -----------------------------------------------------------------------------
6069
6061
  function decorate(node, f, hookName) {
6070
- const result = f.bind(node.component);
6071
6062
  if (node.app.dev) {
6072
- const suffix = f.name ? ` <${f.name}>` : "";
6073
- Reflect.defineProperty(result, "name", {
6074
- value: hookName + suffix,
6075
- });
6063
+ const component = node.component;
6064
+ const componentName = component ? component.constructor.name : "Component";
6065
+ const name = `${componentName}.${hookName}`;
6066
+ // Create a named wrapper so the name appears in stack traces.
6067
+ // V8 uses computed property keys as inferred function names.
6068
+ const wrapper = {
6069
+ [name]() {
6070
+ return f.call(component);
6071
+ },
6072
+ };
6073
+ return wrapper[name];
6076
6074
  }
6077
- return result;
6075
+ return f.bind(node.component);
6078
6076
  }
6079
6077
  function onWillStart(fn) {
6080
6078
  const { node } = getContext("component");
@@ -6332,22 +6330,30 @@
6332
6330
  }
6333
6331
  }
6334
6332
 
6335
- const anyType = function validateAny() { };
6336
- const booleanType = function validateBoolean(context) {
6337
- if (typeof context.value !== "boolean") {
6338
- context.addIssue({ message: "value is not a boolean" });
6339
- }
6340
- };
6341
- const numberType = function validateNumber(context) {
6342
- if (typeof context.value !== "number") {
6343
- context.addIssue({ message: "value is not a number" });
6344
- }
6345
- };
6346
- const stringType = function validateString(context) {
6347
- if (typeof context.value !== "string") {
6348
- context.addIssue({ message: "value is not a string" });
6349
- }
6350
- };
6333
+ function anyType() {
6334
+ return function validateAny() { };
6335
+ }
6336
+ function booleanType() {
6337
+ return function validateBoolean(context) {
6338
+ if (typeof context.value !== "boolean") {
6339
+ context.addIssue({ message: "value is not a boolean" });
6340
+ }
6341
+ };
6342
+ }
6343
+ function numberType() {
6344
+ return function validateNumber(context) {
6345
+ if (typeof context.value !== "number") {
6346
+ context.addIssue({ message: "value is not a number" });
6347
+ }
6348
+ };
6349
+ }
6350
+ function stringType() {
6351
+ return function validateString(context) {
6352
+ if (typeof context.value !== "string") {
6353
+ context.addIssue({ message: "value is not a string" });
6354
+ }
6355
+ };
6356
+ }
6351
6357
  function arrayType(elementType) {
6352
6358
  return function validateArray(context) {
6353
6359
  if (!Array.isArray(context.value)) {
@@ -6538,6 +6544,9 @@
6538
6544
  }
6539
6545
  };
6540
6546
  }
6547
+ function componentType() {
6548
+ return constructorType(Component);
6549
+ }
6541
6550
  function ref(type) {
6542
6551
  return union([literalType(null), instanceType(type)]);
6543
6552
  }
@@ -6546,6 +6555,7 @@
6546
6555
  any: anyType,
6547
6556
  array: arrayType,
6548
6557
  boolean: booleanType,
6558
+ component: componentType,
6549
6559
  constructor: constructorType,
6550
6560
  customValidator: customValidator,
6551
6561
  function: functionType,
@@ -6814,8 +6824,8 @@
6814
6824
  exports.xml = xml;
6815
6825
 
6816
6826
 
6817
- __info__.date = '2026-04-02T11:14:58.432Z';
6818
- __info__.hash = '9ca35d8';
6827
+ __info__.date = '2026-04-10T07:28:23.029Z';
6828
+ __info__.hash = 'e5e6d92';
6819
6829
  __info__.url = 'https://github.com/odoo/owl';
6820
6830
 
6821
6831