xdbc 1.0.217 → 1.0.218
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/.gitattributes +8 -0
- package/.vscode/settings.json +3 -3
- package/.vscode/tasks.json +23 -23
- package/ASSESSMENT.md +249 -0
- package/README.md +131 -1
- package/__tests__/DBC/AE.test.ts +62 -62
- package/__tests__/DBC/ARRAY.test.ts +91 -91
- package/__tests__/DBC/DEFINED.test.ts +53 -53
- package/__tests__/DBC/DOM.test.ts +481 -0
- package/__tests__/DBC/Decorators.test.ts +367 -367
- package/__tests__/DBC/EQ.test.ts +13 -13
- package/__tests__/DBC/GREATER.test.ts +31 -31
- package/__tests__/DBC/HasAttribute.test.ts +60 -60
- package/__tests__/DBC/IF.test.ts +62 -62
- package/__tests__/DBC/INSTANCE.test.ts +13 -13
- package/__tests__/DBC/JSON.OP.test.ts +47 -47
- package/__tests__/DBC/JSON.Parse.test.ts +17 -17
- package/__tests__/DBC/OR.test.ts +14 -14
- package/__tests__/DBC/PLAIN_OBJECT.test.ts +109 -109
- package/__tests__/DBC/REGEX.test.ts +17 -17
- package/__tests__/DBC/TYPE.test.ts +13 -13
- package/__tests__/DBC/UNDEFINED.test.ts +45 -45
- package/__tests__/DBC/ZOD.test.ts +54 -54
- package/__tests__/DBC/onInfringement.test.ts +262 -0
- package/biome.json +40 -40
- package/dist/DBC/AE.js +172 -0
- package/dist/DBC/ARR/PLAIN_OBJECT.d.ts +0 -3
- package/dist/DBC/ARR/PLAIN_OBJECT.js +95 -0
- package/dist/DBC/ARRAY.d.ts +0 -3
- package/dist/DBC/ARRAY.js +90 -0
- package/dist/DBC/COMPARISON/GREATER.js +21 -0
- package/dist/DBC/COMPARISON/GREATER_OR_EQUAL.js +21 -0
- package/dist/DBC/COMPARISON/LESS.js +21 -0
- package/dist/DBC/COMPARISON/LESS_OR_EQUAL.js +21 -0
- package/dist/DBC/COMPARISON.js +98 -0
- package/dist/DBC/DEFINED.js +87 -0
- package/dist/DBC/DOM.d.ts +87 -0
- package/dist/DBC/DOM.js +223 -0
- package/dist/DBC/EQ/DIFFERENT.js +34 -0
- package/dist/DBC/EQ.js +101 -0
- package/dist/DBC/HasAttribute.js +101 -0
- package/dist/DBC/IF.js +96 -0
- package/dist/DBC/INSTANCE.js +122 -0
- package/dist/DBC/JSON.OP.js +120 -0
- package/dist/DBC/JSON.Parse.js +104 -0
- package/dist/DBC/OR.js +125 -0
- package/dist/DBC/REGEX.js +136 -0
- package/dist/DBC/TYPE.js +112 -0
- package/dist/DBC/UNDEFINED.js +87 -0
- package/dist/DBC/ZOD.js +99 -0
- package/dist/DBC.d.ts +18 -4
- package/dist/DBC.js +645 -0
- package/dist/Demo.d.ts +10 -0
- package/dist/Demo.js +713 -0
- package/dist/bundle.js +6140 -405
- package/dist/index.d.ts +22 -0
- package/dist/index.js +22 -0
- package/jest.config.js +32 -32
- package/package.json +71 -55
- package/src/DBC/AE.ts +269 -288
- package/src/DBC/ARR/PLAIN_OBJECT.ts +122 -133
- package/src/DBC/ARRAY.ts +117 -127
- package/src/DBC/COMPARISON/GREATER.ts +41 -46
- package/src/DBC/COMPARISON/GREATER_OR_EQUAL.ts +41 -45
- package/src/DBC/COMPARISON/LESS.ts +41 -45
- package/src/DBC/COMPARISON/LESS_OR_EQUAL.ts +41 -45
- package/src/DBC/COMPARISON.ts +149 -159
- package/src/DBC/DEFINED.ts +117 -122
- package/src/DBC/DOM.ts +291 -0
- package/src/DBC/EQ/DIFFERENT.ts +51 -57
- package/src/DBC/EQ.ts +154 -163
- package/src/DBC/HasAttribute.ts +149 -154
- package/src/DBC/IF.ts +173 -179
- package/src/DBC/INSTANCE.ts +168 -171
- package/src/DBC/JSON.OP.ts +178 -186
- package/src/DBC/JSON.Parse.ts +150 -157
- package/src/DBC/OR.ts +183 -187
- package/src/DBC/REGEX.ts +195 -196
- package/src/DBC/TYPE.ts +142 -149
- package/src/DBC/UNDEFINED.ts +115 -117
- package/src/DBC/ZOD.ts +130 -135
- package/src/DBC.ts +902 -904
- package/src/Demo.ts +537 -404
- package/src/index.ts +22 -0
- package/tsconfig.json +18 -18
- package/tsconfig.test.json +7 -7
- package/typedoc.json +16 -16
- package/webpack.config.js +27 -27
- package/Assessment.md +0 -507
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { DBC } from "../DBC";
|
|
2
|
+
/**
|
|
3
|
+
* A {@link DBC } defining that a value must be an array.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Maintainer: Salvatore Callari (XDBC@WaXCode.net) */
|
|
7
|
+
export class ARRAY extends DBC {
|
|
8
|
+
/**
|
|
9
|
+
* Checks if the value **toCheck** is an array.
|
|
10
|
+
*
|
|
11
|
+
* @param toCheck The value to check.
|
|
12
|
+
*
|
|
13
|
+
* @returns TRUE if the value **toCheck** is an array, otherwise a string describing the infringement. */
|
|
14
|
+
static checkAlgorithm(toCheck) {
|
|
15
|
+
if (toCheck === undefined || toCheck === null)
|
|
16
|
+
return true;
|
|
17
|
+
if (!Array.isArray(toCheck)) {
|
|
18
|
+
return `Value has to be an ARRAY but is of type "${typeof toCheck}"`;
|
|
19
|
+
}
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A parameter-decorator factory using the {@link ARRAY.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
24
|
+
* by the tagged parameter.
|
|
25
|
+
*
|
|
26
|
+
* @param path See {@link DBC.decPrecondition }.
|
|
27
|
+
* @param hint See {@link DBC.decPrecondition }.
|
|
28
|
+
* @param dbc See {@link DBC.decPrecondition }.
|
|
29
|
+
*
|
|
30
|
+
* @returns See {@link DBC.decPrecondition }. */
|
|
31
|
+
static PRE(path = undefined, hint = undefined, dbc = undefined) {
|
|
32
|
+
return DBC.createPRE(ARRAY.checkAlgorithm, [], dbc, path, hint);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A method-decorator factory using the {@link ARRAY.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
36
|
+
* by the tagged method's returnvalue.
|
|
37
|
+
*
|
|
38
|
+
* @param path See {@link DBC.decPostcondition }.
|
|
39
|
+
* @param hint See {@link DBC.decPostcondition }.
|
|
40
|
+
* @param dbc See {@link DBC.decPostcondition }.
|
|
41
|
+
*
|
|
42
|
+
* @returns See {@link DBC.decPostcondition }. */
|
|
43
|
+
static POST(path = undefined, hint = undefined, dbc = undefined) {
|
|
44
|
+
return DBC.createPOST(ARRAY.checkAlgorithm, [], dbc, path, hint);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A field-decorator factory using the {@link ARRAY.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
48
|
+
* by the tagged field.
|
|
49
|
+
*
|
|
50
|
+
* @param path See {@link DBC.decInvariant }.
|
|
51
|
+
* @param hint See {@link DBC.decInvariant }.
|
|
52
|
+
* @param dbc See {@link DBC.decInvariant }.
|
|
53
|
+
*
|
|
54
|
+
* @returns See {@link DBC.decInvariant }. */
|
|
55
|
+
static INVARIANT(path = undefined, hint = undefined, dbc = undefined) {
|
|
56
|
+
return DBC.createINVARIANT(ARRAY, [], dbc, path, hint);
|
|
57
|
+
}
|
|
58
|
+
// #endregion Condition checking.
|
|
59
|
+
// #region Referenced Condition checking.
|
|
60
|
+
//
|
|
61
|
+
// For usage in dynamic scenarios (like with AE-DBC).
|
|
62
|
+
//
|
|
63
|
+
/**
|
|
64
|
+
* Invokes the {@link ARRAY.checkAlgorithm } passing the value **toCheck**.
|
|
65
|
+
*
|
|
66
|
+
* @param toCheck See {@link ARRAY.checkAlgorithm }.
|
|
67
|
+
*
|
|
68
|
+
* @returns See {@link ARRAY.checkAlgorithm}. */
|
|
69
|
+
check(toCheck) {
|
|
70
|
+
return ARRAY.checkAlgorithm(toCheck);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Invokes the {@link ARRAY.checkAlgorithm } passing the value **toCheck**.
|
|
74
|
+
*
|
|
75
|
+
* @param toCheck See {@link ARRAY.checkAlgorithm }.
|
|
76
|
+
* @param hint An optional {@link string } providing extra information in case of an infringement.
|
|
77
|
+
* @param id A {@link string } identifying this {@link ARRAY } via the {@link DBC.Infringement }-Message.
|
|
78
|
+
*
|
|
79
|
+
* @returns The **CANDIDATE** **toCheck** if this {@link ARRAY } is fulfilled.
|
|
80
|
+
*
|
|
81
|
+
* @throws A {@link DBC.Infringement } if the **CANDIDATE** **toCheck** does not fulfill this {@link ARRAY }. */
|
|
82
|
+
static tsCheck(toCheck, hint = undefined, id = undefined, dbc = undefined) {
|
|
83
|
+
const result = ARRAY.checkAlgorithm(toCheck);
|
|
84
|
+
if (result === true) {
|
|
85
|
+
return toCheck;
|
|
86
|
+
}
|
|
87
|
+
DBC.reportTsCheckInfringement(`${id ? `(${id}) ` : ""}${result}${hint ? ` ✨ ${hint} ✨` : ""}`, dbc);
|
|
88
|
+
return toCheck;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { COMPARISON } from "../COMPARISON";
|
|
2
|
+
/** See {@link COMPARISON }. */
|
|
3
|
+
export class GREATER extends COMPARISON {
|
|
4
|
+
/** See {@link COMPARISON.PRE }. */
|
|
5
|
+
static PRE(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
6
|
+
return COMPARISON.PRE(equivalent, false, false, path, hint, dbc);
|
|
7
|
+
}
|
|
8
|
+
/** See {@link COMPARISON.POST }. */
|
|
9
|
+
static POST(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
10
|
+
return COMPARISON.POST(equivalent, false, false, path, hint, dbc);
|
|
11
|
+
}
|
|
12
|
+
/** See {@link COMPARISON.INVARIANT }. */
|
|
13
|
+
static INVARIANT(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
14
|
+
return COMPARISON.INVARIANT(equivalent, false, false, path, hint, dbc);
|
|
15
|
+
}
|
|
16
|
+
/** See {@link COMPARISON.constructor }. */
|
|
17
|
+
constructor(equivalent) {
|
|
18
|
+
super(equivalent, false, false);
|
|
19
|
+
this.equivalent = equivalent;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { COMPARISON } from "../COMPARISON";
|
|
2
|
+
/** See {@link COMPARISON }. */
|
|
3
|
+
export class GREATER_OR_EQUAL extends COMPARISON {
|
|
4
|
+
/** See {@link COMPARISON.PRE }. */
|
|
5
|
+
static PRE(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
6
|
+
return COMPARISON.PRE(equivalent, true, false, path, hint, dbc);
|
|
7
|
+
}
|
|
8
|
+
/** See {@link COMPARISON.POST }. */
|
|
9
|
+
static POST(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
10
|
+
return COMPARISON.POST(equivalent, true, false, path, hint, dbc);
|
|
11
|
+
}
|
|
12
|
+
/** See {@link COMPARISON.INVARIANT }. */
|
|
13
|
+
static INVARIANT(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
14
|
+
return COMPARISON.INVARIANT(equivalent, true, false, path, hint, dbc);
|
|
15
|
+
}
|
|
16
|
+
/** See {@link COMPARISON.constructor }. */
|
|
17
|
+
constructor(equivalent) {
|
|
18
|
+
super(equivalent, true, false);
|
|
19
|
+
this.equivalent = equivalent;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { COMPARISON } from "../COMPARISON";
|
|
2
|
+
/** See {@link COMPARISON }. */
|
|
3
|
+
export class LESS extends COMPARISON {
|
|
4
|
+
/** See {@link COMPARISON.PRE }. */
|
|
5
|
+
static PRE(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
6
|
+
return COMPARISON.PRE(equivalent, false, true, path, hint, dbc);
|
|
7
|
+
}
|
|
8
|
+
/** See {@link COMPARISON.POST }. */
|
|
9
|
+
static POST(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
10
|
+
return COMPARISON.POST(equivalent, false, true, path, hint, dbc);
|
|
11
|
+
}
|
|
12
|
+
/** See {@link COMPARISON.INVARIANT }. */
|
|
13
|
+
static INVARIANT(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
14
|
+
return COMPARISON.INVARIANT(equivalent, false, true, path, hint, dbc);
|
|
15
|
+
}
|
|
16
|
+
/** See {@link COMPARISON.constructor }. */
|
|
17
|
+
constructor(equivalent) {
|
|
18
|
+
super(equivalent, false, true);
|
|
19
|
+
this.equivalent = equivalent;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { COMPARISON } from "../COMPARISON";
|
|
2
|
+
/** See {@link COMPARISON }. */
|
|
3
|
+
export class LESS_OR_EQUAL extends COMPARISON {
|
|
4
|
+
/** See {@link COMPARISON.PRE }. */
|
|
5
|
+
static PRE(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
6
|
+
return COMPARISON.PRE(equivalent, true, true, path, hint, dbc);
|
|
7
|
+
}
|
|
8
|
+
/** See {@link COMPARISON.POST }. */
|
|
9
|
+
static POST(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
10
|
+
return COMPARISON.POST(equivalent, true, true, path, hint, dbc);
|
|
11
|
+
}
|
|
12
|
+
/** See {@link COMPARISON.INVARIANT }. */
|
|
13
|
+
static INVARIANT(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
14
|
+
return COMPARISON.INVARIANT(equivalent, true, true, path, hint, dbc);
|
|
15
|
+
}
|
|
16
|
+
/** See {@link COMPARISON.constructor }. */
|
|
17
|
+
constructor(equivalent) {
|
|
18
|
+
super(equivalent, true, true);
|
|
19
|
+
this.equivalent = equivalent;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { DBC } from "../DBC";
|
|
2
|
+
/**
|
|
3
|
+
* A {@link DBC } defining a comparison between two {@link object }s.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Maintainer: Callari, Salvatore (XDBC@WaXCode.net) */
|
|
7
|
+
export class COMPARISON extends DBC {
|
|
8
|
+
// #region Condition checking.
|
|
9
|
+
/**
|
|
10
|
+
* Does a comparison between the {@link object } **toCheck** and the **equivalent**.
|
|
11
|
+
*
|
|
12
|
+
* @param toCheck The value that has to be equal to it's possible **equivalent** for this {@link DBC } to be fulfilled.
|
|
13
|
+
* @param equivalent The {@link object } the one **toCheck** has to be equal to in order for this {@link DBC } to be
|
|
14
|
+
* fulfilled.
|
|
15
|
+
*
|
|
16
|
+
* @returns TRUE if the value **toCheck** and the **equivalent** are equal to each other, otherwise FALSE. */
|
|
17
|
+
static checkAlgorithm(toCheck, equivalent, equalityPermitted, invert) {
|
|
18
|
+
if (equalityPermitted && !invert && toCheck < equivalent) {
|
|
19
|
+
return `Value has to be greater than or equal to "${equivalent}"`;
|
|
20
|
+
}
|
|
21
|
+
if (equalityPermitted && invert && toCheck > equivalent) {
|
|
22
|
+
return `Value has to be less than or equal to "${equivalent}"`;
|
|
23
|
+
}
|
|
24
|
+
if (!equalityPermitted && !invert && toCheck <= equivalent) {
|
|
25
|
+
return `Value has to be greater than "${equivalent}"`;
|
|
26
|
+
}
|
|
27
|
+
if (!equalityPermitted && invert && toCheck >= equivalent) {
|
|
28
|
+
return `Value has to be less than "${equivalent}"`;
|
|
29
|
+
}
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A parameter-decorator factory using the {@link COMPARISON.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
34
|
+
* by the tagged parameter.
|
|
35
|
+
*
|
|
36
|
+
* @param equivalent See {@link COMPARISON.checkAlgorithm }.
|
|
37
|
+
* @param equalityPermitted See {@link COMPARISON.checkAlgorithm }.
|
|
38
|
+
* @param path See {@link DBC.decPrecondition }.
|
|
39
|
+
* @param hint See {@link DBC.decPrecondition }.
|
|
40
|
+
* @param dbc See {@link DBC.decPrecondition }.
|
|
41
|
+
*
|
|
42
|
+
* @returns See {@link DBC.decPrecondition }. */
|
|
43
|
+
static PRE(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
44
|
+
return DBC.createPRE(COMPARISON.checkAlgorithm, [equivalent, equalityPermitted, invert], dbc, path, hint);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A method-decorator factory using the {@link COMPARISON.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
48
|
+
* by the tagged method's returnvalue.
|
|
49
|
+
*
|
|
50
|
+
* @param equivalent See {@link COMPARISON.checkAlgorithm }.
|
|
51
|
+
* @param equalityPermitted See {@link COMPARISON.checkAlgorithm }.
|
|
52
|
+
* @param path See {@link DBC.Postcondition }.
|
|
53
|
+
* @param hint See {@link DBC.decPostcondition }.
|
|
54
|
+
* @param dbc See {@link DBC.decPostcondition }.
|
|
55
|
+
*
|
|
56
|
+
* @returns See {@link DBC.decPostcondition }. */
|
|
57
|
+
static POST(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
58
|
+
return DBC.createPOST(COMPARISON.checkAlgorithm, [equivalent, equalityPermitted, invert], dbc, path, hint);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A field-decorator factory using the {@link COMPARISON.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
62
|
+
* by the tagged field.
|
|
63
|
+
*
|
|
64
|
+
* @param equivalent See {@link COMPARISON.checkAlgorithm }.
|
|
65
|
+
* @param equalityPermitted See {@link COMPARISON.checkAlgorithm }.
|
|
66
|
+
* @param path See {@link DBC.decInvariant }.
|
|
67
|
+
* @param hint See {@link DBC.decInvariant }.
|
|
68
|
+
* @param dbc See {@link DBC.decInvariant }.
|
|
69
|
+
*
|
|
70
|
+
* @returns See {@link DBC.decInvariant }. */
|
|
71
|
+
static INVARIANT(equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
72
|
+
return DBC.createINVARIANT(COMPARISON, [equivalent, equalityPermitted, invert], dbc, path, hint);
|
|
73
|
+
}
|
|
74
|
+
// #endregion Condition checking.
|
|
75
|
+
// #region Referenced Condition checking.
|
|
76
|
+
// #region Dynamic usage.
|
|
77
|
+
/**
|
|
78
|
+
* Invokes the {@link COMPARISON.checkAlgorithm } passing the value **toCheck**, {@link COMPARISON.equivalent } and {@link COMPARISON.invert }.
|
|
79
|
+
*
|
|
80
|
+
* @param toCheck See {@link COMPARISON.checkAlgorithm }.
|
|
81
|
+
*
|
|
82
|
+
* @returns See {@link COMPARISON.checkAlgorithm}. */
|
|
83
|
+
check(toCheck) {
|
|
84
|
+
return COMPARISON.checkAlgorithm(toCheck, this.equivalent, this.equalityPermitted, this.invert);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Creates this {@link COMPARISON } by setting the protected property {@link COMPARISON.equivalent }, {@link COMPARISON.equalityPermitted } and {@link COMPARISON.invert } used by {@link COMPARISON.check }.
|
|
88
|
+
*
|
|
89
|
+
* @param equivalent See {@link COMPARISON.check }.
|
|
90
|
+
* @param equalityPermitted See {@link COMPARISON.check }.
|
|
91
|
+
* @param invert See {@link COMPARISON.check }. */
|
|
92
|
+
constructor(equivalent, equalityPermitted = false, invert = false) {
|
|
93
|
+
super();
|
|
94
|
+
this.equivalent = equivalent;
|
|
95
|
+
this.equalityPermitted = equalityPermitted;
|
|
96
|
+
this.invert = invert;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { DBC } from "../DBC";
|
|
2
|
+
/**
|
|
3
|
+
* A {@link DBC } defining that an {@link object }s must be defined thus it's value may not be **null** or **undefined**.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Maintainer: Salvatore Callari (XDBC@WaXCode.net) */
|
|
7
|
+
export class DEFINED extends DBC {
|
|
8
|
+
/**
|
|
9
|
+
* Checks if the value **toCheck** is null or undefined.
|
|
10
|
+
*
|
|
11
|
+
* @param toCheck The {@link Object } to check.
|
|
12
|
+
*
|
|
13
|
+
* @returns TRUE if the value **toCheck** is of the specified **type**, otherwise FALSE. */
|
|
14
|
+
static checkAlgorithm(toCheck) {
|
|
15
|
+
if (toCheck === undefined || toCheck === null) {
|
|
16
|
+
return `Value may not be UNDEFINED or NULL but it is ${toCheck === undefined ? "UNDEFINED" : "NULL"}`;
|
|
17
|
+
}
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A parameter-decorator factory using the {@link DEFINED.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
22
|
+
* by the tagged parameter.
|
|
23
|
+
*
|
|
24
|
+
* @param type See {@link DEFINED.checkAlgorithm }.
|
|
25
|
+
* @param path See {@link DBC.decPrecondition }.
|
|
26
|
+
* @param dbc See {@link DBC.decPrecondition }.
|
|
27
|
+
*
|
|
28
|
+
* @returns See {@link DBC.decPrecondition }. */
|
|
29
|
+
static PRE(path = undefined, hint = undefined, dbc = undefined) {
|
|
30
|
+
return DBC.createPRE(DEFINED.checkAlgorithm, [], dbc, path, hint);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A method-decorator factory using the {@link DEFINED.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
34
|
+
* by the tagged method's returnvalue.
|
|
35
|
+
*
|
|
36
|
+
* @param type See {@link DEFINED.checkAlgorithm }.
|
|
37
|
+
* @param path See {@link DBC.Postcondition }.
|
|
38
|
+
* @param dbc See {@link DBC.decPostcondition }.
|
|
39
|
+
*
|
|
40
|
+
* @returns See {@link DBC.decPostcondition }. */
|
|
41
|
+
static POST(type, path = undefined, hint = undefined, dbc = undefined) {
|
|
42
|
+
return DBC.createPOST(DEFINED.checkAlgorithm, [], dbc, path, hint);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* A field-decorator factory using the {@link DEFINED.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
46
|
+
* by the tagged field.
|
|
47
|
+
*
|
|
48
|
+
* @param type See {@link DEFINED.checkAlgorithm }.
|
|
49
|
+
* @param path See {@link DBC.decInvariant }.
|
|
50
|
+
* @param dbc See {@link DBC.decInvariant }.
|
|
51
|
+
*
|
|
52
|
+
* @returns See {@link DBC.decInvariant }. */
|
|
53
|
+
static INVARIANT(type, path = undefined, hint = undefined, dbc = undefined) {
|
|
54
|
+
return DBC.createINVARIANT(DEFINED, [], dbc, path, hint);
|
|
55
|
+
}
|
|
56
|
+
// #endregion Condition checking.
|
|
57
|
+
// #region Referenced Condition checking.
|
|
58
|
+
//
|
|
59
|
+
// For usage in dynamic scenarios (like with AE-DBC).
|
|
60
|
+
//
|
|
61
|
+
/**
|
|
62
|
+
* Invokes the {@link DEFINED.checkAlgorithm } passing the value **toCheck** and the {@link DEFINED.type } .
|
|
63
|
+
*
|
|
64
|
+
* @param toCheck See {@link DEFINED.checkAlgorithm }.
|
|
65
|
+
*
|
|
66
|
+
* @returns See {@link DEFINED.checkAlgorithm}. */
|
|
67
|
+
check(toCheck) {
|
|
68
|
+
return DEFINED.checkAlgorithm(toCheck);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Invokes the {@link DEFINED.checkAlgorithm } passing the value **toCheck** and the {@link DEFINED.type } .
|
|
72
|
+
*
|
|
73
|
+
* @param toCheck See {@link DEFINED.checkAlgorithm }.
|
|
74
|
+
* @param id A {@link string } identifying this {@link INSTANCE } via the {@link DBC.Infringement }-Message.
|
|
75
|
+
*
|
|
76
|
+
* @returns The **CANDIDATE** **toCheck** doesn't fulfill this {@link DEFINED }.
|
|
77
|
+
*
|
|
78
|
+
* @throws A {@link DBC.Infringement } if the **CANDIDATE** **toCheck** does not fulfill this {@link DEFINED }.*/
|
|
79
|
+
static tsCheck(toCheck, hint = undefined, id = undefined, dbc = undefined) {
|
|
80
|
+
const result = DEFINED.checkAlgorithm(toCheck);
|
|
81
|
+
if (result === true) {
|
|
82
|
+
return toCheck;
|
|
83
|
+
}
|
|
84
|
+
DBC.reportTsCheckInfringement(`${id ? `(${id}) ` : ""}${result}${hint ? ` ✨ ${hint} ✨` : ""}`, dbc);
|
|
85
|
+
return toCheck;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/** A check function that receives the current field value and the raw attribute string. */
|
|
2
|
+
export type DOMContractCheck = (value: string, attrValue: string) => boolean | string;
|
|
3
|
+
/**
|
|
4
|
+
* Registers a check function for a `data-xdbc-<key>` attribute.
|
|
5
|
+
* Call this before {@link scanDOM } to make a contract available declaratively.
|
|
6
|
+
*
|
|
7
|
+
* @param key The attribute suffix (e.g. `"type"` → `data-xdbc-type`).
|
|
8
|
+
* @param checkFn Receives the live field value and the raw attribute string.
|
|
9
|
+
* Return `true` when the value is valid, or a `string` message when it is not.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { registerDOMContract } from "xdbc/DBC/DOM";
|
|
14
|
+
* import { MY_CONTRACT } from "./MY_CONTRACT";
|
|
15
|
+
*
|
|
16
|
+
* registerDOMContract("my-contract", (value, attr) =>
|
|
17
|
+
* MY_CONTRACT.checkAlgorithm(value, attr),
|
|
18
|
+
* );
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function registerDOMContract(key: string, checkFn: DOMContractCheck): void;
|
|
22
|
+
/**
|
|
23
|
+
* Scans the given **root** for `<input>` and `<textarea>` elements marked with the
|
|
24
|
+
* `data-xdbc` attribute, and binds XDBC contracts to their `input` events (covering
|
|
25
|
+
* keyboard, paste, IME / mobile on-screen keyboard, voice input, and autofill).
|
|
26
|
+
*
|
|
27
|
+
* ### Supported attributes
|
|
28
|
+
*
|
|
29
|
+
* | Attribute | Example value | Contract |
|
|
30
|
+
* |----------------------------|----------------------------|-----------------|
|
|
31
|
+
* | `data-xdbc` | *(path or empty)* | marker / DBC path |
|
|
32
|
+
* | `data-xdbc-regex` | `^\d*$` | {@link REGEX} |
|
|
33
|
+
* | `data-xdbc-type` | `string\|number` | {@link TYPE} |
|
|
34
|
+
* | `data-xdbc-eq` | `hello` | {@link EQ} |
|
|
35
|
+
* | `data-xdbc-different` | `forbidden` | {@link EQ} (inverted) |
|
|
36
|
+
* | `data-xdbc-defined` | *(no value needed)* | {@link DEFINED} |
|
|
37
|
+
* | `data-xdbc-undefined` | *(no value needed)* | {@link UNDEFINED} |
|
|
38
|
+
* | `data-xdbc-greater` | `5` | {@link COMPARISON} |
|
|
39
|
+
* | `data-xdbc-greater-or-equal` | `5` | {@link COMPARISON} |
|
|
40
|
+
* | `data-xdbc-less` | `100` | {@link COMPARISON} |
|
|
41
|
+
* | `data-xdbc-less-or-equal` | `100` | {@link COMPARISON} |
|
|
42
|
+
* | `data-xdbc-or` | `regex:^\d+$;;type:string` | {@link OR} (fragment syntax) |
|
|
43
|
+
*
|
|
44
|
+
* Use {@link registerDOMContract } to add further contracts at any time.
|
|
45
|
+
*
|
|
46
|
+
* ### OR fragment syntax
|
|
47
|
+
*
|
|
48
|
+
* Fragments are separated by `;;`. Each fragment is `<contract-key>:<value>`, where the
|
|
49
|
+
* split is on the **first** `:` only, so colons inside values (e.g. regex) are safe.
|
|
50
|
+
* The OR passes as long as **at least one** fragment passes.
|
|
51
|
+
*
|
|
52
|
+
* ```html
|
|
53
|
+
* <!-- digits OR exactly "N/A" -->
|
|
54
|
+
* <input data-xdbc data-xdbc-or="regex:^\d+$;;eq:N/A" />
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* ### Behaviour on infringement
|
|
58
|
+
*
|
|
59
|
+
* 1. The element's value is **reverted** to the last accepted state (blocking the invalid input).
|
|
60
|
+
* 2. The configured DBC instance's infringement settings are honoured — `logToConsole`,
|
|
61
|
+
* `onInfringement`, and `throwException` all fire in the usual order. Any throw is caught
|
|
62
|
+
* internally so it cannot propagate out of the DOM event handler.
|
|
63
|
+
*
|
|
64
|
+
* ### IME / composition awareness
|
|
65
|
+
*
|
|
66
|
+
* Validation is suspended during IME composition (e.g. CJK input) and runs once after
|
|
67
|
+
* `compositionend`, so partially composed characters are never incorrectly rejected.
|
|
68
|
+
*
|
|
69
|
+
* @param root Element or Document to scan (default: `document`).
|
|
70
|
+
* @returns A cleanup function that removes all bound event listeners.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```html
|
|
74
|
+
* <input type="text" data-xdbc data-xdbc-regex="^\d*$" />
|
|
75
|
+
* <input type="text" data-xdbc="MyApp.DBC" data-xdbc-type="string" data-xdbc-greater="0" />
|
|
76
|
+
* <input type="text" data-xdbc data-xdbc-or="regex:^\d+$;;eq:N/A" />
|
|
77
|
+
* <textarea data-xdbc data-xdbc-regex="^[\w\s]*$"></textarea>
|
|
78
|
+
* ```
|
|
79
|
+
* ```ts
|
|
80
|
+
* import { scanDOM, registerDOMContract } from "xdbc/DBC/DOM";
|
|
81
|
+
*
|
|
82
|
+
* const cleanup = scanDOM();
|
|
83
|
+
* // later:
|
|
84
|
+
* cleanup();
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare function scanDOM(root?: Element | Document): () => void;
|
package/dist/DBC/DOM.js
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { DBC } from "../DBC";
|
|
2
|
+
import { COMPARISON } from "./COMPARISON";
|
|
3
|
+
import { DEFINED } from "./DEFINED";
|
|
4
|
+
import { EQ } from "./EQ";
|
|
5
|
+
import { REGEX } from "./REGEX";
|
|
6
|
+
import { TYPE } from "./TYPE";
|
|
7
|
+
import { UNDEFINED } from "./UNDEFINED";
|
|
8
|
+
// ─── Contract registry ────────────────────────────────────────────────────────
|
|
9
|
+
/**
|
|
10
|
+
* Maps a `data-xdbc-<key>` attribute suffix to a check function.
|
|
11
|
+
* Populated by {@link registerDOMContract } and the built-in defaults below.
|
|
12
|
+
*/
|
|
13
|
+
const registry = new Map();
|
|
14
|
+
/**
|
|
15
|
+
* Registers a check function for a `data-xdbc-<key>` attribute.
|
|
16
|
+
* Call this before {@link scanDOM } to make a contract available declaratively.
|
|
17
|
+
*
|
|
18
|
+
* @param key The attribute suffix (e.g. `"type"` → `data-xdbc-type`).
|
|
19
|
+
* @param checkFn Receives the live field value and the raw attribute string.
|
|
20
|
+
* Return `true` when the value is valid, or a `string` message when it is not.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { registerDOMContract } from "xdbc/DBC/DOM";
|
|
25
|
+
* import { MY_CONTRACT } from "./MY_CONTRACT";
|
|
26
|
+
*
|
|
27
|
+
* registerDOMContract("my-contract", (value, attr) =>
|
|
28
|
+
* MY_CONTRACT.checkAlgorithm(value, attr),
|
|
29
|
+
* );
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function registerDOMContract(key, checkFn) {
|
|
33
|
+
registry.set(key, checkFn);
|
|
34
|
+
}
|
|
35
|
+
// ─── Built-in registrations ───────────────────────────────────────────────────
|
|
36
|
+
// data-xdbc-regex="^\d*$"
|
|
37
|
+
registerDOMContract("regex", (value, attr) => {
|
|
38
|
+
let rx;
|
|
39
|
+
try {
|
|
40
|
+
rx = new RegExp(attr);
|
|
41
|
+
}
|
|
42
|
+
catch (_a) {
|
|
43
|
+
return `[XDBC] Invalid RegExp pattern: "${attr}"`;
|
|
44
|
+
}
|
|
45
|
+
return REGEX.checkAlgorithm(value, rx);
|
|
46
|
+
});
|
|
47
|
+
// data-xdbc-type="string|number"
|
|
48
|
+
registerDOMContract("type", (value, attr) => TYPE.checkAlgorithm(value, attr));
|
|
49
|
+
// data-xdbc-eq="hello"
|
|
50
|
+
registerDOMContract("eq", (value, attr) => EQ.checkAlgorithm(value, attr, false));
|
|
51
|
+
// data-xdbc-different="forbidden"
|
|
52
|
+
registerDOMContract("different", (value, attr) => EQ.checkAlgorithm(value, attr, true));
|
|
53
|
+
// data-xdbc-defined (attribute presence is enough; value ignored)
|
|
54
|
+
registerDOMContract("defined", (value) => DEFINED.checkAlgorithm(value));
|
|
55
|
+
// data-xdbc-undefined
|
|
56
|
+
registerDOMContract("undefined", (value) => UNDEFINED.checkAlgorithm(value));
|
|
57
|
+
// data-xdbc-greater="5"
|
|
58
|
+
registerDOMContract("greater", (value, attr) => COMPARISON.checkAlgorithm(Number(value), Number(attr), false, false));
|
|
59
|
+
// data-xdbc-greater-or-equal="5"
|
|
60
|
+
registerDOMContract("greater-or-equal", (value, attr) => COMPARISON.checkAlgorithm(Number(value), Number(attr), true, false));
|
|
61
|
+
// data-xdbc-less="100"
|
|
62
|
+
registerDOMContract("less", (value, attr) => COMPARISON.checkAlgorithm(Number(value), Number(attr), false, true));
|
|
63
|
+
// data-xdbc-less-or-equal="100"
|
|
64
|
+
registerDOMContract("less-or-equal", (value, attr) => COMPARISON.checkAlgorithm(Number(value), Number(attr), true, true));
|
|
65
|
+
// data-xdbc-or="regex:^\d+$;;type:string;;eq:42"
|
|
66
|
+
// Fragments are separated by ";;". Each fragment is "<contract-key>:<attr-value>",
|
|
67
|
+
// where the split is on the FIRST ":" only, so colons in the value (e.g. regex) are safe.
|
|
68
|
+
// The OR passes as long as at least one fragment passes.
|
|
69
|
+
registerDOMContract("or", (value, attr) => {
|
|
70
|
+
const fragments = attr.split(";;");
|
|
71
|
+
const messages = [];
|
|
72
|
+
for (const fragment of fragments) {
|
|
73
|
+
const colonIdx = fragment.indexOf(":");
|
|
74
|
+
const key = colonIdx === -1 ? fragment.trim() : fragment.slice(0, colonIdx).trim();
|
|
75
|
+
const fragAttr = colonIdx === -1 ? "" : fragment.slice(colonIdx + 1);
|
|
76
|
+
const checkFn = registry.get(key);
|
|
77
|
+
if (!checkFn) {
|
|
78
|
+
console.warn(`[XDBC] data-xdbc-or: unknown contract key "${key}"`);
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const result = checkFn(value, fragAttr);
|
|
82
|
+
if (result === true)
|
|
83
|
+
return true; // short-circuit on first pass
|
|
84
|
+
if (typeof result === "string")
|
|
85
|
+
messages.push(result);
|
|
86
|
+
}
|
|
87
|
+
return messages.length > 0
|
|
88
|
+
? `Value did not satisfy any of: ${messages.join(" | ")}`
|
|
89
|
+
: true;
|
|
90
|
+
});
|
|
91
|
+
// ─── scanDOM ──────────────────────────────────────────────────────────────────
|
|
92
|
+
/**
|
|
93
|
+
* Scans the given **root** for `<input>` and `<textarea>` elements marked with the
|
|
94
|
+
* `data-xdbc` attribute, and binds XDBC contracts to their `input` events (covering
|
|
95
|
+
* keyboard, paste, IME / mobile on-screen keyboard, voice input, and autofill).
|
|
96
|
+
*
|
|
97
|
+
* ### Supported attributes
|
|
98
|
+
*
|
|
99
|
+
* | Attribute | Example value | Contract |
|
|
100
|
+
* |----------------------------|----------------------------|-----------------|
|
|
101
|
+
* | `data-xdbc` | *(path or empty)* | marker / DBC path |
|
|
102
|
+
* | `data-xdbc-regex` | `^\d*$` | {@link REGEX} |
|
|
103
|
+
* | `data-xdbc-type` | `string\|number` | {@link TYPE} |
|
|
104
|
+
* | `data-xdbc-eq` | `hello` | {@link EQ} |
|
|
105
|
+
* | `data-xdbc-different` | `forbidden` | {@link EQ} (inverted) |
|
|
106
|
+
* | `data-xdbc-defined` | *(no value needed)* | {@link DEFINED} |
|
|
107
|
+
* | `data-xdbc-undefined` | *(no value needed)* | {@link UNDEFINED} |
|
|
108
|
+
* | `data-xdbc-greater` | `5` | {@link COMPARISON} |
|
|
109
|
+
* | `data-xdbc-greater-or-equal` | `5` | {@link COMPARISON} |
|
|
110
|
+
* | `data-xdbc-less` | `100` | {@link COMPARISON} |
|
|
111
|
+
* | `data-xdbc-less-or-equal` | `100` | {@link COMPARISON} |
|
|
112
|
+
* | `data-xdbc-or` | `regex:^\d+$;;type:string` | {@link OR} (fragment syntax) |
|
|
113
|
+
*
|
|
114
|
+
* Use {@link registerDOMContract } to add further contracts at any time.
|
|
115
|
+
*
|
|
116
|
+
* ### OR fragment syntax
|
|
117
|
+
*
|
|
118
|
+
* Fragments are separated by `;;`. Each fragment is `<contract-key>:<value>`, where the
|
|
119
|
+
* split is on the **first** `:` only, so colons inside values (e.g. regex) are safe.
|
|
120
|
+
* The OR passes as long as **at least one** fragment passes.
|
|
121
|
+
*
|
|
122
|
+
* ```html
|
|
123
|
+
* <!-- digits OR exactly "N/A" -->
|
|
124
|
+
* <input data-xdbc data-xdbc-or="regex:^\d+$;;eq:N/A" />
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* ### Behaviour on infringement
|
|
128
|
+
*
|
|
129
|
+
* 1. The element's value is **reverted** to the last accepted state (blocking the invalid input).
|
|
130
|
+
* 2. The configured DBC instance's infringement settings are honoured — `logToConsole`,
|
|
131
|
+
* `onInfringement`, and `throwException` all fire in the usual order. Any throw is caught
|
|
132
|
+
* internally so it cannot propagate out of the DOM event handler.
|
|
133
|
+
*
|
|
134
|
+
* ### IME / composition awareness
|
|
135
|
+
*
|
|
136
|
+
* Validation is suspended during IME composition (e.g. CJK input) and runs once after
|
|
137
|
+
* `compositionend`, so partially composed characters are never incorrectly rejected.
|
|
138
|
+
*
|
|
139
|
+
* @param root Element or Document to scan (default: `document`).
|
|
140
|
+
* @returns A cleanup function that removes all bound event listeners.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```html
|
|
144
|
+
* <input type="text" data-xdbc data-xdbc-regex="^\d*$" />
|
|
145
|
+
* <input type="text" data-xdbc="MyApp.DBC" data-xdbc-type="string" data-xdbc-greater="0" />
|
|
146
|
+
* <input type="text" data-xdbc data-xdbc-or="regex:^\d+$;;eq:N/A" />
|
|
147
|
+
* <textarea data-xdbc data-xdbc-regex="^[\w\s]*$"></textarea>
|
|
148
|
+
* ```
|
|
149
|
+
* ```ts
|
|
150
|
+
* import { scanDOM, registerDOMContract } from "xdbc/DBC/DOM";
|
|
151
|
+
*
|
|
152
|
+
* const cleanup = scanDOM();
|
|
153
|
+
* // later:
|
|
154
|
+
* cleanup();
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
export function scanDOM(root = document) {
|
|
158
|
+
var _a;
|
|
159
|
+
const bound = [];
|
|
160
|
+
const elements = Array.from(root.querySelectorAll("[data-xdbc]"));
|
|
161
|
+
for (const el of elements) {
|
|
162
|
+
const dbcPath = el.dataset.xdbc || "WaXCode.DBC";
|
|
163
|
+
// Collect every registered contract that has a corresponding attribute on this element.
|
|
164
|
+
const checks = [];
|
|
165
|
+
for (const [key, checkFn] of registry) {
|
|
166
|
+
// dataset converts "xdbc-greater-or-equal" → "xdbcGreaterOrEqual" via camelCase.
|
|
167
|
+
// Build the camelCase key from the registry key.
|
|
168
|
+
const datasetKey = `xdbc${key
|
|
169
|
+
.split("-")
|
|
170
|
+
.map((s) => s.charAt(0).toUpperCase() + s.slice(1))
|
|
171
|
+
.join("")}`;
|
|
172
|
+
if (datasetKey in el.dataset) {
|
|
173
|
+
checks.push({ checkFn, attrValue: (_a = el.dataset[datasetKey]) !== null && _a !== void 0 ? _a : "" });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (checks.length === 0)
|
|
177
|
+
continue;
|
|
178
|
+
let lastValid = el.value;
|
|
179
|
+
let composing = false;
|
|
180
|
+
const inputListener = () => {
|
|
181
|
+
if (composing)
|
|
182
|
+
return;
|
|
183
|
+
const value = el.value;
|
|
184
|
+
for (const { checkFn, attrValue } of checks) {
|
|
185
|
+
const result = checkFn(value, attrValue);
|
|
186
|
+
if (typeof result === "string") {
|
|
187
|
+
el.value = lastValid;
|
|
188
|
+
try {
|
|
189
|
+
DBC.getRegistered(dbcPath).reportParameterInfringement(result, el, undefined, el.name || el.id || "input", 0, value);
|
|
190
|
+
}
|
|
191
|
+
catch (_a) {
|
|
192
|
+
// swallowed — throwException must not propagate out of a DOM event handler
|
|
193
|
+
}
|
|
194
|
+
return; // stop checking further contracts once one fails
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
lastValid = value;
|
|
198
|
+
};
|
|
199
|
+
const compositionStartListener = () => {
|
|
200
|
+
composing = true;
|
|
201
|
+
};
|
|
202
|
+
const compositionEndListener = () => {
|
|
203
|
+
composing = false;
|
|
204
|
+
inputListener();
|
|
205
|
+
};
|
|
206
|
+
el.addEventListener("input", inputListener);
|
|
207
|
+
el.addEventListener("compositionstart", compositionStartListener);
|
|
208
|
+
el.addEventListener("compositionend", compositionEndListener);
|
|
209
|
+
bound.push({
|
|
210
|
+
element: el,
|
|
211
|
+
inputListener,
|
|
212
|
+
compositionStartListener,
|
|
213
|
+
compositionEndListener,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
return () => {
|
|
217
|
+
for (const { element, inputListener, compositionStartListener, compositionEndListener, } of bound) {
|
|
218
|
+
element.removeEventListener("input", inputListener);
|
|
219
|
+
element.removeEventListener("compositionstart", compositionStartListener);
|
|
220
|
+
element.removeEventListener("compositionend", compositionEndListener);
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
}
|