@odoo/owl 3.0.0-alpha.33 → 3.0.0-alpha.34
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 +157 -79
- package/dist/owl.es.js +157 -79
- package/dist/owl.iife.js +157 -79
- package/dist/owl.iife.min.js +9 -9
- package/dist/types/owl.d.ts +24 -12
- package/package.json +4 -4
package/dist/owl.es.js
CHANGED
|
@@ -752,7 +752,7 @@ function createContext(issues, value, path, parent) {
|
|
|
752
752
|
addIssue(issue) {
|
|
753
753
|
issues.push({
|
|
754
754
|
received: this.value,
|
|
755
|
-
path: this.path,
|
|
755
|
+
path: this.path.join(" > "),
|
|
756
756
|
...issue
|
|
757
757
|
});
|
|
758
758
|
},
|
|
@@ -1126,6 +1126,13 @@ var Plugin = class {
|
|
|
1126
1126
|
static set id(shadowId) {
|
|
1127
1127
|
this._shadowId = shadowId;
|
|
1128
1128
|
}
|
|
1129
|
+
// Plugins passed to `startPlugins` are started in batches of equal sequence,
|
|
1130
|
+
// ascending (lower first), like Resource/Registry. Each batch's onWillStart
|
|
1131
|
+
// callbacks fully settle before the next batch is instantiated, so
|
|
1132
|
+
// foundational plugins (low sequence) are ready before later plugins even
|
|
1133
|
+
// run their setup. Explicit `plugin(X)` dependencies bypass batching and
|
|
1134
|
+
// start immediately.
|
|
1135
|
+
static sequence = 50;
|
|
1129
1136
|
__owl__;
|
|
1130
1137
|
constructor(manager) {
|
|
1131
1138
|
this.__owl__ = manager;
|
|
@@ -1136,11 +1143,13 @@ var Plugin = class {
|
|
|
1136
1143
|
var PluginManager = class extends Scope {
|
|
1137
1144
|
config;
|
|
1138
1145
|
plugins;
|
|
1139
|
-
// Resolves once all
|
|
1140
|
-
// scope transitions to MOUNTED as the last step
|
|
1141
|
-
// (the root's mount(), providePlugins) await this
|
|
1142
|
-
// manager as ready. `willStart` itself is inherited
|
|
1146
|
+
// Resolves once all batches of plugins have started and their willStart
|
|
1147
|
+
// callbacks have settled. The scope transitions to MOUNTED as the last step
|
|
1148
|
+
// of this chain. Consumers (the root's mount(), providePlugins) await this
|
|
1149
|
+
// before treating the manager as ready. `willStart` itself is inherited
|
|
1150
|
+
// from Scope.
|
|
1143
1151
|
ready = Promise.resolve();
|
|
1152
|
+
hasPendingReady = false;
|
|
1144
1153
|
constructor(app, options = {}) {
|
|
1145
1154
|
super(app);
|
|
1146
1155
|
this.config = options.config ?? {};
|
|
@@ -1181,24 +1190,61 @@ var PluginManager = class extends Scope {
|
|
|
1181
1190
|
return plugin2;
|
|
1182
1191
|
}
|
|
1183
1192
|
startPlugins(pluginConstructors) {
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1193
|
+
const fresh = pluginConstructors.filter((ctor) => {
|
|
1194
|
+
if (!ctor.id || this.plugins.hasOwnProperty(ctor.id)) {
|
|
1195
|
+
this.startPlugin(ctor);
|
|
1196
|
+
return false;
|
|
1188
1197
|
}
|
|
1189
|
-
|
|
1190
|
-
|
|
1198
|
+
return true;
|
|
1199
|
+
});
|
|
1200
|
+
if (!fresh.length) {
|
|
1201
|
+
return;
|
|
1191
1202
|
}
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1203
|
+
fresh.sort((p1, p2) => p1.sequence - p2.sequence);
|
|
1204
|
+
const batches = [];
|
|
1205
|
+
for (const ctor of fresh) {
|
|
1206
|
+
const batch = batches[batches.length - 1];
|
|
1207
|
+
if (batch && batch[0].sequence === ctor.sequence) {
|
|
1208
|
+
batch.push(ctor);
|
|
1209
|
+
} else {
|
|
1210
|
+
batches.push([ctor]);
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
const startBatch = (batch) => {
|
|
1214
|
+
scopeStack.push(this);
|
|
1215
|
+
try {
|
|
1216
|
+
for (const ctor of batch) {
|
|
1217
|
+
this.startPlugin(ctor);
|
|
1197
1218
|
}
|
|
1198
|
-
}
|
|
1199
|
-
|
|
1200
|
-
|
|
1219
|
+
} finally {
|
|
1220
|
+
scopeStack.pop();
|
|
1221
|
+
}
|
|
1222
|
+
const pending = this.willStart.splice(0);
|
|
1223
|
+
return pending.length ? Promise.all(pending.map((fn) => fn())) : null;
|
|
1224
|
+
};
|
|
1225
|
+
let chain = this.hasPendingReady ? this.ready : null;
|
|
1226
|
+
for (const batch of batches) {
|
|
1227
|
+
if (chain) {
|
|
1228
|
+
chain = chain.then(() => startBatch(batch));
|
|
1229
|
+
} else {
|
|
1230
|
+
chain = startBatch(batch);
|
|
1231
|
+
}
|
|
1201
1232
|
}
|
|
1233
|
+
if (!chain) {
|
|
1234
|
+
if (this.status < STATUS.MOUNTED) {
|
|
1235
|
+
this.status = STATUS.MOUNTED;
|
|
1236
|
+
}
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
this.hasPendingReady = true;
|
|
1240
|
+
const ready = this.ready = chain.then(() => {
|
|
1241
|
+
if (this.status < STATUS.MOUNTED) {
|
|
1242
|
+
this.status = STATUS.MOUNTED;
|
|
1243
|
+
}
|
|
1244
|
+
if (this.ready === ready) {
|
|
1245
|
+
this.hasPendingReady = false;
|
|
1246
|
+
}
|
|
1247
|
+
});
|
|
1202
1248
|
}
|
|
1203
1249
|
};
|
|
1204
1250
|
function startPlugins(manager, plugins) {
|
|
@@ -1309,7 +1355,7 @@ function markup(valueOrStrings, ...placeholders) {
|
|
|
1309
1355
|
}
|
|
1310
1356
|
|
|
1311
1357
|
// ../owl-runtime/dist/owl-runtime.es.js
|
|
1312
|
-
var version = "3.0.0-alpha.
|
|
1358
|
+
var version = "3.0.0-alpha.34";
|
|
1313
1359
|
var fibersInError = /* @__PURE__ */ new WeakMap();
|
|
1314
1360
|
var nodeErrorHandlers = /* @__PURE__ */ new WeakMap();
|
|
1315
1361
|
function invokeErrorHandlers(node, error, finalize, markFibers) {
|
|
@@ -1589,20 +1635,20 @@ function toClassObj(expr) {
|
|
|
1589
1635
|
}
|
|
1590
1636
|
}
|
|
1591
1637
|
var CSS_PROP_CACHE = {};
|
|
1592
|
-
function toKebabCase(
|
|
1593
|
-
if (
|
|
1594
|
-
return CSS_PROP_CACHE[
|
|
1638
|
+
function toKebabCase(prop) {
|
|
1639
|
+
if (prop in CSS_PROP_CACHE) {
|
|
1640
|
+
return CSS_PROP_CACHE[prop];
|
|
1595
1641
|
}
|
|
1596
|
-
const result =
|
|
1597
|
-
CSS_PROP_CACHE[
|
|
1642
|
+
const result = prop.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
|
|
1643
|
+
CSS_PROP_CACHE[prop] = result;
|
|
1598
1644
|
return result;
|
|
1599
1645
|
}
|
|
1600
1646
|
var IMPORTANT_RE = /\s*!\s*important\s*$/i;
|
|
1601
|
-
function setStyleProp(style,
|
|
1647
|
+
function setStyleProp(style, prop, value) {
|
|
1602
1648
|
if (IMPORTANT_RE.test(value)) {
|
|
1603
|
-
style.setProperty(
|
|
1649
|
+
style.setProperty(prop, value.replace(IMPORTANT_RE, ""), "important");
|
|
1604
1650
|
} else {
|
|
1605
|
-
style.setProperty(
|
|
1651
|
+
style.setProperty(prop, value);
|
|
1606
1652
|
}
|
|
1607
1653
|
}
|
|
1608
1654
|
function toStyleObj(expr) {
|
|
@@ -1646,19 +1692,19 @@ function toStyleObj(expr) {
|
|
|
1646
1692
|
if (colonIdx === -1) {
|
|
1647
1693
|
continue;
|
|
1648
1694
|
}
|
|
1649
|
-
const
|
|
1695
|
+
const prop = trim.call(part.slice(0, colonIdx));
|
|
1650
1696
|
const value = trim.call(part.slice(colonIdx + 1));
|
|
1651
|
-
if (
|
|
1652
|
-
result[
|
|
1697
|
+
if (prop && value && value !== "undefined") {
|
|
1698
|
+
result[prop] = value;
|
|
1653
1699
|
}
|
|
1654
1700
|
}
|
|
1655
1701
|
return result;
|
|
1656
1702
|
}
|
|
1657
1703
|
case "object":
|
|
1658
|
-
for (let
|
|
1659
|
-
const value = expr[
|
|
1704
|
+
for (let prop in expr) {
|
|
1705
|
+
const value = expr[prop];
|
|
1660
1706
|
if (value || value === 0) {
|
|
1661
|
-
result[toKebabCase(
|
|
1707
|
+
result[toKebabCase(prop)] = String(value);
|
|
1662
1708
|
}
|
|
1663
1709
|
}
|
|
1664
1710
|
return result;
|
|
@@ -1689,22 +1735,22 @@ function updateClass(val, oldVal) {
|
|
|
1689
1735
|
function setStyle(val) {
|
|
1690
1736
|
val = val === "" ? {} : toStyleObj(val);
|
|
1691
1737
|
const style = this.style;
|
|
1692
|
-
for (let
|
|
1693
|
-
setStyleProp(style,
|
|
1738
|
+
for (let prop in val) {
|
|
1739
|
+
setStyleProp(style, prop, val[prop]);
|
|
1694
1740
|
}
|
|
1695
1741
|
}
|
|
1696
1742
|
function updateStyle(val, oldVal) {
|
|
1697
1743
|
oldVal = oldVal === "" ? {} : toStyleObj(oldVal);
|
|
1698
1744
|
val = val === "" ? {} : toStyleObj(val);
|
|
1699
1745
|
const style = this.style;
|
|
1700
|
-
for (let
|
|
1701
|
-
if (!(
|
|
1702
|
-
style.removeProperty(
|
|
1746
|
+
for (let prop in oldVal) {
|
|
1747
|
+
if (!(prop in val)) {
|
|
1748
|
+
style.removeProperty(prop);
|
|
1703
1749
|
}
|
|
1704
1750
|
}
|
|
1705
|
-
for (let
|
|
1706
|
-
if (val[
|
|
1707
|
-
setStyleProp(style,
|
|
1751
|
+
for (let prop in val) {
|
|
1752
|
+
if (val[prop] !== oldVal[prop]) {
|
|
1753
|
+
setStyleProp(style, prop, val[prop]);
|
|
1708
1754
|
}
|
|
1709
1755
|
}
|
|
1710
1756
|
if (!style.cssText) {
|
|
@@ -3196,6 +3242,10 @@ var ComponentNode = class extends Scope {
|
|
|
3196
3242
|
parent;
|
|
3197
3243
|
children = /* @__PURE__ */ Object.create(null);
|
|
3198
3244
|
willUpdateProps = [];
|
|
3245
|
+
// Fired right after `props` is applied to `node.props` on a parent re-render,
|
|
3246
|
+
// so reactive prop notifications happen once the new values are observable
|
|
3247
|
+
// (after user `onWillUpdateProps` hooks, including async ones, have run).
|
|
3248
|
+
propsUpdated = [];
|
|
3199
3249
|
willUnmount = [];
|
|
3200
3250
|
mounted = [];
|
|
3201
3251
|
willPatch = [];
|
|
@@ -3730,6 +3780,7 @@ function createComponent(app, name, isStatic, hasSlotsProp, hasDynamicPropList,
|
|
|
3730
3780
|
() => {
|
|
3731
3781
|
if (fiber !== node.fiber) return;
|
|
3732
3782
|
node.props = props2;
|
|
3783
|
+
for (const f of node.propsUpdated) f();
|
|
3733
3784
|
fiber.render();
|
|
3734
3785
|
},
|
|
3735
3786
|
(error) => {
|
|
@@ -3738,6 +3789,7 @@ function createComponent(app, name, isStatic, hasSlotsProp, hasDynamicPropList,
|
|
|
3738
3789
|
);
|
|
3739
3790
|
} else {
|
|
3740
3791
|
node.props = props2;
|
|
3792
|
+
for (const f of node.propsUpdated) f();
|
|
3741
3793
|
fiber.render();
|
|
3742
3794
|
}
|
|
3743
3795
|
}
|
|
@@ -4110,6 +4162,24 @@ function onError(callback) {
|
|
|
4110
4162
|
}
|
|
4111
4163
|
handlers.push(callback.bind(scope.component));
|
|
4112
4164
|
}
|
|
4165
|
+
function staticProp(key, type, ...args) {
|
|
4166
|
+
const node = getComponentScope();
|
|
4167
|
+
const hasDefault = args.length > 0;
|
|
4168
|
+
const propValue = node.props[key];
|
|
4169
|
+
if (node.app.dev) {
|
|
4170
|
+
if (type !== void 0 && (!hasDefault || propValue !== void 0)) {
|
|
4171
|
+
assertType(propValue, type, `Invalid prop '${key}' in '${node.componentName}'`);
|
|
4172
|
+
}
|
|
4173
|
+
node.willUpdateProps.push((nextProps) => {
|
|
4174
|
+
if (nextProps[key] !== node.props[key]) {
|
|
4175
|
+
throw new OwlError(
|
|
4176
|
+
`Prop '${key}' changed in component '${node.componentName}'. Props declared with \`props.static()\` are static and should not change. If the prop is a signal, pass the same signal reference (its inner value may change).`
|
|
4177
|
+
);
|
|
4178
|
+
}
|
|
4179
|
+
});
|
|
4180
|
+
}
|
|
4181
|
+
return propValue === void 0 && hasDefault ? args[0] : propValue;
|
|
4182
|
+
}
|
|
4113
4183
|
function componentType() {
|
|
4114
4184
|
return constructorType(Component);
|
|
4115
4185
|
}
|
|
@@ -4131,35 +4201,51 @@ function validateDefaults(schema) {
|
|
|
4131
4201
|
}
|
|
4132
4202
|
return types2.strictObject(validation);
|
|
4133
4203
|
}
|
|
4134
|
-
function
|
|
4204
|
+
function makeProps(type, defaults) {
|
|
4135
4205
|
const node = getComponentScope();
|
|
4136
4206
|
const { app, componentName } = node;
|
|
4137
4207
|
if (defaults) {
|
|
4138
4208
|
node.defaultProps = Object.assign(node.defaultProps || {}, defaults);
|
|
4139
4209
|
}
|
|
4140
|
-
function
|
|
4141
|
-
if (
|
|
4210
|
+
function resolveValue(props2, key) {
|
|
4211
|
+
if (props2[key] === void 0 && defaults) {
|
|
4142
4212
|
return defaults[key];
|
|
4143
4213
|
}
|
|
4144
|
-
return
|
|
4214
|
+
return props2[key];
|
|
4145
4215
|
}
|
|
4216
|
+
const signals = /* @__PURE__ */ Object.create(null);
|
|
4146
4217
|
const result = /* @__PURE__ */ Object.create(null);
|
|
4147
|
-
function
|
|
4218
|
+
function defineProp(key) {
|
|
4219
|
+
signals[key] = signal(resolveValue(node.props, key));
|
|
4220
|
+
Reflect.defineProperty(result, key, {
|
|
4221
|
+
enumerable: true,
|
|
4222
|
+
configurable: true,
|
|
4223
|
+
get: signals[key]
|
|
4224
|
+
});
|
|
4225
|
+
}
|
|
4226
|
+
function defineProps(keys) {
|
|
4148
4227
|
for (const key of keys) {
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4228
|
+
defineProp(key);
|
|
4229
|
+
}
|
|
4230
|
+
}
|
|
4231
|
+
function updateSignals(keys) {
|
|
4232
|
+
for (const key of keys) {
|
|
4233
|
+
signals[key].set(resolveValue(node.props, key));
|
|
4153
4234
|
}
|
|
4154
4235
|
}
|
|
4155
4236
|
if (type) {
|
|
4156
4237
|
const keys = (Array.isArray(type) ? type : Object.keys(type)).map(
|
|
4157
4238
|
(key) => key.endsWith("?") ? key.slice(0, -1) : key
|
|
4158
4239
|
);
|
|
4159
|
-
|
|
4240
|
+
defineProps(keys);
|
|
4241
|
+
node.propsUpdated.push(() => updateSignals(keys));
|
|
4160
4242
|
if (app.dev) {
|
|
4161
4243
|
if (defaults) {
|
|
4162
|
-
assertType(
|
|
4244
|
+
assertType(
|
|
4245
|
+
defaults,
|
|
4246
|
+
validateDefaults(type),
|
|
4247
|
+
`Invalid component default props (${componentName})`
|
|
4248
|
+
);
|
|
4163
4249
|
}
|
|
4164
4250
|
const validation = types2.object(type);
|
|
4165
4251
|
assertType(node.props, validation, `Invalid component props (${componentName})`);
|
|
@@ -4185,17 +4271,28 @@ function props(type, defaults) {
|
|
|
4185
4271
|
return keys2;
|
|
4186
4272
|
};
|
|
4187
4273
|
let keys = getKeys(node.props);
|
|
4188
|
-
|
|
4189
|
-
node.
|
|
4274
|
+
defineProps(keys);
|
|
4275
|
+
node.propsUpdated.push(() => {
|
|
4276
|
+
const nextKeys = getKeys(node.props);
|
|
4277
|
+
const nextKeySet = new Set(nextKeys);
|
|
4190
4278
|
for (const key of keys) {
|
|
4191
|
-
|
|
4279
|
+
if (!nextKeySet.has(key)) {
|
|
4280
|
+
Reflect.deleteProperty(result, key);
|
|
4281
|
+
delete signals[key];
|
|
4282
|
+
}
|
|
4283
|
+
}
|
|
4284
|
+
for (const key of nextKeys) {
|
|
4285
|
+
if (!(key in signals)) {
|
|
4286
|
+
defineProp(key);
|
|
4287
|
+
}
|
|
4192
4288
|
}
|
|
4193
|
-
|
|
4194
|
-
|
|
4289
|
+
updateSignals(nextKeys);
|
|
4290
|
+
keys = nextKeys;
|
|
4195
4291
|
});
|
|
4196
4292
|
}
|
|
4197
4293
|
return result;
|
|
4198
4294
|
}
|
|
4295
|
+
var props = Object.assign(makeProps, { static: staticProp });
|
|
4199
4296
|
var ErrorBoundary = class extends Component {
|
|
4200
4297
|
static template = xml`
|
|
4201
4298
|
<t t-if="this.props.error()">
|
|
@@ -4294,24 +4391,6 @@ var Suspense = class extends Component {
|
|
|
4294
4391
|
onWillDestroy(() => root.destroy());
|
|
4295
4392
|
}
|
|
4296
4393
|
};
|
|
4297
|
-
function prop(key, type, ...args) {
|
|
4298
|
-
const node = getComponentScope();
|
|
4299
|
-
const hasDefault = args.length > 0;
|
|
4300
|
-
const propValue = node.props[key];
|
|
4301
|
-
if (node.app.dev) {
|
|
4302
|
-
if (type !== void 0 && (!hasDefault || propValue !== void 0)) {
|
|
4303
|
-
assertType(propValue, type, `Invalid prop '${key}' in '${node.componentName}'`);
|
|
4304
|
-
}
|
|
4305
|
-
node.willUpdateProps.push((nextProps) => {
|
|
4306
|
-
if (nextProps[key] !== node.props[key]) {
|
|
4307
|
-
throw new OwlError(
|
|
4308
|
-
`Prop '${key}' changed in component '${node.componentName}'. Props declared with \`prop()\` are static and should not change. If the prop is a signal, pass the same signal reference (its inner value may change).`
|
|
4309
|
-
);
|
|
4310
|
-
}
|
|
4311
|
-
});
|
|
4312
|
-
}
|
|
4313
|
-
return propValue === void 0 && hasDefault ? args[0] : propValue;
|
|
4314
|
-
}
|
|
4315
4394
|
function providePlugins(pluginConstructors, config3) {
|
|
4316
4395
|
const node = getComponentScope();
|
|
4317
4396
|
const manager = new PluginManager(node.app, { parent: node.pluginManager, config: config3 });
|
|
@@ -4340,8 +4419,8 @@ var blockDom = {
|
|
|
4340
4419
|
};
|
|
4341
4420
|
var __info__ = {
|
|
4342
4421
|
version: App.version,
|
|
4343
|
-
date: "2026-
|
|
4344
|
-
hash: "
|
|
4422
|
+
date: "2026-06-05T08:44:38.319Z",
|
|
4423
|
+
hash: "3206cf27",
|
|
4345
4424
|
url: "https://github.com/odoo/owl"
|
|
4346
4425
|
};
|
|
4347
4426
|
|
|
@@ -6552,7 +6631,6 @@ export {
|
|
|
6552
6631
|
onWillUnmount,
|
|
6553
6632
|
onWillUpdateProps,
|
|
6554
6633
|
plugin,
|
|
6555
|
-
prop,
|
|
6556
6634
|
props,
|
|
6557
6635
|
providePlugins,
|
|
6558
6636
|
proxy,
|