@jinntec/fore 2.1.1 → 2.3.0
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/README.md +2 -2
- package/dist/fore-dev.js +2 -2
- package/dist/fore-dev.js.map +1 -1
- package/dist/fore.js +2 -2
- package/dist/fore.js.map +1 -1
- package/index.js +4 -2
- package/package.json +10 -38
- package/resources/fore.css +263 -262
- package/resources/vars.css +8 -0
- package/src/DependencyNotifyingDomFacade.js +1 -0
- package/src/ForeElementMixin.js +243 -228
- package/src/actions/abstract-action.js +407 -398
- package/src/actions/fx-action.js +6 -6
- package/src/actions/fx-append.js +1 -1
- package/src/actions/fx-call.js +63 -62
- package/src/actions/fx-confirm.js +11 -11
- package/src/actions/fx-construct-done.js +4 -4
- package/src/actions/fx-copy.js +36 -36
- package/src/actions/fx-delete.js +77 -79
- package/src/actions/fx-dispatch.js +14 -14
- package/src/actions/fx-hide.js +15 -15
- package/src/actions/fx-insert.js +9 -12
- package/src/actions/fx-insertchild.js +88 -0
- package/src/actions/fx-load.js +188 -185
- package/src/actions/fx-message.js +18 -19
- package/src/actions/fx-refresh.js +10 -10
- package/src/actions/fx-reload.js +16 -14
- package/src/actions/fx-replace.js +0 -1
- package/src/actions/fx-reset.js +31 -31
- package/src/actions/fx-send.js +59 -52
- package/src/actions/fx-setattribute.js +48 -49
- package/src/actions/fx-setfocus.js +54 -58
- package/src/actions/fx-setvalue.js +85 -81
- package/src/actions/fx-show.js +11 -11
- package/src/actions/fx-toggle.js +2 -2
- package/src/actions/fx-toggleboolean.js +38 -39
- package/src/actions/fx-unmodified.js +27 -0
- package/src/actions/fx-update.js +6 -6
- package/src/dep_graph.js +1 -1
- package/src/drawdown.js +23 -30
- package/src/events.js +19 -19
- package/src/fore.js +143 -125
- package/src/functions/common-function.js +24 -25
- package/src/functions/fx-function.js +6 -99
- package/src/functions/fx-functionlib.js +56 -0
- package/src/functions/registerFunction.js +112 -0
- package/src/fx-bind.js +19 -24
- package/src/fx-connection.js +226 -0
- package/src/fx-fore.js +844 -815
- package/src/fx-header.js +4 -4
- package/src/fx-instance.js +25 -29
- package/src/fx-model.js +405 -380
- package/src/fx-submission.js +399 -397
- package/src/fx-var.js +13 -12
- package/src/getInScopeContext.js +102 -89
- package/src/json-util.js +24 -24
- package/src/lab/fore-component.js +48 -52
- package/src/lab/instance-inspector.js +13 -16
- package/src/modelitem.js +48 -10
- package/src/relevance.js +12 -16
- package/src/tools/adi.js +858 -812
- package/src/tools/fx-action-log.js +377 -295
- package/src/tools/fx-devtools.js +210 -210
- package/src/tools/fx-dom-inspector.js +123 -122
- package/src/tools/fx-json-instance.js +262 -253
- package/src/tools/fx-log-item.js +6 -11
- package/src/tools/fx-log-settings.js +358 -301
- package/src/tools/fx-minimap.js +186 -177
- package/src/tools/helpers.js +1 -1
- package/src/ui/abstract-control.js +73 -53
- package/src/ui/fx-case.js +59 -7
- package/src/ui/fx-container.js +13 -14
- package/src/ui/fx-control.js +572 -538
- package/src/ui/fx-dialog.js +3 -3
- package/src/ui/fx-droptarget.js +3 -4
- package/src/ui/fx-group.js +4 -2
- package/src/ui/fx-hint.js +3 -0
- package/src/ui/fx-inspector.js +5 -5
- package/src/ui/fx-items.js +11 -11
- package/src/ui/fx-output.js +10 -12
- package/src/ui/fx-repeat-attributes.js +23 -27
- package/src/ui/fx-repeat.js +347 -344
- package/src/ui/fx-repeatitem.js +75 -68
- package/src/ui/fx-switch.js +39 -14
- package/src/ui/fx-trigger.js +4 -4
- package/src/withDraggability.js +193 -191
- package/src/xpath-evaluation.js +969 -958
- package/src/xpath-util.js +161 -134
package/src/xpath-util.js
CHANGED
|
@@ -1,160 +1,187 @@
|
|
|
1
1
|
import * as fx from 'fontoxpath';
|
|
2
2
|
|
|
3
3
|
export class XPathUtil {
|
|
4
|
+
/**
|
|
5
|
+
* Alternative to `contains` that respects shadowroots
|
|
6
|
+
* @param {Node} ancestor
|
|
7
|
+
* @param {Node} descendant
|
|
8
|
+
* @returns {boolean}
|
|
9
|
+
*/
|
|
10
|
+
static contains(ancestor, descendant) {
|
|
11
|
+
while (descendant) {
|
|
12
|
+
if (descendant === ancestor) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
4
15
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return true;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (descendant.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
|
15
|
-
// We are passing a shadow root boundary
|
|
16
|
-
descendant = descendant.host;
|
|
17
|
-
} else {
|
|
18
|
-
descendant = descendant.parentNode;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
return false;
|
|
16
|
+
if (descendant.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
|
17
|
+
// We are passing a shadow root boundary
|
|
18
|
+
descendant = descendant.host;
|
|
19
|
+
} else {
|
|
20
|
+
descendant = descendant.parentNode;
|
|
21
|
+
}
|
|
22
22
|
}
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Alternative to `closest` that respects subcontrol boundaries
|
|
28
|
+
*
|
|
29
|
+
* @param {string} querySelector
|
|
30
|
+
* @param {Node} start
|
|
31
|
+
* @returns {HTMLElement}
|
|
32
|
+
*/
|
|
33
|
+
static getClosest(querySelector, start) {
|
|
34
|
+
while ((start && !start.matches) || !start.matches(querySelector)) {
|
|
35
|
+
if (start.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
|
36
|
+
// We are passing a shadow root boundary
|
|
37
|
+
start = start.host;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (start.nodeType === Node.ATTRIBUTE_NODE) {
|
|
41
|
+
// We are passing an attribute
|
|
42
|
+
start = start.ownerElement;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (start.nodeType === Node.TEXT_NODE) {
|
|
46
|
+
start = start.parentNode;
|
|
47
|
+
}
|
|
48
|
+
if (start.matches('fx-fore')) {
|
|
49
|
+
// Subform reached. Bail out
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
start = start.parentNode;
|
|
53
|
+
if (!start) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
52
56
|
}
|
|
57
|
+
return start;
|
|
58
|
+
}
|
|
53
59
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
/**
|
|
61
|
+
* returns next bound element upwards in tree
|
|
62
|
+
* @param {Node} start where to start the search
|
|
63
|
+
* @returns {*|null}
|
|
64
|
+
*/
|
|
65
|
+
static getParentBindingElement(start) {
|
|
66
|
+
/* if (start.parentNode.host) {
|
|
61
67
|
const { host } = start.parentNode;
|
|
62
68
|
if (host.hasAttribute('ref')) {
|
|
63
69
|
return host;
|
|
64
70
|
}
|
|
65
71
|
} else */
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
return XPathUtil.getParentBindingElement(start.parentNode);
|
|
73
|
-
*/
|
|
74
|
-
|
|
75
|
-
return start.parentNode.closest('[ref]');
|
|
76
|
-
}
|
|
77
|
-
return null;
|
|
72
|
+
if (
|
|
73
|
+
start.parentNode &&
|
|
74
|
+
(start.parentNode.nodeType !== Node.DOCUMENT_NODE ||
|
|
75
|
+
start.parentNode.nodeType !== Node.DOCUMENT_FRAGMENT_NODE)
|
|
76
|
+
) {
|
|
77
|
+
return start.parentNode.closest('[ref]');
|
|
78
78
|
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
79
81
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Checks whether the specified path expression is an absolute path.
|
|
84
|
+
*
|
|
85
|
+
* @param {string} path the path expression.
|
|
86
|
+
* @returns {boolean} <code>true</code> if specified path expression is an absolute
|
|
87
|
+
* path, otherwise <code>false</code>.
|
|
88
|
+
*/
|
|
89
|
+
static isAbsolutePath(path) {
|
|
90
|
+
return path != null && (path.startsWith('/') || path.startsWith('instance('));
|
|
91
|
+
}
|
|
90
92
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
93
|
+
/**
|
|
94
|
+
* @param {string} ref
|
|
95
|
+
*/
|
|
96
|
+
static isSelfReference(ref) {
|
|
97
|
+
return ref === '.' || ref === './text()' || ref === 'text()' || ref === '' || ref === null;
|
|
98
|
+
}
|
|
94
99
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
if (ref.startsWith('instance()')) {
|
|
109
|
-
return 'default';
|
|
110
|
-
}
|
|
111
|
-
if (ref.startsWith('instance(')) {
|
|
112
|
-
const result = ref.substring(ref.indexOf('(') + 1);
|
|
113
|
-
return result.substring(1, result.indexOf(')') - 1);
|
|
114
|
-
}
|
|
115
|
-
return null;
|
|
100
|
+
/**
|
|
101
|
+
* returns the instance id from a complete XPath using `instance()` function.
|
|
102
|
+
*
|
|
103
|
+
* Will return 'default' in case no ref is given at all or the `instance()` function is called without arg.
|
|
104
|
+
*
|
|
105
|
+
* Otherwise instance id is extracted from function and returned. If all fails null is returned.
|
|
106
|
+
* @param {string} ref
|
|
107
|
+
* @returns {string}
|
|
108
|
+
*/
|
|
109
|
+
static getInstanceId(ref) {
|
|
110
|
+
if (!ref) {
|
|
111
|
+
return 'default';
|
|
116
112
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
let instanceId = XPathUtil.getInstanceId(path);
|
|
120
|
-
if (!instanceId) {
|
|
121
|
-
instanceId = XPathUtil.getInstanceId(boundElement.getAttribute('ref'));
|
|
122
|
-
}
|
|
123
|
-
if (instanceId !== null) {
|
|
124
|
-
return instanceId;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const parentBinding = XPathUtil.getParentBindingElement(boundElement);
|
|
128
|
-
if (parentBinding) {
|
|
129
|
-
return this.resolveInstance(parentBinding, path);
|
|
130
|
-
}
|
|
131
|
-
return 'default';
|
|
113
|
+
if (ref.startsWith('instance()')) {
|
|
114
|
+
return 'default';
|
|
132
115
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
// Path is like `$default/x[1]/y[1]`
|
|
137
|
-
const shortened = XPathUtil.shortenPath(path);
|
|
138
|
-
return shortened.startsWith('/') ? `${shortened}` : `/${shortened}`;
|
|
116
|
+
if (ref.startsWith('instance(')) {
|
|
117
|
+
const result = ref.substring(ref.indexOf('(') + 1);
|
|
118
|
+
return result.substring(1, result.indexOf(')') - 1);
|
|
139
119
|
}
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
140
122
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
123
|
+
/**
|
|
124
|
+
* @param {HTMLElement} boundElement
|
|
125
|
+
* @param {string} path
|
|
126
|
+
* @returns {string}
|
|
127
|
+
*/
|
|
128
|
+
static resolveInstance(boundElement, path) {
|
|
129
|
+
let instanceId = XPathUtil.getInstanceId(path);
|
|
130
|
+
if (!instanceId) {
|
|
131
|
+
instanceId = XPathUtil.getInstanceId(boundElement.getAttribute('ref'));
|
|
146
132
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const tmp = path.replaceAll(/(Q{(.*?)\})/g, '');
|
|
150
|
-
// cut off leading slash
|
|
151
|
-
const tmp1 = tmp.substring(1, tmp.length);
|
|
152
|
-
// ### cut-off root node ref
|
|
153
|
-
return tmp1.substring(tmp1.indexOf('/'), tmp.length);
|
|
133
|
+
if (instanceId !== null) {
|
|
134
|
+
return instanceId;
|
|
154
135
|
}
|
|
155
136
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
137
|
+
const parentBinding = XPathUtil.getParentBindingElement(boundElement);
|
|
138
|
+
if (parentBinding) {
|
|
139
|
+
return this.resolveInstance(parentBinding, path);
|
|
159
140
|
}
|
|
141
|
+
return 'default';
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* @param {Node} node
|
|
146
|
+
* @returns string
|
|
147
|
+
*/
|
|
148
|
+
static getDocPath(node) {
|
|
149
|
+
const path = fx.evaluateXPathToString('path()', node);
|
|
150
|
+
// Path is like `$default/x[1]/y[1]`
|
|
151
|
+
const shortened = XPathUtil.shortenPath(path);
|
|
152
|
+
return shortened.startsWith('/') ? `${shortened}` : `/${shortened}`;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @param {Node} node
|
|
157
|
+
* @param {string} instanceId
|
|
158
|
+
* @returns string
|
|
159
|
+
*/
|
|
160
|
+
static getPath(node, instanceId) {
|
|
161
|
+
const path = fx.evaluateXPathToString('path()', node);
|
|
162
|
+
// Path is like `$default/x[1]/y[1]`
|
|
163
|
+
const shortened = XPathUtil.shortenPath(path);
|
|
164
|
+
return shortened.startsWith('/') ? `$${instanceId}${shortened}` : `$${instanceId}/${shortened}`;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @param {string} path
|
|
169
|
+
* @returns string
|
|
170
|
+
*/
|
|
171
|
+
static shortenPath(path) {
|
|
172
|
+
const tmp = path.replaceAll(/(Q{(.*?)\})/g, '');
|
|
173
|
+
// cut off leading slash
|
|
174
|
+
const tmp1 = tmp.substring(1, tmp.length);
|
|
175
|
+
// ### cut-off root node ref
|
|
176
|
+
return tmp1.substring(tmp1.indexOf('/'), tmp.length);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* @param {string} dep
|
|
181
|
+
* @returns {string}
|
|
182
|
+
*/
|
|
183
|
+
static getBasePath(dep) {
|
|
184
|
+
const split = dep.split(':');
|
|
185
|
+
return split[0];
|
|
186
|
+
}
|
|
160
187
|
}
|