@odoo/owl 2.0.0-beta-14 → 2.0.0-beta-17
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 +142 -124
- package/dist/owl.es.js +142 -125
- package/dist/owl.iife.js +142 -124
- package/dist/owl.iife.min.js +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 +2 -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;
|
|
@@ -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;
|
|
@@ -2123,12 +2130,18 @@
|
|
|
2123
2130
|
};
|
|
2124
2131
|
}
|
|
2125
2132
|
function validateTarget(target) {
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2133
|
+
// Get the document and HTMLElement corresponding to the target to allow mounting in iframes
|
|
2134
|
+
const document = target && target.ownerDocument;
|
|
2135
|
+
if (document) {
|
|
2136
|
+
const HTMLElement = document.defaultView.HTMLElement;
|
|
2137
|
+
if (target instanceof HTMLElement) {
|
|
2138
|
+
if (!document.body.contains(target)) {
|
|
2139
|
+
throw new OwlError("Cannot mount a component on a detached dom node");
|
|
2140
|
+
}
|
|
2141
|
+
return;
|
|
2142
|
+
}
|
|
2131
2143
|
}
|
|
2144
|
+
throw new OwlError("Cannot mount component: the target is not a valid DOM element");
|
|
2132
2145
|
}
|
|
2133
2146
|
class EventBus extends EventTarget {
|
|
2134
2147
|
trigger(name, payload) {
|
|
@@ -2148,7 +2161,7 @@
|
|
|
2148
2161
|
async function loadFile(url) {
|
|
2149
2162
|
const result = await fetch(url);
|
|
2150
2163
|
if (!result.ok) {
|
|
2151
|
-
throw new
|
|
2164
|
+
throw new OwlError("Error while fetching xml templates");
|
|
2152
2165
|
}
|
|
2153
2166
|
return await result.text();
|
|
2154
2167
|
}
|
|
@@ -2170,7 +2183,7 @@
|
|
|
2170
2183
|
let currentNode = null;
|
|
2171
2184
|
function getCurrent() {
|
|
2172
2185
|
if (!currentNode) {
|
|
2173
|
-
throw new
|
|
2186
|
+
throw new OwlError("No active component (a hook function should only be called in 'setup')");
|
|
2174
2187
|
}
|
|
2175
2188
|
return currentNode;
|
|
2176
2189
|
}
|
|
@@ -2232,7 +2245,6 @@
|
|
|
2232
2245
|
this.parent = parent;
|
|
2233
2246
|
this.props = props;
|
|
2234
2247
|
this.parentKey = parentKey;
|
|
2235
|
-
this.level = parent ? parent.level + 1 : 0;
|
|
2236
2248
|
const defaultProps = C.defaultProps;
|
|
2237
2249
|
props = Object.assign({}, props);
|
|
2238
2250
|
if (defaultProps) {
|
|
@@ -2465,17 +2477,27 @@
|
|
|
2465
2477
|
|
|
2466
2478
|
const TIMEOUT = Symbol("timeout");
|
|
2467
2479
|
function wrapError(fn, hookName) {
|
|
2468
|
-
const error = new
|
|
2469
|
-
const timeoutError = new
|
|
2480
|
+
const error = new OwlError(`The following error occurred in ${hookName}: `);
|
|
2481
|
+
const timeoutError = new OwlError(`${hookName}'s promise hasn't resolved after 3 seconds`);
|
|
2470
2482
|
const node = getCurrent();
|
|
2471
2483
|
return (...args) => {
|
|
2484
|
+
const onError = (cause) => {
|
|
2485
|
+
error.cause = cause;
|
|
2486
|
+
if (cause instanceof Error) {
|
|
2487
|
+
error.message += `"${cause.message}"`;
|
|
2488
|
+
}
|
|
2489
|
+
else {
|
|
2490
|
+
error.message = `Something that is not an Error was thrown in ${hookName} (see this Error's "cause" property)`;
|
|
2491
|
+
}
|
|
2492
|
+
throw error;
|
|
2493
|
+
};
|
|
2472
2494
|
try {
|
|
2473
2495
|
const result = fn(...args);
|
|
2474
2496
|
if (result instanceof Promise) {
|
|
2475
2497
|
if (hookName === "onWillStart" || hookName === "onWillUpdateProps") {
|
|
2476
2498
|
const fiber = node.fiber;
|
|
2477
2499
|
Promise.race([
|
|
2478
|
-
result,
|
|
2500
|
+
result.catch(() => { }),
|
|
2479
2501
|
new Promise((resolve) => setTimeout(() => resolve(TIMEOUT), 3000)),
|
|
2480
2502
|
]).then((res) => {
|
|
2481
2503
|
if (res === TIMEOUT && node.fiber === fiber) {
|
|
@@ -2483,21 +2505,12 @@
|
|
|
2483
2505
|
}
|
|
2484
2506
|
});
|
|
2485
2507
|
}
|
|
2486
|
-
return result.catch(
|
|
2487
|
-
error.cause = cause;
|
|
2488
|
-
if (cause instanceof Error) {
|
|
2489
|
-
error.message += `"${cause.message}"`;
|
|
2490
|
-
}
|
|
2491
|
-
throw error;
|
|
2492
|
-
});
|
|
2508
|
+
return result.catch(onError);
|
|
2493
2509
|
}
|
|
2494
2510
|
return result;
|
|
2495
2511
|
}
|
|
2496
2512
|
catch (cause) {
|
|
2497
|
-
|
|
2498
|
-
error.message += `"${cause.message}"`;
|
|
2499
|
-
}
|
|
2500
|
-
throw error;
|
|
2513
|
+
onError(cause);
|
|
2501
2514
|
}
|
|
2502
2515
|
};
|
|
2503
2516
|
}
|
|
@@ -2601,7 +2614,7 @@
|
|
|
2601
2614
|
}
|
|
2602
2615
|
this.target = el && el.querySelector(this.selector);
|
|
2603
2616
|
if (!this.target) {
|
|
2604
|
-
throw new
|
|
2617
|
+
throw new OwlError("invalid portal target");
|
|
2605
2618
|
}
|
|
2606
2619
|
}
|
|
2607
2620
|
this.realBDom.mount(this.target, null);
|
|
@@ -2695,7 +2708,7 @@
|
|
|
2695
2708
|
function validate(obj, spec) {
|
|
2696
2709
|
let errors = validateSchema(obj, spec);
|
|
2697
2710
|
if (errors.length) {
|
|
2698
|
-
throw new
|
|
2711
|
+
throw new OwlError("Invalid object: " + errors.join(", "));
|
|
2699
2712
|
}
|
|
2700
2713
|
}
|
|
2701
2714
|
/**
|
|
@@ -2848,7 +2861,7 @@
|
|
|
2848
2861
|
keys = Object.values(collection);
|
|
2849
2862
|
}
|
|
2850
2863
|
else {
|
|
2851
|
-
throw new
|
|
2864
|
+
throw new OwlError("Invalid loop expression");
|
|
2852
2865
|
}
|
|
2853
2866
|
const n = values.length;
|
|
2854
2867
|
return [keys, values, n, new Array(n)];
|
|
@@ -2954,7 +2967,7 @@
|
|
|
2954
2967
|
if (el) {
|
|
2955
2968
|
count++;
|
|
2956
2969
|
if (count > 1) {
|
|
2957
|
-
throw new
|
|
2970
|
+
throw new OwlError("Cannot have 2 elements with same ref name at the same time");
|
|
2958
2971
|
}
|
|
2959
2972
|
}
|
|
2960
2973
|
if (count === 0 || el) {
|
|
@@ -2991,13 +3004,13 @@
|
|
|
2991
3004
|
: name in schema && !("*" in schema) && !isOptional(schema[name]);
|
|
2992
3005
|
for (let p in defaultProps) {
|
|
2993
3006
|
if (isMandatory(p)) {
|
|
2994
|
-
throw new
|
|
3007
|
+
throw new OwlError(`A default value cannot be defined for a mandatory prop (name: '${p}', component: ${ComponentClass.name})`);
|
|
2995
3008
|
}
|
|
2996
3009
|
}
|
|
2997
3010
|
}
|
|
2998
3011
|
const errors = validateSchema(props, schema);
|
|
2999
3012
|
if (errors.length) {
|
|
3000
|
-
throw new
|
|
3013
|
+
throw new OwlError(`Invalid props for component '${ComponentClass.name}': ` + errors.join(", "));
|
|
3001
3014
|
}
|
|
3002
3015
|
}
|
|
3003
3016
|
const helpers = {
|
|
@@ -3018,6 +3031,7 @@
|
|
|
3018
3031
|
bind,
|
|
3019
3032
|
createCatcher,
|
|
3020
3033
|
markRaw,
|
|
3034
|
+
OwlError,
|
|
3021
3035
|
};
|
|
3022
3036
|
|
|
3023
3037
|
const bdom = { text, createBlock, list, multi, html, toggler, comment };
|
|
@@ -3045,7 +3059,7 @@
|
|
|
3045
3059
|
}
|
|
3046
3060
|
}
|
|
3047
3061
|
}
|
|
3048
|
-
throw new
|
|
3062
|
+
throw new OwlError(msg);
|
|
3049
3063
|
}
|
|
3050
3064
|
return doc;
|
|
3051
3065
|
}
|
|
@@ -3076,7 +3090,7 @@
|
|
|
3076
3090
|
if (currentAsString === newAsString) {
|
|
3077
3091
|
return;
|
|
3078
3092
|
}
|
|
3079
|
-
throw new
|
|
3093
|
+
throw new OwlError(`Template ${name} already defined with different content`);
|
|
3080
3094
|
}
|
|
3081
3095
|
this.rawTemplates[name] = template;
|
|
3082
3096
|
}
|
|
@@ -3101,7 +3115,7 @@
|
|
|
3101
3115
|
extraInfo = ` (for component "${componentName}")`;
|
|
3102
3116
|
}
|
|
3103
3117
|
catch { }
|
|
3104
|
-
throw new
|
|
3118
|
+
throw new OwlError(`Missing template: "${name}"${extraInfo}`);
|
|
3105
3119
|
}
|
|
3106
3120
|
const isFn = typeof rawTemplate === "function" && !(rawTemplate instanceof Element);
|
|
3107
3121
|
const templateFn = isFn ? rawTemplate : this._compileTemplate(name, rawTemplate);
|
|
@@ -3117,7 +3131,7 @@
|
|
|
3117
3131
|
return this.templates[name];
|
|
3118
3132
|
}
|
|
3119
3133
|
_compileTemplate(name, template) {
|
|
3120
|
-
throw new
|
|
3134
|
+
throw new OwlError(`Unable to compile a template. Please use owl full build instead`);
|
|
3121
3135
|
}
|
|
3122
3136
|
callTemplate(owner, subTemplate, ctx, parent, key) {
|
|
3123
3137
|
const template = this.getTemplate(subTemplate);
|
|
@@ -3199,14 +3213,14 @@
|
|
|
3199
3213
|
i++;
|
|
3200
3214
|
cur = expr[i];
|
|
3201
3215
|
if (!cur) {
|
|
3202
|
-
throw new
|
|
3216
|
+
throw new OwlError("Invalid expression");
|
|
3203
3217
|
}
|
|
3204
3218
|
s += cur;
|
|
3205
3219
|
}
|
|
3206
3220
|
i++;
|
|
3207
3221
|
}
|
|
3208
3222
|
if (expr[i] !== start) {
|
|
3209
|
-
throw new
|
|
3223
|
+
throw new OwlError("Invalid expression");
|
|
3210
3224
|
}
|
|
3211
3225
|
s += start;
|
|
3212
3226
|
if (start === "`") {
|
|
@@ -3313,7 +3327,7 @@
|
|
|
3313
3327
|
error = e; // Silence all errors and throw a generic error below
|
|
3314
3328
|
}
|
|
3315
3329
|
if (current.length || error) {
|
|
3316
|
-
throw new
|
|
3330
|
+
throw new OwlError(`Tokenizer error: could not tokenize \`${expr}\``);
|
|
3317
3331
|
}
|
|
3318
3332
|
return result;
|
|
3319
3333
|
}
|
|
@@ -3864,7 +3878,7 @@
|
|
|
3864
3878
|
.slice(1)
|
|
3865
3879
|
.map((m) => {
|
|
3866
3880
|
if (!MODS.has(m)) {
|
|
3867
|
-
throw new
|
|
3881
|
+
throw new OwlError(`Unknown event modifier: '${m}'`);
|
|
3868
3882
|
}
|
|
3869
3883
|
return `"${m}"`;
|
|
3870
3884
|
});
|
|
@@ -3910,8 +3924,13 @@
|
|
|
3910
3924
|
expr = compileExpr(ast.attrs[key]);
|
|
3911
3925
|
if (attrName && isProp(ast.tag, attrName)) {
|
|
3912
3926
|
// we force a new string or new boolean to bypass the equality check in blockdom when patching same value
|
|
3913
|
-
|
|
3914
|
-
|
|
3927
|
+
if (attrName === "value") {
|
|
3928
|
+
// When the expression is falsy, fall back to an empty string
|
|
3929
|
+
expr = `new String((${expr}) || "")`;
|
|
3930
|
+
}
|
|
3931
|
+
else {
|
|
3932
|
+
expr = `new Boolean(${expr})`;
|
|
3933
|
+
}
|
|
3915
3934
|
}
|
|
3916
3935
|
const idx = block.insertData(expr, "attr");
|
|
3917
3936
|
if (key === "t-att") {
|
|
@@ -4185,7 +4204,8 @@
|
|
|
4185
4204
|
this.define(`key${this.target.loopLevel}`, ast.key ? compileExpr(ast.key) : loopVar);
|
|
4186
4205
|
if (this.dev) {
|
|
4187
4206
|
// Throw error on duplicate keys in dev mode
|
|
4188
|
-
this.
|
|
4207
|
+
this.helpers.add("OwlError");
|
|
4208
|
+
this.addLine(`if (keys${block.id}.has(key${this.target.loopLevel})) { throw new OwlError(\`Got duplicate key in t-foreach: \${key${this.target.loopLevel}}\`)}`);
|
|
4189
4209
|
this.addLine(`keys${block.id}.add(key${this.target.loopLevel});`);
|
|
4190
4210
|
}
|
|
4191
4211
|
let id;
|
|
@@ -4399,7 +4419,7 @@
|
|
|
4399
4419
|
value = `bind(ctx, ${value || undefined})`;
|
|
4400
4420
|
}
|
|
4401
4421
|
else {
|
|
4402
|
-
throw new
|
|
4422
|
+
throw new OwlError("Invalid prop suffix");
|
|
4403
4423
|
}
|
|
4404
4424
|
}
|
|
4405
4425
|
name = /^[a-z_]+$/i.test(name) ? name : `'${name}'`;
|
|
@@ -4592,9 +4612,6 @@
|
|
|
4592
4612
|
}
|
|
4593
4613
|
}
|
|
4594
4614
|
|
|
4595
|
-
// -----------------------------------------------------------------------------
|
|
4596
|
-
// AST Type definition
|
|
4597
|
-
// -----------------------------------------------------------------------------
|
|
4598
4615
|
// -----------------------------------------------------------------------------
|
|
4599
4616
|
// Parser
|
|
4600
4617
|
// -----------------------------------------------------------------------------
|
|
@@ -4703,7 +4720,7 @@
|
|
|
4703
4720
|
return null;
|
|
4704
4721
|
}
|
|
4705
4722
|
if (tagName.startsWith("block-")) {
|
|
4706
|
-
throw new
|
|
4723
|
+
throw new OwlError(`Invalid tag name: '${tagName}'`);
|
|
4707
4724
|
}
|
|
4708
4725
|
ctx = Object.assign({}, ctx);
|
|
4709
4726
|
if (tagName === "pre") {
|
|
@@ -4722,14 +4739,14 @@
|
|
|
4722
4739
|
const value = node.getAttribute(attr);
|
|
4723
4740
|
if (attr.startsWith("t-on")) {
|
|
4724
4741
|
if (attr === "t-on") {
|
|
4725
|
-
throw new
|
|
4742
|
+
throw new OwlError("Missing event name with t-on directive");
|
|
4726
4743
|
}
|
|
4727
4744
|
on = on || {};
|
|
4728
4745
|
on[attr.slice(5)] = value;
|
|
4729
4746
|
}
|
|
4730
4747
|
else if (attr.startsWith("t-model")) {
|
|
4731
4748
|
if (!["input", "select", "textarea"].includes(tagName)) {
|
|
4732
|
-
throw new
|
|
4749
|
+
throw new OwlError("The t-model directive only works with <input>, <textarea> and <select>");
|
|
4733
4750
|
}
|
|
4734
4751
|
let baseExpr, expr;
|
|
4735
4752
|
if (hasDotAtTheEnd.test(value)) {
|
|
@@ -4743,7 +4760,7 @@
|
|
|
4743
4760
|
expr = value.slice(index + 1, -1);
|
|
4744
4761
|
}
|
|
4745
4762
|
else {
|
|
4746
|
-
throw new
|
|
4763
|
+
throw new OwlError(`Invalid t-model expression: "${value}" (it should be assignable)`);
|
|
4747
4764
|
}
|
|
4748
4765
|
const typeAttr = node.getAttribute("type");
|
|
4749
4766
|
const isInput = tagName === "input";
|
|
@@ -4773,11 +4790,11 @@
|
|
|
4773
4790
|
}
|
|
4774
4791
|
}
|
|
4775
4792
|
else if (attr.startsWith("block-")) {
|
|
4776
|
-
throw new
|
|
4793
|
+
throw new OwlError(`Invalid attribute: '${attr}'`);
|
|
4777
4794
|
}
|
|
4778
4795
|
else if (attr !== "t-name") {
|
|
4779
4796
|
if (attr.startsWith("t-") && !attr.startsWith("t-att")) {
|
|
4780
|
-
throw new
|
|
4797
|
+
throw new OwlError(`Unknown QWeb directive: '${attr}'`);
|
|
4781
4798
|
}
|
|
4782
4799
|
const tModel = ctx.tModelInfo;
|
|
4783
4800
|
if (tModel && ["t-att-value", "t-attf-value"].includes(attr)) {
|
|
@@ -4828,7 +4845,7 @@
|
|
|
4828
4845
|
};
|
|
4829
4846
|
}
|
|
4830
4847
|
if (ast.type === 11 /* TComponent */) {
|
|
4831
|
-
throw new
|
|
4848
|
+
throw new OwlError("t-esc is not supported on Component nodes");
|
|
4832
4849
|
}
|
|
4833
4850
|
return tesc;
|
|
4834
4851
|
}
|
|
@@ -4876,7 +4893,7 @@
|
|
|
4876
4893
|
node.removeAttribute("t-as");
|
|
4877
4894
|
const key = node.getAttribute("t-key");
|
|
4878
4895
|
if (!key) {
|
|
4879
|
-
throw new
|
|
4896
|
+
throw new OwlError(`"Directive t-foreach should always be used with a t-key!" (expression: t-foreach="${collection}" t-as="${elem}")`);
|
|
4880
4897
|
}
|
|
4881
4898
|
node.removeAttribute("t-key");
|
|
4882
4899
|
const memo = node.getAttribute("t-memo") || "";
|
|
@@ -5036,7 +5053,7 @@
|
|
|
5036
5053
|
const firstLetter = name[0];
|
|
5037
5054
|
let isDynamic = node.hasAttribute("t-component");
|
|
5038
5055
|
if (isDynamic && name !== "t") {
|
|
5039
|
-
throw new
|
|
5056
|
+
throw new OwlError(`Directive 't-component' can only be used on <t> nodes (used on a <${name}>)`);
|
|
5040
5057
|
}
|
|
5041
5058
|
if (!(firstLetter === firstLetter.toUpperCase() || isDynamic)) {
|
|
5042
5059
|
return null;
|
|
@@ -5060,7 +5077,7 @@
|
|
|
5060
5077
|
}
|
|
5061
5078
|
else {
|
|
5062
5079
|
const message = directiveErrorMap.get(name.split("-").slice(0, 2).join("-"));
|
|
5063
|
-
throw new
|
|
5080
|
+
throw new OwlError(message || `unsupported directive on Component: ${name}`);
|
|
5064
5081
|
}
|
|
5065
5082
|
}
|
|
5066
5083
|
else {
|
|
@@ -5075,7 +5092,7 @@
|
|
|
5075
5092
|
const slotNodes = Array.from(clone.querySelectorAll("[t-set-slot]"));
|
|
5076
5093
|
for (let slotNode of slotNodes) {
|
|
5077
5094
|
if (slotNode.tagName !== "t") {
|
|
5078
|
-
throw new
|
|
5095
|
+
throw new OwlError(`Directive 't-set-slot' can only be used on <t> nodes (used on a <${slotNode.tagName}>)`);
|
|
5079
5096
|
}
|
|
5080
5097
|
const name = slotNode.getAttribute("t-set-slot");
|
|
5081
5098
|
// check if this is defined in a sub component (in which case it should
|
|
@@ -5240,25 +5257,25 @@
|
|
|
5240
5257
|
let nattr = (name) => +!!node.getAttribute(name);
|
|
5241
5258
|
if (prevElem && (pattr("t-if") || pattr("t-elif"))) {
|
|
5242
5259
|
if (pattr("t-foreach")) {
|
|
5243
|
-
throw new
|
|
5260
|
+
throw new OwlError("t-if cannot stay at the same level as t-foreach when using t-elif or t-else");
|
|
5244
5261
|
}
|
|
5245
5262
|
if (["t-if", "t-elif", "t-else"].map(nattr).reduce(function (a, b) {
|
|
5246
5263
|
return a + b;
|
|
5247
5264
|
}) > 1) {
|
|
5248
|
-
throw new
|
|
5265
|
+
throw new OwlError("Only one conditional branching directive is allowed per node");
|
|
5249
5266
|
}
|
|
5250
5267
|
// All text (with only spaces) and comment nodes (nodeType 8) between
|
|
5251
5268
|
// branch nodes are removed
|
|
5252
5269
|
let textNode;
|
|
5253
5270
|
while ((textNode = node.previousSibling) !== prevElem) {
|
|
5254
5271
|
if (textNode.nodeValue.trim().length && textNode.nodeType !== 8) {
|
|
5255
|
-
throw new
|
|
5272
|
+
throw new OwlError("text is not allowed between branching directives");
|
|
5256
5273
|
}
|
|
5257
5274
|
textNode.remove();
|
|
5258
5275
|
}
|
|
5259
5276
|
}
|
|
5260
5277
|
else {
|
|
5261
|
-
throw new
|
|
5278
|
+
throw new OwlError("t-elif and t-else directives must be preceded by a t-if or t-elif directive");
|
|
5262
5279
|
}
|
|
5263
5280
|
}
|
|
5264
5281
|
}
|
|
@@ -5274,7 +5291,7 @@
|
|
|
5274
5291
|
const elements = [...el.querySelectorAll("[t-esc]")].filter((el) => el.tagName[0] === el.tagName[0].toUpperCase() || el.hasAttribute("t-component"));
|
|
5275
5292
|
for (const el of elements) {
|
|
5276
5293
|
if (el.childNodes.length) {
|
|
5277
|
-
throw new
|
|
5294
|
+
throw new OwlError("Cannot have t-esc on a component that already has content");
|
|
5278
5295
|
}
|
|
5279
5296
|
const value = el.getAttribute("t-esc");
|
|
5280
5297
|
el.removeAttribute("t-esc");
|
|
@@ -5326,7 +5343,7 @@
|
|
|
5326
5343
|
}
|
|
5327
5344
|
}
|
|
5328
5345
|
}
|
|
5329
|
-
throw new
|
|
5346
|
+
throw new OwlError(msg);
|
|
5330
5347
|
}
|
|
5331
5348
|
return doc;
|
|
5332
5349
|
}
|
|
@@ -5380,7 +5397,7 @@
|
|
|
5380
5397
|
if (Object.hasOwnProperty.call(data, 0)) {
|
|
5381
5398
|
const handler = data[0];
|
|
5382
5399
|
if (typeof handler !== "function") {
|
|
5383
|
-
throw new
|
|
5400
|
+
throw new OwlError(`Invalid handler (expected a function, received: '${handler}')`);
|
|
5384
5401
|
}
|
|
5385
5402
|
let node = data[1] ? data[1].__owl__ : null;
|
|
5386
5403
|
if (node ? node.status === 1 /* MOUNTED */ : true) {
|
|
@@ -5564,10 +5581,10 @@ See https://github.com/odoo/owl/blob/${hash}/doc/reference/app.md#configuration
|
|
|
5564
5581
|
if (isStatic) {
|
|
5565
5582
|
C = parent.constructor.components[name];
|
|
5566
5583
|
if (!C) {
|
|
5567
|
-
throw new
|
|
5584
|
+
throw new OwlError(`Cannot find the definition of component "${name}"`);
|
|
5568
5585
|
}
|
|
5569
5586
|
else if (!(C.prototype instanceof Component)) {
|
|
5570
|
-
throw new
|
|
5587
|
+
throw new OwlError(`"${name}" is not a Component. It must inherit from the Component class`);
|
|
5571
5588
|
}
|
|
5572
5589
|
}
|
|
5573
5590
|
node = new ComponentNode(C, props, this, ctx, key);
|
|
@@ -5726,6 +5743,7 @@ See https://github.com/odoo/owl/blob/${hash}/doc/reference/app.md#configuration
|
|
|
5726
5743
|
exports.App = App;
|
|
5727
5744
|
exports.Component = Component;
|
|
5728
5745
|
exports.EventBus = EventBus;
|
|
5746
|
+
exports.OwlError = OwlError;
|
|
5729
5747
|
exports.__info__ = __info__;
|
|
5730
5748
|
exports.blockDom = blockDom;
|
|
5731
5749
|
exports.loadFile = loadFile;
|
|
@@ -5760,9 +5778,9 @@ See https://github.com/odoo/owl/blob/${hash}/doc/reference/app.md#configuration
|
|
|
5760
5778
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5761
5779
|
|
|
5762
5780
|
|
|
5763
|
-
__info__.version = '2.0.0-beta-
|
|
5764
|
-
__info__.date = '2022-
|
|
5765
|
-
__info__.hash = '
|
|
5781
|
+
__info__.version = '2.0.0-beta-17';
|
|
5782
|
+
__info__.date = '2022-09-01T13:41:44.572Z';
|
|
5783
|
+
__info__.hash = '9cb74d6';
|
|
5766
5784
|
__info__.url = 'https://github.com/odoo/owl';
|
|
5767
5785
|
|
|
5768
5786
|
|