@odoo/owl 3.0.0-alpha.32 → 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 +310 -208
- package/dist/owl.es.js +310 -208
- package/dist/owl.iife.js +310 -208
- package/dist/owl.iife.min.js +9 -9
- package/dist/types/owl.d.ts +121 -120
- package/package.json +4 -4
package/dist/owl.iife.js
CHANGED
|
@@ -39,7 +39,7 @@ var owl = (() => {
|
|
|
39
39
|
batched: () => batched,
|
|
40
40
|
blockDom: () => blockDom,
|
|
41
41
|
computed: () => computed,
|
|
42
|
-
config: () =>
|
|
42
|
+
config: () => config,
|
|
43
43
|
effect: () => effect,
|
|
44
44
|
getScope: () => getScope,
|
|
45
45
|
globalTemplates: () => globalTemplates,
|
|
@@ -56,7 +56,6 @@ var owl = (() => {
|
|
|
56
56
|
onWillUnmount: () => onWillUnmount,
|
|
57
57
|
onWillUpdateProps: () => onWillUpdateProps,
|
|
58
58
|
plugin: () => plugin,
|
|
59
|
-
prop: () => prop,
|
|
60
59
|
props: () => props,
|
|
61
60
|
providePlugins: () => providePlugins,
|
|
62
61
|
proxy: () => proxy,
|
|
@@ -65,7 +64,7 @@ var owl = (() => {
|
|
|
65
64
|
toRaw: () => toRaw,
|
|
66
65
|
types: () => types2,
|
|
67
66
|
untrack: () => untrack,
|
|
68
|
-
useApp: () =>
|
|
67
|
+
useApp: () => useApp2,
|
|
69
68
|
useEffect: () => useEffect,
|
|
70
69
|
useListener: () => useListener,
|
|
71
70
|
useScope: () => useScope,
|
|
@@ -191,13 +190,15 @@ var owl = (() => {
|
|
|
191
190
|
sources.clear();
|
|
192
191
|
}
|
|
193
192
|
function disposeComputation(computation) {
|
|
194
|
-
|
|
193
|
+
const sources = computation.sources;
|
|
194
|
+
for (const source of sources) {
|
|
195
195
|
source.observers.delete(computation);
|
|
196
|
-
|
|
197
|
-
|
|
196
|
+
const derived = source;
|
|
197
|
+
if (derived.isDerived && derived.observers.size === 0) {
|
|
198
|
+
disposeComputation(derived);
|
|
198
199
|
}
|
|
199
200
|
}
|
|
200
|
-
|
|
201
|
+
sources.clear();
|
|
201
202
|
computation.state = 1;
|
|
202
203
|
}
|
|
203
204
|
function markDownstream(computation) {
|
|
@@ -238,6 +239,7 @@ var owl = (() => {
|
|
|
238
239
|
}
|
|
239
240
|
var Scope = class {
|
|
240
241
|
app;
|
|
242
|
+
pluginManager;
|
|
241
243
|
status = STATUS.NEW;
|
|
242
244
|
computations = [];
|
|
243
245
|
willStart = [];
|
|
@@ -245,6 +247,7 @@ var owl = (() => {
|
|
|
245
247
|
_destroyCbs = null;
|
|
246
248
|
constructor(app) {
|
|
247
249
|
this.app = app;
|
|
250
|
+
this.pluginManager = app.pluginManager;
|
|
248
251
|
}
|
|
249
252
|
/**
|
|
250
253
|
* Pushes this scope on the stack for the duration of `callback`. Any code
|
|
@@ -688,14 +691,19 @@ var owl = (() => {
|
|
|
688
691
|
}
|
|
689
692
|
function effect(fn) {
|
|
690
693
|
const computation = createComputation(() => {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
+
if (computation.value || computation.observers.size) {
|
|
695
|
+
setComputation(void 0);
|
|
696
|
+
unsubscribeEffect(computation);
|
|
697
|
+
setComputation(computation);
|
|
698
|
+
} else {
|
|
699
|
+
removeSources(computation);
|
|
700
|
+
}
|
|
694
701
|
return fn();
|
|
695
702
|
}, false);
|
|
696
703
|
getCurrentComputation()?.observers.add(computation);
|
|
697
704
|
updateComputation(computation);
|
|
698
705
|
return function cleanupEffect2() {
|
|
706
|
+
computation.state = 0;
|
|
699
707
|
const previousComputation = getCurrentComputation();
|
|
700
708
|
setComputation(void 0);
|
|
701
709
|
unsubscribeEffect(computation);
|
|
@@ -707,7 +715,6 @@ var owl = (() => {
|
|
|
707
715
|
cleanupEffect(effect2);
|
|
708
716
|
for (const childEffect of effect2.observers) {
|
|
709
717
|
childEffect.state = 0;
|
|
710
|
-
removeSources(childEffect);
|
|
711
718
|
unsubscribeEffect(childEffect);
|
|
712
719
|
}
|
|
713
720
|
effect2.observers.clear();
|
|
@@ -784,19 +791,27 @@ var owl = (() => {
|
|
|
784
791
|
read.dispose = dispose;
|
|
785
792
|
return read;
|
|
786
793
|
}
|
|
794
|
+
function safeReplacer(knownObjects, _key, value) {
|
|
795
|
+
if (typeof value === "function") {
|
|
796
|
+
return value.name || "[Function]";
|
|
797
|
+
}
|
|
798
|
+
if (value && typeof value === "object") {
|
|
799
|
+
const ctor = value.constructor;
|
|
800
|
+
if (ctor && ctor !== Object && ctor !== Array) {
|
|
801
|
+
return `[Instance of ${ctor.name || "anonymous"}]`;
|
|
802
|
+
}
|
|
803
|
+
if (knownObjects.includes(value)) {
|
|
804
|
+
return `[Known object]`;
|
|
805
|
+
}
|
|
806
|
+
knownObjects.push(value);
|
|
807
|
+
}
|
|
808
|
+
return value;
|
|
809
|
+
}
|
|
787
810
|
function assertType(value, validation, errorMessage = "Value does not match the type") {
|
|
788
811
|
const issues = validateType(value, validation);
|
|
789
812
|
if (issues.length) {
|
|
790
|
-
const
|
|
791
|
-
|
|
792
|
-
(key, value2) => {
|
|
793
|
-
if (typeof value2 === "function") {
|
|
794
|
-
return value2.name;
|
|
795
|
-
}
|
|
796
|
-
return value2;
|
|
797
|
-
},
|
|
798
|
-
2
|
|
799
|
-
);
|
|
813
|
+
const knownObjects = [];
|
|
814
|
+
const issueStrings = JSON.stringify(issues, safeReplacer.bind(null, knownObjects), 2);
|
|
800
815
|
throw new OwlError(`${errorMessage}
|
|
801
816
|
${issueStrings}`);
|
|
802
817
|
}
|
|
@@ -812,7 +827,7 @@ ${issueStrings}`);
|
|
|
812
827
|
addIssue(issue) {
|
|
813
828
|
issues.push({
|
|
814
829
|
received: this.value,
|
|
815
|
-
path: this.path,
|
|
830
|
+
path: this.path.join(" > "),
|
|
816
831
|
...issue
|
|
817
832
|
});
|
|
818
833
|
},
|
|
@@ -937,15 +952,20 @@ ${issueStrings}`);
|
|
|
937
952
|
return;
|
|
938
953
|
}
|
|
939
954
|
const isShape = !Array.isArray(schema);
|
|
940
|
-
let shape
|
|
941
|
-
|
|
955
|
+
let shape;
|
|
956
|
+
let keys;
|
|
957
|
+
if (isShape) {
|
|
958
|
+
keys = Object.keys(schema);
|
|
959
|
+
shape = schema;
|
|
960
|
+
} else {
|
|
961
|
+
keys = schema;
|
|
942
962
|
shape = {};
|
|
943
|
-
for (const key of
|
|
963
|
+
for (const key of keys) {
|
|
944
964
|
shape[key] = null;
|
|
945
965
|
}
|
|
946
966
|
}
|
|
947
967
|
const missingKeys = [];
|
|
948
|
-
for (const key
|
|
968
|
+
for (const key of keys) {
|
|
949
969
|
const property = key.endsWith("?") ? key.slice(0, -1) : key;
|
|
950
970
|
if (context.value[property] === void 0) {
|
|
951
971
|
if (!key.endsWith("?")) {
|
|
@@ -960,20 +980,22 @@ ${issueStrings}`);
|
|
|
960
980
|
if (missingKeys.length) {
|
|
961
981
|
context.addIssue({
|
|
962
982
|
message: "object value has missing keys",
|
|
963
|
-
missingKeys
|
|
983
|
+
missingKeys,
|
|
984
|
+
expectedKeys: keys
|
|
964
985
|
});
|
|
965
986
|
}
|
|
966
987
|
if (isStrict) {
|
|
967
988
|
const unknownKeys = [];
|
|
968
989
|
for (const key in context.value) {
|
|
969
|
-
if (!(key
|
|
990
|
+
if (!keys.includes(key) && !(`${key}?` in shape)) {
|
|
970
991
|
unknownKeys.push(key);
|
|
971
992
|
}
|
|
972
993
|
}
|
|
973
994
|
if (unknownKeys.length) {
|
|
974
995
|
context.addIssue({
|
|
975
996
|
message: "object value has unknown keys",
|
|
976
|
-
unknownKeys
|
|
997
|
+
unknownKeys,
|
|
998
|
+
expectedKeys: keys
|
|
977
999
|
});
|
|
978
1000
|
}
|
|
979
1001
|
}
|
|
@@ -1179,6 +1201,13 @@ ${issueStrings}`);
|
|
|
1179
1201
|
static set id(shadowId) {
|
|
1180
1202
|
this._shadowId = shadowId;
|
|
1181
1203
|
}
|
|
1204
|
+
// Plugins passed to `startPlugins` are started in batches of equal sequence,
|
|
1205
|
+
// ascending (lower first), like Resource/Registry. Each batch's onWillStart
|
|
1206
|
+
// callbacks fully settle before the next batch is instantiated, so
|
|
1207
|
+
// foundational plugins (low sequence) are ready before later plugins even
|
|
1208
|
+
// run their setup. Explicit `plugin(X)` dependencies bypass batching and
|
|
1209
|
+
// start immediately.
|
|
1210
|
+
static sequence = 50;
|
|
1182
1211
|
__owl__;
|
|
1183
1212
|
constructor(manager) {
|
|
1184
1213
|
this.__owl__ = manager;
|
|
@@ -1189,14 +1218,17 @@ ${issueStrings}`);
|
|
|
1189
1218
|
var PluginManager = class extends Scope {
|
|
1190
1219
|
config;
|
|
1191
1220
|
plugins;
|
|
1192
|
-
// Resolves once all
|
|
1193
|
-
// scope transitions to MOUNTED as the last step
|
|
1194
|
-
// (
|
|
1195
|
-
// ready. `willStart` itself is inherited
|
|
1221
|
+
// Resolves once all batches of plugins have started and their willStart
|
|
1222
|
+
// callbacks have settled. The scope transitions to MOUNTED as the last step
|
|
1223
|
+
// of this chain. Consumers (the root's mount(), providePlugins) await this
|
|
1224
|
+
// before treating the manager as ready. `willStart` itself is inherited
|
|
1225
|
+
// from Scope.
|
|
1196
1226
|
ready = Promise.resolve();
|
|
1227
|
+
hasPendingReady = false;
|
|
1197
1228
|
constructor(app, options = {}) {
|
|
1198
1229
|
super(app);
|
|
1199
1230
|
this.config = options.config ?? {};
|
|
1231
|
+
this.pluginManager = this;
|
|
1200
1232
|
if (options.parent) {
|
|
1201
1233
|
const parent = options.parent;
|
|
1202
1234
|
parent.onDestroy(() => this.destroy());
|
|
@@ -1233,24 +1265,61 @@ ${issueStrings}`);
|
|
|
1233
1265
|
return plugin2;
|
|
1234
1266
|
}
|
|
1235
1267
|
startPlugins(pluginConstructors) {
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1268
|
+
const fresh = pluginConstructors.filter((ctor) => {
|
|
1269
|
+
if (!ctor.id || this.plugins.hasOwnProperty(ctor.id)) {
|
|
1270
|
+
this.startPlugin(ctor);
|
|
1271
|
+
return false;
|
|
1240
1272
|
}
|
|
1241
|
-
|
|
1242
|
-
|
|
1273
|
+
return true;
|
|
1274
|
+
});
|
|
1275
|
+
if (!fresh.length) {
|
|
1276
|
+
return;
|
|
1243
1277
|
}
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1278
|
+
fresh.sort((p1, p2) => p1.sequence - p2.sequence);
|
|
1279
|
+
const batches = [];
|
|
1280
|
+
for (const ctor of fresh) {
|
|
1281
|
+
const batch = batches[batches.length - 1];
|
|
1282
|
+
if (batch && batch[0].sequence === ctor.sequence) {
|
|
1283
|
+
batch.push(ctor);
|
|
1284
|
+
} else {
|
|
1285
|
+
batches.push([ctor]);
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
const startBatch = (batch) => {
|
|
1289
|
+
scopeStack.push(this);
|
|
1290
|
+
try {
|
|
1291
|
+
for (const ctor of batch) {
|
|
1292
|
+
this.startPlugin(ctor);
|
|
1249
1293
|
}
|
|
1250
|
-
}
|
|
1251
|
-
|
|
1252
|
-
|
|
1294
|
+
} finally {
|
|
1295
|
+
scopeStack.pop();
|
|
1296
|
+
}
|
|
1297
|
+
const pending = this.willStart.splice(0);
|
|
1298
|
+
return pending.length ? Promise.all(pending.map((fn) => fn())) : null;
|
|
1299
|
+
};
|
|
1300
|
+
let chain = this.hasPendingReady ? this.ready : null;
|
|
1301
|
+
for (const batch of batches) {
|
|
1302
|
+
if (chain) {
|
|
1303
|
+
chain = chain.then(() => startBatch(batch));
|
|
1304
|
+
} else {
|
|
1305
|
+
chain = startBatch(batch);
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
if (!chain) {
|
|
1309
|
+
if (this.status < STATUS.MOUNTED) {
|
|
1310
|
+
this.status = STATUS.MOUNTED;
|
|
1311
|
+
}
|
|
1312
|
+
return;
|
|
1253
1313
|
}
|
|
1314
|
+
this.hasPendingReady = true;
|
|
1315
|
+
const ready = this.ready = chain.then(() => {
|
|
1316
|
+
if (this.status < STATUS.MOUNTED) {
|
|
1317
|
+
this.status = STATUS.MOUNTED;
|
|
1318
|
+
}
|
|
1319
|
+
if (this.ready === ready) {
|
|
1320
|
+
this.hasPendingReady = false;
|
|
1321
|
+
}
|
|
1322
|
+
});
|
|
1254
1323
|
}
|
|
1255
1324
|
};
|
|
1256
1325
|
function startPlugins(manager, plugins) {
|
|
@@ -1265,9 +1334,103 @@ ${issueStrings}`);
|
|
|
1265
1334
|
);
|
|
1266
1335
|
}
|
|
1267
1336
|
}
|
|
1337
|
+
function onWillStart(fn) {
|
|
1338
|
+
const scope = useScope();
|
|
1339
|
+
scope.willStart.push(scope.decorate(fn, "onWillStart"));
|
|
1340
|
+
}
|
|
1341
|
+
function onWillDestroy(fn) {
|
|
1342
|
+
const scope = useScope();
|
|
1343
|
+
scope.onDestroy(scope.decorate(fn, "onWillDestroy"));
|
|
1344
|
+
}
|
|
1345
|
+
function useEffect(fn) {
|
|
1346
|
+
onWillDestroy(effect(fn));
|
|
1347
|
+
}
|
|
1348
|
+
function useListener(target, eventName, handler, eventParams) {
|
|
1349
|
+
if (typeof target === "function") {
|
|
1350
|
+
useEffect(() => {
|
|
1351
|
+
const el = target();
|
|
1352
|
+
if (el) {
|
|
1353
|
+
el.addEventListener(eventName, handler, eventParams);
|
|
1354
|
+
return () => el.removeEventListener(eventName, handler, eventParams);
|
|
1355
|
+
}
|
|
1356
|
+
return;
|
|
1357
|
+
});
|
|
1358
|
+
} else {
|
|
1359
|
+
target.addEventListener(eventName, handler, eventParams);
|
|
1360
|
+
onWillDestroy(() => target.removeEventListener(eventName, handler, eventParams));
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
function useApp() {
|
|
1364
|
+
return useScope().app;
|
|
1365
|
+
}
|
|
1366
|
+
function plugin(pluginType) {
|
|
1367
|
+
const scope = useScope();
|
|
1368
|
+
let plugin2 = scope.pluginManager.getPluginById(pluginType.id);
|
|
1369
|
+
if (!plugin2) {
|
|
1370
|
+
if (scope instanceof PluginManager) {
|
|
1371
|
+
plugin2 = scope.pluginManager.startPlugin(pluginType);
|
|
1372
|
+
} else {
|
|
1373
|
+
throw new OwlError(`Unknown plugin "${pluginType.id}"`);
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
return plugin2;
|
|
1377
|
+
}
|
|
1378
|
+
function config(key, type, defaultValue) {
|
|
1379
|
+
const scope = useScope();
|
|
1380
|
+
if (!(scope instanceof PluginManager)) {
|
|
1381
|
+
throw new OwlError("Expected to be in a plugin scope");
|
|
1382
|
+
}
|
|
1383
|
+
if (scope.app.dev && type) {
|
|
1384
|
+
assertType(scope.config, types.object({ [key]: type }), "Config does not match the type");
|
|
1385
|
+
}
|
|
1386
|
+
const configValue = scope.config[key.endsWith("?") ? key.slice(0, -1) : key];
|
|
1387
|
+
return configValue === void 0 ? defaultValue : configValue;
|
|
1388
|
+
}
|
|
1389
|
+
var EventBus = class extends EventTarget {
|
|
1390
|
+
trigger(name, payload) {
|
|
1391
|
+
this.dispatchEvent(new CustomEvent(name, { detail: payload }));
|
|
1392
|
+
}
|
|
1393
|
+
};
|
|
1394
|
+
var Markup = class extends String {
|
|
1395
|
+
};
|
|
1396
|
+
function htmlEscape(str) {
|
|
1397
|
+
if (str instanceof Markup) {
|
|
1398
|
+
return str;
|
|
1399
|
+
}
|
|
1400
|
+
if (str === void 0) {
|
|
1401
|
+
return markup("");
|
|
1402
|
+
}
|
|
1403
|
+
if (typeof str === "number") {
|
|
1404
|
+
return markup(String(str));
|
|
1405
|
+
}
|
|
1406
|
+
[
|
|
1407
|
+
["&", "&"],
|
|
1408
|
+
["<", "<"],
|
|
1409
|
+
[">", ">"],
|
|
1410
|
+
["'", "'"],
|
|
1411
|
+
['"', """],
|
|
1412
|
+
["`", "`"]
|
|
1413
|
+
].forEach((pairs) => {
|
|
1414
|
+
str = String(str).replace(new RegExp(pairs[0], "g"), pairs[1]);
|
|
1415
|
+
});
|
|
1416
|
+
return markup(str);
|
|
1417
|
+
}
|
|
1418
|
+
function markup(valueOrStrings, ...placeholders) {
|
|
1419
|
+
if (!Array.isArray(valueOrStrings)) {
|
|
1420
|
+
return new Markup(valueOrStrings);
|
|
1421
|
+
}
|
|
1422
|
+
const strings = valueOrStrings;
|
|
1423
|
+
let acc = "";
|
|
1424
|
+
let i = 0;
|
|
1425
|
+
for (; i < placeholders.length; ++i) {
|
|
1426
|
+
acc += strings[i] + htmlEscape(placeholders[i]);
|
|
1427
|
+
}
|
|
1428
|
+
acc += strings[i];
|
|
1429
|
+
return new Markup(acc);
|
|
1430
|
+
}
|
|
1268
1431
|
|
|
1269
1432
|
// ../owl-runtime/dist/owl-runtime.es.js
|
|
1270
|
-
var version = "3.0.0-alpha.
|
|
1433
|
+
var version = "3.0.0-alpha.34";
|
|
1271
1434
|
var fibersInError = /* @__PURE__ */ new WeakMap();
|
|
1272
1435
|
var nodeErrorHandlers = /* @__PURE__ */ new WeakMap();
|
|
1273
1436
|
function invokeErrorHandlers(node, error, finalize, markFibers) {
|
|
@@ -1340,7 +1503,7 @@ ${issueStrings}`);
|
|
|
1340
1503
|
}
|
|
1341
1504
|
return { modifiers, data: dataList };
|
|
1342
1505
|
}
|
|
1343
|
-
var
|
|
1506
|
+
var config2 = {
|
|
1344
1507
|
// whether or not blockdom should normalize DOM whenever a block is created.
|
|
1345
1508
|
// Normalizing dom mean removing empty text nodes (or containing only spaces)
|
|
1346
1509
|
shouldNormalizeDom: true,
|
|
@@ -1547,20 +1710,20 @@ ${issueStrings}`);
|
|
|
1547
1710
|
}
|
|
1548
1711
|
}
|
|
1549
1712
|
var CSS_PROP_CACHE = {};
|
|
1550
|
-
function toKebabCase(
|
|
1551
|
-
if (
|
|
1552
|
-
return CSS_PROP_CACHE[
|
|
1713
|
+
function toKebabCase(prop) {
|
|
1714
|
+
if (prop in CSS_PROP_CACHE) {
|
|
1715
|
+
return CSS_PROP_CACHE[prop];
|
|
1553
1716
|
}
|
|
1554
|
-
const result =
|
|
1555
|
-
CSS_PROP_CACHE[
|
|
1717
|
+
const result = prop.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
|
|
1718
|
+
CSS_PROP_CACHE[prop] = result;
|
|
1556
1719
|
return result;
|
|
1557
1720
|
}
|
|
1558
1721
|
var IMPORTANT_RE = /\s*!\s*important\s*$/i;
|
|
1559
|
-
function setStyleProp(style,
|
|
1722
|
+
function setStyleProp(style, prop, value) {
|
|
1560
1723
|
if (IMPORTANT_RE.test(value)) {
|
|
1561
|
-
style.setProperty(
|
|
1724
|
+
style.setProperty(prop, value.replace(IMPORTANT_RE, ""), "important");
|
|
1562
1725
|
} else {
|
|
1563
|
-
style.setProperty(
|
|
1726
|
+
style.setProperty(prop, value);
|
|
1564
1727
|
}
|
|
1565
1728
|
}
|
|
1566
1729
|
function toStyleObj(expr) {
|
|
@@ -1604,19 +1767,19 @@ ${issueStrings}`);
|
|
|
1604
1767
|
if (colonIdx === -1) {
|
|
1605
1768
|
continue;
|
|
1606
1769
|
}
|
|
1607
|
-
const
|
|
1770
|
+
const prop = trim.call(part.slice(0, colonIdx));
|
|
1608
1771
|
const value = trim.call(part.slice(colonIdx + 1));
|
|
1609
|
-
if (
|
|
1610
|
-
result[
|
|
1772
|
+
if (prop && value && value !== "undefined") {
|
|
1773
|
+
result[prop] = value;
|
|
1611
1774
|
}
|
|
1612
1775
|
}
|
|
1613
1776
|
return result;
|
|
1614
1777
|
}
|
|
1615
1778
|
case "object":
|
|
1616
|
-
for (let
|
|
1617
|
-
const value = expr[
|
|
1779
|
+
for (let prop in expr) {
|
|
1780
|
+
const value = expr[prop];
|
|
1618
1781
|
if (value || value === 0) {
|
|
1619
|
-
result[toKebabCase(
|
|
1782
|
+
result[toKebabCase(prop)] = String(value);
|
|
1620
1783
|
}
|
|
1621
1784
|
}
|
|
1622
1785
|
return result;
|
|
@@ -1647,22 +1810,22 @@ ${issueStrings}`);
|
|
|
1647
1810
|
function setStyle(val) {
|
|
1648
1811
|
val = val === "" ? {} : toStyleObj(val);
|
|
1649
1812
|
const style = this.style;
|
|
1650
|
-
for (let
|
|
1651
|
-
setStyleProp(style,
|
|
1813
|
+
for (let prop in val) {
|
|
1814
|
+
setStyleProp(style, prop, val[prop]);
|
|
1652
1815
|
}
|
|
1653
1816
|
}
|
|
1654
1817
|
function updateStyle(val, oldVal) {
|
|
1655
1818
|
oldVal = oldVal === "" ? {} : toStyleObj(oldVal);
|
|
1656
1819
|
val = val === "" ? {} : toStyleObj(val);
|
|
1657
1820
|
const style = this.style;
|
|
1658
|
-
for (let
|
|
1659
|
-
if (!(
|
|
1660
|
-
style.removeProperty(
|
|
1821
|
+
for (let prop in oldVal) {
|
|
1822
|
+
if (!(prop in val)) {
|
|
1823
|
+
style.removeProperty(prop);
|
|
1661
1824
|
}
|
|
1662
1825
|
}
|
|
1663
|
-
for (let
|
|
1664
|
-
if (val[
|
|
1665
|
-
setStyleProp(style,
|
|
1826
|
+
for (let prop in val) {
|
|
1827
|
+
if (val[prop] !== oldVal[prop]) {
|
|
1828
|
+
setStyleProp(style, prop, val[prop]);
|
|
1666
1829
|
}
|
|
1667
1830
|
}
|
|
1668
1831
|
if (!style.cssText) {
|
|
@@ -1714,11 +1877,6 @@ ${issueStrings}`);
|
|
|
1714
1877
|
}
|
|
1715
1878
|
throw new OwlError("Cannot mount component: the target is not a valid DOM element");
|
|
1716
1879
|
}
|
|
1717
|
-
var EventBus = class extends EventTarget {
|
|
1718
|
-
trigger(name, payload) {
|
|
1719
|
-
this.dispatchEvent(new CustomEvent(name, { detail: payload }));
|
|
1720
|
-
}
|
|
1721
|
-
};
|
|
1722
1880
|
function whenReady(fn) {
|
|
1723
1881
|
return new Promise(function(resolve) {
|
|
1724
1882
|
if (document.readyState !== "loading") {
|
|
@@ -1729,43 +1887,6 @@ ${issueStrings}`);
|
|
|
1729
1887
|
}).then(fn || function() {
|
|
1730
1888
|
});
|
|
1731
1889
|
}
|
|
1732
|
-
var Markup = class extends String {
|
|
1733
|
-
};
|
|
1734
|
-
function htmlEscape(str) {
|
|
1735
|
-
if (str instanceof Markup) {
|
|
1736
|
-
return str;
|
|
1737
|
-
}
|
|
1738
|
-
if (str === void 0) {
|
|
1739
|
-
return markup("");
|
|
1740
|
-
}
|
|
1741
|
-
if (typeof str === "number") {
|
|
1742
|
-
return markup(String(str));
|
|
1743
|
-
}
|
|
1744
|
-
[
|
|
1745
|
-
["&", "&"],
|
|
1746
|
-
["<", "<"],
|
|
1747
|
-
[">", ">"],
|
|
1748
|
-
["'", "'"],
|
|
1749
|
-
['"', """],
|
|
1750
|
-
["`", "`"]
|
|
1751
|
-
].forEach((pairs) => {
|
|
1752
|
-
str = String(str).replace(new RegExp(pairs[0], "g"), pairs[1]);
|
|
1753
|
-
});
|
|
1754
|
-
return markup(str);
|
|
1755
|
-
}
|
|
1756
|
-
function markup(valueOrStrings, ...placeholders) {
|
|
1757
|
-
if (!Array.isArray(valueOrStrings)) {
|
|
1758
|
-
return new Markup(valueOrStrings);
|
|
1759
|
-
}
|
|
1760
|
-
const strings = valueOrStrings;
|
|
1761
|
-
let acc = "";
|
|
1762
|
-
let i = 0;
|
|
1763
|
-
for (; i < placeholders.length; ++i) {
|
|
1764
|
-
acc += strings[i] + htmlEscape(placeholders[i]);
|
|
1765
|
-
}
|
|
1766
|
-
acc += strings[i];
|
|
1767
|
-
return new Markup(acc);
|
|
1768
|
-
}
|
|
1769
1890
|
function createEventHandler(rawEvent) {
|
|
1770
1891
|
const eventName = rawEvent.split(".")[0];
|
|
1771
1892
|
const capture = rawEvent.includes(".capture");
|
|
@@ -1787,7 +1908,7 @@ ${issueStrings}`);
|
|
|
1787
1908
|
if (!currentTarget || !inOwnerDocument(currentTarget)) return;
|
|
1788
1909
|
const data = currentTarget[eventKey];
|
|
1789
1910
|
if (!data) return;
|
|
1790
|
-
|
|
1911
|
+
config2.mainEventHandler(data, ev, currentTarget);
|
|
1791
1912
|
}
|
|
1792
1913
|
const options = { capture, passive };
|
|
1793
1914
|
function setup(data) {
|
|
@@ -1827,7 +1948,7 @@ ${issueStrings}`);
|
|
|
1827
1948
|
const _data = dom[eventKey];
|
|
1828
1949
|
if (_data) {
|
|
1829
1950
|
for (const data of Object.values(_data)) {
|
|
1830
|
-
const stopped =
|
|
1951
|
+
const stopped = config2.mainEventHandler(data, event, dom);
|
|
1831
1952
|
if (stopped) return;
|
|
1832
1953
|
}
|
|
1833
1954
|
}
|
|
@@ -2073,7 +2194,7 @@ ${issueStrings}`);
|
|
|
2073
2194
|
}
|
|
2074
2195
|
const doc = new DOMParser().parseFromString(`<t>${str}</t>`, "text/xml");
|
|
2075
2196
|
const node = doc.firstChild.firstChild;
|
|
2076
|
-
if (
|
|
2197
|
+
if (config2.shouldNormalizeDom) {
|
|
2077
2198
|
normalizeNode(node);
|
|
2078
2199
|
}
|
|
2079
2200
|
const tree = buildTree(node);
|
|
@@ -3196,12 +3317,15 @@ ${issueStrings}`);
|
|
|
3196
3317
|
parent;
|
|
3197
3318
|
children = /* @__PURE__ */ Object.create(null);
|
|
3198
3319
|
willUpdateProps = [];
|
|
3320
|
+
// Fired right after `props` is applied to `node.props` on a parent re-render,
|
|
3321
|
+
// so reactive prop notifications happen once the new values are observable
|
|
3322
|
+
// (after user `onWillUpdateProps` hooks, including async ones, have run).
|
|
3323
|
+
propsUpdated = [];
|
|
3199
3324
|
willUnmount = [];
|
|
3200
3325
|
mounted = [];
|
|
3201
3326
|
willPatch = [];
|
|
3202
3327
|
patched = [];
|
|
3203
3328
|
signalComputation;
|
|
3204
|
-
pluginManager;
|
|
3205
3329
|
constructor(C, props2, app, parent, parentKey) {
|
|
3206
3330
|
super(app);
|
|
3207
3331
|
this.parent = parent;
|
|
@@ -3731,6 +3855,7 @@ ${issueStrings}`);
|
|
|
3731
3855
|
() => {
|
|
3732
3856
|
if (fiber !== node.fiber) return;
|
|
3733
3857
|
node.props = props2;
|
|
3858
|
+
for (const f of node.propsUpdated) f();
|
|
3734
3859
|
fiber.render();
|
|
3735
3860
|
},
|
|
3736
3861
|
(error) => {
|
|
@@ -3739,6 +3864,7 @@ ${issueStrings}`);
|
|
|
3739
3864
|
);
|
|
3740
3865
|
} else {
|
|
3741
3866
|
node.props = props2;
|
|
3867
|
+
for (const f of node.propsUpdated) f();
|
|
3742
3868
|
fiber.render();
|
|
3743
3869
|
}
|
|
3744
3870
|
}
|
|
@@ -4079,10 +4205,6 @@ ${issueStrings}`);
|
|
|
4079
4205
|
}
|
|
4080
4206
|
return stopped;
|
|
4081
4207
|
};
|
|
4082
|
-
function onWillStart(fn) {
|
|
4083
|
-
const scope = useScope();
|
|
4084
|
-
scope.willStart.push(scope.decorate(fn, "onWillStart"));
|
|
4085
|
-
}
|
|
4086
4208
|
function onWillUpdateProps(fn) {
|
|
4087
4209
|
const scope = getComponentScope();
|
|
4088
4210
|
function swapped(s, nextProps) {
|
|
@@ -4106,10 +4228,6 @@ ${issueStrings}`);
|
|
|
4106
4228
|
const scope = getComponentScope();
|
|
4107
4229
|
scope.willUnmount.unshift(scope.decorate(fn, "onWillUnmount"));
|
|
4108
4230
|
}
|
|
4109
|
-
function onWillDestroy(fn) {
|
|
4110
|
-
const scope = useScope();
|
|
4111
|
-
scope.onDestroy(scope.decorate(fn, "onWillDestroy"));
|
|
4112
|
-
}
|
|
4113
4231
|
function onError(callback) {
|
|
4114
4232
|
const scope = getComponentScope();
|
|
4115
4233
|
let handlers = nodeErrorHandlers.get(scope);
|
|
@@ -4119,6 +4237,24 @@ ${issueStrings}`);
|
|
|
4119
4237
|
}
|
|
4120
4238
|
handlers.push(callback.bind(scope.component));
|
|
4121
4239
|
}
|
|
4240
|
+
function staticProp(key, type, ...args) {
|
|
4241
|
+
const node = getComponentScope();
|
|
4242
|
+
const hasDefault = args.length > 0;
|
|
4243
|
+
const propValue = node.props[key];
|
|
4244
|
+
if (node.app.dev) {
|
|
4245
|
+
if (type !== void 0 && (!hasDefault || propValue !== void 0)) {
|
|
4246
|
+
assertType(propValue, type, `Invalid prop '${key}' in '${node.componentName}'`);
|
|
4247
|
+
}
|
|
4248
|
+
node.willUpdateProps.push((nextProps) => {
|
|
4249
|
+
if (nextProps[key] !== node.props[key]) {
|
|
4250
|
+
throw new OwlError(
|
|
4251
|
+
`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).`
|
|
4252
|
+
);
|
|
4253
|
+
}
|
|
4254
|
+
});
|
|
4255
|
+
}
|
|
4256
|
+
return propValue === void 0 && hasDefault ? args[0] : propValue;
|
|
4257
|
+
}
|
|
4122
4258
|
function componentType() {
|
|
4123
4259
|
return constructorType(Component);
|
|
4124
4260
|
}
|
|
@@ -4140,35 +4276,51 @@ ${issueStrings}`);
|
|
|
4140
4276
|
}
|
|
4141
4277
|
return types2.strictObject(validation);
|
|
4142
4278
|
}
|
|
4143
|
-
function
|
|
4279
|
+
function makeProps(type, defaults) {
|
|
4144
4280
|
const node = getComponentScope();
|
|
4145
4281
|
const { app, componentName } = node;
|
|
4146
4282
|
if (defaults) {
|
|
4147
4283
|
node.defaultProps = Object.assign(node.defaultProps || {}, defaults);
|
|
4148
4284
|
}
|
|
4149
|
-
function
|
|
4150
|
-
if (
|
|
4285
|
+
function resolveValue(props2, key) {
|
|
4286
|
+
if (props2[key] === void 0 && defaults) {
|
|
4151
4287
|
return defaults[key];
|
|
4152
4288
|
}
|
|
4153
|
-
return
|
|
4289
|
+
return props2[key];
|
|
4154
4290
|
}
|
|
4291
|
+
const signals = /* @__PURE__ */ Object.create(null);
|
|
4155
4292
|
const result = /* @__PURE__ */ Object.create(null);
|
|
4156
|
-
function
|
|
4293
|
+
function defineProp(key) {
|
|
4294
|
+
signals[key] = signal(resolveValue(node.props, key));
|
|
4295
|
+
Reflect.defineProperty(result, key, {
|
|
4296
|
+
enumerable: true,
|
|
4297
|
+
configurable: true,
|
|
4298
|
+
get: signals[key]
|
|
4299
|
+
});
|
|
4300
|
+
}
|
|
4301
|
+
function defineProps(keys) {
|
|
4157
4302
|
for (const key of keys) {
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4303
|
+
defineProp(key);
|
|
4304
|
+
}
|
|
4305
|
+
}
|
|
4306
|
+
function updateSignals(keys) {
|
|
4307
|
+
for (const key of keys) {
|
|
4308
|
+
signals[key].set(resolveValue(node.props, key));
|
|
4162
4309
|
}
|
|
4163
4310
|
}
|
|
4164
4311
|
if (type) {
|
|
4165
4312
|
const keys = (Array.isArray(type) ? type : Object.keys(type)).map(
|
|
4166
4313
|
(key) => key.endsWith("?") ? key.slice(0, -1) : key
|
|
4167
4314
|
);
|
|
4168
|
-
|
|
4315
|
+
defineProps(keys);
|
|
4316
|
+
node.propsUpdated.push(() => updateSignals(keys));
|
|
4169
4317
|
if (app.dev) {
|
|
4170
4318
|
if (defaults) {
|
|
4171
|
-
assertType(
|
|
4319
|
+
assertType(
|
|
4320
|
+
defaults,
|
|
4321
|
+
validateDefaults(type),
|
|
4322
|
+
`Invalid component default props (${componentName})`
|
|
4323
|
+
);
|
|
4172
4324
|
}
|
|
4173
4325
|
const validation = types2.object(type);
|
|
4174
4326
|
assertType(node.props, validation, `Invalid component props (${componentName})`);
|
|
@@ -4194,17 +4346,28 @@ ${issueStrings}`);
|
|
|
4194
4346
|
return keys2;
|
|
4195
4347
|
};
|
|
4196
4348
|
let keys = getKeys(node.props);
|
|
4197
|
-
|
|
4198
|
-
node.
|
|
4349
|
+
defineProps(keys);
|
|
4350
|
+
node.propsUpdated.push(() => {
|
|
4351
|
+
const nextKeys = getKeys(node.props);
|
|
4352
|
+
const nextKeySet = new Set(nextKeys);
|
|
4199
4353
|
for (const key of keys) {
|
|
4200
|
-
|
|
4354
|
+
if (!nextKeySet.has(key)) {
|
|
4355
|
+
Reflect.deleteProperty(result, key);
|
|
4356
|
+
delete signals[key];
|
|
4357
|
+
}
|
|
4358
|
+
}
|
|
4359
|
+
for (const key of nextKeys) {
|
|
4360
|
+
if (!(key in signals)) {
|
|
4361
|
+
defineProp(key);
|
|
4362
|
+
}
|
|
4201
4363
|
}
|
|
4202
|
-
|
|
4203
|
-
|
|
4364
|
+
updateSignals(nextKeys);
|
|
4365
|
+
keys = nextKeys;
|
|
4204
4366
|
});
|
|
4205
4367
|
}
|
|
4206
4368
|
return result;
|
|
4207
4369
|
}
|
|
4370
|
+
var props = Object.assign(makeProps, { static: staticProp });
|
|
4208
4371
|
var ErrorBoundary = class extends Component {
|
|
4209
4372
|
static template = xml`
|
|
4210
4373
|
<t t-if="this.props.error()">
|
|
@@ -4219,27 +4382,7 @@ ${issueStrings}`);
|
|
|
4219
4382
|
onError((e) => this.props.error.set(e));
|
|
4220
4383
|
}
|
|
4221
4384
|
};
|
|
4222
|
-
|
|
4223
|
-
onWillDestroy(effect(fn));
|
|
4224
|
-
}
|
|
4225
|
-
function useListener(target, eventName, handler, eventParams) {
|
|
4226
|
-
if (typeof target === "function") {
|
|
4227
|
-
useEffect(() => {
|
|
4228
|
-
const el = target();
|
|
4229
|
-
if (el) {
|
|
4230
|
-
el.addEventListener(eventName, handler, eventParams);
|
|
4231
|
-
return () => el.removeEventListener(eventName, handler, eventParams);
|
|
4232
|
-
}
|
|
4233
|
-
return;
|
|
4234
|
-
});
|
|
4235
|
-
} else {
|
|
4236
|
-
target.addEventListener(eventName, handler, eventParams);
|
|
4237
|
-
onWillDestroy(() => target.removeEventListener(eventName, handler, eventParams));
|
|
4238
|
-
}
|
|
4239
|
-
}
|
|
4240
|
-
function useApp() {
|
|
4241
|
-
return useScope().app;
|
|
4242
|
-
}
|
|
4385
|
+
var useApp2 = useApp;
|
|
4243
4386
|
var PortalContent = class extends Component {
|
|
4244
4387
|
static template = xml`<t t-call-slot="default"/>`;
|
|
4245
4388
|
};
|
|
@@ -4323,47 +4466,6 @@ ${issueStrings}`);
|
|
|
4323
4466
|
onWillDestroy(() => root.destroy());
|
|
4324
4467
|
}
|
|
4325
4468
|
};
|
|
4326
|
-
function prop(key, type, ...args) {
|
|
4327
|
-
const node = getComponentScope();
|
|
4328
|
-
const hasDefault = args.length > 0;
|
|
4329
|
-
const propValue = node.props[key];
|
|
4330
|
-
if (node.app.dev) {
|
|
4331
|
-
if (type !== void 0 && (!hasDefault || propValue !== void 0)) {
|
|
4332
|
-
assertType(propValue, type, `Invalid prop '${key}' in '${node.componentName}'`);
|
|
4333
|
-
}
|
|
4334
|
-
node.willUpdateProps.push((nextProps) => {
|
|
4335
|
-
if (nextProps[key] !== node.props[key]) {
|
|
4336
|
-
throw new OwlError(
|
|
4337
|
-
`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).`
|
|
4338
|
-
);
|
|
4339
|
-
}
|
|
4340
|
-
});
|
|
4341
|
-
}
|
|
4342
|
-
return propValue === void 0 && hasDefault ? args[0] : propValue;
|
|
4343
|
-
}
|
|
4344
|
-
function plugin(pluginType) {
|
|
4345
|
-
const scope = useScope();
|
|
4346
|
-
const manager = scope instanceof ComponentNode ? scope.pluginManager : scope;
|
|
4347
|
-
let plugin2 = manager.getPluginById(pluginType.id);
|
|
4348
|
-
if (!plugin2) {
|
|
4349
|
-
if (scope instanceof PluginManager) {
|
|
4350
|
-
plugin2 = manager.startPlugin(pluginType);
|
|
4351
|
-
} else {
|
|
4352
|
-
throw new OwlError(`Unknown plugin "${pluginType.id}"`);
|
|
4353
|
-
}
|
|
4354
|
-
}
|
|
4355
|
-
return plugin2;
|
|
4356
|
-
}
|
|
4357
|
-
function config2(name, type) {
|
|
4358
|
-
const scope = useScope();
|
|
4359
|
-
if (!(scope instanceof PluginManager)) {
|
|
4360
|
-
throw new OwlError("Expected to be in a plugin scope");
|
|
4361
|
-
}
|
|
4362
|
-
if (scope.app.dev && type) {
|
|
4363
|
-
assertType(scope.config, types2.object({ [name]: type }), "Config does not match the type");
|
|
4364
|
-
}
|
|
4365
|
-
return scope.config[name.endsWith("?") ? name.slice(0, -1) : name];
|
|
4366
|
-
}
|
|
4367
4469
|
function providePlugins(pluginConstructors, config3) {
|
|
4368
4470
|
const node = getComponentScope();
|
|
4369
4471
|
const manager = new PluginManager(node.app, { parent: node.pluginManager, config: config3 });
|
|
@@ -4374,10 +4476,10 @@ ${issueStrings}`);
|
|
|
4374
4476
|
onWillStart(() => manager.ready);
|
|
4375
4477
|
}
|
|
4376
4478
|
}
|
|
4377
|
-
|
|
4378
|
-
|
|
4479
|
+
config2.shouldNormalizeDom = false;
|
|
4480
|
+
config2.mainEventHandler = mainEventHandler;
|
|
4379
4481
|
var blockDom = {
|
|
4380
|
-
config,
|
|
4482
|
+
config: config2,
|
|
4381
4483
|
// bdom entry points
|
|
4382
4484
|
mount,
|
|
4383
4485
|
patch,
|
|
@@ -4392,8 +4494,8 @@ ${issueStrings}`);
|
|
|
4392
4494
|
};
|
|
4393
4495
|
var __info__ = {
|
|
4394
4496
|
version: App.version,
|
|
4395
|
-
date: "2026-
|
|
4396
|
-
hash: "
|
|
4497
|
+
date: "2026-06-05T08:44:38.319Z",
|
|
4498
|
+
hash: "3206cf27",
|
|
4397
4499
|
url: "https://github.com/odoo/owl"
|
|
4398
4500
|
};
|
|
4399
4501
|
|