@jinntec/fore 1.10.3 → 2.1.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 +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 +3 -0
- package/package.json +1 -1
- package/src/actions/abstract-action.js +101 -67
- package/src/actions/fx-confirm.js +3 -3
- package/src/actions/fx-construct-done.js +28 -0
- package/src/actions/fx-insert.js +53 -51
- package/src/actions/fx-load.js +3 -35
- package/src/actions/fx-refresh.js +3 -0
- package/src/actions/fx-setattribute.js +68 -0
- package/src/actions/fx-toggle.js +1 -1
- package/src/fore.js +79 -2
- package/src/fx-bind.js +1 -0
- package/src/fx-fore.js +116 -66
- package/src/fx-instance.js +1 -0
- package/src/fx-model.js +36 -11
- package/src/fx-submission.js +25 -5
- package/src/getInScopeContext.js +11 -5
- package/src/json-util.js +27 -0
- package/src/relevance.js +18 -0
- package/src/ui/abstract-control.js +2 -0
- package/src/ui/fx-case.js +5 -2
- package/src/ui/fx-container.js +22 -0
- package/src/ui/fx-control.js +25 -31
- package/src/ui/fx-droptarget.js +9 -0
- package/src/ui/fx-inspector.js +16 -12
- package/src/ui/fx-repeat-attributes.js +4 -2
- package/src/ui/fx-repeat.js +366 -355
- package/src/ui/fx-repeatitem.js +78 -86
- package/src/ui/fx-switch.js +7 -2
- package/src/ui/fx-trigger.js +0 -1
- package/src/withDraggability.js +218 -0
- package/src/xpath-evaluation.js +137 -0
package/index.js
CHANGED
|
@@ -22,6 +22,7 @@ import './src/ui/fx-case.js';
|
|
|
22
22
|
import './src/ui/fx-inspector.js';
|
|
23
23
|
import './src/ui/fx-dialog.js';
|
|
24
24
|
import './src/ui/fx-items.js';
|
|
25
|
+
import './src/ui/fx-droptarget.js';
|
|
25
26
|
|
|
26
27
|
import './src/tools/fx-action-log.js';
|
|
27
28
|
import './src/tools/fx-log-settings.js';
|
|
@@ -57,6 +58,8 @@ import './src/actions/fx-reset.js';
|
|
|
57
58
|
import './src/actions/fx-load.js';
|
|
58
59
|
import './src/actions/fx-toggleboolean.js';
|
|
59
60
|
import './src/actions/fx-call.js';
|
|
61
|
+
import './src/actions/fx-setattribute.js';
|
|
62
|
+
import './src/actions/fx-construct-done.js';
|
|
60
63
|
|
|
61
64
|
import './src/functions/fx-function.js';
|
|
62
65
|
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {foreElementMixin} from '../ForeElementMixin.js';
|
|
2
|
-
import {evaluateXPathToBoolean, resolveId} from '../xpath-evaluation.js';
|
|
2
|
+
import {evaluateXPathToBoolean, resolveId, evaluateXPath} from '../xpath-evaluation.js';
|
|
3
3
|
import getInScopeContext from '../getInScopeContext.js';
|
|
4
4
|
import {Fore} from '../fore.js';
|
|
5
5
|
import {FxFore} from '../fx-fore.js';
|
|
@@ -56,6 +56,18 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
|
|
|
56
56
|
ifExpr: {
|
|
57
57
|
type: String,
|
|
58
58
|
},
|
|
59
|
+
/**
|
|
60
|
+
* The iterate attribute can be added to any XForms action. It contains an expression
|
|
61
|
+
* that is evaluated once using the in-scope evaluation context before the action is
|
|
62
|
+
* executed, which will result in a sequence of items. The action will be executed with
|
|
63
|
+
* each item in the sequence as its context. This context replaces the default in scope
|
|
64
|
+
* evaluation context.
|
|
65
|
+
*
|
|
66
|
+
* The interaction with `@while` and `@if` is undefined.
|
|
67
|
+
*/
|
|
68
|
+
iterateExpr: {
|
|
69
|
+
type: String
|
|
70
|
+
},
|
|
59
71
|
/**
|
|
60
72
|
* whether nor not an action needs to run the update cycle
|
|
61
73
|
*/
|
|
@@ -88,8 +100,8 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
|
|
|
88
100
|
type: String,
|
|
89
101
|
},
|
|
90
102
|
/**
|
|
91
|
-
* boolean XPath expression. If true loop will be executed. If an ifExpr is present this
|
|
92
|
-
* to actually run the action.
|
|
103
|
+
* boolean XPath expression. If true loop will be executed. If an ifExpr is present this
|
|
104
|
+
* also needs to be true to actually run the action.
|
|
93
105
|
*/
|
|
94
106
|
whileExpr: {
|
|
95
107
|
type: String,
|
|
@@ -103,6 +115,9 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
|
|
|
103
115
|
this.needsUpdate = false;
|
|
104
116
|
}
|
|
105
117
|
|
|
118
|
+
disconnectedCallback() {
|
|
119
|
+
}
|
|
120
|
+
|
|
106
121
|
connectedCallback() {
|
|
107
122
|
this.style.display = 'none';
|
|
108
123
|
this.propagate = this.hasAttribute('propagate') ? this.getAttribute('propagate') : 'continue';
|
|
@@ -132,6 +147,7 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
|
|
|
132
147
|
this.ifExpr = this.hasAttribute('if') ? this.getAttribute('if') : null;
|
|
133
148
|
this.whileExpr = this.hasAttribute('while') ? this.getAttribute('while') : null;
|
|
134
149
|
this.delay = this.hasAttribute('delay') ? Number(this.getAttribute('delay')) : 0;
|
|
150
|
+
this.iterateExpr = this.hasAttribute('iterate') ? this.getAttribute('iterate') : null;
|
|
135
151
|
|
|
136
152
|
this._addUpdateListener();
|
|
137
153
|
|
|
@@ -185,9 +201,7 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
|
|
|
185
201
|
* @param e
|
|
186
202
|
*/
|
|
187
203
|
async execute(e) {
|
|
188
|
-
console.log(this);
|
|
189
|
-
// console.log('execute', this.event);
|
|
190
|
-
|
|
204
|
+
console.log(this, this.event);
|
|
191
205
|
|
|
192
206
|
if (e && e.target.nodeType !== Node.DOCUMENT_NODE && e.target !== window ){
|
|
193
207
|
/*
|
|
@@ -219,19 +233,8 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
|
|
|
219
233
|
);
|
|
220
234
|
}
|
|
221
235
|
|
|
222
|
-
|
|
223
|
-
// console.log('executing e', e);
|
|
224
|
-
// console.log('executing e phase', e.eventPhase);
|
|
236
|
+
// Outermost handling
|
|
225
237
|
if (FxFore.outermostHandler === null) {
|
|
226
|
-
// console.time('outermostHandler');
|
|
227
|
-
/*
|
|
228
|
-
console.info(
|
|
229
|
-
`%coutermost Action `,
|
|
230
|
-
'background:#e65100; color:white; padding:0.3rem; display:inline-block; white-space: nowrap; border-radius:0.3rem;',
|
|
231
|
-
this,
|
|
232
|
-
);
|
|
233
|
-
*/
|
|
234
|
-
// console.log('starting outermost handler',this);
|
|
235
238
|
FxFore.outermostHandler = this;
|
|
236
239
|
this.dispatchEvent(new CustomEvent('outermost-action-start', {
|
|
237
240
|
composed: true,
|
|
@@ -240,16 +243,6 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
|
|
|
240
243
|
}));
|
|
241
244
|
}
|
|
242
245
|
|
|
243
|
-
/*
|
|
244
|
-
if (FxFore.outermostHandler !== this) {
|
|
245
|
-
console.info(
|
|
246
|
-
`%cAction `,
|
|
247
|
-
'background:orange; color:white; padding:0.3rem; display:inline-block; white-space: nowrap; border-radius:0.3rem;',
|
|
248
|
-
this,
|
|
249
|
-
);
|
|
250
|
-
}
|
|
251
|
-
*/
|
|
252
|
-
// console.log('>>> outermostHandler', FxFore.outermostHandler);
|
|
253
246
|
|
|
254
247
|
if (e) {
|
|
255
248
|
this.currentEvent = e;
|
|
@@ -265,51 +258,26 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
|
|
|
265
258
|
this.nodeset = this.targetElement.nodeset;
|
|
266
259
|
}
|
|
267
260
|
|
|
268
|
-
|
|
261
|
+
// Order of application between if / while and iterate is undefined. See
|
|
262
|
+
// https://www.w3.org/MarkUp/Forms/wiki/@iterate
|
|
263
|
+
if (this.iterateExpr) {
|
|
264
|
+
// Same as whileExpr, let it go update UI afterwards
|
|
265
|
+
await this.handleIterateExpr();
|
|
266
|
+
this._finalizePerform(resolveThisEvent);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Check if 'if' condition is true - otherwise exist right away
|
|
269
271
|
if (this.ifExpr && !evaluateXPathToBoolean(this.ifExpr, getInScopeContext(this), this)) {
|
|
270
272
|
this._finalizePerform(resolveThisEvent);
|
|
271
273
|
return;
|
|
272
274
|
}
|
|
273
275
|
|
|
274
|
-
// console.log('performing action', this);
|
|
275
|
-
|
|
276
276
|
if (this.whileExpr) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
if (!XPathUtil.contains(this.getOwnerForm(), this)) {
|
|
283
|
-
// We are no longer in the document. Stop working
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
if (!evaluateXPathToBoolean(this.whileExpr, getInScopeContext(this), this)) {
|
|
288
|
-
// Done with iterating
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// Perform the action once. But quit if it errored
|
|
293
|
-
if (!this.performSafe()) {
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Go for one more iteration
|
|
298
|
-
if (this.delay) {
|
|
299
|
-
// If we have a delay, fire and forget this.
|
|
300
|
-
// Otherwise, if we have no delay, keep waiting for all iterations to be done.
|
|
301
|
-
// The while is then uninterruptable and immediate
|
|
302
|
-
loop();
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
await loop();
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
// After loop is done call actionPerformed to update the model and UI
|
|
309
|
-
await loop();
|
|
310
|
-
this._finalizePerform(resolveThisEvent);
|
|
311
|
-
|
|
312
|
-
return;
|
|
277
|
+
// After loop is done call actionPerformed to update the model and UI
|
|
278
|
+
await this.handleWhileExpr();
|
|
279
|
+
this._finalizePerform(resolveThisEvent);
|
|
280
|
+
return;
|
|
313
281
|
}
|
|
314
282
|
|
|
315
283
|
if (this.delay) {
|
|
@@ -327,6 +295,72 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
|
|
|
327
295
|
this._finalizePerform(resolveThisEvent);
|
|
328
296
|
}
|
|
329
297
|
|
|
298
|
+
async handleWhileExpr () {
|
|
299
|
+
// While: while the condition is true, delay a bit and execute the action
|
|
300
|
+
// Start by waiting
|
|
301
|
+
await wait(this.delay || 0);
|
|
302
|
+
|
|
303
|
+
if (!XPathUtil.contains(this.getOwnerForm(), this)) {
|
|
304
|
+
// We are no longer in the document. Stop working
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (!evaluateXPathToBoolean(this.whileExpr, getInScopeContext(this), this)) {
|
|
309
|
+
// Done with iterating
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Perform the action once. But quit if it failed
|
|
314
|
+
if (!this.performSafe()) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Go for one more iteration
|
|
319
|
+
if (this.delay) {
|
|
320
|
+
// If we have a delay, fire and forget this.
|
|
321
|
+
// Otherwise, if we have no delay, keep waiting for all iterations to be done.
|
|
322
|
+
// The while is then uninterruptable and immediate
|
|
323
|
+
|
|
324
|
+
this.handleWhileExpr();
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
await this.handleWhileExpr();
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
async handleIterateExpr () {
|
|
333
|
+
try {
|
|
334
|
+
// Iterate: get the context sequence and perform the action once per item.
|
|
335
|
+
const contextSequence = evaluateXPath(this.iterateExpr, getInScopeContext(this), this);
|
|
336
|
+
|
|
337
|
+
if (contextSequence.length === 0) {
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (!XPathUtil.contains(this.getOwnerForm(), this)) {
|
|
342
|
+
// We are no longer in the document. Stop working
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
for (const item of contextSequence) {
|
|
347
|
+
if (this.delay) {
|
|
348
|
+
await wait(this.delay || 0);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// This will be picked up in `getInscopeContext`
|
|
352
|
+
this.currentContext = item;
|
|
353
|
+
|
|
354
|
+
// Perform the action once. But quit if it failed
|
|
355
|
+
if (!await this.performSafe()) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
} finally {
|
|
360
|
+
this.currentContext = null;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
330
364
|
_finalizePerform(resolveThisEvent) {
|
|
331
365
|
this.currentEvent = null;
|
|
332
366
|
this.actionPerformed();
|
|
@@ -18,15 +18,15 @@ export class FxConfirm extends FxAction {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
connectedCallback() {
|
|
21
|
-
if(super.connectedCallback){
|
|
22
|
-
|
|
21
|
+
if (super.connectedCallback){
|
|
22
|
+
super.connectedCallback();
|
|
23
23
|
}
|
|
24
24
|
this.message = this.hasAttribute('message') ? this.getAttribute('message') : null;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
async perform() {
|
|
28
28
|
if (window.confirm(this.message)) {
|
|
29
|
-
super.perform();
|
|
29
|
+
await super.perform();
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { AbstractAction } from './abstract-action.js';
|
|
2
|
+
import {FxAction} from "./fx-action.js";
|
|
3
|
+
import {Fore} from "../fore.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* `fx-action`
|
|
7
|
+
* an action to wrap other actions and defers the update cycle until the end of the block.
|
|
8
|
+
*
|
|
9
|
+
* @customElement
|
|
10
|
+
* @demo demo/index.html
|
|
11
|
+
*/
|
|
12
|
+
export class FxConstructDone extends FxAction {
|
|
13
|
+
connectedCallback() {
|
|
14
|
+
// eslint-disable-next-line wc/guard-super-call
|
|
15
|
+
super.connectedCallback();
|
|
16
|
+
console.log('parentNode', this.parentNode);
|
|
17
|
+
if(this.parentNode.nodeName !== 'FX-MODEL'){
|
|
18
|
+
Fore.dispatch(this, 'error', {message:'parent is not a model'})
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
this.parentNode.addEventListener('model-construct-done', e => {
|
|
22
|
+
super.perform();
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (!customElements.get('fx-construct-done')) {
|
|
27
|
+
window.customElements.define('fx-construct-done', FxConstructDone);
|
|
28
|
+
}
|
package/src/actions/fx-insert.js
CHANGED
|
@@ -15,23 +15,23 @@ import {Fore} from '../fore.js';
|
|
|
15
15
|
* @customElement
|
|
16
16
|
*/
|
|
17
17
|
export class FxInsert extends AbstractAction {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
18
|
+
static get properties() {
|
|
19
|
+
return {
|
|
20
|
+
...super.properties,
|
|
21
|
+
at: {
|
|
22
|
+
type: Number,
|
|
23
|
+
},
|
|
24
|
+
position: {
|
|
25
|
+
type: Number,
|
|
26
|
+
},
|
|
27
|
+
origin: {
|
|
28
|
+
type: Object,
|
|
29
|
+
},
|
|
30
|
+
keepValues: {
|
|
31
|
+
type: Boolean,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
35
|
|
|
36
36
|
constructor() {
|
|
37
37
|
super();
|
|
@@ -127,26 +127,23 @@ export class FxInsert extends AbstractAction {
|
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
async perform() {
|
|
130
|
-
//
|
|
131
|
-
//
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
/*
|
|
135
|
-
todo: !!! calling super here does not correctly give the nodeset - it's likely still a bug in ForeElementMixin !!!
|
|
136
|
-
// super.perform();
|
|
137
|
-
console.log('this.nodeset', this.nodeset);
|
|
138
|
-
*/
|
|
139
|
-
|
|
130
|
+
// We have a few terms here: `inScope` is the 'current item' we have. It is the item we're
|
|
131
|
+
// copying and inserting elsewhere. If we have a `ref`, one of the nodes returned will
|
|
132
|
+
// become the sibling of this copy. The `context` is the new parent of the copied
|
|
133
|
+
// element. It's usually better to add a `context` because that deals with empty elements.
|
|
140
134
|
let inscope;
|
|
135
|
+
let context;
|
|
136
|
+
let targetSequence = [];
|
|
137
|
+
const inscopeContext = getInScopeContext(this);
|
|
138
|
+
|
|
141
139
|
// ### 'context' attribute takes precedence over 'ref'
|
|
142
|
-
let targetSequence;
|
|
143
140
|
if (this.hasAttribute('context')) {
|
|
144
|
-
|
|
145
|
-
targetSequence = evaluateXPathToNodes(
|
|
141
|
+
[context] = evaluateXPathToNodes(
|
|
146
142
|
this.getAttribute('context'),
|
|
147
|
-
|
|
143
|
+
inscopeContext,
|
|
148
144
|
this.getOwnerForm(),
|
|
149
145
|
);
|
|
146
|
+
inscope = inscopeContext;
|
|
150
147
|
}
|
|
151
148
|
|
|
152
149
|
if (this.hasAttribute('ref')) {
|
|
@@ -163,14 +160,19 @@ export class FxInsert extends AbstractAction {
|
|
|
163
160
|
let insertLocationNode;
|
|
164
161
|
let index;
|
|
165
162
|
|
|
166
|
-
// const idx = this._getInsertIndex(inscope, targetSequence);
|
|
167
|
-
// console.log('insert index', idx);
|
|
168
|
-
|
|
169
163
|
// if the targetSequence is empty but we got an originSequence use inscope as context and ignore 'at' and 'position'
|
|
170
164
|
if (targetSequence.length === 0) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
165
|
+
if (context) {
|
|
166
|
+
insertLocationNode = context;
|
|
167
|
+
context.appendChild(originSequenceClone);
|
|
168
|
+
index = 1;
|
|
169
|
+
} else {
|
|
170
|
+
// No context. We can insert into the `inscope`.
|
|
171
|
+
insertLocationNode = inscope;
|
|
172
|
+
inscope.appendChild(originSequenceClone);
|
|
173
|
+
index = 1;
|
|
174
|
+
|
|
175
|
+
}
|
|
174
176
|
} else {
|
|
175
177
|
/* ### insert at position given by 'at' or use the last item in the targetSequence ### */
|
|
176
178
|
if (this.hasAttribute('at')) {
|
|
@@ -221,31 +223,31 @@ export class FxInsert extends AbstractAction {
|
|
|
221
223
|
}
|
|
222
224
|
}
|
|
223
225
|
}
|
|
224
|
-
|
|
226
|
+
// instance('default')/items/item[index()]
|
|
225
227
|
|
|
226
228
|
// console.log('insert context item ', insertLocationNode);
|
|
227
229
|
// console.log('parent ', insertLocationNode.parentNode);
|
|
228
230
|
// console.log('instance ', this.getModel().getDefaultContext());
|
|
229
231
|
// Fore.dispatch()
|
|
230
232
|
|
|
231
|
-
|
|
233
|
+
// const instanceId = XPathUtil.resolveInstance(this, this.getAttribute('context'));
|
|
232
234
|
const instanceId = XPathUtil.resolveInstance(this, this.ref);
|
|
233
235
|
const inst = this.getModel().getInstance(instanceId);
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
236
|
+
// console.log('<<<<<<< resolved instance', inst);
|
|
237
|
+
// 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
|
|
238
|
+
// const xpath = XPathUtil.getPath(originSequenceClone.parentNode, instanceId);
|
|
237
239
|
const xpath = XPathUtil.getPath(insertLocationNode.parentNode, instanceId);
|
|
238
240
|
|
|
239
241
|
|
|
240
242
|
|
|
241
243
|
const path = Fore.getDomNodeIndexString(originSequenceClone);
|
|
242
244
|
this.dispatchEvent(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
245
|
+
new CustomEvent('execute-action', {
|
|
246
|
+
composed: true,
|
|
247
|
+
bubbles: true,
|
|
248
|
+
cancelable:true,
|
|
249
|
+
detail: { action: this, event:this.event, path },
|
|
250
|
+
}),
|
|
249
251
|
);
|
|
250
252
|
|
|
251
253
|
Fore.dispatch(inst,'insert',{
|
|
@@ -267,9 +269,9 @@ export class FxInsert extends AbstractAction {
|
|
|
267
269
|
}),
|
|
268
270
|
);
|
|
269
271
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
272
|
+
this.needsUpdate = true;
|
|
273
|
+
console.log('Changed!', xpath)
|
|
274
|
+
return [xpath];
|
|
273
275
|
}
|
|
274
276
|
|
|
275
277
|
// eslint-disable-next-line class-methods-use-this
|
package/src/actions/fx-load.js
CHANGED
|
@@ -5,10 +5,9 @@ import {XPathUtil} from "../xpath-util.js";
|
|
|
5
5
|
import {Fore} from "../fore.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* `fx-
|
|
9
|
-
*
|
|
10
|
-
* Action to display messages to the user.
|
|
8
|
+
* `fx-load`
|
|
11
9
|
*
|
|
10
|
+
* Action to load a window, tab or embed some Html into the current page at given location.
|
|
12
11
|
*
|
|
13
12
|
*/
|
|
14
13
|
class FxLoad extends AbstractAction {
|
|
@@ -145,24 +144,14 @@ class FxLoad extends AbstractAction {
|
|
|
145
144
|
});
|
|
146
145
|
const data = await response.text();
|
|
147
146
|
// console.log('data loaded: ', data);
|
|
147
|
+
// const data = Fore.loadHtml(resolvedUrl);
|
|
148
148
|
|
|
149
149
|
// todo: if data contain '<template' element as first child instanciate and insert it
|
|
150
150
|
if (!this.attachTo) {
|
|
151
151
|
this.innerHtml = data;
|
|
152
152
|
}
|
|
153
|
-
/*
|
|
154
|
-
if (this.attachTo.startsWith('#')) {
|
|
155
|
-
const targetId = this.attachTo.substring(1);
|
|
156
|
-
const resolved = resolveId(targetId, this);
|
|
157
|
-
resolved.innerHTML = '';
|
|
158
|
-
resolved.innerHTML = data;
|
|
159
|
-
}
|
|
160
|
-
*/
|
|
161
153
|
this._attachToElement(data);
|
|
162
|
-
|
|
163
|
-
|
|
164
154
|
Fore.dispatch(this, 'loaded', {url: this.url})
|
|
165
|
-
|
|
166
155
|
} catch (error) {
|
|
167
156
|
throw new Error(`failed loading data ${error}`);
|
|
168
157
|
}
|
|
@@ -228,27 +217,6 @@ class FxLoad extends AbstractAction {
|
|
|
228
217
|
return replaced;
|
|
229
218
|
}
|
|
230
219
|
|
|
231
|
-
|
|
232
|
-
/*
|
|
233
|
-
_getValue() {
|
|
234
|
-
if (this.hasAttribute('value')) {
|
|
235
|
-
const valAttr = this.getAttribute('value');
|
|
236
|
-
try {
|
|
237
|
-
const inscopeContext = getInScopeContext(this, valAttr);
|
|
238
|
-
return evaluateXPathToString(valAttr, inscopeContext, this);
|
|
239
|
-
} catch (error) {
|
|
240
|
-
console.error(error);
|
|
241
|
-
Fore.dispatch(this, 'error', {message: error});
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
if (this.textContent) {
|
|
245
|
-
return this.textContent;
|
|
246
|
-
}
|
|
247
|
-
return null;
|
|
248
|
-
}
|
|
249
|
-
*/
|
|
250
|
-
|
|
251
|
-
|
|
252
220
|
}
|
|
253
221
|
|
|
254
222
|
if (!customElements.get('fx-load')) {
|
|
@@ -21,6 +21,7 @@ class FxRefresh extends AbstractAction {
|
|
|
21
21
|
);
|
|
22
22
|
|
|
23
23
|
if (this.hasAttribute('self')) {
|
|
24
|
+
console.log(`### <<<<< refresh() self ${this} >>>>>`);
|
|
24
25
|
const control = XPathUtil.getClosest('fx-control', this);
|
|
25
26
|
if (control) {
|
|
26
27
|
control.refresh();
|
|
@@ -28,11 +29,13 @@ class FxRefresh extends AbstractAction {
|
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
if(this.hasAttribute('force')){
|
|
32
|
+
console.log(`### <<<<< refresh() force ${this} >>>>>`);
|
|
31
33
|
this.getOwnerForm().forceRefresh();
|
|
32
34
|
return;
|
|
33
35
|
}
|
|
34
36
|
if(this.hasAttribute('control')){
|
|
35
37
|
const targetId = this.getAttribute('control');
|
|
38
|
+
console.log(`### <<<<< refresh() control '${targetId}' >>>>>`);
|
|
36
39
|
const ctrl = resolveId(targetId, this);
|
|
37
40
|
if (ctrl && Fore.isUiElement(ctrl.nodeName) && typeof ctrl.refresh === 'function') {
|
|
38
41
|
ctrl.refresh();
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// import { FxAction } from './fx-action.js';
|
|
2
|
+
import '../fx-model.js';
|
|
3
|
+
import {AbstractAction} from './abstract-action.js';
|
|
4
|
+
import {evaluateXPathToString} from '../xpath-evaluation.js';
|
|
5
|
+
import {Fore} from '../fore.js';
|
|
6
|
+
import getInScopeContext from "../getInScopeContext";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* `fx-setattribute` allows to create and set an attribute value in the data.
|
|
10
|
+
*
|
|
11
|
+
* @customElement
|
|
12
|
+
*/
|
|
13
|
+
export default class FxSetattribute extends AbstractAction {
|
|
14
|
+
static get properties() {
|
|
15
|
+
return {
|
|
16
|
+
...super.properties,
|
|
17
|
+
ref: {
|
|
18
|
+
type: String,
|
|
19
|
+
},
|
|
20
|
+
attrName: {
|
|
21
|
+
type: String,
|
|
22
|
+
},
|
|
23
|
+
attrValue:{
|
|
24
|
+
type: String
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
constructor() {
|
|
30
|
+
super();
|
|
31
|
+
this.ref = '';
|
|
32
|
+
this.attrName = '';
|
|
33
|
+
this.attrValue = '';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
connectedCallback() {
|
|
37
|
+
if (super.connectedCallback) {
|
|
38
|
+
super.connectedCallback();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (this.hasAttribute('ref')) {
|
|
42
|
+
this.ref = this.getAttribute('ref');
|
|
43
|
+
} else {
|
|
44
|
+
throw new Error('fx-setvalue must specify a "ref" attribute');
|
|
45
|
+
}
|
|
46
|
+
this.attrName = this.hasAttribute('name') ? this.getAttribute('name') : null;
|
|
47
|
+
this.attrValue = this.hasAttribute('value') ? this.getAttribute('value') : '';
|
|
48
|
+
if(!this.attrName){
|
|
49
|
+
Fore.dispatch('this', 'error',{message:'name or value not specified'});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async perform() {
|
|
54
|
+
super.perform();
|
|
55
|
+
const mi = this.getModelItem();
|
|
56
|
+
if(mi.node.nodeType !== Node.ELEMENT_NODE){
|
|
57
|
+
Fore.dispatch('this', 'error',{message:'referenced item is not an element'});
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
mi.node.setAttribute(this.attrName, this.attrValue);
|
|
61
|
+
this.needsUpdate = true;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!customElements.get('fx-setattribute')) {
|
|
67
|
+
window.customElements.define('fx-setattribute', FxSetattribute);
|
|
68
|
+
}
|