@jinntec/fore 2.5.0 → 2.6.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/dist/fore-dev.js +34261 -9
- package/dist/fore.js +34123 -9
- package/index.js +1 -1
- package/package.json +1 -1
- package/resources/fore.css +29 -0
- package/src/DataObserver.js +181 -0
- package/src/DependentXPathQueries.js +32 -0
- package/src/ForeElementMixin.js +289 -260
- package/src/actions/abstract-action.js +24 -24
- package/src/actions/fx-append.js +2 -0
- package/src/actions/fx-delete.js +14 -2
- package/src/actions/fx-hide.js +1 -1
- package/src/actions/fx-insert.js +47 -41
- package/src/actions/fx-load.js +7 -2
- package/src/actions/fx-setvalue.js +104 -86
- package/src/actions/fx-show.js +4 -2
- package/src/fore.js +40 -23
- package/src/fx-fore.js +92 -93
- package/src/fx-submission.js +28 -23
- package/src/getInScopeContext.js +1 -0
- package/src/modelitem.js +107 -96
- package/src/ui/UIElement.js +91 -0
- package/src/ui/abstract-control.js +10 -7
- package/src/ui/fx-container.js +5 -3
- package/src/ui/fx-control-menu.js +198 -0
- package/src/ui/fx-control.js +61 -17
- package/src/ui/fx-dialog.js +2 -2
- package/src/ui/fx-group.js +14 -0
- package/src/ui/fx-repeat.js +33 -3
- package/src/xpath-util.js +284 -256
- package/dist/fore-dev.js.map +0 -1
- package/dist/fore.js.map +0 -1
- package/src/ui/fx-select.js +0 -89
|
@@ -122,6 +122,7 @@ export class AbstractAction extends ForeElementMixin {
|
|
|
122
122
|
disconnectedCallback() {}
|
|
123
123
|
|
|
124
124
|
connectedCallback() {
|
|
125
|
+
super.connectedCallback();
|
|
125
126
|
this.setAttribute('inert', 'true');
|
|
126
127
|
this.style.display = 'none';
|
|
127
128
|
this.propagate = this.hasAttribute('propagate') ? this.getAttribute('propagate') : 'continue';
|
|
@@ -176,6 +177,7 @@ export class AbstractAction extends ForeElementMixin {
|
|
|
176
177
|
}
|
|
177
178
|
} else {
|
|
178
179
|
this.targetElement = this.parentNode;
|
|
180
|
+
if(!this.targetElement || this.targetElement.nodeType !== Node.ELEMENT_NODE) return;
|
|
179
181
|
this.targetElement.addEventListener(this.event, e => this.execute(e), {
|
|
180
182
|
capture: this.phase === 'capture',
|
|
181
183
|
});
|
|
@@ -212,30 +214,28 @@ export class AbstractAction extends ForeElementMixin {
|
|
|
212
214
|
* @param e
|
|
213
215
|
*/
|
|
214
216
|
async execute(e) {
|
|
215
|
-
if(!this.getModel().modelConstructed) return;
|
|
217
|
+
if (!this.getModel().modelConstructed) return;
|
|
216
218
|
// console.log(this, this.event);
|
|
217
|
-
if(this.event){
|
|
218
|
-
if(this.event === 'submit-done'){
|
|
219
|
+
if (this.event) {
|
|
220
|
+
if (this.event === 'submit-done') {
|
|
219
221
|
console.info(
|
|
220
|
-
|
|
221
|
-
|
|
222
|
+
`%csubmit-done ${this.event} #${this?.parentNode?.id}`,
|
|
223
|
+
'background:lime; color:black; padding:.5rem; display:inline-block; white-space: nowrap; border-radius:0.3rem;width:100%;',
|
|
222
224
|
);
|
|
223
|
-
}else{
|
|
225
|
+
} else {
|
|
224
226
|
console.info(
|
|
225
|
-
|
|
226
|
-
|
|
227
|
+
`%cexecuting ${this.constructor.name} ${this.event}`,
|
|
228
|
+
'background:lime; color:black; padding:.5rem; display:inline-block; white-space: nowrap; border-radius:0.3rem;width:100%;',
|
|
227
229
|
);
|
|
228
230
|
}
|
|
229
|
-
|
|
230
|
-
}else{
|
|
231
|
+
} else {
|
|
231
232
|
console.info(
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
233
|
+
`%cexecuting ${this.constructor.name}`,
|
|
234
|
+
'background:limegreen; color:black; margin-left:1rem; padding:.5rem; display:inline-block; white-space: nowrap; border-radius:0.3rem;width:100%;',
|
|
235
|
+
this,
|
|
235
236
|
);
|
|
236
237
|
}
|
|
237
238
|
|
|
238
|
-
|
|
239
239
|
if (e && e.target.nodeType !== Node.DOCUMENT_NODE && e.target !== window) {
|
|
240
240
|
/*
|
|
241
241
|
### ignore event if there's a parent fore and the current element is NOT part of it. This avoids
|
|
@@ -260,7 +260,7 @@ export class AbstractAction extends ForeElementMixin {
|
|
|
260
260
|
let resolveThisEvent = () => {};
|
|
261
261
|
if (e && e.listenerPromises) {
|
|
262
262
|
e.listenerPromises.push(
|
|
263
|
-
new Promise(
|
|
263
|
+
new Promise(resolve => {
|
|
264
264
|
resolveThisEvent = resolve;
|
|
265
265
|
}),
|
|
266
266
|
);
|
|
@@ -269,9 +269,9 @@ export class AbstractAction extends ForeElementMixin {
|
|
|
269
269
|
// Outermost handling
|
|
270
270
|
if (FxFore.outermostHandler === null) {
|
|
271
271
|
console.log(
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
272
|
+
`%coutermost Action on ${this.getOwnerForm().id}`,
|
|
273
|
+
'background:darkblue; color:white; padding:0.3rem; display:inline-block; white-space: nowrap; border-radius:0.3rem;',
|
|
274
|
+
this,
|
|
275
275
|
);
|
|
276
276
|
|
|
277
277
|
FxFore.outermostHandler = this;
|
|
@@ -406,9 +406,9 @@ export class AbstractAction extends ForeElementMixin {
|
|
|
406
406
|
this.actionPerformed();
|
|
407
407
|
if (FxFore.outermostHandler === this) {
|
|
408
408
|
console.log(
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
409
|
+
`%cfinalizing outermost Action on ${this.getOwnerForm().id}`,
|
|
410
|
+
'background:darkblue; color:white; padding:0.3rem; display:inline-block; white-space: nowrap; border-radius:0.3rem;',
|
|
411
|
+
this,
|
|
412
412
|
);
|
|
413
413
|
|
|
414
414
|
FxFore.outermostHandler = null;
|
|
@@ -467,8 +467,8 @@ export class AbstractAction extends ForeElementMixin {
|
|
|
467
467
|
return;
|
|
468
468
|
}
|
|
469
469
|
if (
|
|
470
|
-
FxFore.outermostHandler
|
|
471
|
-
|
|
470
|
+
FxFore.outermostHandler &&
|
|
471
|
+
!XPathUtil.contains(FxFore.outermostHandler.ownerDocument, FxFore.outermostHandler)
|
|
472
472
|
) {
|
|
473
473
|
// The old outermostHandler fell out of the document. An error has happened.
|
|
474
474
|
// Just remove the old one and act like we are starting anew.
|
|
@@ -480,7 +480,7 @@ export class AbstractAction extends ForeElementMixin {
|
|
|
480
480
|
// console.log('running update cycle for outermostHandler', this);
|
|
481
481
|
model.recalculate();
|
|
482
482
|
model.revalidate();
|
|
483
|
-
|
|
483
|
+
this.getOwnerForm().refresh(true);
|
|
484
484
|
this.dispatchActionPerformed();
|
|
485
485
|
} else if (this.needsUpdate) {
|
|
486
486
|
// console.log('Update delayed!');
|
package/src/actions/fx-append.js
CHANGED
|
@@ -109,6 +109,8 @@ class FxAppend extends AbstractAction {
|
|
|
109
109
|
const data = this._generateInstance(templ.content, rootNode);
|
|
110
110
|
// console.log('_dataFromTemplate DATA', data);
|
|
111
111
|
inscope.appendChild(data);
|
|
112
|
+
parentForm.signalChangeToElement(inscope.localName);
|
|
113
|
+
parentForm.signalChangeToElement(data.localName);
|
|
112
114
|
// console.log('appended new item ', data);
|
|
113
115
|
// return data;
|
|
114
116
|
}
|
package/src/actions/fx-delete.js
CHANGED
|
@@ -52,19 +52,31 @@ class FxDelete extends AbstractAction {
|
|
|
52
52
|
}),
|
|
53
53
|
);
|
|
54
54
|
|
|
55
|
+
const fore = this.getOwnerForm();
|
|
56
|
+
|
|
55
57
|
let parent;
|
|
56
58
|
if (Array.isArray(nodesToDelete)) {
|
|
57
59
|
if (nodesToDelete.length === 0) return;
|
|
58
60
|
parent = nodesToDelete[0].parentNode;
|
|
61
|
+
fore.signalChangeToElement(parent.localName);
|
|
59
62
|
nodesToDelete.forEach(item => {
|
|
60
63
|
this._deleteNode(parent, item);
|
|
64
|
+
fore.signalChangeToElement(item.localName);
|
|
61
65
|
});
|
|
62
66
|
} else {
|
|
63
67
|
parent = nodesToDelete.parentNode;
|
|
68
|
+
fore.signalChangeToElement(parent.localName);
|
|
69
|
+
|
|
64
70
|
this._deleteNode(parent, nodesToDelete);
|
|
71
|
+
fore.signalChangeToElement(nodesToDelete.localName);
|
|
65
72
|
}
|
|
66
|
-
|
|
67
|
-
await Fore.dispatch(instance, 'deleted', {
|
|
73
|
+
|
|
74
|
+
await Fore.dispatch(instance, 'deleted', {
|
|
75
|
+
ref: path,
|
|
76
|
+
deletedNodes: nodesToDelete,
|
|
77
|
+
instanceId,
|
|
78
|
+
foreId: fore.id,
|
|
79
|
+
});
|
|
68
80
|
this.needsUpdate = true;
|
|
69
81
|
}
|
|
70
82
|
|
package/src/actions/fx-hide.js
CHANGED
package/src/actions/fx-insert.js
CHANGED
|
@@ -60,30 +60,6 @@ export class FxInsert extends AbstractAction {
|
|
|
60
60
|
this.keepValues = !!this.hasAttribute('keep-values');
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
_getOriginSequence(inscope, targetSequence) {
|
|
64
|
-
let originSequence;
|
|
65
|
-
if (this.origin) {
|
|
66
|
-
// ### if there's an origin attribute use it
|
|
67
|
-
let originTarget;
|
|
68
|
-
try {
|
|
69
|
-
originTarget = evaluateXPathToFirstNode(this.origin, inscope, this);
|
|
70
|
-
if (Array.isArray(originTarget) && originTarget.length === 0) {
|
|
71
|
-
console.warn('invalid origin for this insert action - ignoring...', this);
|
|
72
|
-
originSequence = null;
|
|
73
|
-
}
|
|
74
|
-
originSequence = originTarget;
|
|
75
|
-
} catch (error) {
|
|
76
|
-
console.warn('invalid origin for this insert action - ignoring...', this);
|
|
77
|
-
}
|
|
78
|
-
} else if (targetSequence) {
|
|
79
|
-
// ### use last item of targetSequence
|
|
80
|
-
originSequence = targetSequence;
|
|
81
|
-
if (originSequence && !this.keepValues) {
|
|
82
|
-
this._clear(originSequence);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return originSequence;
|
|
86
|
-
}
|
|
87
63
|
|
|
88
64
|
_cloneOriginSequence(inscope, targetSequence) {
|
|
89
65
|
let originSequenceClone;
|
|
@@ -96,13 +72,25 @@ export class FxInsert extends AbstractAction {
|
|
|
96
72
|
*/
|
|
97
73
|
// this.setInScopeVariables(this.detail);
|
|
98
74
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
75
|
+
/*
|
|
76
|
+
if in 'create-nodes' mode and origin targets a repeat, the repeat
|
|
77
|
+
we use the already during initData() created nodeset as a template for insertion
|
|
78
|
+
*/
|
|
79
|
+
if(this.origin.startsWith('#') && this.getOwnerForm().createNodes){
|
|
80
|
+
const repeat = this.getOwnerForm().querySelector(this.origin);
|
|
81
|
+
originSequenceClone = repeat.createdNodeset.cloneNode(true);
|
|
82
|
+
if(!originSequenceClone){
|
|
83
|
+
console.error(`createdNodeset for repeat ${this.origin} does not exist`);
|
|
84
|
+
}
|
|
85
|
+
}else{
|
|
86
|
+
// originTarget = evaluateXPathToFirstNode(this.origin, inscope, this);
|
|
87
|
+
originTarget = evaluateXPathToFirstNode(this.origin, inscope, this);
|
|
88
|
+
if (Array.isArray(originTarget) && originTarget.length === 0) {
|
|
89
|
+
console.warn('invalid origin for this insert action - ignoring...', this);
|
|
90
|
+
originSequenceClone = null;
|
|
91
|
+
}
|
|
92
|
+
originSequenceClone = originTarget.cloneNode(true);
|
|
104
93
|
}
|
|
105
|
-
originSequenceClone = originTarget.cloneNode(true);
|
|
106
94
|
} catch (error) {
|
|
107
95
|
console.warn('invalid origin for this insert action - ignoring...', this);
|
|
108
96
|
}
|
|
@@ -136,13 +124,11 @@ export class FxInsert extends AbstractAction {
|
|
|
136
124
|
let targetSequence = [];
|
|
137
125
|
const inscopeContext = getInScopeContext(this);
|
|
138
126
|
|
|
127
|
+
const fore = this.getOwnerForm();
|
|
128
|
+
|
|
139
129
|
// ### 'context' attribute takes precedence over 'ref'
|
|
140
130
|
if (this.hasAttribute('context')) {
|
|
141
|
-
[context] = evaluateXPathToNodes(
|
|
142
|
-
this.getAttribute('context'),
|
|
143
|
-
inscopeContext,
|
|
144
|
-
this.getOwnerForm(),
|
|
145
|
-
);
|
|
131
|
+
[context] = evaluateXPathToNodes(this.getAttribute('context'), inscopeContext, fore);
|
|
146
132
|
inscope = inscopeContext;
|
|
147
133
|
}
|
|
148
134
|
|
|
@@ -154,6 +140,8 @@ export class FxInsert extends AbstractAction {
|
|
|
154
140
|
targetSequence = evaluateXPathToNodes(this.ref, inscope, this);
|
|
155
141
|
}
|
|
156
142
|
}
|
|
143
|
+
// const originSequenceClone = this._cloneOriginSequence(inscope, targetSequence);
|
|
144
|
+
|
|
157
145
|
const originSequenceClone = this._cloneOriginSequence(inscope, targetSequence);
|
|
158
146
|
if (!originSequenceClone) return; // if no origin back out without effect
|
|
159
147
|
|
|
@@ -165,12 +153,24 @@ export class FxInsert extends AbstractAction {
|
|
|
165
153
|
if (context) {
|
|
166
154
|
insertLocationNode = context;
|
|
167
155
|
context.appendChild(originSequenceClone);
|
|
156
|
+
fore.signalChangeToElement(insertLocationNode.localName);
|
|
157
|
+
fore.signalChangeToElement(originSequenceClone.localName);
|
|
168
158
|
index = 1;
|
|
169
159
|
} else {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
inscope.
|
|
173
|
-
|
|
160
|
+
|
|
161
|
+
// No context but creating nodes from UI
|
|
162
|
+
if(!inscope && this.getOwnerForm().createNodes){
|
|
163
|
+
const repeat = this.getOwnerForm().querySelector(this.origin);
|
|
164
|
+
inscope = getInScopeContext(repeat, repeat.ref);
|
|
165
|
+
insertLocationNode = inscope;
|
|
166
|
+
inscope.appendChild(originSequenceClone);
|
|
167
|
+
index = inscope.length - 1;
|
|
168
|
+
}else{
|
|
169
|
+
insertLocationNode = inscope;
|
|
170
|
+
inscope.appendChild(originSequenceClone);
|
|
171
|
+
index = 1;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
174
|
}
|
|
175
175
|
} else {
|
|
176
176
|
/* ### insert at position given by 'at' or use the last item in the targetSequence ### */
|
|
@@ -205,6 +205,8 @@ export class FxInsert extends AbstractAction {
|
|
|
205
205
|
if (this.position && this.position === 'before') {
|
|
206
206
|
// this.at -= 1;
|
|
207
207
|
insertLocationNode.parentNode.insertBefore(originSequenceClone, insertLocationNode);
|
|
208
|
+
fore.signalChangeToElement(insertLocationNode.parentNode);
|
|
209
|
+
fore.signalChangeToElement(originSequenceClone.localName);
|
|
208
210
|
}
|
|
209
211
|
|
|
210
212
|
if (this.position && this.position === 'after') {
|
|
@@ -217,8 +219,12 @@ export class FxInsert extends AbstractAction {
|
|
|
217
219
|
} else if (this.hasAttribute('context')) {
|
|
218
220
|
index = 1;
|
|
219
221
|
insertLocationNode.prepend(originSequenceClone);
|
|
222
|
+
fore.signalChangeToElement(insertLocationNode);
|
|
223
|
+
fore.signalChangeToElement(originSequenceClone.localName);
|
|
220
224
|
} else {
|
|
221
225
|
insertLocationNode.insertAdjacentElement('afterend', originSequenceClone);
|
|
226
|
+
fore.signalChangeToElement(insertLocationNode);
|
|
227
|
+
fore.signalChangeToElement(originSequenceClone.localName);
|
|
222
228
|
}
|
|
223
229
|
}
|
|
224
230
|
}
|
|
@@ -251,8 +257,8 @@ export class FxInsert extends AbstractAction {
|
|
|
251
257
|
'inserted-nodes': originSequenceClone,
|
|
252
258
|
'insert-location-node': insertLocationNode,
|
|
253
259
|
position: this.position,
|
|
254
|
-
instanceId
|
|
255
|
-
foreId:
|
|
260
|
+
instanceId,
|
|
261
|
+
foreId: fore.id,
|
|
256
262
|
});
|
|
257
263
|
|
|
258
264
|
// todo: this actually should dispatch to respective instance
|
package/src/actions/fx-load.js
CHANGED
|
@@ -27,12 +27,13 @@ class FxLoad extends AbstractAction {
|
|
|
27
27
|
super();
|
|
28
28
|
this.attachShadow({ mode: 'open' });
|
|
29
29
|
this.url = '';
|
|
30
|
+
this.replace=false;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
connectedCallback() {
|
|
33
34
|
super.connectedCallback();
|
|
34
35
|
this.attachTo = this.hasAttribute('attach-to') ? this.getAttribute('attach-to') : '_self';
|
|
35
|
-
|
|
36
|
+
this.replace = this.hasAttribute('replace') ? true : false;
|
|
36
37
|
// Add a 'doneEvent' to block the action chain untill the event fired on the element we're
|
|
37
38
|
// loading something into.
|
|
38
39
|
this.awaitEvent = this.hasAttribute('await') ? this.getAttribute('await') : '';
|
|
@@ -88,7 +89,11 @@ class FxLoad extends AbstractAction {
|
|
|
88
89
|
resolved.removeEventListener(this.awaitEvent, eventListener);
|
|
89
90
|
};
|
|
90
91
|
|
|
91
|
-
|
|
92
|
+
if(this.replace){
|
|
93
|
+
this.parentNode.replaceChild(content,resolved);
|
|
94
|
+
}else{
|
|
95
|
+
resolved.appendChild(content);
|
|
96
|
+
}
|
|
92
97
|
resolved.addEventListener(this.awaitEvent, eventListener);
|
|
93
98
|
|
|
94
99
|
await waitForEvent;
|
|
@@ -3,6 +3,7 @@ import '../fx-model.js';
|
|
|
3
3
|
import { AbstractAction } from './abstract-action.js';
|
|
4
4
|
import { evaluateXPath } from '../xpath-evaluation.js';
|
|
5
5
|
import { Fore } from '../fore.js';
|
|
6
|
+
import getInScopeContext from '../getInScopeContext.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* `fx-setvalue`
|
|
@@ -10,106 +11,123 @@ import { Fore } from '../fore.js';
|
|
|
10
11
|
* @customElement
|
|
11
12
|
*/
|
|
12
13
|
export default class FxSetvalue extends AbstractAction {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
constructor() {
|
|
26
|
-
super();
|
|
27
|
-
this.ref = '';
|
|
28
|
-
this.valueAttr = '';
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
connectedCallback() {
|
|
32
|
-
if (super.connectedCallback) {
|
|
33
|
-
super.connectedCallback();
|
|
14
|
+
static get properties() {
|
|
15
|
+
return {
|
|
16
|
+
...super.properties,
|
|
17
|
+
ref: {
|
|
18
|
+
type: String,
|
|
19
|
+
},
|
|
20
|
+
valueAttr: {
|
|
21
|
+
type: String,
|
|
22
|
+
},
|
|
23
|
+
};
|
|
34
24
|
}
|
|
35
25
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
26
|
+
constructor() {
|
|
27
|
+
super();
|
|
28
|
+
this.ref = '';
|
|
29
|
+
this.valueAttr = '';
|
|
40
30
|
}
|
|
41
|
-
this.valueAttr = this.getAttribute('value');
|
|
42
|
-
}
|
|
43
31
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
32
|
+
connectedCallback() {
|
|
33
|
+
if (super.connectedCallback) {
|
|
34
|
+
super.connectedCallback();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (this.hasAttribute('ref')) {
|
|
38
|
+
this.ref = this.getAttribute('ref');
|
|
39
|
+
} else {
|
|
40
|
+
throw new Error('fx-setvalue must specify a "ref" attribute');
|
|
41
|
+
}
|
|
42
|
+
this.valueAttr = this.getAttribute('value');
|
|
53
43
|
}
|
|
54
|
-
|
|
55
|
-
|
|
44
|
+
|
|
45
|
+
async perform() {
|
|
46
|
+
super.perform();
|
|
47
|
+
let { value } = this;
|
|
48
|
+
if (this.valueAttr !== null) {
|
|
49
|
+
const inscopeContext = getInScopeContext(this, this.valueAttr);
|
|
50
|
+
/*
|
|
51
|
+
todo: review @martin - shouldn't we always return a string value?
|
|
52
|
+
this comes down to the question if setvalue should only allow setting of strings
|
|
53
|
+
which i tend to agree. Can't remember a case where i wanted to set an attribute
|
|
54
|
+
or element (for json wouldn't make much sense either) - for cases like that
|
|
55
|
+
fx-replace would be more appropriate.
|
|
56
|
+
|
|
57
|
+
This is of practical relevance cause currently forces to append 'text()' to value expressions
|
|
58
|
+
or getting unexpected results.
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
[value] = evaluateXPath(
|
|
62
|
+
this.valueAttr,
|
|
63
|
+
inscopeContext,
|
|
64
|
+
this,
|
|
65
|
+
this.detail,
|
|
66
|
+
);
|
|
67
|
+
} else if (this.textContent !== '') {
|
|
68
|
+
value = this.textContent;
|
|
69
|
+
} else {
|
|
70
|
+
value = '';
|
|
71
|
+
}
|
|
72
|
+
if (value?.nodeType && value.nodeType === Node.ATTRIBUTE_NODE) {
|
|
73
|
+
value = value.nodeValue;
|
|
74
|
+
}
|
|
75
|
+
const mi = this.getModelItem();
|
|
76
|
+
this.setValue(mi, value);
|
|
77
|
+
// todo: check this again - logically needsUpate should be set but makes tests fail
|
|
78
|
+
// this.needsUpdate = true;
|
|
56
79
|
}
|
|
57
|
-
const mi = this.getModelItem();
|
|
58
|
-
this.setValue(mi, value);
|
|
59
|
-
// todo: check this again - logically needsUpate should be set but makes tests fail
|
|
60
|
-
// this.needsUpdate = true;
|
|
61
|
-
}
|
|
62
80
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
81
|
+
/**
|
|
82
|
+
* need to overwrite default dispatchExecute to do it ourselves. This is necessary for tracking control value changes
|
|
83
|
+
* which call setvalue directly without perform().
|
|
84
|
+
*/
|
|
85
|
+
dispatchExecute() {}
|
|
68
86
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
87
|
+
setValue(modelItem, newVal) {
|
|
88
|
+
const item = modelItem;
|
|
89
|
+
if (!item) return;
|
|
72
90
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
91
|
+
if (item.value !== newVal) {
|
|
92
|
+
// const path = XPathUtil.getPath(modelItem.node);
|
|
93
|
+
const path = Fore.getDomNodeIndexString(modelItem.node);
|
|
76
94
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
95
|
+
const ev = this.event;
|
|
96
|
+
const targetElem = this;
|
|
97
|
+
this.dispatchEvent(
|
|
98
|
+
new CustomEvent('execute-action', {
|
|
99
|
+
composed: true,
|
|
100
|
+
bubbles: true,
|
|
101
|
+
cancelable: true,
|
|
102
|
+
detail: {
|
|
103
|
+
action: targetElem,
|
|
104
|
+
event: ev,
|
|
105
|
+
value: newVal,
|
|
106
|
+
path,
|
|
107
|
+
},
|
|
108
|
+
}),
|
|
109
|
+
);
|
|
92
110
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
111
|
+
if (newVal?.nodeType) {
|
|
112
|
+
if (newVal.nodeType === Node.ELEMENT_NODE) {
|
|
113
|
+
item.value = newVal;
|
|
114
|
+
}
|
|
115
|
+
if (newVal.nodeType === Node.ATTRIBUTE_NODE) {
|
|
116
|
+
item.value = newVal.getValue();
|
|
117
|
+
}
|
|
118
|
+
if (newVal.nodeType === Node.TEXT_NODE) {
|
|
119
|
+
item.value = newVal.textContent;
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
item.value = newVal;
|
|
123
|
+
item.node.textContent = newVal;
|
|
124
|
+
}
|
|
125
|
+
this.getModel().changed.push(modelItem);
|
|
126
|
+
this.needsUpdate = true;
|
|
102
127
|
}
|
|
103
|
-
} else {
|
|
104
|
-
item.value = newVal;
|
|
105
|
-
item.node.textContent = newVal;
|
|
106
|
-
}
|
|
107
|
-
this.getModel().changed.push(modelItem);
|
|
108
|
-
this.needsUpdate = true;
|
|
109
128
|
}
|
|
110
|
-
}
|
|
111
129
|
}
|
|
112
130
|
|
|
113
131
|
if (!customElements.get('fx-setvalue')) {
|
|
114
|
-
|
|
132
|
+
window.customElements.define('fx-setvalue', FxSetvalue);
|
|
115
133
|
}
|
package/src/actions/fx-show.js
CHANGED
|
@@ -4,7 +4,9 @@ import { resolveId } from '../xpath-evaluation.js';
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* `fx-show`
|
|
7
|
-
*
|
|
7
|
+
* to show a `<dialog>` with given id.
|
|
8
|
+
*
|
|
9
|
+
*
|
|
8
10
|
*
|
|
9
11
|
* @customElement
|
|
10
12
|
* @event fx-show dispatched when dialog is shown
|
|
@@ -34,7 +36,7 @@ export class FxShow extends FxAction {
|
|
|
34
36
|
if (!targetDlg) {
|
|
35
37
|
console.error('target dialog with given id does not exist', this.dialog);
|
|
36
38
|
}
|
|
37
|
-
targetDlg.
|
|
39
|
+
targetDlg.showModal();
|
|
38
40
|
Fore.dispatch(targetDlg, 'dialog-shown', {});
|
|
39
41
|
}
|
|
40
42
|
}
|
package/src/fore.js
CHANGED
|
@@ -275,7 +275,7 @@ export class Fore {
|
|
|
275
275
|
* recursively refreshes all UI Elements.
|
|
276
276
|
*
|
|
277
277
|
* @param {HTMLElement} startElement
|
|
278
|
-
* @param {(boolean|{reason:'index-function'})} force Whether to do a forced refresh. Forced
|
|
278
|
+
* @param {(boolean|{reason:'index-function', elementLocalnamesWithChanges: string[]})} force Whether to do a forced refresh. Forced
|
|
279
279
|
* refreshes are very bad for performance, try to limit them. If the forced refresh is because index functions may change, it is better to pass the reason
|
|
280
280
|
* @returns {Promise<void>}
|
|
281
281
|
*/
|
|
@@ -300,30 +300,47 @@ export class Fore {
|
|
|
300
300
|
const { children } = startElement;
|
|
301
301
|
if (children) {
|
|
302
302
|
for (const element of Array.from(children)) {
|
|
303
|
-
|
|
304
|
-
|
|
303
|
+
if (element.nodeName.toUpperCase() === 'FX-FORE') {
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
if (Fore.isUiElement(element.nodeName) && typeof element.refresh === 'function') {
|
|
307
|
+
/**
|
|
308
|
+
* @type {import('./ForeElementMixin.js').default}
|
|
309
|
+
*/
|
|
310
|
+
const bound = element;
|
|
311
|
+
if (!force) {
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
if (force === true) {
|
|
315
|
+
// Unconditional force refresh
|
|
316
|
+
bound.refresh(force);
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
if (typeof force !== 'object') {
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
if (
|
|
323
|
+
force.reason === 'index-function' &&
|
|
324
|
+
bound.dependencies.isInvalidatedByIndexFunction()
|
|
325
|
+
) {
|
|
326
|
+
bound.refresh(force);
|
|
327
|
+
continue;
|
|
305
328
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
typeof force === 'object' &&
|
|
313
|
-
force.reason === 'index-function' &&
|
|
314
|
-
element._dependencies.isInvalidatedByIndexFunction()
|
|
315
|
-
) {
|
|
316
|
-
element.refresh(force);
|
|
317
|
-
continue;
|
|
318
|
-
} else if (force === true) {
|
|
319
|
-
element.refresh(force);
|
|
320
|
-
}
|
|
321
|
-
// console.log('refreshing', element, element?.ref);
|
|
322
|
-
// console.log('refreshing ',element);
|
|
323
|
-
} else if (!(element.inert === true) ) {
|
|
324
|
-
// testing for inert catches model and action elements and should just leave updateable html elements
|
|
325
|
-
Fore.refreshChildren(element, force);
|
|
329
|
+
|
|
330
|
+
if (
|
|
331
|
+
bound.dependencies.isInvalidatedByChildlistChanges(force.elementLocalnamesWithChanges)
|
|
332
|
+
) {
|
|
333
|
+
bound.refresh(force);
|
|
334
|
+
continue;
|
|
326
335
|
}
|
|
336
|
+
|
|
337
|
+
// console.log('refreshing', element, element?.ref);
|
|
338
|
+
// console.log('refreshing ',element);
|
|
339
|
+
}
|
|
340
|
+
if (!(element.inert === true)) {
|
|
341
|
+
// testing for inert catches model and action elements and should just leave updateable html elements
|
|
342
|
+
Fore.refreshChildren(element, force);
|
|
343
|
+
}
|
|
327
344
|
}
|
|
328
345
|
}
|
|
329
346
|
resolve('done');
|