@jinntec/fore 2.6.0 → 2.7.1
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/fore-dev.js +4472 -2645
- package/dist/fore.js +4417 -2622
- package/index.js +2 -0
- package/package.json +10 -4
- package/resources/fore.css +2 -6
- package/src/DependencyNotifyingDomFacade.js +27 -21
- package/src/ForeElementMixin.js +282 -277
- package/src/actions/abstract-action.js +7 -12
- package/src/actions/fx-append.js +23 -2
- package/src/actions/fx-call.js +2 -2
- package/src/actions/fx-delete.js +54 -29
- package/src/actions/fx-insert.js +23 -15
- package/src/actions/fx-load.js +2 -2
- package/src/actions/fx-refresh.js +15 -5
- package/src/actions/fx-replace.js +18 -3
- package/src/actions/fx-reset.js +6 -0
- package/src/actions/fx-send.js +10 -7
- package/src/actions/fx-setattribute.js +12 -0
- package/src/actions/fx-setfocus.js +11 -8
- package/src/actions/fx-setvalue.js +93 -93
- package/src/actions/fx-toggle.js +1 -1
- package/src/extract-predicate-deps.js +57 -0
- package/src/extractPredicateDependencies.js +36 -0
- package/src/fore.js +41 -16
- package/src/fx-bind.js +128 -23
- package/src/fx-connection.js +24 -7
- package/src/fx-fore.js +506 -259
- package/src/fx-instance.js +9 -11
- package/src/fx-model.js +154 -65
- package/src/fx-submission.js +19 -30
- package/src/fx-var.js +5 -0
- package/src/getInScopeContext.js +7 -8
- package/src/modelitem.js +247 -112
- package/src/tools/fx-action-log.js +21 -19
- package/src/tools/fx-log-settings.js +4 -2
- package/src/ui/TemplateExpression.js +12 -0
- package/src/ui/UIElement.js +125 -10
- package/src/ui/abstract-control.js +5 -0
- package/src/ui/fx-case.js +15 -3
- package/src/ui/fx-container.js +5 -0
- package/src/ui/fx-control-menu.js +23 -14
- package/src/ui/fx-control.js +55 -15
- package/src/ui/fx-items.js +10 -4
- package/src/ui/fx-repeat-attributes.js +111 -35
- package/src/ui/fx-repeat.js +332 -85
- package/src/ui/fx-repeatitem.js +23 -20
- package/src/ui/fx-switch.js +5 -3
- package/src/ui/fx-upload.js +36 -40
- package/src/ui/repeat-base.js +532 -0
- package/src/withDraggability.js +8 -4
- package/src/xpath-evaluation.js +26 -8
- package/src/xpath-path.js +79 -0
- package/src/xpath-util.js +357 -289
package/src/modelitem.js
CHANGED
|
@@ -1,132 +1,267 @@
|
|
|
1
|
+
import { evaluateXPath, evaluateXPathToBoolean, evaluateXPathToNodes } from './xpath-evaluation';
|
|
2
|
+
import { XPathUtil } from './xpath-util';
|
|
3
|
+
import getInScopeContext from './getInScopeContext';
|
|
4
|
+
|
|
1
5
|
/**
|
|
2
6
|
* Class for holding ModelItem facets.
|
|
3
7
|
*
|
|
4
|
-
* A ModelItem annotates nodes that are referred by
|
|
5
|
-
*
|
|
8
|
+
* A ModelItem annotates nodes that are referred by an fx-bind element with facets for calculation and validation.
|
|
6
9
|
* Each bound node in an instance has exactly one ModelItem associated with it.
|
|
10
|
+
*
|
|
11
|
+
* This refactored version includes observable mechanics and scoped XPath evaluation support.
|
|
7
12
|
*/
|
|
8
13
|
export class ModelItem {
|
|
14
|
+
static READONLY_DEFAULT = false;
|
|
15
|
+
static REQUIRED_DEFAULT = false;
|
|
16
|
+
static RELEVANT_DEFAULT = true;
|
|
17
|
+
static CONSTRAINT_DEFAULT = true;
|
|
18
|
+
static TYPE_DEFAULT = 'xs:string';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {string} path - Calculated normalized path expression linking to data
|
|
22
|
+
* @param {string} ref - Relative binding expression
|
|
23
|
+
* @param {Node} node - The node the 'ref' expression is referring to
|
|
24
|
+
* @param {import('./fx-bind').FxBind} bind - The fx-bind element having created this ModelItem
|
|
25
|
+
* @param {string} instance - The fx-instance id having created this ModelItem
|
|
26
|
+
* @param {import('./fx-fore').FxFore} fore - The fx-fore element this ModelItem belongs to
|
|
27
|
+
*/
|
|
28
|
+
constructor(path, ref, node, bind, instance, fore) {
|
|
29
|
+
this.path = path;
|
|
30
|
+
this.ref = ref;
|
|
31
|
+
this.readonly = ModelItem.READONLY_DEFAULT;
|
|
32
|
+
this.relevant = ModelItem.RELEVANT_DEFAULT;
|
|
33
|
+
this.required = ModelItem.REQUIRED_DEFAULT;
|
|
34
|
+
this.constraint = ModelItem.CONSTRAINT_DEFAULT;
|
|
35
|
+
this.type = ModelItem.TYPE_DEFAULT;
|
|
36
|
+
this.node = node;
|
|
37
|
+
this.bind = bind;
|
|
38
|
+
this.instanceId = instance;
|
|
39
|
+
this.fore = fore;
|
|
40
|
+
this.changed = false;
|
|
41
|
+
|
|
42
|
+
// console.log('[ModelItem] created:', this.path);
|
|
43
|
+
|
|
44
|
+
/** @type {import('./ui/fx-alert').FxAlert[]} */
|
|
45
|
+
this.alerts = [];
|
|
46
|
+
|
|
47
|
+
/** @type {import('./ui/abstract-control').default[]} */
|
|
48
|
+
// For backward compatibility
|
|
49
|
+
this.boundControls = [];
|
|
50
|
+
|
|
51
|
+
// Observable mechanics
|
|
9
52
|
/**
|
|
10
|
-
*
|
|
11
|
-
* @param {string} path calculated normalized path expression linking to data
|
|
12
|
-
* @param {string} ref relative binding expression
|
|
13
|
-
* @param {boolean} readonly - boolean to signal readonly/readwrite state
|
|
14
|
-
* @param {boolean} relevant - boolean to signal relevant/non-relevant state
|
|
15
|
-
* @param {boolean} required - boolean to signal required/optional state
|
|
16
|
-
* @param {boolean} constraint - boolean boolean to signal valid/invalid state
|
|
17
|
-
* @param {string} type - string expression to set a datatype
|
|
18
|
-
* @param {Node} node - the node the 'ref' expression is referring to
|
|
19
|
-
* @param {import('./fx-bind').FxBind} bind - the fx-bind element having created this modelItem
|
|
20
|
-
* @param {string} instance - the fx-instance id having created this modelItem
|
|
53
|
+
* @type {Set<import('./ui/UIElement').UIElement>}
|
|
21
54
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
55
|
+
this.observers = new Set();
|
|
56
|
+
this.dependencies = new Set();
|
|
57
|
+
this.stateExpressions = {}; // e.g. { required: { expr: '../x', type: 'boolean' } }
|
|
58
|
+
this.state = {}; // evaluated expression results
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get value() {
|
|
62
|
+
if (!this.node) return null;
|
|
63
|
+
if (!this.node.nodeType) return this.node;
|
|
64
|
+
if (this.node.nodeType === Node.ATTRIBUTE_NODE) {
|
|
65
|
+
return this.node.nodeValue;
|
|
66
|
+
}
|
|
67
|
+
return this.node.textContent;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
set value(newVal) {
|
|
71
|
+
if (!this.node) return;
|
|
72
|
+
const oldVal = this.value;
|
|
73
|
+
|
|
74
|
+
if (newVal?.nodeType === Node.DOCUMENT_NODE) {
|
|
75
|
+
this.node.replaceWith(newVal.firstElementChild);
|
|
76
|
+
this.node = newVal.firstElementChild;
|
|
77
|
+
} else if (newVal?.nodeType === Node.ELEMENT_NODE) {
|
|
78
|
+
this.node.replaceWith(newVal);
|
|
79
|
+
this.node = newVal;
|
|
80
|
+
} else if (this.node.nodeType === Node.ATTRIBUTE_NODE) {
|
|
81
|
+
this.node.nodeValue = newVal;
|
|
82
|
+
} else {
|
|
83
|
+
this.node.textContent = newVal;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (this.value !== oldVal) {
|
|
87
|
+
this.notify();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Add an observer to this ModelItem
|
|
93
|
+
* @param {Object} observer - The observer to add
|
|
94
|
+
*/
|
|
95
|
+
addObserver(observer) {
|
|
96
|
+
// console.log('[ModelItem] adding observer:', observer);
|
|
97
|
+
this.observers.add(observer);
|
|
98
|
+
|
|
99
|
+
// For backward compatibility with boundControls
|
|
100
|
+
if (
|
|
101
|
+
observer.nodeName &&
|
|
102
|
+
(observer.nodeName.startsWith('FX-') || observer.nodeName.startsWith('UI-')) &&
|
|
103
|
+
!this.boundControls.includes(observer)
|
|
33
104
|
) {
|
|
34
|
-
|
|
35
|
-
* @type {string}
|
|
36
|
-
*/
|
|
37
|
-
this.path = path;
|
|
38
|
-
/**
|
|
39
|
-
* @type {string}
|
|
40
|
-
*/
|
|
41
|
-
this.ref = ref;
|
|
42
|
-
/**
|
|
43
|
-
* @type {boolean}
|
|
44
|
-
*/
|
|
45
|
-
this.constraint = constraint;
|
|
46
|
-
/**
|
|
47
|
-
* @type {boolean}
|
|
48
|
-
*/
|
|
49
|
-
this.readonly = readonly;
|
|
50
|
-
/**
|
|
51
|
-
* @type {boolean}
|
|
52
|
-
*/
|
|
53
|
-
this.relevant = relevant;
|
|
54
|
-
/**
|
|
55
|
-
* @type {boolean}
|
|
56
|
-
*/
|
|
57
|
-
this.required = required;
|
|
58
|
-
/**
|
|
59
|
-
* @type {string}
|
|
60
|
-
*/
|
|
61
|
-
this.type = type;
|
|
62
|
-
/**
|
|
63
|
-
* @type {Node}
|
|
64
|
-
*/
|
|
65
|
-
this.node = node;
|
|
66
|
-
/**
|
|
67
|
-
* @type {import('./fx-bind').FxBind}
|
|
68
|
-
*/
|
|
69
|
-
this.bind = bind;
|
|
70
|
-
this.changed = false;
|
|
71
|
-
/**
|
|
72
|
-
* @type {import('./ui/fx-alert').FxAlert[]}
|
|
73
|
-
*/
|
|
74
|
-
this.alerts = [];
|
|
75
|
-
/**
|
|
76
|
-
* @type {import('./ui/abstract-control').default[]}
|
|
77
|
-
*/
|
|
78
|
-
this.boundControls = [];
|
|
79
|
-
// this.value = this._getValue();
|
|
80
|
-
this.instanceId = instance;
|
|
105
|
+
this.boundControls.push(observer);
|
|
81
106
|
}
|
|
107
|
+
}
|
|
82
108
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Remove an observer from this ModelItem
|
|
111
|
+
* @param {Object} observer - The observer to remove
|
|
112
|
+
*/
|
|
113
|
+
removeObserver(observer) {
|
|
114
|
+
this.observers.delete(observer);
|
|
115
|
+
|
|
116
|
+
// For backward compatibility with boundControls
|
|
117
|
+
const index = this.boundControls.indexOf(observer);
|
|
118
|
+
if (index !== -1) {
|
|
119
|
+
this.boundControls.splice(index, 1);
|
|
86
120
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Notify all observers that this ModelItem has changed
|
|
125
|
+
*/
|
|
126
|
+
notify() {
|
|
127
|
+
// Only log in debug mode or reduce verbosity to prevent console flooding
|
|
128
|
+
// console.log('[ModelItem] notifying observers for path:', this);
|
|
129
|
+
|
|
130
|
+
// Add to batched notifications. TODO: is the else needed?
|
|
131
|
+
if (this.fore) {
|
|
132
|
+
this.fore.addToBatchedNotifications(this);
|
|
133
|
+
} else {
|
|
134
|
+
// Otherwise, notify observers immediately
|
|
135
|
+
if (this.observers) {
|
|
136
|
+
this.observers.forEach(observer => {
|
|
137
|
+
if (typeof observer.update === 'function') {
|
|
138
|
+
observer.update(this);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
99
142
|
}
|
|
143
|
+
}
|
|
100
144
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
this.node.replaceWith(newVal.firstElementChild);
|
|
110
|
-
this.node = newVal.firstElementChild;
|
|
111
|
-
// this.node.appendChild(newVal.firstElementChild);
|
|
112
|
-
} else if (newVal.nodeType === Node.ELEMENT_NODE) {
|
|
113
|
-
this.node.replaceWith(newVal);
|
|
114
|
-
this.node = newVal;
|
|
115
|
-
// this.node.appendChild(newVal);
|
|
116
|
-
} else if (this.node.nodeType === Node.ATTRIBUTE_NODE) {
|
|
117
|
-
this.node.nodeValue = newVal;
|
|
118
|
-
} else {
|
|
119
|
-
this.node.textContent = newVal;
|
|
120
|
-
}
|
|
145
|
+
update() {
|
|
146
|
+
console.log('[ModelItem] update:', this);
|
|
147
|
+
this.evaluateStateExpressions();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
addAlert(alert) {
|
|
151
|
+
if (!this.alerts.includes(alert)) {
|
|
152
|
+
this.alerts.push(alert);
|
|
121
153
|
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
cleanAlerts() {
|
|
157
|
+
this.alerts = [];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Attach dynamic expressions (fx-bind style) to this model item.
|
|
162
|
+
* @param {{ [key: string]: { expr: string, type: 'boolean' | 'value' } }} expressionMap
|
|
163
|
+
*/
|
|
164
|
+
setStateExpressions(expressionMap) {
|
|
165
|
+
this.stateExpressions = expressionMap;
|
|
166
|
+
this.resolveDependencies();
|
|
167
|
+
this.evaluateStateExpressions();
|
|
168
|
+
}
|
|
122
169
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
170
|
+
/**
|
|
171
|
+
* Register dependencies based on expression references.
|
|
172
|
+
*/
|
|
173
|
+
resolveDependencies() {
|
|
174
|
+
this.dependencies.forEach(dep => dep.removeObserver(this));
|
|
175
|
+
this.dependencies.clear();
|
|
176
|
+
|
|
177
|
+
const refs = Object.values(this.stateExpressions).flatMap(({ expr }) => this.extractRefs(expr));
|
|
178
|
+
|
|
179
|
+
for (const ref of refs) {
|
|
180
|
+
const dep = this.bind?.resolveModelItem?.(ref);
|
|
181
|
+
if (dep) {
|
|
182
|
+
dep.addObserver(this);
|
|
183
|
+
this.dependencies.add(dep);
|
|
184
|
+
}
|
|
127
185
|
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Extract ref strings like '../required' => 'required'
|
|
190
|
+
* @param {string} expr
|
|
191
|
+
* @returns {string[]}
|
|
192
|
+
*/
|
|
193
|
+
extractRefs(expr) {
|
|
194
|
+
const matches = expr.match(/\.\.\/\w+/g);
|
|
195
|
+
return matches ? matches.map(s => s.replace('../', '')) : [];
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Evaluate all state expressions attached to this model item.
|
|
200
|
+
*/
|
|
201
|
+
evaluateStateExpressions() {
|
|
202
|
+
let changed = false;
|
|
203
|
+
|
|
204
|
+
for (const [key, { expr, type }] of Object.entries(this.stateExpressions)) {
|
|
205
|
+
const result = this.evaluateExpression(expr, type);
|
|
206
|
+
if (this.state[key] !== result) {
|
|
207
|
+
this.state[key] = result;
|
|
208
|
+
changed = true;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (changed) this.notify();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Evaluate expression in in-scope context using XPath.
|
|
217
|
+
* @param {string} expr
|
|
218
|
+
* @param {'boolean' | 'value'} type
|
|
219
|
+
* @returns {*}
|
|
220
|
+
*/
|
|
221
|
+
evaluateExpression(expr, type = 'boolean') {
|
|
222
|
+
const contextNodes = this._evalInContext();
|
|
128
223
|
|
|
129
|
-
|
|
130
|
-
|
|
224
|
+
if (!contextNodes || contextNodes.length === 0) {
|
|
225
|
+
return type === 'boolean' ? false : null;
|
|
131
226
|
}
|
|
227
|
+
|
|
228
|
+
try {
|
|
229
|
+
if (type === 'boolean') {
|
|
230
|
+
return contextNodes.some(node => evaluateXPathToBoolean(expr, node, this));
|
|
231
|
+
} else if (type === 'value') {
|
|
232
|
+
return evaluateXPath(expr, contextNodes[0], this);
|
|
233
|
+
}
|
|
234
|
+
} catch (e) {
|
|
235
|
+
console.warn(`Error evaluating XPath expression [${expr}] in context:`, e);
|
|
236
|
+
return type === 'boolean' ? false : null;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Resolves the in-scope context for this.ref using the bind and returns the nodeset.
|
|
242
|
+
* Does NOT mutate this.nodeset or this.node.
|
|
243
|
+
* @returns {Node[]}
|
|
244
|
+
*/
|
|
245
|
+
_evalInContext() {
|
|
246
|
+
const refAttrNode = this.bind?.getAttributeNode?.('ref') || this.bind;
|
|
247
|
+
const inScopeContext = getInScopeContext(refAttrNode, this.ref);
|
|
248
|
+
|
|
249
|
+
if (this.ref === '' || this.ref === null) {
|
|
250
|
+
return Array.isArray(inScopeContext) ? inScopeContext : [inScopeContext];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (Array.isArray(inScopeContext)) {
|
|
254
|
+
if (XPathUtil.isSelfReference(this.ref)) {
|
|
255
|
+
return inScopeContext;
|
|
256
|
+
}
|
|
257
|
+
return inScopeContext.flatMap(n => evaluateXPathToNodes(this.ref, n, this));
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const instance = this.bind?.getInstance?.(this.instanceId);
|
|
261
|
+
if (instance?.type === 'xml') {
|
|
262
|
+
return evaluateXPathToNodes(this.ref, inScopeContext, this);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return [];
|
|
266
|
+
}
|
|
132
267
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { XPathUtil } from '../xpath-util';
|
|
2
2
|
import './fx-log-item.js';
|
|
3
3
|
import { FxLogSettings } from './fx-log-settings.js';
|
|
4
|
+
import { getDocPath, getPath } from '../xpath-path.js';
|
|
4
5
|
|
|
5
6
|
export class FxActionLog extends HTMLElement {
|
|
6
7
|
constructor() {
|
|
@@ -30,7 +31,7 @@ export class FxActionLog extends HTMLElement {
|
|
|
30
31
|
}
|
|
31
32
|
a[alt]:hover::after {
|
|
32
33
|
content:attr(alt);
|
|
33
|
-
position:absolute;
|
|
34
|
+
position:absolute;
|
|
34
35
|
left:0;
|
|
35
36
|
bottom:-0.5em;
|
|
36
37
|
border:thin solid;
|
|
@@ -56,9 +57,9 @@ export class FxActionLog extends HTMLElement {
|
|
|
56
57
|
.value{
|
|
57
58
|
display:inline-block;
|
|
58
59
|
width:60%;
|
|
59
|
-
|
|
60
|
+
|
|
60
61
|
}
|
|
61
|
-
|
|
62
|
+
|
|
62
63
|
.buttons{
|
|
63
64
|
position:absolute;
|
|
64
65
|
top:0;
|
|
@@ -107,9 +108,9 @@ export class FxActionLog extends HTMLElement {
|
|
|
107
108
|
margin:0;
|
|
108
109
|
border-bottom:2px solid #ddd;
|
|
109
110
|
}
|
|
110
|
-
|
|
111
|
+
|
|
111
112
|
.info:hover{
|
|
112
|
-
outline:3px solid lightblue;
|
|
113
|
+
outline:3px solid lightblue;
|
|
113
114
|
transition:height 0.4s;
|
|
114
115
|
}
|
|
115
116
|
|
|
@@ -118,7 +119,7 @@ export class FxActionLog extends HTMLElement {
|
|
|
118
119
|
padding: 0.5em 0 0 2em;
|
|
119
120
|
border-left:3px solid red;
|
|
120
121
|
}
|
|
121
|
-
|
|
122
|
+
|
|
122
123
|
.event-name{
|
|
123
124
|
display:inline-block;
|
|
124
125
|
}
|
|
@@ -171,7 +172,7 @@ export class FxActionLog extends HTMLElement {
|
|
|
171
172
|
.nested .event-name{
|
|
172
173
|
display:none;
|
|
173
174
|
}
|
|
174
|
-
|
|
175
|
+
|
|
175
176
|
.setvalue .value{
|
|
176
177
|
background:lightyellow;
|
|
177
178
|
}
|
|
@@ -185,7 +186,7 @@ export class FxActionLog extends HTMLElement {
|
|
|
185
186
|
margin-top:2rem;
|
|
186
187
|
background:rgba(250, 250, 250, 0.9);
|
|
187
188
|
}
|
|
188
|
-
|
|
189
|
+
|
|
189
190
|
.outer-details > header{
|
|
190
191
|
position:absolute;
|
|
191
192
|
top:-1px;
|
|
@@ -224,7 +225,7 @@ export class FxActionLog extends HTMLElement {
|
|
|
224
225
|
|
|
225
226
|
const html = `
|
|
226
227
|
<section open class="outer-details">
|
|
227
|
-
<header>Log
|
|
228
|
+
<header>Log
|
|
228
229
|
<span class="buttons">
|
|
229
230
|
<button id="del"" title="empty log - Ctrl+d">
|
|
230
231
|
<svg viewBox="0 0 24 24" style="width:24px;height:24px;" preserveAspectRatio="xMidYMid meet" focusable="true"><g><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zm2.46-7.12l1.41-1.41L12 12.59l2.12-2.12 1.41 1.41L13.41 14l2.12 2.12-1.41 1.41L12 15.41l-2.12 2.12-1.41-1.41L10.59 14l-2.13-2.12zM15.5 4l-1-1h-5l-1 1H5v2h14V4z"></path></g></svg></a>
|
|
@@ -520,7 +521,7 @@ export class FxActionLog extends HTMLElement {
|
|
|
520
521
|
*/
|
|
521
522
|
_logDetails(e) {
|
|
522
523
|
const eventType = e.type;
|
|
523
|
-
const path = XPathUtil.
|
|
524
|
+
const path = XPathUtil.getPath(e.target, '');
|
|
524
525
|
// console.log('>>>> _logDetails', path);
|
|
525
526
|
const cut = path.substring(path.indexOf('/fx-fore'), path.length);
|
|
526
527
|
const xpath = `/${cut}`;
|
|
@@ -569,7 +570,7 @@ export class FxActionLog extends HTMLElement {
|
|
|
569
570
|
<fx-log-item event-name="${eventType}"
|
|
570
571
|
xpath="${xpath}"
|
|
571
572
|
short-name="${e.target.nodeName.toLowerCase()}">
|
|
572
|
-
|
|
573
|
+
|
|
573
574
|
<section class="details">
|
|
574
575
|
${this._listEventDetails(e)}
|
|
575
576
|
</section>
|
|
@@ -596,7 +597,7 @@ export class FxActionLog extends HTMLElement {
|
|
|
596
597
|
<fx-log-item event-name="${eventName}"
|
|
597
598
|
xpath="${xpath}"
|
|
598
599
|
short-name="ACTION"
|
|
599
|
-
data-path="${e.detail.path}"
|
|
600
|
+
data-path="${e.detail.path}"
|
|
600
601
|
class="action">
|
|
601
602
|
<section class="details">
|
|
602
603
|
<header>Attributes</header>
|
|
@@ -608,10 +609,10 @@ export class FxActionLog extends HTMLElement {
|
|
|
608
609
|
<span class="value">${item.nodeValue}</span>
|
|
609
610
|
`,
|
|
610
611
|
)
|
|
611
|
-
.join('')}
|
|
612
|
+
.join('')}
|
|
612
613
|
</section>
|
|
613
614
|
</section>
|
|
614
|
-
</fx-log-item>
|
|
615
|
+
</fx-log-item>
|
|
615
616
|
`;
|
|
616
617
|
// break;
|
|
617
618
|
case 'FX-MESSAGE':
|
|
@@ -646,14 +647,15 @@ export class FxActionLog extends HTMLElement {
|
|
|
646
647
|
<span class="value">${item.nodeValue}</span>
|
|
647
648
|
`,
|
|
648
649
|
)
|
|
649
|
-
.join('')}
|
|
650
|
-
</section>
|
|
650
|
+
.join('')}
|
|
651
|
+
</section>
|
|
651
652
|
</section>
|
|
652
653
|
</fx-log-item>
|
|
653
654
|
`;
|
|
654
655
|
// break;
|
|
655
656
|
case 'FX-SETVALUE':
|
|
656
|
-
const
|
|
657
|
+
const instanceId = XPathUtil.getInstanceId(xpath, actionElement);
|
|
658
|
+
const instPath = getPath(e.target.nodeset, instanceId);
|
|
657
659
|
const listensOn =
|
|
658
660
|
e.target.nodeName === 'FX-CONTROL'
|
|
659
661
|
? e.target.updateEvent
|
|
@@ -680,10 +682,10 @@ export class FxActionLog extends HTMLElement {
|
|
|
680
682
|
? e.detail.event
|
|
681
683
|
: '';
|
|
682
684
|
return `
|
|
683
|
-
<fx-log-item event-name="${eventName}"
|
|
685
|
+
<fx-log-item event-name="${eventName}"
|
|
684
686
|
short-name="${e.target.nodeName}"
|
|
685
687
|
xpath="${xpath}"
|
|
686
|
-
data-path="${e.detail.path}"
|
|
688
|
+
data-path="${e.detail.path}"
|
|
687
689
|
class="action">
|
|
688
690
|
<section class="details">
|
|
689
691
|
</section>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { XPathUtil } from '../xpath-util';
|
|
2
2
|
import './fx-log-item.js';
|
|
3
|
+
import { getPath } from '../xpath-path.js';
|
|
3
4
|
|
|
4
5
|
export class FxLogSettings extends HTMLElement {
|
|
5
6
|
constructor() {
|
|
@@ -330,7 +331,7 @@ export class FxLogSettings extends HTMLElement {
|
|
|
330
331
|
_logDetails(e) {
|
|
331
332
|
const eventType = e.type;
|
|
332
333
|
// console.log('>>>> event type', type)
|
|
333
|
-
const path =
|
|
334
|
+
const path = getPath(e.target);
|
|
334
335
|
const cut = path.substring(path.indexOf('/fx-fore'), path.length);
|
|
335
336
|
|
|
336
337
|
const xpath = `/${cut}`;
|
|
@@ -452,7 +453,8 @@ export class FxLogSettings extends HTMLElement {
|
|
|
452
453
|
`;
|
|
453
454
|
// break;
|
|
454
455
|
case 'FX-SETVALUE':
|
|
455
|
-
const
|
|
456
|
+
const instanceId = XPathUtil.getInstanceId(xpath, actionElement);
|
|
457
|
+
const instPath = getPath(e.target.nodeset, instanceId);
|
|
456
458
|
const listensOn =
|
|
457
459
|
e.target.nodeName === 'FX-CONTROL' ? e.target.updateEvent : e.detail.event;
|
|
458
460
|
return `
|