@odoo/owl 2.0.0-beta-12 → 2.0.0-beta-16
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 +133 -121
- package/dist/owl.es.js +133 -122
- package/dist/owl.iife.js +133 -121
- package/dist/owl.iife.min.js +1 -1
- package/dist/types/compiler/code_generator.d.ts +1 -1
- package/dist/types/compiler/inline_expressions.d.ts +0 -22
- package/dist/types/owl.d.ts +5 -2
- package/dist/types/runtime/component_node.d.ts +0 -1
- package/dist/types/runtime/error_handling.d.ts +3 -0
- package/dist/types/runtime/index.d.ts +1 -0
- package/dist/types/runtime/template_helpers.d.ts +2 -0
- package/package.json +1 -2
package/dist/owl.iife.js
CHANGED
|
@@ -80,6 +80,68 @@
|
|
|
80
80
|
return new VToggler(key, child);
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
// Custom error class that wraps error that happen in the owl lifecycle
|
|
84
|
+
class OwlError extends Error {
|
|
85
|
+
}
|
|
86
|
+
// Maps fibers to thrown errors
|
|
87
|
+
const fibersInError = new WeakMap();
|
|
88
|
+
const nodeErrorHandlers = new WeakMap();
|
|
89
|
+
function _handleError(node, error) {
|
|
90
|
+
if (!node) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
const fiber = node.fiber;
|
|
94
|
+
if (fiber) {
|
|
95
|
+
fibersInError.set(fiber, error);
|
|
96
|
+
}
|
|
97
|
+
const errorHandlers = nodeErrorHandlers.get(node);
|
|
98
|
+
if (errorHandlers) {
|
|
99
|
+
let handled = false;
|
|
100
|
+
// execute in the opposite order
|
|
101
|
+
for (let i = errorHandlers.length - 1; i >= 0; i--) {
|
|
102
|
+
try {
|
|
103
|
+
errorHandlers[i](error);
|
|
104
|
+
handled = true;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
catch (e) {
|
|
108
|
+
error = e;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (handled) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return _handleError(node.parent, error);
|
|
116
|
+
}
|
|
117
|
+
function handleError(params) {
|
|
118
|
+
let { error } = params;
|
|
119
|
+
// Wrap error if it wasn't wrapped by wrapError (ie when not in dev mode)
|
|
120
|
+
if (!(error instanceof OwlError)) {
|
|
121
|
+
error = Object.assign(new OwlError(`An error occured in the owl lifecycle (see this Error's "cause" property)`), { cause: error });
|
|
122
|
+
}
|
|
123
|
+
const node = "node" in params ? params.node : params.fiber.node;
|
|
124
|
+
const fiber = "fiber" in params ? params.fiber : node.fiber;
|
|
125
|
+
// resets the fibers on components if possible. This is important so that
|
|
126
|
+
// new renderings can be properly included in the initial one, if any.
|
|
127
|
+
let current = fiber;
|
|
128
|
+
do {
|
|
129
|
+
current.node.fiber = current;
|
|
130
|
+
current = current.parent;
|
|
131
|
+
} while (current);
|
|
132
|
+
fibersInError.set(fiber.root, error);
|
|
133
|
+
const handled = _handleError(node, error);
|
|
134
|
+
if (!handled) {
|
|
135
|
+
console.warn(`[Owl] Unhandled error. Destroying the root component`);
|
|
136
|
+
try {
|
|
137
|
+
node.app.destroy();
|
|
138
|
+
}
|
|
139
|
+
catch (e) {
|
|
140
|
+
console.error(e);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
83
145
|
const { setAttribute: elemSetAttribute, removeAttribute } = Element.prototype;
|
|
84
146
|
const tokenList = DOMTokenList.prototype;
|
|
85
147
|
const tokenListAdd = tokenList.add;
|
|
@@ -217,7 +279,7 @@
|
|
|
217
279
|
function makePropSetter(name) {
|
|
218
280
|
return function setProp(value) {
|
|
219
281
|
// support 0, fallback to empty string for other falsy values
|
|
220
|
-
this[name] = value === 0 ? 0 : value
|
|
282
|
+
this[name] = value === 0 ? 0 : value ? value.valueOf() : "";
|
|
221
283
|
};
|
|
222
284
|
}
|
|
223
285
|
function isProp(tag, key) {
|
|
@@ -701,7 +763,7 @@
|
|
|
701
763
|
};
|
|
702
764
|
}
|
|
703
765
|
}
|
|
704
|
-
throw new
|
|
766
|
+
throw new OwlError("boom");
|
|
705
767
|
}
|
|
706
768
|
function addRef(tree) {
|
|
707
769
|
tree.isRef = true;
|
|
@@ -1385,61 +1447,6 @@
|
|
|
1385
1447
|
vnode.remove();
|
|
1386
1448
|
}
|
|
1387
1449
|
|
|
1388
|
-
// Maps fibers to thrown errors
|
|
1389
|
-
const fibersInError = new WeakMap();
|
|
1390
|
-
const nodeErrorHandlers = new WeakMap();
|
|
1391
|
-
function _handleError(node, error) {
|
|
1392
|
-
if (!node) {
|
|
1393
|
-
return false;
|
|
1394
|
-
}
|
|
1395
|
-
const fiber = node.fiber;
|
|
1396
|
-
if (fiber) {
|
|
1397
|
-
fibersInError.set(fiber, error);
|
|
1398
|
-
}
|
|
1399
|
-
const errorHandlers = nodeErrorHandlers.get(node);
|
|
1400
|
-
if (errorHandlers) {
|
|
1401
|
-
let handled = false;
|
|
1402
|
-
// execute in the opposite order
|
|
1403
|
-
for (let i = errorHandlers.length - 1; i >= 0; i--) {
|
|
1404
|
-
try {
|
|
1405
|
-
errorHandlers[i](error);
|
|
1406
|
-
handled = true;
|
|
1407
|
-
break;
|
|
1408
|
-
}
|
|
1409
|
-
catch (e) {
|
|
1410
|
-
error = e;
|
|
1411
|
-
}
|
|
1412
|
-
}
|
|
1413
|
-
if (handled) {
|
|
1414
|
-
return true;
|
|
1415
|
-
}
|
|
1416
|
-
}
|
|
1417
|
-
return _handleError(node.parent, error);
|
|
1418
|
-
}
|
|
1419
|
-
function handleError(params) {
|
|
1420
|
-
const error = params.error;
|
|
1421
|
-
const node = "node" in params ? params.node : params.fiber.node;
|
|
1422
|
-
const fiber = "fiber" in params ? params.fiber : node.fiber;
|
|
1423
|
-
// resets the fibers on components if possible. This is important so that
|
|
1424
|
-
// new renderings can be properly included in the initial one, if any.
|
|
1425
|
-
let current = fiber;
|
|
1426
|
-
do {
|
|
1427
|
-
current.node.fiber = current;
|
|
1428
|
-
current = current.parent;
|
|
1429
|
-
} while (current);
|
|
1430
|
-
fibersInError.set(fiber.root, error);
|
|
1431
|
-
const handled = _handleError(node, error);
|
|
1432
|
-
if (!handled) {
|
|
1433
|
-
console.warn(`[Owl] Unhandled error. Destroying the root component`);
|
|
1434
|
-
try {
|
|
1435
|
-
node.app.destroy();
|
|
1436
|
-
}
|
|
1437
|
-
catch (e) {
|
|
1438
|
-
console.error(e);
|
|
1439
|
-
}
|
|
1440
|
-
}
|
|
1441
|
-
}
|
|
1442
|
-
|
|
1443
1450
|
function makeChildFiber(node, parent) {
|
|
1444
1451
|
let current = node.fiber;
|
|
1445
1452
|
if (current) {
|
|
@@ -1478,7 +1485,7 @@
|
|
|
1478
1485
|
return fiber;
|
|
1479
1486
|
}
|
|
1480
1487
|
function throwOnRender() {
|
|
1481
|
-
throw new
|
|
1488
|
+
throw new OwlError("Attempted to render cancelled fiber");
|
|
1482
1489
|
}
|
|
1483
1490
|
/**
|
|
1484
1491
|
* @returns number of not-yet rendered fibers cancelled
|
|
@@ -1855,7 +1862,7 @@
|
|
|
1855
1862
|
*/
|
|
1856
1863
|
function reactive(target, callback = () => { }) {
|
|
1857
1864
|
if (!canBeMadeReactive(target)) {
|
|
1858
|
-
throw new
|
|
1865
|
+
throw new OwlError(`Cannot make the given value reactive`);
|
|
1859
1866
|
}
|
|
1860
1867
|
if (SKIP in target) {
|
|
1861
1868
|
return target;
|
|
@@ -2124,10 +2131,10 @@
|
|
|
2124
2131
|
}
|
|
2125
2132
|
function validateTarget(target) {
|
|
2126
2133
|
if (!(target instanceof HTMLElement)) {
|
|
2127
|
-
throw new
|
|
2134
|
+
throw new OwlError("Cannot mount component: the target is not a valid DOM element");
|
|
2128
2135
|
}
|
|
2129
2136
|
if (!document.body.contains(target)) {
|
|
2130
|
-
throw new
|
|
2137
|
+
throw new OwlError("Cannot mount a component on a detached dom node");
|
|
2131
2138
|
}
|
|
2132
2139
|
}
|
|
2133
2140
|
class EventBus extends EventTarget {
|
|
@@ -2148,7 +2155,7 @@
|
|
|
2148
2155
|
async function loadFile(url) {
|
|
2149
2156
|
const result = await fetch(url);
|
|
2150
2157
|
if (!result.ok) {
|
|
2151
|
-
throw new
|
|
2158
|
+
throw new OwlError("Error while fetching xml templates");
|
|
2152
2159
|
}
|
|
2153
2160
|
return await result.text();
|
|
2154
2161
|
}
|
|
@@ -2170,7 +2177,7 @@
|
|
|
2170
2177
|
let currentNode = null;
|
|
2171
2178
|
function getCurrent() {
|
|
2172
2179
|
if (!currentNode) {
|
|
2173
|
-
throw new
|
|
2180
|
+
throw new OwlError("No active component (a hook function should only be called in 'setup')");
|
|
2174
2181
|
}
|
|
2175
2182
|
return currentNode;
|
|
2176
2183
|
}
|
|
@@ -2232,7 +2239,6 @@
|
|
|
2232
2239
|
this.parent = parent;
|
|
2233
2240
|
this.props = props;
|
|
2234
2241
|
this.parentKey = parentKey;
|
|
2235
|
-
this.level = parent ? parent.level + 1 : 0;
|
|
2236
2242
|
const defaultProps = C.defaultProps;
|
|
2237
2243
|
props = Object.assign({}, props);
|
|
2238
2244
|
if (defaultProps) {
|
|
@@ -2465,17 +2471,27 @@
|
|
|
2465
2471
|
|
|
2466
2472
|
const TIMEOUT = Symbol("timeout");
|
|
2467
2473
|
function wrapError(fn, hookName) {
|
|
2468
|
-
const error = new
|
|
2469
|
-
const timeoutError = new
|
|
2474
|
+
const error = new OwlError(`The following error occurred in ${hookName}: `);
|
|
2475
|
+
const timeoutError = new OwlError(`${hookName}'s promise hasn't resolved after 3 seconds`);
|
|
2470
2476
|
const node = getCurrent();
|
|
2471
2477
|
return (...args) => {
|
|
2478
|
+
const onError = (cause) => {
|
|
2479
|
+
error.cause = cause;
|
|
2480
|
+
if (cause instanceof Error) {
|
|
2481
|
+
error.message += `"${cause.message}"`;
|
|
2482
|
+
}
|
|
2483
|
+
else {
|
|
2484
|
+
error.message = `Something that is not an Error was thrown in ${hookName} (see this Error's "cause" property)`;
|
|
2485
|
+
}
|
|
2486
|
+
throw error;
|
|
2487
|
+
};
|
|
2472
2488
|
try {
|
|
2473
2489
|
const result = fn(...args);
|
|
2474
2490
|
if (result instanceof Promise) {
|
|
2475
2491
|
if (hookName === "onWillStart" || hookName === "onWillUpdateProps") {
|
|
2476
2492
|
const fiber = node.fiber;
|
|
2477
2493
|
Promise.race([
|
|
2478
|
-
result,
|
|
2494
|
+
result.catch(() => { }),
|
|
2479
2495
|
new Promise((resolve) => setTimeout(() => resolve(TIMEOUT), 3000)),
|
|
2480
2496
|
]).then((res) => {
|
|
2481
2497
|
if (res === TIMEOUT && node.fiber === fiber) {
|
|
@@ -2483,21 +2499,12 @@
|
|
|
2483
2499
|
}
|
|
2484
2500
|
});
|
|
2485
2501
|
}
|
|
2486
|
-
return result.catch(
|
|
2487
|
-
error.cause = cause;
|
|
2488
|
-
if (cause instanceof Error) {
|
|
2489
|
-
error.message += `"${cause.message}"`;
|
|
2490
|
-
}
|
|
2491
|
-
throw error;
|
|
2492
|
-
});
|
|
2502
|
+
return result.catch(onError);
|
|
2493
2503
|
}
|
|
2494
2504
|
return result;
|
|
2495
2505
|
}
|
|
2496
2506
|
catch (cause) {
|
|
2497
|
-
|
|
2498
|
-
error.message += `"${cause.message}"`;
|
|
2499
|
-
}
|
|
2500
|
-
throw error;
|
|
2507
|
+
onError(cause);
|
|
2501
2508
|
}
|
|
2502
2509
|
};
|
|
2503
2510
|
}
|
|
@@ -2601,7 +2608,7 @@
|
|
|
2601
2608
|
}
|
|
2602
2609
|
this.target = el && el.querySelector(this.selector);
|
|
2603
2610
|
if (!this.target) {
|
|
2604
|
-
throw new
|
|
2611
|
+
throw new OwlError("invalid portal target");
|
|
2605
2612
|
}
|
|
2606
2613
|
}
|
|
2607
2614
|
this.realBDom.mount(this.target, null);
|
|
@@ -2695,7 +2702,7 @@
|
|
|
2695
2702
|
function validate(obj, spec) {
|
|
2696
2703
|
let errors = validateSchema(obj, spec);
|
|
2697
2704
|
if (errors.length) {
|
|
2698
|
-
throw new
|
|
2705
|
+
throw new OwlError("Invalid object: " + errors.join(", "));
|
|
2699
2706
|
}
|
|
2700
2707
|
}
|
|
2701
2708
|
/**
|
|
@@ -2848,7 +2855,7 @@
|
|
|
2848
2855
|
keys = Object.values(collection);
|
|
2849
2856
|
}
|
|
2850
2857
|
else {
|
|
2851
|
-
throw new
|
|
2858
|
+
throw new OwlError("Invalid loop expression");
|
|
2852
2859
|
}
|
|
2853
2860
|
const n = values.length;
|
|
2854
2861
|
return [keys, values, n, new Array(n)];
|
|
@@ -2954,7 +2961,7 @@
|
|
|
2954
2961
|
if (el) {
|
|
2955
2962
|
count++;
|
|
2956
2963
|
if (count > 1) {
|
|
2957
|
-
throw new
|
|
2964
|
+
throw new OwlError("Cannot have 2 elements with same ref name at the same time");
|
|
2958
2965
|
}
|
|
2959
2966
|
}
|
|
2960
2967
|
if (count === 0 || el) {
|
|
@@ -2991,13 +2998,13 @@
|
|
|
2991
2998
|
: name in schema && !("*" in schema) && !isOptional(schema[name]);
|
|
2992
2999
|
for (let p in defaultProps) {
|
|
2993
3000
|
if (isMandatory(p)) {
|
|
2994
|
-
throw new
|
|
3001
|
+
throw new OwlError(`A default value cannot be defined for a mandatory prop (name: '${p}', component: ${ComponentClass.name})`);
|
|
2995
3002
|
}
|
|
2996
3003
|
}
|
|
2997
3004
|
}
|
|
2998
3005
|
const errors = validateSchema(props, schema);
|
|
2999
3006
|
if (errors.length) {
|
|
3000
|
-
throw new
|
|
3007
|
+
throw new OwlError(`Invalid props for component '${ComponentClass.name}': ` + errors.join(", "));
|
|
3001
3008
|
}
|
|
3002
3009
|
}
|
|
3003
3010
|
const helpers = {
|
|
@@ -3018,6 +3025,7 @@
|
|
|
3018
3025
|
bind,
|
|
3019
3026
|
createCatcher,
|
|
3020
3027
|
markRaw,
|
|
3028
|
+
OwlError,
|
|
3021
3029
|
};
|
|
3022
3030
|
|
|
3023
3031
|
const bdom = { text, createBlock, list, multi, html, toggler, comment };
|
|
@@ -3045,7 +3053,7 @@
|
|
|
3045
3053
|
}
|
|
3046
3054
|
}
|
|
3047
3055
|
}
|
|
3048
|
-
throw new
|
|
3056
|
+
throw new OwlError(msg);
|
|
3049
3057
|
}
|
|
3050
3058
|
return doc;
|
|
3051
3059
|
}
|
|
@@ -3076,7 +3084,7 @@
|
|
|
3076
3084
|
if (currentAsString === newAsString) {
|
|
3077
3085
|
return;
|
|
3078
3086
|
}
|
|
3079
|
-
throw new
|
|
3087
|
+
throw new OwlError(`Template ${name} already defined with different content`);
|
|
3080
3088
|
}
|
|
3081
3089
|
this.rawTemplates[name] = template;
|
|
3082
3090
|
}
|
|
@@ -3101,7 +3109,7 @@
|
|
|
3101
3109
|
extraInfo = ` (for component "${componentName}")`;
|
|
3102
3110
|
}
|
|
3103
3111
|
catch { }
|
|
3104
|
-
throw new
|
|
3112
|
+
throw new OwlError(`Missing template: "${name}"${extraInfo}`);
|
|
3105
3113
|
}
|
|
3106
3114
|
const isFn = typeof rawTemplate === "function" && !(rawTemplate instanceof Element);
|
|
3107
3115
|
const templateFn = isFn ? rawTemplate : this._compileTemplate(name, rawTemplate);
|
|
@@ -3117,7 +3125,7 @@
|
|
|
3117
3125
|
return this.templates[name];
|
|
3118
3126
|
}
|
|
3119
3127
|
_compileTemplate(name, template) {
|
|
3120
|
-
throw new
|
|
3128
|
+
throw new OwlError(`Unable to compile a template. Please use owl full build instead`);
|
|
3121
3129
|
}
|
|
3122
3130
|
callTemplate(owner, subTemplate, ctx, parent, key) {
|
|
3123
3131
|
const template = this.getTemplate(subTemplate);
|
|
@@ -3199,14 +3207,14 @@
|
|
|
3199
3207
|
i++;
|
|
3200
3208
|
cur = expr[i];
|
|
3201
3209
|
if (!cur) {
|
|
3202
|
-
throw new
|
|
3210
|
+
throw new OwlError("Invalid expression");
|
|
3203
3211
|
}
|
|
3204
3212
|
s += cur;
|
|
3205
3213
|
}
|
|
3206
3214
|
i++;
|
|
3207
3215
|
}
|
|
3208
3216
|
if (expr[i] !== start) {
|
|
3209
|
-
throw new
|
|
3217
|
+
throw new OwlError("Invalid expression");
|
|
3210
3218
|
}
|
|
3211
3219
|
s += start;
|
|
3212
3220
|
if (start === "`") {
|
|
@@ -3313,7 +3321,7 @@
|
|
|
3313
3321
|
error = e; // Silence all errors and throw a generic error below
|
|
3314
3322
|
}
|
|
3315
3323
|
if (current.length || error) {
|
|
3316
|
-
throw new
|
|
3324
|
+
throw new OwlError(`Tokenizer error: could not tokenize \`${expr}\``);
|
|
3317
3325
|
}
|
|
3318
3326
|
return result;
|
|
3319
3327
|
}
|
|
@@ -3864,7 +3872,7 @@
|
|
|
3864
3872
|
.slice(1)
|
|
3865
3873
|
.map((m) => {
|
|
3866
3874
|
if (!MODS.has(m)) {
|
|
3867
|
-
throw new
|
|
3875
|
+
throw new OwlError(`Unknown event modifier: '${m}'`);
|
|
3868
3876
|
}
|
|
3869
3877
|
return `"${m}"`;
|
|
3870
3878
|
});
|
|
@@ -3906,13 +3914,18 @@
|
|
|
3906
3914
|
attrs["block-attribute-" + idx] = attrName;
|
|
3907
3915
|
}
|
|
3908
3916
|
else if (key.startsWith("t-att")) {
|
|
3917
|
+
attrName = key === "t-att" ? null : key.slice(6);
|
|
3909
3918
|
expr = compileExpr(ast.attrs[key]);
|
|
3919
|
+
if (attrName && isProp(ast.tag, attrName)) {
|
|
3920
|
+
// we force a new string or new boolean to bypass the equality check in blockdom when patching same value
|
|
3921
|
+
const C = attrName === "value" ? "String" : "Boolean";
|
|
3922
|
+
expr = `new ${C}(${expr})`;
|
|
3923
|
+
}
|
|
3910
3924
|
const idx = block.insertData(expr, "attr");
|
|
3911
3925
|
if (key === "t-att") {
|
|
3912
3926
|
attrs[`block-attributes`] = String(idx);
|
|
3913
3927
|
}
|
|
3914
3928
|
else {
|
|
3915
|
-
attrName = key.slice(6);
|
|
3916
3929
|
attrs[`block-attribute-${idx}`] = attrName;
|
|
3917
3930
|
}
|
|
3918
3931
|
}
|
|
@@ -4180,7 +4193,8 @@
|
|
|
4180
4193
|
this.define(`key${this.target.loopLevel}`, ast.key ? compileExpr(ast.key) : loopVar);
|
|
4181
4194
|
if (this.dev) {
|
|
4182
4195
|
// Throw error on duplicate keys in dev mode
|
|
4183
|
-
this.
|
|
4196
|
+
this.helpers.add("OwlError");
|
|
4197
|
+
this.addLine(`if (keys${block.id}.has(key${this.target.loopLevel})) { throw new OwlError(\`Got duplicate key in t-foreach: \${key${this.target.loopLevel}}\`)}`);
|
|
4184
4198
|
this.addLine(`keys${block.id}.add(key${this.target.loopLevel});`);
|
|
4185
4199
|
}
|
|
4186
4200
|
let id;
|
|
@@ -4394,7 +4408,7 @@
|
|
|
4394
4408
|
value = `bind(ctx, ${value || undefined})`;
|
|
4395
4409
|
}
|
|
4396
4410
|
else {
|
|
4397
|
-
throw new
|
|
4411
|
+
throw new OwlError("Invalid prop suffix");
|
|
4398
4412
|
}
|
|
4399
4413
|
}
|
|
4400
4414
|
name = /^[a-z_]+$/i.test(name) ? name : `'${name}'`;
|
|
@@ -4587,9 +4601,6 @@
|
|
|
4587
4601
|
}
|
|
4588
4602
|
}
|
|
4589
4603
|
|
|
4590
|
-
// -----------------------------------------------------------------------------
|
|
4591
|
-
// AST Type definition
|
|
4592
|
-
// -----------------------------------------------------------------------------
|
|
4593
4604
|
// -----------------------------------------------------------------------------
|
|
4594
4605
|
// Parser
|
|
4595
4606
|
// -----------------------------------------------------------------------------
|
|
@@ -4698,7 +4709,7 @@
|
|
|
4698
4709
|
return null;
|
|
4699
4710
|
}
|
|
4700
4711
|
if (tagName.startsWith("block-")) {
|
|
4701
|
-
throw new
|
|
4712
|
+
throw new OwlError(`Invalid tag name: '${tagName}'`);
|
|
4702
4713
|
}
|
|
4703
4714
|
ctx = Object.assign({}, ctx);
|
|
4704
4715
|
if (tagName === "pre") {
|
|
@@ -4717,14 +4728,14 @@
|
|
|
4717
4728
|
const value = node.getAttribute(attr);
|
|
4718
4729
|
if (attr.startsWith("t-on")) {
|
|
4719
4730
|
if (attr === "t-on") {
|
|
4720
|
-
throw new
|
|
4731
|
+
throw new OwlError("Missing event name with t-on directive");
|
|
4721
4732
|
}
|
|
4722
4733
|
on = on || {};
|
|
4723
4734
|
on[attr.slice(5)] = value;
|
|
4724
4735
|
}
|
|
4725
4736
|
else if (attr.startsWith("t-model")) {
|
|
4726
4737
|
if (!["input", "select", "textarea"].includes(tagName)) {
|
|
4727
|
-
throw new
|
|
4738
|
+
throw new OwlError("The t-model directive only works with <input>, <textarea> and <select>");
|
|
4728
4739
|
}
|
|
4729
4740
|
let baseExpr, expr;
|
|
4730
4741
|
if (hasDotAtTheEnd.test(value)) {
|
|
@@ -4738,7 +4749,7 @@
|
|
|
4738
4749
|
expr = value.slice(index + 1, -1);
|
|
4739
4750
|
}
|
|
4740
4751
|
else {
|
|
4741
|
-
throw new
|
|
4752
|
+
throw new OwlError(`Invalid t-model expression: "${value}" (it should be assignable)`);
|
|
4742
4753
|
}
|
|
4743
4754
|
const typeAttr = node.getAttribute("type");
|
|
4744
4755
|
const isInput = tagName === "input";
|
|
@@ -4768,11 +4779,11 @@
|
|
|
4768
4779
|
}
|
|
4769
4780
|
}
|
|
4770
4781
|
else if (attr.startsWith("block-")) {
|
|
4771
|
-
throw new
|
|
4782
|
+
throw new OwlError(`Invalid attribute: '${attr}'`);
|
|
4772
4783
|
}
|
|
4773
4784
|
else if (attr !== "t-name") {
|
|
4774
4785
|
if (attr.startsWith("t-") && !attr.startsWith("t-att")) {
|
|
4775
|
-
throw new
|
|
4786
|
+
throw new OwlError(`Unknown QWeb directive: '${attr}'`);
|
|
4776
4787
|
}
|
|
4777
4788
|
const tModel = ctx.tModelInfo;
|
|
4778
4789
|
if (tModel && ["t-att-value", "t-attf-value"].includes(attr)) {
|
|
@@ -4823,7 +4834,7 @@
|
|
|
4823
4834
|
};
|
|
4824
4835
|
}
|
|
4825
4836
|
if (ast.type === 11 /* TComponent */) {
|
|
4826
|
-
throw new
|
|
4837
|
+
throw new OwlError("t-esc is not supported on Component nodes");
|
|
4827
4838
|
}
|
|
4828
4839
|
return tesc;
|
|
4829
4840
|
}
|
|
@@ -4871,7 +4882,7 @@
|
|
|
4871
4882
|
node.removeAttribute("t-as");
|
|
4872
4883
|
const key = node.getAttribute("t-key");
|
|
4873
4884
|
if (!key) {
|
|
4874
|
-
throw new
|
|
4885
|
+
throw new OwlError(`"Directive t-foreach should always be used with a t-key!" (expression: t-foreach="${collection}" t-as="${elem}")`);
|
|
4875
4886
|
}
|
|
4876
4887
|
node.removeAttribute("t-key");
|
|
4877
4888
|
const memo = node.getAttribute("t-memo") || "";
|
|
@@ -5031,7 +5042,7 @@
|
|
|
5031
5042
|
const firstLetter = name[0];
|
|
5032
5043
|
let isDynamic = node.hasAttribute("t-component");
|
|
5033
5044
|
if (isDynamic && name !== "t") {
|
|
5034
|
-
throw new
|
|
5045
|
+
throw new OwlError(`Directive 't-component' can only be used on <t> nodes (used on a <${name}>)`);
|
|
5035
5046
|
}
|
|
5036
5047
|
if (!(firstLetter === firstLetter.toUpperCase() || isDynamic)) {
|
|
5037
5048
|
return null;
|
|
@@ -5055,7 +5066,7 @@
|
|
|
5055
5066
|
}
|
|
5056
5067
|
else {
|
|
5057
5068
|
const message = directiveErrorMap.get(name.split("-").slice(0, 2).join("-"));
|
|
5058
|
-
throw new
|
|
5069
|
+
throw new OwlError(message || `unsupported directive on Component: ${name}`);
|
|
5059
5070
|
}
|
|
5060
5071
|
}
|
|
5061
5072
|
else {
|
|
@@ -5070,7 +5081,7 @@
|
|
|
5070
5081
|
const slotNodes = Array.from(clone.querySelectorAll("[t-set-slot]"));
|
|
5071
5082
|
for (let slotNode of slotNodes) {
|
|
5072
5083
|
if (slotNode.tagName !== "t") {
|
|
5073
|
-
throw new
|
|
5084
|
+
throw new OwlError(`Directive 't-set-slot' can only be used on <t> nodes (used on a <${slotNode.tagName}>)`);
|
|
5074
5085
|
}
|
|
5075
5086
|
const name = slotNode.getAttribute("t-set-slot");
|
|
5076
5087
|
// check if this is defined in a sub component (in which case it should
|
|
@@ -5235,25 +5246,25 @@
|
|
|
5235
5246
|
let nattr = (name) => +!!node.getAttribute(name);
|
|
5236
5247
|
if (prevElem && (pattr("t-if") || pattr("t-elif"))) {
|
|
5237
5248
|
if (pattr("t-foreach")) {
|
|
5238
|
-
throw new
|
|
5249
|
+
throw new OwlError("t-if cannot stay at the same level as t-foreach when using t-elif or t-else");
|
|
5239
5250
|
}
|
|
5240
5251
|
if (["t-if", "t-elif", "t-else"].map(nattr).reduce(function (a, b) {
|
|
5241
5252
|
return a + b;
|
|
5242
5253
|
}) > 1) {
|
|
5243
|
-
throw new
|
|
5254
|
+
throw new OwlError("Only one conditional branching directive is allowed per node");
|
|
5244
5255
|
}
|
|
5245
5256
|
// All text (with only spaces) and comment nodes (nodeType 8) between
|
|
5246
5257
|
// branch nodes are removed
|
|
5247
5258
|
let textNode;
|
|
5248
5259
|
while ((textNode = node.previousSibling) !== prevElem) {
|
|
5249
5260
|
if (textNode.nodeValue.trim().length && textNode.nodeType !== 8) {
|
|
5250
|
-
throw new
|
|
5261
|
+
throw new OwlError("text is not allowed between branching directives");
|
|
5251
5262
|
}
|
|
5252
5263
|
textNode.remove();
|
|
5253
5264
|
}
|
|
5254
5265
|
}
|
|
5255
5266
|
else {
|
|
5256
|
-
throw new
|
|
5267
|
+
throw new OwlError("t-elif and t-else directives must be preceded by a t-if or t-elif directive");
|
|
5257
5268
|
}
|
|
5258
5269
|
}
|
|
5259
5270
|
}
|
|
@@ -5269,7 +5280,7 @@
|
|
|
5269
5280
|
const elements = [...el.querySelectorAll("[t-esc]")].filter((el) => el.tagName[0] === el.tagName[0].toUpperCase() || el.hasAttribute("t-component"));
|
|
5270
5281
|
for (const el of elements) {
|
|
5271
5282
|
if (el.childNodes.length) {
|
|
5272
|
-
throw new
|
|
5283
|
+
throw new OwlError("Cannot have t-esc on a component that already has content");
|
|
5273
5284
|
}
|
|
5274
5285
|
const value = el.getAttribute("t-esc");
|
|
5275
5286
|
el.removeAttribute("t-esc");
|
|
@@ -5321,7 +5332,7 @@
|
|
|
5321
5332
|
}
|
|
5322
5333
|
}
|
|
5323
5334
|
}
|
|
5324
|
-
throw new
|
|
5335
|
+
throw new OwlError(msg);
|
|
5325
5336
|
}
|
|
5326
5337
|
return doc;
|
|
5327
5338
|
}
|
|
@@ -5375,7 +5386,7 @@
|
|
|
5375
5386
|
if (Object.hasOwnProperty.call(data, 0)) {
|
|
5376
5387
|
const handler = data[0];
|
|
5377
5388
|
if (typeof handler !== "function") {
|
|
5378
|
-
throw new
|
|
5389
|
+
throw new OwlError(`Invalid handler (expected a function, received: '${handler}')`);
|
|
5379
5390
|
}
|
|
5380
5391
|
let node = data[1] ? data[1].__owl__ : null;
|
|
5381
5392
|
if (node ? node.status === 1 /* MOUNTED */ : true) {
|
|
@@ -5559,10 +5570,10 @@ See https://github.com/odoo/owl/blob/${hash}/doc/reference/app.md#configuration
|
|
|
5559
5570
|
if (isStatic) {
|
|
5560
5571
|
C = parent.constructor.components[name];
|
|
5561
5572
|
if (!C) {
|
|
5562
|
-
throw new
|
|
5573
|
+
throw new OwlError(`Cannot find the definition of component "${name}"`);
|
|
5563
5574
|
}
|
|
5564
5575
|
else if (!(C.prototype instanceof Component)) {
|
|
5565
|
-
throw new
|
|
5576
|
+
throw new OwlError(`"${name}" is not a Component. It must inherit from the Component class`);
|
|
5566
5577
|
}
|
|
5567
5578
|
}
|
|
5568
5579
|
node = new ComponentNode(C, props, this, ctx, key);
|
|
@@ -5721,6 +5732,7 @@ See https://github.com/odoo/owl/blob/${hash}/doc/reference/app.md#configuration
|
|
|
5721
5732
|
exports.App = App;
|
|
5722
5733
|
exports.Component = Component;
|
|
5723
5734
|
exports.EventBus = EventBus;
|
|
5735
|
+
exports.OwlError = OwlError;
|
|
5724
5736
|
exports.__info__ = __info__;
|
|
5725
5737
|
exports.blockDom = blockDom;
|
|
5726
5738
|
exports.loadFile = loadFile;
|
|
@@ -5755,9 +5767,9 @@ See https://github.com/odoo/owl/blob/${hash}/doc/reference/app.md#configuration
|
|
|
5755
5767
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5756
5768
|
|
|
5757
5769
|
|
|
5758
|
-
__info__.version = '2.0.0-beta-
|
|
5759
|
-
__info__.date = '2022-
|
|
5760
|
-
__info__.hash = '
|
|
5770
|
+
__info__.version = '2.0.0-beta-16';
|
|
5771
|
+
__info__.date = '2022-07-22T07:43:54.584Z';
|
|
5772
|
+
__info__.hash = 'b90aa0e';
|
|
5761
5773
|
__info__.url = 'https://github.com/odoo/owl';
|
|
5762
5774
|
|
|
5763
5775
|
|