@jinntec/fore 2.6.0 → 2.7.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 +4470 -2643
- package/dist/fore.js +4415 -2620
- 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-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-repeat.updated.js +821 -0
- 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/actions/fx-append.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { AbstractAction } from './abstract-action.js';
|
|
2
2
|
import { Fore } from '../fore.js';
|
|
3
3
|
import { resolveId } from '../xpath-evaluation.js';
|
|
4
|
+
import { XPathUtil } from '../xpath-util.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* `fx-append` appends an entry to a repeat.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
9
|
* @deprecated - will be replaced with `fx-insert`
|
|
11
10
|
* @fires index-changed - fired after new item is appended
|
|
12
11
|
* @customElement
|
|
@@ -76,6 +75,8 @@ class FxAppend extends AbstractAction {
|
|
|
76
75
|
|
|
77
76
|
actionPerformed() {
|
|
78
77
|
super.actionPerformed();
|
|
78
|
+
const mi = this.getModelItem();
|
|
79
|
+
mi.notify();
|
|
79
80
|
// const repeat = document.getElementById(this.repeat);
|
|
80
81
|
// repeat.setIndex(repeat.nodeset.length);
|
|
81
82
|
this._dispatch();
|
|
@@ -103,6 +104,9 @@ class FxAppend extends AbstractAction {
|
|
|
103
104
|
|
|
104
105
|
// const rootNode = document.createElement(repeat.ref);
|
|
105
106
|
// const rootNode = inscope.ownerDocument.createElement(repeat.ref);
|
|
107
|
+
/**
|
|
108
|
+
* @type {Element}
|
|
109
|
+
*/
|
|
106
110
|
const rootNode = inscope.ownerDocument.createElement(repeat.ref);
|
|
107
111
|
|
|
108
112
|
// const data = this._dataFromRefs(rootNode, templ.content)
|
|
@@ -111,6 +115,23 @@ class FxAppend extends AbstractAction {
|
|
|
111
115
|
inscope.appendChild(data);
|
|
112
116
|
parentForm.signalChangeToElement(inscope.localName);
|
|
113
117
|
parentForm.signalChangeToElement(data.localName);
|
|
118
|
+
|
|
119
|
+
const instanceId = XPathUtil.resolveInstance(this, this.ref);
|
|
120
|
+
const inst = this.getModel().getInstance(instanceId);
|
|
121
|
+
|
|
122
|
+
const fore = this.getOwnerForm();
|
|
123
|
+
|
|
124
|
+
Fore.dispatch(inst, 'insert', {
|
|
125
|
+
insertedNodes: data,
|
|
126
|
+
insertedParent: inscope,
|
|
127
|
+
ref: this.ref,
|
|
128
|
+
location: data.previousSibling,
|
|
129
|
+
position: 'after',
|
|
130
|
+
instanceId: inst.id,
|
|
131
|
+
foreId: fore.id,
|
|
132
|
+
index: Array.from(inscope.children).indexOf(data),
|
|
133
|
+
});
|
|
134
|
+
|
|
114
135
|
// console.log('appended new item ', data);
|
|
115
136
|
// return data;
|
|
116
137
|
}
|
package/src/actions/fx-call.js
CHANGED
|
@@ -3,7 +3,7 @@ import { AbstractAction } from './abstract-action.js';
|
|
|
3
3
|
import { evaluateXPath } from '../xpath-evaluation.js';
|
|
4
4
|
import { Fore } from '../fore.js';
|
|
5
5
|
import getInScopeContext from '../getInScopeContext.js';
|
|
6
|
-
import {
|
|
6
|
+
import { getDocPath } from '../xpath-path.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* `fx-call`
|
|
@@ -67,7 +67,7 @@ export default class FxCall extends AbstractAction {
|
|
|
67
67
|
Fore.dispatch(this, 'error', {
|
|
68
68
|
origin: this,
|
|
69
69
|
message: `Action '${this.action}' not found`,
|
|
70
|
-
expr:
|
|
70
|
+
expr: getDocPath(this),
|
|
71
71
|
level: 'Error',
|
|
72
72
|
});
|
|
73
73
|
}
|
package/src/actions/fx-delete.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import * as fx from 'fontoxpath';
|
|
2
1
|
import { AbstractAction } from './abstract-action.js';
|
|
3
2
|
import { Fore } from '../fore.js';
|
|
4
|
-
import { evaluateXPathToNodes
|
|
3
|
+
import { evaluateXPathToNodes } from '../xpath-evaluation.js';
|
|
5
4
|
import { XPathUtil } from '../xpath-util.js';
|
|
6
5
|
import getInScopeContext from '../getInScopeContext.js';
|
|
7
6
|
|
|
@@ -55,49 +54,75 @@ class FxDelete extends AbstractAction {
|
|
|
55
54
|
const fore = this.getOwnerForm();
|
|
56
55
|
|
|
57
56
|
let parent;
|
|
57
|
+
|
|
58
|
+
const removedNodes = [];
|
|
58
59
|
if (Array.isArray(nodesToDelete)) {
|
|
59
|
-
if (nodesToDelete.length === 0)
|
|
60
|
+
if (nodesToDelete.length === 0) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
60
63
|
parent = nodesToDelete[0].parentNode;
|
|
61
|
-
|
|
64
|
+
|
|
62
65
|
nodesToDelete.forEach(item => {
|
|
63
|
-
this._deleteNode(parent, item)
|
|
64
|
-
|
|
66
|
+
if (this._deleteNode(parent, item)) {
|
|
67
|
+
fore.signalChangeToElement(item.localName);
|
|
68
|
+
removedNodes.push(item);
|
|
69
|
+
}
|
|
65
70
|
});
|
|
71
|
+
if (removedNodes.length) {
|
|
72
|
+
fore.signalChangeToElement(parent.localName);
|
|
73
|
+
}
|
|
66
74
|
} else {
|
|
67
75
|
parent = nodesToDelete.parentNode;
|
|
68
|
-
|
|
76
|
+
if (this._deleteNode(parent, nodesToDelete)) {
|
|
77
|
+
fore.signalChangeToElement(parent.localName);
|
|
69
78
|
|
|
70
|
-
|
|
71
|
-
|
|
79
|
+
fore.signalChangeToElement(nodesToDelete.localName);
|
|
80
|
+
removedNodes.push(nodesToDelete);
|
|
81
|
+
}
|
|
72
82
|
}
|
|
73
83
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
if (removedNodes.length) {
|
|
85
|
+
await Fore.dispatch(instance, 'deleted', {
|
|
86
|
+
ref: path,
|
|
87
|
+
deletedNodes: removedNodes,
|
|
88
|
+
instanceId,
|
|
89
|
+
parent,
|
|
90
|
+
foreId: fore.id,
|
|
91
|
+
});
|
|
92
|
+
this.needsUpdate = true;
|
|
93
|
+
}
|
|
81
94
|
}
|
|
82
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Delete a node (if allowed). Does not hold for JSON
|
|
98
|
+
*
|
|
99
|
+
* @param {ParentNode} parent - The parent of the node to remove
|
|
100
|
+
* @param {ChildNode} node - The child to remove
|
|
101
|
+
*
|
|
102
|
+
* @returns {boolean} Whether the delete is allowed and succeeded
|
|
103
|
+
*/
|
|
83
104
|
_deleteNode(parent, node) {
|
|
84
|
-
if (
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
105
|
+
if (
|
|
106
|
+
parent.nodeType === Node.DOCUMENT_NODE ||
|
|
107
|
+
node.nodeType === Node.DOCUMENT_NODE ||
|
|
108
|
+
node.nodeType === Node.DOCUMENT_FRAGMENT_NODE ||
|
|
109
|
+
node.parentNode === null
|
|
110
|
+
) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
88
113
|
|
|
89
|
-
const mi = this.getModelItem();
|
|
90
|
-
|
|
114
|
+
const mi = this.getModel().getModelItem(node);
|
|
115
|
+
// Note that the model item can be absent, For elements that had no controls on them.
|
|
116
|
+
// In that case, allow removals
|
|
117
|
+
if (mi?.readonly) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
91
120
|
|
|
92
121
|
parent.removeChild(node);
|
|
93
|
-
}
|
|
94
122
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
actionPerformed() {
|
|
99
|
-
this.getModel().rebuild();
|
|
100
|
-
super.actionPerformed();
|
|
123
|
+
this.getModel().removeModelItem(node);
|
|
124
|
+
|
|
125
|
+
return true;
|
|
101
126
|
}
|
|
102
127
|
}
|
|
103
128
|
|
package/src/actions/fx-insert.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
} from '../xpath-evaluation.js';
|
|
8
8
|
import { XPathUtil } from '../xpath-util';
|
|
9
9
|
import { Fore } from '../fore.js';
|
|
10
|
+
import { getPath } from '../xpath-path.js';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* `fx-insert`
|
|
@@ -60,7 +61,6 @@ export class FxInsert extends AbstractAction {
|
|
|
60
61
|
this.keepValues = !!this.hasAttribute('keep-values');
|
|
61
62
|
}
|
|
62
63
|
|
|
63
|
-
|
|
64
64
|
_cloneOriginSequence(inscope, targetSequence) {
|
|
65
65
|
let originSequenceClone;
|
|
66
66
|
if (this.origin) {
|
|
@@ -76,13 +76,13 @@ export class FxInsert extends AbstractAction {
|
|
|
76
76
|
if in 'create-nodes' mode and origin targets a repeat, the repeat
|
|
77
77
|
we use the already during initData() created nodeset as a template for insertion
|
|
78
78
|
*/
|
|
79
|
-
if(this.origin.startsWith('#') && this.getOwnerForm().createNodes){
|
|
79
|
+
if (this.origin.startsWith('#') && this.getOwnerForm().createNodes) {
|
|
80
80
|
const repeat = this.getOwnerForm().querySelector(this.origin);
|
|
81
81
|
originSequenceClone = repeat.createdNodeset.cloneNode(true);
|
|
82
|
-
if(!originSequenceClone){
|
|
82
|
+
if (!originSequenceClone) {
|
|
83
83
|
console.error(`createdNodeset for repeat ${this.origin} does not exist`);
|
|
84
84
|
}
|
|
85
|
-
}else{
|
|
85
|
+
} else {
|
|
86
86
|
// originTarget = evaluateXPathToFirstNode(this.origin, inscope, this);
|
|
87
87
|
originTarget = evaluateXPathToFirstNode(this.origin, inscope, this);
|
|
88
88
|
if (Array.isArray(originTarget) && originTarget.length === 0) {
|
|
@@ -128,7 +128,7 @@ export class FxInsert extends AbstractAction {
|
|
|
128
128
|
|
|
129
129
|
// ### 'context' attribute takes precedence over 'ref'
|
|
130
130
|
if (this.hasAttribute('context')) {
|
|
131
|
-
[context] = evaluateXPathToNodes(this.getAttribute('context'), inscopeContext,
|
|
131
|
+
[context] = evaluateXPathToNodes(this.getAttribute('context'), inscopeContext, this);
|
|
132
132
|
inscope = inscopeContext;
|
|
133
133
|
}
|
|
134
134
|
|
|
@@ -145,7 +145,13 @@ export class FxInsert extends AbstractAction {
|
|
|
145
145
|
const originSequenceClone = this._cloneOriginSequence(inscope, targetSequence);
|
|
146
146
|
if (!originSequenceClone) return; // if no origin back out without effect
|
|
147
147
|
|
|
148
|
+
/**
|
|
149
|
+
* @type {Node}
|
|
150
|
+
*/
|
|
148
151
|
let insertLocationNode;
|
|
152
|
+
/**
|
|
153
|
+
* @type {number}
|
|
154
|
+
*/
|
|
149
155
|
let index;
|
|
150
156
|
|
|
151
157
|
// if the targetSequence is empty but we got an originSequence use inscope as context and ignore 'at' and 'position'
|
|
@@ -157,20 +163,18 @@ export class FxInsert extends AbstractAction {
|
|
|
157
163
|
fore.signalChangeToElement(originSequenceClone.localName);
|
|
158
164
|
index = 1;
|
|
159
165
|
} else {
|
|
160
|
-
|
|
161
166
|
// No context but creating nodes from UI
|
|
162
|
-
if(!inscope && this.getOwnerForm().createNodes){
|
|
167
|
+
if (!inscope && this.getOwnerForm().createNodes) {
|
|
163
168
|
const repeat = this.getOwnerForm().querySelector(this.origin);
|
|
164
169
|
inscope = getInScopeContext(repeat, repeat.ref);
|
|
165
170
|
insertLocationNode = inscope;
|
|
166
171
|
inscope.appendChild(originSequenceClone);
|
|
167
172
|
index = inscope.length - 1;
|
|
168
|
-
}else{
|
|
173
|
+
} else {
|
|
169
174
|
insertLocationNode = inscope;
|
|
170
175
|
inscope.appendChild(originSequenceClone);
|
|
171
176
|
index = 1;
|
|
172
177
|
}
|
|
173
|
-
|
|
174
178
|
}
|
|
175
179
|
} else {
|
|
176
180
|
/* ### insert at position given by 'at' or use the last item in the targetSequence ### */
|
|
@@ -216,6 +220,8 @@ export class FxInsert extends AbstractAction {
|
|
|
216
220
|
if (this.hasAttribute('context') && this.hasAttribute('ref')) {
|
|
217
221
|
// index=1;
|
|
218
222
|
inscope.append(originSequenceClone);
|
|
223
|
+
fore.signalChangeToElement(insertLocationNode);
|
|
224
|
+
fore.signalChangeToElement(originSequenceClone.localName);
|
|
219
225
|
} else if (this.hasAttribute('context')) {
|
|
220
226
|
index = 1;
|
|
221
227
|
insertLocationNode.prepend(originSequenceClone);
|
|
@@ -241,7 +247,7 @@ export class FxInsert extends AbstractAction {
|
|
|
241
247
|
// console.log('<<<<<<< resolved instance', inst);
|
|
242
248
|
// Note: the parent to insert under is always the parent of the inserted node. The 'context' is not always the parent if the sequence is empty, or the position is different
|
|
243
249
|
// const xpath = XPathUtil.getPath(originSequenceClone.parentNode, instanceId);
|
|
244
|
-
const xpath =
|
|
250
|
+
const xpath = getPath(insertLocationNode, instanceId);
|
|
245
251
|
|
|
246
252
|
const path = Fore.getDomNodeIndexString(originSequenceClone);
|
|
247
253
|
this.dispatchEvent(
|
|
@@ -252,13 +258,16 @@ export class FxInsert extends AbstractAction {
|
|
|
252
258
|
detail: { action: this, event: this.event, path },
|
|
253
259
|
}),
|
|
254
260
|
);
|
|
255
|
-
|
|
256
261
|
Fore.dispatch(inst, 'insert', {
|
|
257
|
-
|
|
258
|
-
|
|
262
|
+
insertedNodes: originSequenceClone,
|
|
263
|
+
insertedParent: insertLocationNode.parentNode,
|
|
264
|
+
ref: this.ref,
|
|
265
|
+
location: insertLocationNode,
|
|
259
266
|
position: this.position,
|
|
260
267
|
instanceId,
|
|
261
268
|
foreId: fore.id,
|
|
269
|
+
index,
|
|
270
|
+
xpath,
|
|
262
271
|
});
|
|
263
272
|
|
|
264
273
|
// todo: this actually should dispatch to respective instance
|
|
@@ -275,7 +284,6 @@ export class FxInsert extends AbstractAction {
|
|
|
275
284
|
);
|
|
276
285
|
|
|
277
286
|
this.needsUpdate = true;
|
|
278
|
-
console.log('Changed!', xpath);
|
|
279
287
|
return [xpath];
|
|
280
288
|
}
|
|
281
289
|
|
|
@@ -292,7 +300,7 @@ export class FxInsert extends AbstractAction {
|
|
|
292
300
|
|
|
293
301
|
actionPerformed(changedPaths) {
|
|
294
302
|
// ### make sure the necessary modelItems will get created
|
|
295
|
-
this.getModel().rebuild();
|
|
303
|
+
// this.getModel().rebuild();
|
|
296
304
|
super.actionPerformed();
|
|
297
305
|
}
|
|
298
306
|
|
|
@@ -22,23 +22,33 @@ class FxRefresh extends AbstractAction {
|
|
|
22
22
|
|
|
23
23
|
if (this.hasAttribute('self')) {
|
|
24
24
|
console.log(`### <<<<< refresh() self ${this} >>>>>`);
|
|
25
|
-
const control = XPathUtil.getClosest('fx-control', this);
|
|
25
|
+
const control = XPathUtil.getClosest('fx-control, fx-output, fx-upload', this);
|
|
26
26
|
if (control) {
|
|
27
|
-
control.refresh();
|
|
27
|
+
control.refresh(true);
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
if (this.hasAttribute('force')) {
|
|
32
32
|
console.log(`### <<<<< refresh() force ${this} >>>>>`);
|
|
33
|
-
this.getOwnerForm().
|
|
33
|
+
this.getOwnerForm().refresh(true);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if(this.hasAttribute('selector')){
|
|
37
|
+
const target = document.querySelector(this.getAttribute('selector'));
|
|
38
|
+
if (target && Fore.isUiElement(target.nodeName) && typeof target.refresh === 'function') {
|
|
39
|
+
target.refresh(true);
|
|
40
|
+
}
|
|
34
41
|
return;
|
|
35
42
|
}
|
|
36
43
|
if (this.hasAttribute('control')) {
|
|
37
44
|
const targetId = this.getAttribute('control');
|
|
38
45
|
console.log(`### <<<<< refresh() control '${targetId}' >>>>>`);
|
|
39
|
-
|
|
46
|
+
let ctrl = resolveId(targetId, this);
|
|
47
|
+
if(!ctrl){
|
|
48
|
+
ctrl = document.querySelector(`#${targetId}`);
|
|
49
|
+
}
|
|
40
50
|
if (ctrl && Fore.isUiElement(ctrl.nodeName) && typeof ctrl.refresh === 'function') {
|
|
41
|
-
ctrl.refresh();
|
|
51
|
+
ctrl.refresh(true);
|
|
42
52
|
}
|
|
43
53
|
return;
|
|
44
54
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import '../fx-model.js';
|
|
3
3
|
import { AbstractAction } from './abstract-action.js';
|
|
4
4
|
import { evaluateXPathToFirstNode } from '../xpath-evaluation.js';
|
|
5
|
+
import { FxBind } from '../fx-bind.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* `fx-replace` - replaces the node referred to with 'ref' with node referred to with 'with' attribute.
|
|
@@ -44,8 +45,9 @@ export default class FxReplace extends AbstractAction {
|
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
actionPerformed() {
|
|
47
|
-
this.getModel().
|
|
48
|
-
|
|
48
|
+
this.getModel().updateModel();
|
|
49
|
+
this.getOwnerForm().refresh(true); //todo: optimize and update only the affected subtree
|
|
50
|
+
this.dispatchActionPerformed();
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
replace(toReplace, replaceWith) {
|
|
@@ -63,7 +65,20 @@ export default class FxReplace extends AbstractAction {
|
|
|
63
65
|
const cloned = replaceWith.cloneNode(true);
|
|
64
66
|
toReplace.replaceWith(cloned);
|
|
65
67
|
}
|
|
66
|
-
//
|
|
68
|
+
// todo: add selective update and create and notify modelItem for toReplace and replaceWith
|
|
69
|
+
/*
|
|
70
|
+
let replaceWithModelItem = this.getModel().getModelItem(replaceWith);
|
|
71
|
+
if (!replaceWithModelItem) {
|
|
72
|
+
const replaceWithModelItem = FxBind.createModelItem(
|
|
73
|
+
this.getAttribute('with'),
|
|
74
|
+
replaceWith,
|
|
75
|
+
this,
|
|
76
|
+
null,
|
|
77
|
+
);
|
|
78
|
+
this.getModel().registerModelItem(replaceWithModelItem);
|
|
79
|
+
this.getOwnerForm().addToBatchedNotifications(replaceWithModelItem);
|
|
80
|
+
}
|
|
81
|
+
*/
|
|
67
82
|
// this.getModel().changed.push(modelitem);
|
|
68
83
|
this.needsUpdate = true;
|
|
69
84
|
}
|
package/src/actions/fx-reset.js
CHANGED
|
@@ -41,6 +41,12 @@ export class FxReset extends AbstractAction {
|
|
|
41
41
|
data.reset();
|
|
42
42
|
this.needsUpdate = true;
|
|
43
43
|
}
|
|
44
|
+
|
|
45
|
+
actionPerformed() {
|
|
46
|
+
this.getModel().updateModel();
|
|
47
|
+
this.getOwnerForm().refresh(true);
|
|
48
|
+
this.dispatchActionPerformed();
|
|
49
|
+
}
|
|
44
50
|
}
|
|
45
51
|
|
|
46
52
|
if (!customElements.get('fx-reset')) {
|
package/src/actions/fx-send.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import '../fx-model.js';
|
|
2
2
|
import '../fx-submission.js';
|
|
3
3
|
import { AbstractAction } from './abstract-action.js';
|
|
4
|
-
import {
|
|
4
|
+
import { getDocPath } from '../xpath-path.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* `fx-send` - finds and activates a `fx-submission` or a `fx-connection` element.
|
|
@@ -44,7 +44,7 @@ class FxSend extends AbstractAction {
|
|
|
44
44
|
id: this.id,
|
|
45
45
|
origin: this,
|
|
46
46
|
message: `<fx-connection id="${this.connection}"> not found`,
|
|
47
|
-
expr:
|
|
47
|
+
expr: getDocPath(this),
|
|
48
48
|
level: 'Error',
|
|
49
49
|
},
|
|
50
50
|
}),
|
|
@@ -66,7 +66,7 @@ class FxSend extends AbstractAction {
|
|
|
66
66
|
id: this.id,
|
|
67
67
|
origin: this,
|
|
68
68
|
message: `<fx-submission id="${this.submission}"> not found`,
|
|
69
|
-
expr:
|
|
69
|
+
expr: getDocPath(this),
|
|
70
70
|
level: 'Error',
|
|
71
71
|
},
|
|
72
72
|
}),
|
|
@@ -87,10 +87,13 @@ class FxSend extends AbstractAction {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
await submission.submit();
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
if (submission.replace === 'instance') {
|
|
91
|
+
this.getModel().updateModel();
|
|
92
|
+
// todo: this bypasses observers...
|
|
93
|
+
this.getOwnerForm().refresh(true); //whole instance changes - full refresh necessary
|
|
94
|
+
// this.getOwnerForm().addToBatchedNotifications(this.getOwnerForm());
|
|
95
|
+
// this.needsUpdate = true;
|
|
96
|
+
}
|
|
94
97
|
// if not of type fx-submission signal error
|
|
95
98
|
}
|
|
96
99
|
|
|
@@ -4,6 +4,7 @@ import { AbstractAction } from './abstract-action.js';
|
|
|
4
4
|
import { evaluateXPathToString } from '../xpath-evaluation.js';
|
|
5
5
|
import { Fore } from '../fore.js';
|
|
6
6
|
import getInScopeContext from '../getInScopeContext';
|
|
7
|
+
import { FxBind } from '../fx-bind';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* `fx-setattribute` allows to create and set an attribute value in the data.
|
|
@@ -58,7 +59,18 @@ export default class FxSetattribute extends AbstractAction {
|
|
|
58
59
|
return;
|
|
59
60
|
}
|
|
60
61
|
mi.node.setAttribute(this.attrName, this.attrValue);
|
|
62
|
+
const newModelItem = FxBind.createModelItem(
|
|
63
|
+
`${this.ref}/@${this.attrName}`,
|
|
64
|
+
mi.node.getAttributeNode(this.attrName),
|
|
65
|
+
this,
|
|
66
|
+
null,
|
|
67
|
+
);
|
|
68
|
+
this.getOwnerForm()
|
|
69
|
+
.getModel()
|
|
70
|
+
.registerModelItem(newModelItem);
|
|
71
|
+
this.getOwnerForm().addToBatchedNotifications(newModelItem);
|
|
61
72
|
this.needsUpdate = true;
|
|
73
|
+
newModelItem.notify();
|
|
62
74
|
}
|
|
63
75
|
}
|
|
64
76
|
|
|
@@ -39,14 +39,6 @@ export class FxSetfocus extends AbstractAction {
|
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
// ### focus action is itself hosted within a repeat
|
|
43
|
-
const parentIItem = targetElement.closest('fx-repeatitem');
|
|
44
|
-
if (parentIItem) {
|
|
45
|
-
targetElement = parentIItem.querySelector(selector);
|
|
46
|
-
this._focus(targetElement);
|
|
47
|
-
// return;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
42
|
// ### the target element is hosted within a repeat
|
|
51
43
|
const repeatitem = targetElement.closest('fx-repeatitem, .fx-repeatitem');
|
|
52
44
|
if (repeatitem) {
|
|
@@ -54,7 +46,18 @@ export class FxSetfocus extends AbstractAction {
|
|
|
54
46
|
// get the active repeatitem (only for fx-repeat for now - todo: support repeat attributes
|
|
55
47
|
const repeat = repeatitem.parentNode;
|
|
56
48
|
targetElement = repeat.querySelector(`[repeat-index] ${selector}`);
|
|
49
|
+
this._focus(targetElement);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ### focus action is itself hosted within a repeat
|
|
53
|
+
/*
|
|
54
|
+
const parentIItem = targetElement.closest('fx-repeatitem');
|
|
55
|
+
if (parentIItem) {
|
|
56
|
+
targetElement = parentIItem.querySelector(selector);
|
|
57
|
+
this._focus(targetElement);
|
|
58
|
+
// return;
|
|
57
59
|
}
|
|
60
|
+
*/
|
|
58
61
|
|
|
59
62
|
this._focus(targetElement);
|
|
60
63
|
if (this.hasAttribute('select')) {
|