@odoo/owl 2.0.7 → 2.0.8
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 +212 -192
- package/dist/owl.es.js +212 -192
- package/dist/owl.iife.js +212 -192
- package/dist/owl.iife.min.js +1 -1
- package/dist/types/compiler/code_generator.d.ts +2 -4
- package/dist/types/owl.d.ts +15 -2
- package/dist/types/runtime/app.d.ts +4 -1
- package/dist/types/runtime/blockdom/attributes.d.ts +0 -2
- package/dist/types/runtime/component_node.d.ts +8 -0
- package/dist/types/runtime/index.d.ts +3 -1
- package/dist/types/runtime/template_helpers.d.ts +3 -10
- package/dist/types/version.d.ts +1 -0
- package/package.json +1 -1
package/dist/owl.cjs.js
CHANGED
|
@@ -280,32 +280,6 @@ function updateClass(val, oldVal) {
|
|
|
280
280
|
tokenListAdd.call(cl, c);
|
|
281
281
|
}
|
|
282
282
|
}
|
|
283
|
-
}
|
|
284
|
-
function makePropSetter(name) {
|
|
285
|
-
return function setProp(value) {
|
|
286
|
-
// support 0, fallback to empty string for other falsy values
|
|
287
|
-
this[name] = value === 0 ? 0 : value ? value.valueOf() : "";
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
function isProp(tag, key) {
|
|
291
|
-
switch (tag) {
|
|
292
|
-
case "input":
|
|
293
|
-
return (key === "checked" ||
|
|
294
|
-
key === "indeterminate" ||
|
|
295
|
-
key === "value" ||
|
|
296
|
-
key === "readonly" ||
|
|
297
|
-
key === "disabled");
|
|
298
|
-
case "option":
|
|
299
|
-
return key === "selected" || key === "disabled";
|
|
300
|
-
case "textarea":
|
|
301
|
-
return key === "value" || key === "readonly" || key === "disabled";
|
|
302
|
-
case "select":
|
|
303
|
-
return key === "value" || key === "disabled";
|
|
304
|
-
case "button":
|
|
305
|
-
case "optgroup":
|
|
306
|
-
return key === "disabled";
|
|
307
|
-
}
|
|
308
|
-
return false;
|
|
309
283
|
}
|
|
310
284
|
|
|
311
285
|
function createEventHandler(rawEvent) {
|
|
@@ -609,6 +583,12 @@ const characterDataSetData = getDescriptor$1(characterDataProto, "data").set;
|
|
|
609
583
|
const nodeGetFirstChild = getDescriptor$1(nodeProto$2, "firstChild").get;
|
|
610
584
|
const nodeGetNextSibling = getDescriptor$1(nodeProto$2, "nextSibling").get;
|
|
611
585
|
const NO_OP = () => { };
|
|
586
|
+
function makePropSetter(name) {
|
|
587
|
+
return function setProp(value) {
|
|
588
|
+
// support 0, fallback to empty string for other falsy values
|
|
589
|
+
this[name] = value === 0 ? 0 : value ? value.valueOf() : "";
|
|
590
|
+
};
|
|
591
|
+
}
|
|
612
592
|
const cache$1 = {};
|
|
613
593
|
/**
|
|
614
594
|
* Compiling blocks is a multi-step process:
|
|
@@ -726,6 +706,15 @@ function buildTree(node, parent = null, domParentTree = null) {
|
|
|
726
706
|
tag: tagName,
|
|
727
707
|
});
|
|
728
708
|
}
|
|
709
|
+
else if (attrName.startsWith("block-property-")) {
|
|
710
|
+
const idx = parseInt(attrName.slice(15), 10);
|
|
711
|
+
info.push({
|
|
712
|
+
type: "property",
|
|
713
|
+
idx,
|
|
714
|
+
name: attrValue,
|
|
715
|
+
tag: tagName,
|
|
716
|
+
});
|
|
717
|
+
}
|
|
729
718
|
else if (attrName === "block-attributes") {
|
|
730
719
|
info.push({
|
|
731
720
|
type: "attributes",
|
|
@@ -872,16 +861,22 @@ function updateCtx(ctx, tree) {
|
|
|
872
861
|
};
|
|
873
862
|
}
|
|
874
863
|
break;
|
|
864
|
+
case "property": {
|
|
865
|
+
const refIdx = info.refIdx;
|
|
866
|
+
const setProp = makePropSetter(info.name);
|
|
867
|
+
ctx.locations.push({
|
|
868
|
+
idx: info.idx,
|
|
869
|
+
refIdx,
|
|
870
|
+
setData: setProp,
|
|
871
|
+
updateData: setProp,
|
|
872
|
+
});
|
|
873
|
+
break;
|
|
874
|
+
}
|
|
875
875
|
case "attribute": {
|
|
876
876
|
const refIdx = info.refIdx;
|
|
877
877
|
let updater;
|
|
878
878
|
let setter;
|
|
879
|
-
if (
|
|
880
|
-
const setProp = makePropSetter(info.name);
|
|
881
|
-
setter = setProp;
|
|
882
|
-
updater = setProp;
|
|
883
|
-
}
|
|
884
|
-
else if (info.name === "class") {
|
|
879
|
+
if (info.name === "class") {
|
|
885
880
|
setter = setClass;
|
|
886
881
|
updater = updateClass;
|
|
887
882
|
}
|
|
@@ -2486,6 +2481,18 @@ class ComponentNode {
|
|
|
2486
2481
|
this.fiber = null;
|
|
2487
2482
|
}
|
|
2488
2483
|
}
|
|
2484
|
+
/**
|
|
2485
|
+
* Sets a ref to a given HTMLElement.
|
|
2486
|
+
*
|
|
2487
|
+
* @param name the name of the ref to set
|
|
2488
|
+
* @param el the HTMLElement to set the ref to. The ref is not set if the el
|
|
2489
|
+
* is null, but useRef will not return elements that are not in the DOM
|
|
2490
|
+
*/
|
|
2491
|
+
setRef(name, el) {
|
|
2492
|
+
if (el) {
|
|
2493
|
+
this.refs[name] = el;
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2489
2496
|
// ---------------------------------------------------------------------------
|
|
2490
2497
|
// Block DOM methods
|
|
2491
2498
|
// ---------------------------------------------------------------------------
|
|
@@ -3021,45 +3028,6 @@ function safeOutput(value, defaultValue) {
|
|
|
3021
3028
|
}
|
|
3022
3029
|
return toggler(safeKey, block);
|
|
3023
3030
|
}
|
|
3024
|
-
let boundFunctions = new WeakMap();
|
|
3025
|
-
const WeakMapGet = WeakMap.prototype.get;
|
|
3026
|
-
const WeakMapSet = WeakMap.prototype.set;
|
|
3027
|
-
function bind(component, fn) {
|
|
3028
|
-
let boundFnMap = WeakMapGet.call(boundFunctions, component);
|
|
3029
|
-
if (!boundFnMap) {
|
|
3030
|
-
boundFnMap = new WeakMap();
|
|
3031
|
-
WeakMapSet.call(boundFunctions, component, boundFnMap);
|
|
3032
|
-
}
|
|
3033
|
-
let boundFn = WeakMapGet.call(boundFnMap, fn);
|
|
3034
|
-
if (!boundFn) {
|
|
3035
|
-
boundFn = fn.bind(component);
|
|
3036
|
-
WeakMapSet.call(boundFnMap, fn, boundFn);
|
|
3037
|
-
}
|
|
3038
|
-
return boundFn;
|
|
3039
|
-
}
|
|
3040
|
-
function multiRefSetter(refs, name) {
|
|
3041
|
-
let count = 0;
|
|
3042
|
-
return (el) => {
|
|
3043
|
-
if (el) {
|
|
3044
|
-
count++;
|
|
3045
|
-
if (count > 1) {
|
|
3046
|
-
throw new OwlError("Cannot have 2 elements with same ref name at the same time");
|
|
3047
|
-
}
|
|
3048
|
-
}
|
|
3049
|
-
if (count === 0 || el) {
|
|
3050
|
-
refs[name] = el;
|
|
3051
|
-
}
|
|
3052
|
-
};
|
|
3053
|
-
}
|
|
3054
|
-
function singleRefSetter(refs, name) {
|
|
3055
|
-
let _el = null;
|
|
3056
|
-
return (el) => {
|
|
3057
|
-
if (el || refs[name] === _el) {
|
|
3058
|
-
refs[name] = el;
|
|
3059
|
-
_el = el;
|
|
3060
|
-
}
|
|
3061
|
-
};
|
|
3062
|
-
}
|
|
3063
3031
|
/**
|
|
3064
3032
|
* Validate the component props (or next props) against the (static) props
|
|
3065
3033
|
* description. This is potentially an expensive operation: it may needs to
|
|
@@ -3098,6 +3066,16 @@ function validateProps(name, props, comp) {
|
|
|
3098
3066
|
throw new OwlError(`Invalid props for component '${ComponentClass.name}': ` + errors.join(", "));
|
|
3099
3067
|
}
|
|
3100
3068
|
}
|
|
3069
|
+
function makeRefWrapper(node) {
|
|
3070
|
+
let refNames = new Set();
|
|
3071
|
+
return (name, fn) => {
|
|
3072
|
+
if (refNames.has(name)) {
|
|
3073
|
+
throw new OwlError(`Cannot set the same ref more than once in the same component, ref "${name}" was set multiple times in ${node.name}`);
|
|
3074
|
+
}
|
|
3075
|
+
refNames.add(name);
|
|
3076
|
+
return fn;
|
|
3077
|
+
};
|
|
3078
|
+
}
|
|
3101
3079
|
const helpers = {
|
|
3102
3080
|
withDefault,
|
|
3103
3081
|
zero: Symbol("zero"),
|
|
@@ -3107,17 +3085,15 @@ const helpers = {
|
|
|
3107
3085
|
withKey,
|
|
3108
3086
|
prepareList,
|
|
3109
3087
|
setContextValue,
|
|
3110
|
-
multiRefSetter,
|
|
3111
|
-
singleRefSetter,
|
|
3112
3088
|
shallowEqual,
|
|
3113
3089
|
toNumber,
|
|
3114
3090
|
validateProps,
|
|
3115
3091
|
LazyValue,
|
|
3116
3092
|
safeOutput,
|
|
3117
|
-
bind,
|
|
3118
3093
|
createCatcher,
|
|
3119
3094
|
markRaw,
|
|
3120
3095
|
OwlError,
|
|
3096
|
+
makeRefWrapper,
|
|
3121
3097
|
};
|
|
3122
3098
|
|
|
3123
3099
|
const bdom = { text, createBlock, list, multi, html, toggler, comment };
|
|
@@ -3544,6 +3520,7 @@ function interpolate(s) {
|
|
|
3544
3520
|
return replaceDynamicParts(s, compileExpr);
|
|
3545
3521
|
}
|
|
3546
3522
|
|
|
3523
|
+
const whitespaceRE = /\s+/g;
|
|
3547
3524
|
// using a non-html document so that <inner/outer>HTML serializes as XML instead
|
|
3548
3525
|
// of HTML (as we will parse it as xml later)
|
|
3549
3526
|
const xmlDoc = document.implementation.createDocument(null, null, null);
|
|
@@ -3553,6 +3530,27 @@ function generateId(prefix = "") {
|
|
|
3553
3530
|
nextDataIds[prefix] = (nextDataIds[prefix] || 0) + 1;
|
|
3554
3531
|
return prefix + nextDataIds[prefix];
|
|
3555
3532
|
}
|
|
3533
|
+
function isProp(tag, key) {
|
|
3534
|
+
switch (tag) {
|
|
3535
|
+
case "input":
|
|
3536
|
+
return (key === "checked" ||
|
|
3537
|
+
key === "indeterminate" ||
|
|
3538
|
+
key === "value" ||
|
|
3539
|
+
key === "readonly" ||
|
|
3540
|
+
key === "readOnly" ||
|
|
3541
|
+
key === "disabled");
|
|
3542
|
+
case "option":
|
|
3543
|
+
return key === "selected" || key === "disabled";
|
|
3544
|
+
case "textarea":
|
|
3545
|
+
return key === "value" || key === "readonly" || key === "readOnly" || key === "disabled";
|
|
3546
|
+
case "select":
|
|
3547
|
+
return key === "value" || key === "disabled";
|
|
3548
|
+
case "button":
|
|
3549
|
+
case "optgroup":
|
|
3550
|
+
return key === "disabled";
|
|
3551
|
+
}
|
|
3552
|
+
return false;
|
|
3553
|
+
}
|
|
3556
3554
|
// -----------------------------------------------------------------------------
|
|
3557
3555
|
// BlockDescription
|
|
3558
3556
|
// -----------------------------------------------------------------------------
|
|
@@ -3628,10 +3626,8 @@ class CodeTarget {
|
|
|
3628
3626
|
this.code = [];
|
|
3629
3627
|
this.hasRoot = false;
|
|
3630
3628
|
this.hasCache = false;
|
|
3631
|
-
this.hasRef = false;
|
|
3632
|
-
// maps ref name to [id, expr]
|
|
3633
|
-
this.refInfo = {};
|
|
3634
3629
|
this.shouldProtectScope = false;
|
|
3630
|
+
this.hasRefWrapper = false;
|
|
3635
3631
|
this.name = name;
|
|
3636
3632
|
this.on = on || null;
|
|
3637
3633
|
}
|
|
@@ -3647,17 +3643,13 @@ class CodeTarget {
|
|
|
3647
3643
|
generateCode() {
|
|
3648
3644
|
let result = [];
|
|
3649
3645
|
result.push(`function ${this.name}(ctx, node, key = "") {`);
|
|
3650
|
-
if (this.hasRef) {
|
|
3651
|
-
result.push(` const refs = this.__owl__.refs;`);
|
|
3652
|
-
for (let name in this.refInfo) {
|
|
3653
|
-
const [id, expr] = this.refInfo[name];
|
|
3654
|
-
result.push(` const ${id} = ${expr};`);
|
|
3655
|
-
}
|
|
3656
|
-
}
|
|
3657
3646
|
if (this.shouldProtectScope) {
|
|
3658
3647
|
result.push(` ctx = Object.create(ctx);`);
|
|
3659
3648
|
result.push(` ctx[isBoundary] = 1`);
|
|
3660
3649
|
}
|
|
3650
|
+
if (this.hasRefWrapper) {
|
|
3651
|
+
result.push(` let refWrapper = makeRefWrapper(this.__owl__);`);
|
|
3652
|
+
}
|
|
3661
3653
|
if (this.hasCache) {
|
|
3662
3654
|
result.push(` let cache = ctx.cache || {};`);
|
|
3663
3655
|
result.push(` let nextCache = ctx.cache = {};`);
|
|
@@ -3939,6 +3931,9 @@ class CodeGenerator {
|
|
|
3939
3931
|
const match = translationRE.exec(value);
|
|
3940
3932
|
value = match[1] + this.translateFn(match[2]) + match[3];
|
|
3941
3933
|
}
|
|
3934
|
+
if (!ctx.inPreTag) {
|
|
3935
|
+
value = value.replace(whitespaceRE, " ");
|
|
3936
|
+
}
|
|
3942
3937
|
if (!block || forceNewBlock) {
|
|
3943
3938
|
block = this.createBlock(block, "text", ctx);
|
|
3944
3939
|
this.insertBlock(`text(\`${value}\`)`, block, {
|
|
@@ -4003,21 +3998,29 @@ class CodeGenerator {
|
|
|
4003
3998
|
attrName = key === "t-att" ? null : key.slice(6);
|
|
4004
3999
|
expr = compileExpr(ast.attrs[key]);
|
|
4005
4000
|
if (attrName && isProp(ast.tag, attrName)) {
|
|
4001
|
+
if (attrName === "readonly") {
|
|
4002
|
+
// the property has a different name than the attribute
|
|
4003
|
+
attrName = "readOnly";
|
|
4004
|
+
}
|
|
4006
4005
|
// we force a new string or new boolean to bypass the equality check in blockdom when patching same value
|
|
4007
4006
|
if (attrName === "value") {
|
|
4008
|
-
// When the expression is falsy, fall back to an empty string
|
|
4009
|
-
expr = `new String((${expr}) || "")`;
|
|
4007
|
+
// When the expression is falsy (except 0), fall back to an empty string
|
|
4008
|
+
expr = `new String((${expr}) === 0 ? 0 : ((${expr}) || ""))`;
|
|
4010
4009
|
}
|
|
4011
4010
|
else {
|
|
4012
4011
|
expr = `new Boolean(${expr})`;
|
|
4013
4012
|
}
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
if (key === "t-att") {
|
|
4017
|
-
attrs[`block-attributes`] = String(idx);
|
|
4013
|
+
const idx = block.insertData(expr, "prop");
|
|
4014
|
+
attrs[`block-property-${idx}`] = attrName;
|
|
4018
4015
|
}
|
|
4019
4016
|
else {
|
|
4020
|
-
|
|
4017
|
+
const idx = block.insertData(expr, "attr");
|
|
4018
|
+
if (key === "t-att") {
|
|
4019
|
+
attrs[`block-attributes`] = String(idx);
|
|
4020
|
+
}
|
|
4021
|
+
else {
|
|
4022
|
+
attrs[`block-attribute-${idx}`] = attrName;
|
|
4023
|
+
}
|
|
4021
4024
|
}
|
|
4022
4025
|
}
|
|
4023
4026
|
else if (this.translatableAttributes.includes(key)) {
|
|
@@ -4054,8 +4057,8 @@ class CodeGenerator {
|
|
|
4054
4057
|
targetExpr = compileExpr(dynamicTgExpr);
|
|
4055
4058
|
}
|
|
4056
4059
|
}
|
|
4057
|
-
idx = block.insertData(`${fullExpression} === ${targetExpr}`, "
|
|
4058
|
-
attrs[`block-
|
|
4060
|
+
idx = block.insertData(`${fullExpression} === ${targetExpr}`, "prop");
|
|
4061
|
+
attrs[`block-property-${idx}`] = specialInitTargetAttr;
|
|
4059
4062
|
}
|
|
4060
4063
|
else if (hasDynamicChildren) {
|
|
4061
4064
|
const bValueId = generateId("bValue");
|
|
@@ -4063,8 +4066,8 @@ class CodeGenerator {
|
|
|
4063
4066
|
this.define(tModelSelectedExpr, fullExpression);
|
|
4064
4067
|
}
|
|
4065
4068
|
else {
|
|
4066
|
-
idx = block.insertData(`${fullExpression}`, "
|
|
4067
|
-
attrs[`block-
|
|
4069
|
+
idx = block.insertData(`${fullExpression}`, "prop");
|
|
4070
|
+
attrs[`block-property-${idx}`] = targetAttr;
|
|
4068
4071
|
}
|
|
4069
4072
|
this.helpers.add("toNumber");
|
|
4070
4073
|
let valueCode = `ev.target.${targetAttr}`;
|
|
@@ -4082,32 +4085,21 @@ class CodeGenerator {
|
|
|
4082
4085
|
}
|
|
4083
4086
|
// t-ref
|
|
4084
4087
|
if (ast.ref) {
|
|
4085
|
-
this.
|
|
4088
|
+
if (this.dev) {
|
|
4089
|
+
this.helpers.add("makeRefWrapper");
|
|
4090
|
+
this.target.hasRefWrapper = true;
|
|
4091
|
+
}
|
|
4086
4092
|
const isDynamic = INTERP_REGEXP.test(ast.ref);
|
|
4093
|
+
let name = `\`${ast.ref}\``;
|
|
4087
4094
|
if (isDynamic) {
|
|
4088
|
-
this.
|
|
4089
|
-
const str = replaceDynamicParts(ast.ref, (expr) => this.captureExpression(expr, true));
|
|
4090
|
-
const idx = block.insertData(`singleRefSetter(refs, ${str})`, "ref");
|
|
4091
|
-
attrs["block-ref"] = String(idx);
|
|
4095
|
+
name = replaceDynamicParts(ast.ref, (expr) => this.captureExpression(expr, true));
|
|
4092
4096
|
}
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
// ref has already been defined
|
|
4097
|
-
this.helpers.add("multiRefSetter");
|
|
4098
|
-
const info = this.target.refInfo[name];
|
|
4099
|
-
const index = block.data.push(info[0]) - 1;
|
|
4100
|
-
attrs["block-ref"] = String(index);
|
|
4101
|
-
info[1] = `multiRefSetter(refs, \`${name}\`)`;
|
|
4102
|
-
}
|
|
4103
|
-
else {
|
|
4104
|
-
let id = generateId("ref");
|
|
4105
|
-
this.helpers.add("singleRefSetter");
|
|
4106
|
-
this.target.refInfo[name] = [id, `singleRefSetter(refs, \`${name}\`)`];
|
|
4107
|
-
const index = block.data.push(id) - 1;
|
|
4108
|
-
attrs["block-ref"] = String(index);
|
|
4109
|
-
}
|
|
4097
|
+
let setRefStr = `(el) => this.__owl__.setRef((${name}), el)`;
|
|
4098
|
+
if (this.dev) {
|
|
4099
|
+
setRefStr = `refWrapper(${name}, ${setRefStr})`;
|
|
4110
4100
|
}
|
|
4101
|
+
const idx = block.insertData(setRefStr, "ref");
|
|
4102
|
+
attrs["block-ref"] = String(idx);
|
|
4111
4103
|
}
|
|
4112
4104
|
const dom = xmlDoc.createElement(ast.tag);
|
|
4113
4105
|
for (const [attr, val] of Object.entries(attrs)) {
|
|
@@ -4130,6 +4122,7 @@ class CodeGenerator {
|
|
|
4130
4122
|
tKeyExpr: ctx.tKeyExpr,
|
|
4131
4123
|
nameSpace,
|
|
4132
4124
|
tModelSelectedExpr,
|
|
4125
|
+
inPreTag: ctx.inPreTag || ast.tag === "pre",
|
|
4133
4126
|
});
|
|
4134
4127
|
this.compileAST(child, subCtx);
|
|
4135
4128
|
}
|
|
@@ -4514,13 +4507,15 @@ class CodeGenerator {
|
|
|
4514
4507
|
value = this.captureExpression(value);
|
|
4515
4508
|
if (name.includes(".")) {
|
|
4516
4509
|
let [_name, suffix] = name.split(".");
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4510
|
+
name = _name;
|
|
4511
|
+
switch (suffix) {
|
|
4512
|
+
case "bind":
|
|
4513
|
+
value = `${value}.bind(this)`;
|
|
4514
|
+
break;
|
|
4515
|
+
case "alike":
|
|
4516
|
+
break;
|
|
4517
|
+
default:
|
|
4518
|
+
throw new OwlError("Invalid prop suffix");
|
|
4524
4519
|
}
|
|
4525
4520
|
}
|
|
4526
4521
|
name = /^[a-z_]+$/i.test(name) ? name : `'${name}'`;
|
|
@@ -4607,9 +4602,16 @@ class CodeGenerator {
|
|
|
4607
4602
|
keyArg = `${ctx.tKeyExpr} + ${keyArg}`;
|
|
4608
4603
|
}
|
|
4609
4604
|
let id = generateId("comp");
|
|
4605
|
+
const propList = [];
|
|
4606
|
+
for (let p in ast.props || {}) {
|
|
4607
|
+
let [name, suffix] = p.split(".");
|
|
4608
|
+
if (!suffix) {
|
|
4609
|
+
propList.push(`"${name}"`);
|
|
4610
|
+
}
|
|
4611
|
+
}
|
|
4610
4612
|
this.staticDefs.push({
|
|
4611
4613
|
id,
|
|
4612
|
-
expr: `app.createComponent(${ast.isDynamic ? null : expr}, ${!ast.isDynamic}, ${!!ast.slots}, ${!!ast.dynamicProps}, ${
|
|
4614
|
+
expr: `app.createComponent(${ast.isDynamic ? null : expr}, ${!ast.isDynamic}, ${!!ast.slots}, ${!!ast.dynamicProps}, [${propList}])`,
|
|
4613
4615
|
});
|
|
4614
4616
|
if (ast.isDynamic) {
|
|
4615
4617
|
// If the component class changes, this can cause delayed renders to go
|
|
@@ -4787,15 +4789,11 @@ function parseTNode(node, ctx) {
|
|
|
4787
4789
|
// Text and Comment Nodes
|
|
4788
4790
|
// -----------------------------------------------------------------------------
|
|
4789
4791
|
const lineBreakRE = /[\r\n]/;
|
|
4790
|
-
const whitespaceRE = /\s+/g;
|
|
4791
4792
|
function parseTextCommentNode(node, ctx) {
|
|
4792
4793
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
4793
4794
|
let value = node.textContent || "";
|
|
4794
|
-
if (!ctx.inPreTag) {
|
|
4795
|
-
|
|
4796
|
-
return null;
|
|
4797
|
-
}
|
|
4798
|
-
value = value.replace(whitespaceRE, " ");
|
|
4795
|
+
if (!ctx.inPreTag && lineBreakRE.test(value) && !value.trim()) {
|
|
4796
|
+
return null;
|
|
4799
4797
|
}
|
|
4800
4798
|
return { type: 0 /* Text */, value };
|
|
4801
4799
|
}
|
|
@@ -5483,50 +5481,8 @@ function compile(template, options = {}) {
|
|
|
5483
5481
|
return new Function("app, bdom, helpers", code);
|
|
5484
5482
|
}
|
|
5485
5483
|
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
data = _data;
|
|
5489
|
-
let stopped = false;
|
|
5490
|
-
if (modifiers.length) {
|
|
5491
|
-
let selfMode = false;
|
|
5492
|
-
const isSelf = ev.target === currentTarget;
|
|
5493
|
-
for (const mod of modifiers) {
|
|
5494
|
-
switch (mod) {
|
|
5495
|
-
case "self":
|
|
5496
|
-
selfMode = true;
|
|
5497
|
-
if (isSelf) {
|
|
5498
|
-
continue;
|
|
5499
|
-
}
|
|
5500
|
-
else {
|
|
5501
|
-
return stopped;
|
|
5502
|
-
}
|
|
5503
|
-
case "prevent":
|
|
5504
|
-
if ((selfMode && isSelf) || !selfMode)
|
|
5505
|
-
ev.preventDefault();
|
|
5506
|
-
continue;
|
|
5507
|
-
case "stop":
|
|
5508
|
-
if ((selfMode && isSelf) || !selfMode)
|
|
5509
|
-
ev.stopPropagation();
|
|
5510
|
-
stopped = true;
|
|
5511
|
-
continue;
|
|
5512
|
-
}
|
|
5513
|
-
}
|
|
5514
|
-
}
|
|
5515
|
-
// If handler is empty, the array slot 0 will also be empty, and data will not have the property 0
|
|
5516
|
-
// We check this rather than data[0] being truthy (or typeof function) so that it crashes
|
|
5517
|
-
// as expected when there is a handler expression that evaluates to a falsy value
|
|
5518
|
-
if (Object.hasOwnProperty.call(data, 0)) {
|
|
5519
|
-
const handler = data[0];
|
|
5520
|
-
if (typeof handler !== "function") {
|
|
5521
|
-
throw new OwlError(`Invalid handler (expected a function, received: '${handler}')`);
|
|
5522
|
-
}
|
|
5523
|
-
let node = data[1] ? data[1].__owl__ : null;
|
|
5524
|
-
if (node ? node.status === 1 /* MOUNTED */ : true) {
|
|
5525
|
-
handler.call(node ? node.component : null, ev);
|
|
5526
|
-
}
|
|
5527
|
-
}
|
|
5528
|
-
return stopped;
|
|
5529
|
-
};
|
|
5484
|
+
// do not modify manually. This value is updated by the release script.
|
|
5485
|
+
const version = "2.0.8";
|
|
5530
5486
|
|
|
5531
5487
|
// -----------------------------------------------------------------------------
|
|
5532
5488
|
// Scheduler
|
|
@@ -5611,6 +5567,7 @@ class App extends TemplateSet {
|
|
|
5611
5567
|
super(config);
|
|
5612
5568
|
this.scheduler = new Scheduler();
|
|
5613
5569
|
this.root = null;
|
|
5570
|
+
this.name = config.name || "";
|
|
5614
5571
|
this.Root = Root;
|
|
5615
5572
|
window.__OWL_DEVTOOLS__.apps.add(this);
|
|
5616
5573
|
if (config.test) {
|
|
@@ -5671,21 +5628,36 @@ class App extends TemplateSet {
|
|
|
5671
5628
|
}
|
|
5672
5629
|
window.__OWL_DEVTOOLS__.apps.delete(this);
|
|
5673
5630
|
}
|
|
5674
|
-
createComponent(name, isStatic, hasSlotsProp, hasDynamicPropList,
|
|
5631
|
+
createComponent(name, isStatic, hasSlotsProp, hasDynamicPropList, propList) {
|
|
5675
5632
|
const isDynamic = !isStatic;
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5633
|
+
let arePropsDifferent;
|
|
5634
|
+
const hasNoProp = propList.length === 0;
|
|
5635
|
+
if (hasSlotsProp) {
|
|
5636
|
+
arePropsDifferent = (_1, _2) => true;
|
|
5637
|
+
}
|
|
5638
|
+
else if (hasDynamicPropList) {
|
|
5639
|
+
arePropsDifferent = function (props1, props2) {
|
|
5640
|
+
for (let k in props1) {
|
|
5641
|
+
if (props1[k] !== props2[k]) {
|
|
5642
|
+
return true;
|
|
5643
|
+
}
|
|
5680
5644
|
}
|
|
5681
|
-
|
|
5682
|
-
|
|
5645
|
+
return Object.keys(props1).length !== Object.keys(props2).length;
|
|
5646
|
+
};
|
|
5647
|
+
}
|
|
5648
|
+
else if (hasNoProp) {
|
|
5649
|
+
arePropsDifferent = (_1, _2) => false;
|
|
5650
|
+
}
|
|
5651
|
+
else {
|
|
5652
|
+
arePropsDifferent = function (props1, props2) {
|
|
5653
|
+
for (let p of propList) {
|
|
5654
|
+
if (props1[p] !== props2[p]) {
|
|
5655
|
+
return true;
|
|
5656
|
+
}
|
|
5657
|
+
}
|
|
5658
|
+
return false;
|
|
5659
|
+
};
|
|
5683
5660
|
}
|
|
5684
|
-
const arePropsDifferent = hasSlotsProp
|
|
5685
|
-
? (_1, _2) => true
|
|
5686
|
-
: hasNoProp
|
|
5687
|
-
? (_1, _2) => false
|
|
5688
|
-
: _arePropsDifferent;
|
|
5689
5661
|
const updateAndRender = ComponentNode.prototype.updateAndRender;
|
|
5690
5662
|
const initiateRender = ComponentNode.prototype.initiateRender;
|
|
5691
5663
|
return (props, key, ctx, parent, C) => {
|
|
@@ -5729,10 +5701,56 @@ class App extends TemplateSet {
|
|
|
5729
5701
|
}
|
|
5730
5702
|
}
|
|
5731
5703
|
App.validateTarget = validateTarget;
|
|
5704
|
+
App.version = version;
|
|
5732
5705
|
async function mount(C, target, config = {}) {
|
|
5733
5706
|
return new App(C, config).mount(target, config);
|
|
5734
5707
|
}
|
|
5735
5708
|
|
|
5709
|
+
const mainEventHandler = (data, ev, currentTarget) => {
|
|
5710
|
+
const { data: _data, modifiers } = filterOutModifiersFromData(data);
|
|
5711
|
+
data = _data;
|
|
5712
|
+
let stopped = false;
|
|
5713
|
+
if (modifiers.length) {
|
|
5714
|
+
let selfMode = false;
|
|
5715
|
+
const isSelf = ev.target === currentTarget;
|
|
5716
|
+
for (const mod of modifiers) {
|
|
5717
|
+
switch (mod) {
|
|
5718
|
+
case "self":
|
|
5719
|
+
selfMode = true;
|
|
5720
|
+
if (isSelf) {
|
|
5721
|
+
continue;
|
|
5722
|
+
}
|
|
5723
|
+
else {
|
|
5724
|
+
return stopped;
|
|
5725
|
+
}
|
|
5726
|
+
case "prevent":
|
|
5727
|
+
if ((selfMode && isSelf) || !selfMode)
|
|
5728
|
+
ev.preventDefault();
|
|
5729
|
+
continue;
|
|
5730
|
+
case "stop":
|
|
5731
|
+
if ((selfMode && isSelf) || !selfMode)
|
|
5732
|
+
ev.stopPropagation();
|
|
5733
|
+
stopped = true;
|
|
5734
|
+
continue;
|
|
5735
|
+
}
|
|
5736
|
+
}
|
|
5737
|
+
}
|
|
5738
|
+
// If handler is empty, the array slot 0 will also be empty, and data will not have the property 0
|
|
5739
|
+
// We check this rather than data[0] being truthy (or typeof function) so that it crashes
|
|
5740
|
+
// as expected when there is a handler expression that evaluates to a falsy value
|
|
5741
|
+
if (Object.hasOwnProperty.call(data, 0)) {
|
|
5742
|
+
const handler = data[0];
|
|
5743
|
+
if (typeof handler !== "function") {
|
|
5744
|
+
throw new OwlError(`Invalid handler (expected a function, received: '${handler}')`);
|
|
5745
|
+
}
|
|
5746
|
+
let node = data[1] ? data[1].__owl__ : null;
|
|
5747
|
+
if (node ? node.status === 1 /* MOUNTED */ : true) {
|
|
5748
|
+
handler.call(node ? node.component : null, ev);
|
|
5749
|
+
}
|
|
5750
|
+
}
|
|
5751
|
+
return stopped;
|
|
5752
|
+
};
|
|
5753
|
+
|
|
5736
5754
|
function status(component) {
|
|
5737
5755
|
switch (component.__owl__.status) {
|
|
5738
5756
|
case 0 /* NEW */:
|
|
@@ -5756,7 +5774,8 @@ function useRef(name) {
|
|
|
5756
5774
|
const refs = node.refs;
|
|
5757
5775
|
return {
|
|
5758
5776
|
get el() {
|
|
5759
|
-
|
|
5777
|
+
const el = refs[name];
|
|
5778
|
+
return (el === null || el === void 0 ? void 0 : el.ownerDocument.contains(el)) ? el : null;
|
|
5760
5779
|
},
|
|
5761
5780
|
};
|
|
5762
5781
|
}
|
|
@@ -5861,7 +5880,9 @@ const blockDom = {
|
|
|
5861
5880
|
html,
|
|
5862
5881
|
comment,
|
|
5863
5882
|
};
|
|
5864
|
-
const __info__ = {
|
|
5883
|
+
const __info__ = {
|
|
5884
|
+
version: App.version,
|
|
5885
|
+
};
|
|
5865
5886
|
|
|
5866
5887
|
TemplateSet.prototype._compileTemplate = function _compileTemplate(name, template) {
|
|
5867
5888
|
return compile(template, {
|
|
@@ -5908,7 +5929,6 @@ exports.whenReady = whenReady;
|
|
|
5908
5929
|
exports.xml = xml;
|
|
5909
5930
|
|
|
5910
5931
|
|
|
5911
|
-
__info__.
|
|
5912
|
-
__info__.
|
|
5913
|
-
__info__.hash = '276c8a0';
|
|
5932
|
+
__info__.date = '2023-03-09T12:11:34.048Z';
|
|
5933
|
+
__info__.hash = '532ab7f';
|
|
5914
5934
|
__info__.url = 'https://github.com/odoo/owl';
|