@jinntec/fore 1.0.0-5 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -27
- package/dist/fore-dev.js +43 -0
- package/dist/fore-dev.js.map +1 -0
- package/dist/fore.js +37 -0
- package/dist/fore.js.map +1 -0
- package/index.js +2 -1
- package/package.json +35 -39
- package/resources/fore.css +22 -54
- package/src/DependencyNotifyingDomFacade.js +5 -13
- package/src/ForeElementMixin.js +13 -20
- package/src/actions/abstract-action.js +14 -9
- package/src/actions/fx-action.js +6 -5
- package/src/actions/fx-append.js +8 -17
- package/src/actions/fx-confirm.js +3 -1
- package/src/actions/fx-delete.js +6 -3
- package/src/actions/fx-dispatch.js +9 -8
- package/src/actions/fx-hide.js +9 -6
- package/src/actions/fx-insert.js +27 -14
- package/src/actions/fx-message.js +3 -1
- package/src/actions/fx-refresh.js +11 -1
- package/src/actions/fx-replace.js +68 -0
- package/src/actions/fx-return.js +42 -0
- package/src/actions/fx-send.js +3 -1
- package/src/actions/fx-setvalue.js +58 -51
- package/src/actions/fx-show.js +8 -4
- package/src/actions/fx-toggle.js +13 -9
- package/src/actions/fx-update.js +3 -1
- package/src/dep_graph.js +1 -1
- package/src/drawdown.js +67 -82
- package/src/fore.js +141 -25
- package/src/functions/fx-function.js +11 -3
- package/src/fx-bind.js +39 -199
- package/src/fx-fore.js +101 -68
- package/src/fx-header.js +3 -1
- package/src/fx-instance.js +9 -1
- package/src/fx-model.js +31 -23
- package/src/fx-submission.js +73 -47
- package/src/fx-var.js +7 -4
- package/src/getInScopeContext.js +23 -16
- package/src/modelitem.js +4 -4
- package/src/relevance.js +65 -0
- package/src/ui/abstract-control.js +55 -35
- package/src/ui/fx-alert.js +7 -1
- package/src/ui/fx-case.js +3 -1
- package/src/ui/fx-container.js +4 -2
- package/src/ui/fx-control.js +283 -33
- package/src/ui/fx-dialog.js +50 -45
- package/src/ui/fx-group.js +3 -1
- package/src/ui/fx-hint.js +4 -1
- package/src/ui/fx-inspector.js +117 -17
- package/src/ui/fx-items.js +7 -5
- package/src/ui/fx-output.js +14 -5
- package/src/ui/fx-repeat.js +13 -26
- package/src/ui/fx-repeatitem.js +10 -4
- package/src/ui/fx-switch.js +3 -1
- package/src/ui/fx-trigger.js +3 -1
- package/src/xpath-evaluation.js +114 -102
- package/src/xpath-util.js +1 -5
- package/dist/fore-all.js +0 -140
- package/dist/fore-debug.js +0 -140
- package/src/.DS_Store +0 -0
- package/src/actions/.DS_Store +0 -0
- package/src/ui/.DS_Store +0 -0
package/src/fx-bind.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DependencyNotifyingDomFacade } from './DependencyNotifyingDomFacade.js';
|
|
2
2
|
import { foreElementMixin } from './ForeElementMixin.js';
|
|
3
|
+
import { Fore } from './fore.js';
|
|
3
4
|
import { ModelItem } from './modelitem.js';
|
|
4
5
|
import {
|
|
5
6
|
evaluateXPathToBoolean,
|
|
@@ -32,98 +33,8 @@ export class FxBind extends foreElementMixin(HTMLElement) {
|
|
|
32
33
|
|
|
33
34
|
static TYPE_DEFAULT = 'xs:string';
|
|
34
35
|
|
|
35
|
-
/*
|
|
36
|
-
static get styles() {
|
|
37
|
-
return css`
|
|
38
|
-
:host {
|
|
39
|
-
display: none;
|
|
40
|
-
}
|
|
41
|
-
`;
|
|
42
|
-
}
|
|
43
|
-
*/
|
|
44
|
-
|
|
45
|
-
/*
|
|
46
|
-
static get properties() {
|
|
47
|
-
return {
|
|
48
|
-
...super.properties,
|
|
49
|
-
|
|
50
|
-
/!**
|
|
51
|
-
* allows to calculate a value. This value will become readonly.
|
|
52
|
-
*!/
|
|
53
|
-
calculate: {
|
|
54
|
-
type: String
|
|
55
|
-
},
|
|
56
|
-
contextNode:{
|
|
57
|
-
type:Object
|
|
58
|
-
},
|
|
59
|
-
/!**
|
|
60
|
-
* arbitrary XPath resolving to xs:boolean - defaults to 'true()'
|
|
61
|
-
*!/
|
|
62
|
-
constraint: {
|
|
63
|
-
type: String
|
|
64
|
-
},
|
|
65
|
-
/!**
|
|
66
|
-
* id of this bind
|
|
67
|
-
*!/
|
|
68
|
-
id:{
|
|
69
|
-
type:String
|
|
70
|
-
},
|
|
71
|
-
/!**
|
|
72
|
-
* the nodeset the bind is referring to by it's binding expression (ref attribute)
|
|
73
|
-
*!/
|
|
74
|
-
nodeset: {
|
|
75
|
-
type: Array
|
|
76
|
-
},
|
|
77
|
-
/!**
|
|
78
|
-
* the owning model of this bind
|
|
79
|
-
*!/
|
|
80
|
-
model:{
|
|
81
|
-
type:Object
|
|
82
|
-
},
|
|
83
|
-
/!**
|
|
84
|
-
* XPath statement resolving to xs:boolean to switch between readonly and readwrite mode - defaults to 'false()'
|
|
85
|
-
*!/
|
|
86
|
-
readonly: {
|
|
87
|
-
type: String
|
|
88
|
-
},
|
|
89
|
-
/!**
|
|
90
|
-
* the XPath binding expression of this bind
|
|
91
|
-
*!/
|
|
92
|
-
ref: {
|
|
93
|
-
type: String
|
|
94
|
-
},
|
|
95
|
-
/!**
|
|
96
|
-
* XPath statement resolving to xs:boolean to switch between relevant and non-relevant mode - defaults to 'true()'
|
|
97
|
-
*!/
|
|
98
|
-
relevant: {
|
|
99
|
-
type: String
|
|
100
|
-
},
|
|
101
|
-
/!**
|
|
102
|
-
* XPath statement resolving to xs:boolean to switch between required and optional - defaults to 'false'.
|
|
103
|
-
*!/
|
|
104
|
-
required: {
|
|
105
|
-
type: String
|
|
106
|
-
},
|
|
107
|
-
/!**
|
|
108
|
-
* XPath statement
|
|
109
|
-
*!/
|
|
110
|
-
type: {
|
|
111
|
-
type: String
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
*/
|
|
116
|
-
|
|
117
36
|
constructor() {
|
|
118
37
|
super();
|
|
119
|
-
// this.id='';
|
|
120
|
-
// this.ref = '';
|
|
121
|
-
// this.readonly = 'false()';
|
|
122
|
-
// this.required = 'false()';
|
|
123
|
-
// this.relevant = 'true()';
|
|
124
|
-
// this.constraint = 'true()';
|
|
125
|
-
// this.type = 'xs:string';
|
|
126
|
-
// this.calculate = '';
|
|
127
38
|
this.nodeset = [];
|
|
128
39
|
this.model = {};
|
|
129
40
|
this.contextNode = {};
|
|
@@ -165,26 +76,23 @@ export class FxBind extends foreElementMixin(HTMLElement) {
|
|
|
165
76
|
this._processChildren(model);
|
|
166
77
|
}
|
|
167
78
|
|
|
168
|
-
/*
|
|
169
|
-
//todo: certainly not ideal to rely on duplicating instance id on instance document - better way later ;)
|
|
170
|
-
static getPath(node){
|
|
171
|
-
let path = fx.evaluateXPath('path()',node);
|
|
172
|
-
const instanceId = node.ownerDocument.firstElementChild.getAttribute('id');
|
|
173
|
-
if(instanceId !== 'default'){
|
|
174
|
-
return '#' + instanceId + FxBind.shortenPath(path);
|
|
175
|
-
}else {
|
|
176
|
-
return FxBind.shortenPath(path);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
*/
|
|
181
|
-
|
|
182
79
|
_buildBindGraph() {
|
|
183
80
|
if (this.bindType === 'xml') {
|
|
184
81
|
this.nodeset.forEach(node => {
|
|
185
82
|
const path = XPathUtil.getPath(node);
|
|
186
83
|
this.model.mainGraph.addNode(path, node);
|
|
187
84
|
|
|
85
|
+
/* ### catching references in the 'ref' itself...
|
|
86
|
+
todo: investigate cases where 'ref' attributes use predicates pointing to other nodes. These would not be handled
|
|
87
|
+
in current implementation.
|
|
88
|
+
|
|
89
|
+
General question: are there valid use-cases for using a 'filter' expression to narrow the nodeset
|
|
90
|
+
where to apply constraints? Guess yes and if it's 'just' for reducing the amount of necessary modelItem objects.
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
*/
|
|
94
|
+
// const foreignRefs = this.getReferences(this.ref);
|
|
95
|
+
|
|
188
96
|
if (this.calculate) {
|
|
189
97
|
this.model.mainGraph.addNode(`${path}:calculate`, node);
|
|
190
98
|
// Calculated values are a dependency of the model item.
|
|
@@ -271,14 +179,6 @@ export class FxBind extends foreElementMixin(HTMLElement) {
|
|
|
271
179
|
});
|
|
272
180
|
}
|
|
273
181
|
|
|
274
|
-
/*
|
|
275
|
-
render() {
|
|
276
|
-
return html`
|
|
277
|
-
<slot></slot>
|
|
278
|
-
`;
|
|
279
|
-
}
|
|
280
|
-
*/
|
|
281
|
-
|
|
282
182
|
getAlert() {
|
|
283
183
|
if (this.hasAttribute('alert')) {
|
|
284
184
|
return this.getAttribute('alert');
|
|
@@ -290,33 +190,6 @@ export class FxBind extends foreElementMixin(HTMLElement) {
|
|
|
290
190
|
return null;
|
|
291
191
|
}
|
|
292
192
|
|
|
293
|
-
/*
|
|
294
|
-
firstUpdated(_changedProperties) {
|
|
295
|
-
super.firstUpdated(_changedProperties);
|
|
296
|
-
}
|
|
297
|
-
*/
|
|
298
|
-
|
|
299
|
-
/*
|
|
300
|
-
namespaceResolver(prefix) {
|
|
301
|
-
// TODO: Do proper namespace resolving. Look at the ancestry / namespacesInScope of the declaration
|
|
302
|
-
|
|
303
|
-
/!**
|
|
304
|
-
* for (let ancestor = this; ancestor; ancestor = ancestor.parentNode) {
|
|
305
|
-
* if (ancestor.getAttribute(`xmlns:${prefix}`)) {
|
|
306
|
-
* // Return value
|
|
307
|
-
* }
|
|
308
|
-
* }
|
|
309
|
-
*!/
|
|
310
|
-
|
|
311
|
-
// console.log('namespaceResolver prefix', prefix);
|
|
312
|
-
const ns = {
|
|
313
|
-
xhtml: 'http://www.w3.org/1999/xhtml',
|
|
314
|
-
// '' : Fore.XFORMS_NAMESPACE_URI
|
|
315
|
-
};
|
|
316
|
-
return ns[prefix] || null;
|
|
317
|
-
}
|
|
318
|
-
*/
|
|
319
|
-
|
|
320
193
|
/**
|
|
321
194
|
* overwrites
|
|
322
195
|
*/
|
|
@@ -361,11 +234,6 @@ export class FxBind extends foreElementMixin(HTMLElement) {
|
|
|
361
234
|
_createModelItems() {
|
|
362
235
|
// console.log('#### ', thi+s.nodeset);
|
|
363
236
|
|
|
364
|
-
/*
|
|
365
|
-
if(XPathUtil.isSelfReference(this.ref)){
|
|
366
|
-
return;
|
|
367
|
-
}
|
|
368
|
-
*/
|
|
369
237
|
if (Array.isArray(this.nodeset)) {
|
|
370
238
|
// todo - iterate and create
|
|
371
239
|
// console.log('################################################ ', this.nodeset);
|
|
@@ -380,54 +248,6 @@ export class FxBind extends foreElementMixin(HTMLElement) {
|
|
|
380
248
|
}
|
|
381
249
|
}
|
|
382
250
|
|
|
383
|
-
static lazyCreateModelitems(model, ref, nodeset) {
|
|
384
|
-
if (Array.isArray(nodeset)) {
|
|
385
|
-
Array.from(nodeset).forEach(n => {
|
|
386
|
-
FxBind.lazyCreateModelItem(model, ref, n);
|
|
387
|
-
});
|
|
388
|
-
} else {
|
|
389
|
-
FxBind.lazyCreateModelItem(model, ref, nodeset);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
/*
|
|
394
|
-
static lazyCreateModelItem(model,ref,node){
|
|
395
|
-
console.log('lazyCreateModelItem ', node);
|
|
396
|
-
|
|
397
|
-
let mItem = {};
|
|
398
|
-
let targetNode = {};
|
|
399
|
-
if(node === null) return null;
|
|
400
|
-
if(node.nodeType === node.TEXT_NODE){
|
|
401
|
-
// const parent = node.parentNode;
|
|
402
|
-
// console.log('PARENT ', parent);
|
|
403
|
-
targetNode = node.parentNode;
|
|
404
|
-
}else {
|
|
405
|
-
targetNode = node;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
// const path = fx.evaluateXPath('path()',node);
|
|
409
|
-
const path = FxBind.getPath(node);
|
|
410
|
-
|
|
411
|
-
// const path = Fore.evaluateXPath ('path()', node, this, Fore.namespaceResolver) ;
|
|
412
|
-
|
|
413
|
-
// ### intializing ModelItem with default values (as there is no <fx-bind> matching for given ref)
|
|
414
|
-
const mi = new ModelItem(path,
|
|
415
|
-
ref,
|
|
416
|
-
FxBind.READONLY_DEFAULT,
|
|
417
|
-
FxBind.RELEVANT_DEFAULT,
|
|
418
|
-
FxBind.REQUIRED_DEFAULT,
|
|
419
|
-
FxBind.CONSTRAINT_DEFAULT,
|
|
420
|
-
FxBind.TYPE_DEFAULT,
|
|
421
|
-
targetNode,
|
|
422
|
-
this);
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
// console.log('new ModelItem is instanceof ModelItem ', mi instanceof ModelItem);
|
|
426
|
-
model.registerModelItem(mi);
|
|
427
|
-
return mi;
|
|
428
|
-
}
|
|
429
|
-
*/
|
|
430
|
-
|
|
431
251
|
/**
|
|
432
252
|
* creates a ModelItem for given instance node.
|
|
433
253
|
*
|
|
@@ -452,7 +272,7 @@ export class FxBind extends foreElementMixin(HTMLElement) {
|
|
|
452
272
|
if bind is the dot expression we use the modelitem of the parent
|
|
453
273
|
*/
|
|
454
274
|
if (XPathUtil.isSelfReference(this.ref)) {
|
|
455
|
-
const parentBoundElement =
|
|
275
|
+
const parentBoundElement = Fore.getClosest('fx-bind[ref]', this.parentElement);
|
|
456
276
|
console.log('parent bound element ', parentBoundElement);
|
|
457
277
|
|
|
458
278
|
if (parentBoundElement) {
|
|
@@ -514,16 +334,34 @@ export class FxBind extends foreElementMixin(HTMLElement) {
|
|
|
514
334
|
*/
|
|
515
335
|
_getReferencesForProperty(propertyExpr) {
|
|
516
336
|
if (propertyExpr) {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
337
|
+
return this.getReferences(propertyExpr);
|
|
338
|
+
}
|
|
339
|
+
return [];
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
getReferences(propertyExpr) {
|
|
343
|
+
const touchedNodes = new Set();
|
|
344
|
+
const domFacade = new DependencyNotifyingDomFacade(otherNode => touchedNodes.add(otherNode));
|
|
345
|
+
this.nodeset.forEach(node => {
|
|
346
|
+
evaluateXPathToString(propertyExpr, node, this, domFacade);
|
|
347
|
+
});
|
|
348
|
+
return Array.from(touchedNodes.values());
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/*
|
|
352
|
+
static getReferencesForRef(ref,nodeset){
|
|
353
|
+
if (ref && nodeset) {
|
|
354
|
+
const touchedNodes = new Set();
|
|
355
|
+
const domFacade = new DependencyNotifyingDomFacade(otherNode => touchedNodes.add(otherNode));
|
|
356
|
+
nodeset.forEach(node => {
|
|
357
|
+
evaluateXPathToString(ref, node, this, domFacade);
|
|
358
|
+
});
|
|
522
359
|
|
|
523
360
|
return Array.from(touchedNodes.values());
|
|
524
361
|
}
|
|
525
362
|
return [];
|
|
526
363
|
}
|
|
364
|
+
*/
|
|
527
365
|
|
|
528
366
|
_initBooleanModelItemProperty(property, node) {
|
|
529
367
|
// evaluate expression to boolean
|
|
@@ -562,4 +400,6 @@ export class FxBind extends foreElementMixin(HTMLElement) {
|
|
|
562
400
|
return 'default';
|
|
563
401
|
}
|
|
564
402
|
}
|
|
565
|
-
customElements.
|
|
403
|
+
if (!customElements.get('fx-bind')) {
|
|
404
|
+
customElements.define('fx-bind', FxBind);
|
|
405
|
+
}
|
package/src/fx-fore.js
CHANGED
|
@@ -16,7 +16,10 @@ import { XPathUtil } from './xpath-util.js';
|
|
|
16
16
|
*
|
|
17
17
|
* Main responsiblities are initialization and updating of model and instances, update of UI (refresh) and global messaging.
|
|
18
18
|
*
|
|
19
|
-
*
|
|
19
|
+
* @event compute-exception - dispatched in case the dependency graph is cirular
|
|
20
|
+
* @event refresh-done - dispatched after a refresh() run
|
|
21
|
+
* @event ready - dispatched after Fore has fully been initialized
|
|
22
|
+
* @event error - dispatches error when template expression fails to evaluate
|
|
20
23
|
*
|
|
21
24
|
* @ts-check
|
|
22
25
|
*/
|
|
@@ -73,10 +76,10 @@ export class FxFore extends HTMLElement {
|
|
|
73
76
|
:host ::slotted(fx-model){
|
|
74
77
|
display:none;
|
|
75
78
|
}
|
|
76
|
-
:host(.fx-ready){
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
79
|
+
// :host(.fx-ready){
|
|
80
|
+
// animation: fadein .4s forwards;
|
|
81
|
+
// display:block;
|
|
82
|
+
// }
|
|
80
83
|
|
|
81
84
|
#modalMessage .dialogActions{
|
|
82
85
|
text-align:center;
|
|
@@ -178,6 +181,25 @@ export class FxFore extends HTMLElement {
|
|
|
178
181
|
}
|
|
179
182
|
|
|
180
183
|
connectedCallback() {
|
|
184
|
+
/*
|
|
185
|
+
document.addEventListener('ready', (e) =>{
|
|
186
|
+
if(e.target !== this){
|
|
187
|
+
// e.preventDefault();
|
|
188
|
+
console.log('>>> e', e);
|
|
189
|
+
console.log('event this', this);
|
|
190
|
+
// console.log('event eventPhase', e.eventPhase);
|
|
191
|
+
// console.log('event cancelable', e.cancelable);
|
|
192
|
+
console.log('event target', e.target);
|
|
193
|
+
console.log('event composed', e.composedPath());
|
|
194
|
+
console.log('<<< event stopping');
|
|
195
|
+
e.stopPropagation();
|
|
196
|
+
}else{
|
|
197
|
+
console.log('event proceed', this);
|
|
198
|
+
}
|
|
199
|
+
// e.stopImmediatePropagation();
|
|
200
|
+
},true);
|
|
201
|
+
*/
|
|
202
|
+
|
|
181
203
|
this.lazyRefresh = this.hasAttribute('refresh-on-view');
|
|
182
204
|
if (this.lazyRefresh) {
|
|
183
205
|
const options = {
|
|
@@ -188,10 +210,10 @@ export class FxFore extends HTMLElement {
|
|
|
188
210
|
this.intersectionObserver = new IntersectionObserver(this.handleIntersect, options);
|
|
189
211
|
}
|
|
190
212
|
|
|
191
|
-
this.src = this.hasAttribute('src')? this.getAttribute('src'):null;
|
|
192
|
-
if(this.src){
|
|
213
|
+
this.src = this.hasAttribute('src') ? this.getAttribute('src') : null;
|
|
214
|
+
if (this.src) {
|
|
193
215
|
this._loadFromSrc();
|
|
194
|
-
return
|
|
216
|
+
return;
|
|
195
217
|
}
|
|
196
218
|
|
|
197
219
|
const slot = this.shadowRoot.querySelector('slot');
|
|
@@ -201,7 +223,7 @@ export class FxFore extends HTMLElement {
|
|
|
201
223
|
modelElem => modelElem.nodeName.toUpperCase() === 'FX-MODEL',
|
|
202
224
|
);
|
|
203
225
|
if (!modelElement) {
|
|
204
|
-
const generatedModel = document.createElement('
|
|
226
|
+
const generatedModel = document.createElement('fx-model');
|
|
205
227
|
this.appendChild(generatedModel);
|
|
206
228
|
modelElement = generatedModel;
|
|
207
229
|
}
|
|
@@ -209,23 +231,22 @@ export class FxFore extends HTMLElement {
|
|
|
209
231
|
console.log(
|
|
210
232
|
`########## FORE: kick off processing for ... ${window.location.href} ##########`,
|
|
211
233
|
);
|
|
212
|
-
if(this.src){
|
|
234
|
+
if (this.src) {
|
|
213
235
|
console.log('########## FORE: loaded from ... ', this.src, '##########');
|
|
214
236
|
}
|
|
215
237
|
modelElement.modelConstruct();
|
|
216
238
|
}
|
|
217
239
|
this.model = modelElement;
|
|
218
240
|
});
|
|
219
|
-
this.addEventListener('path-mutated',
|
|
241
|
+
this.addEventListener('path-mutated', e => {
|
|
220
242
|
console.log('path-mutated event received', e.detail.path, e.detail.index);
|
|
221
243
|
this.someInstanceDataStructureChanged = true;
|
|
222
244
|
});
|
|
223
245
|
}
|
|
224
246
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
if(!found){
|
|
247
|
+
addToRefresh(modelItem) {
|
|
248
|
+
const found = this.toRefresh.find(mi => mi.path === modelItem.path);
|
|
249
|
+
if (!found) {
|
|
229
250
|
this.toRefresh.push(modelItem);
|
|
230
251
|
}
|
|
231
252
|
}
|
|
@@ -237,7 +258,7 @@ export class FxFore extends HTMLElement {
|
|
|
237
258
|
* @private
|
|
238
259
|
*/
|
|
239
260
|
_loadFromSrc() {
|
|
240
|
-
console.log('########## loading Fore from ',this.src
|
|
261
|
+
console.log('########## loading Fore from ', this.src, '##########');
|
|
241
262
|
fetch(this.src, {
|
|
242
263
|
method: 'GET',
|
|
243
264
|
mode: 'cors',
|
|
@@ -246,34 +267,40 @@ export class FxFore extends HTMLElement {
|
|
|
246
267
|
'Content-Type': 'text/html',
|
|
247
268
|
},
|
|
248
269
|
})
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
270
|
+
.then(response => {
|
|
271
|
+
const responseContentType = response.headers.get('content-type').toLowerCase();
|
|
272
|
+
console.log('********** responseContentType *********', responseContentType);
|
|
273
|
+
if (responseContentType.startsWith('text/html')) {
|
|
274
|
+
// const htmlResponse = response.text();
|
|
275
|
+
// return new DOMParser().parseFromString(htmlResponse, 'text/html');
|
|
276
|
+
// return response.text();
|
|
277
|
+
return response.text().then(result =>
|
|
278
|
+
// console.log('xml ********', result);
|
|
279
|
+
new DOMParser().parseFromString(result, 'text/html'),
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
return 'done';
|
|
283
|
+
})
|
|
284
|
+
.then(data => {
|
|
285
|
+
// const theFore = fxEvaluateXPathToFirstNode('//fx-fore', data.firstElementChild);
|
|
286
|
+
const theFore = data.querySelector('fx-fore');
|
|
287
|
+
|
|
288
|
+
// console.log('thefore', theFore)
|
|
289
|
+
if (!theFore) {
|
|
290
|
+
Fore.dispatchEvent(this, 'error', {
|
|
291
|
+
detail: {
|
|
292
|
+
message: `Fore element not found in '${this.src}'. Maybe wrapped within 'template' element?`,
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
theFore.setAttribute('from-src', this.src);
|
|
297
|
+
this.replaceWith(theFore);
|
|
298
|
+
})
|
|
299
|
+
.catch(() => {
|
|
300
|
+
Fore.dispatch(this, 'error', {
|
|
301
|
+
message: `'${this.src}' not found or does not contain Fore element.`,
|
|
276
302
|
});
|
|
303
|
+
});
|
|
277
304
|
}
|
|
278
305
|
|
|
279
306
|
/**
|
|
@@ -332,7 +359,7 @@ export class FxFore extends HTMLElement {
|
|
|
332
359
|
* AVT:
|
|
333
360
|
*
|
|
334
361
|
*/
|
|
335
|
-
async refresh(
|
|
362
|
+
async refresh() {
|
|
336
363
|
// refresh () {
|
|
337
364
|
console.group('### refresh');
|
|
338
365
|
|
|
@@ -340,58 +367,60 @@ export class FxFore extends HTMLElement {
|
|
|
340
367
|
|
|
341
368
|
// ### refresh Fore UI elements
|
|
342
369
|
console.time('refreshChildren');
|
|
343
|
-
console.log('toRefresh',this.toRefresh);
|
|
370
|
+
console.log('toRefresh', this.toRefresh);
|
|
344
371
|
|
|
345
|
-
if(!this.initialRun && this.toRefresh.length !== 0){
|
|
372
|
+
if (!this.initialRun && this.toRefresh.length !== 0) {
|
|
346
373
|
let needsRefresh = false;
|
|
347
374
|
|
|
348
375
|
// ### after recalculation the changed modelItems are copied to 'toRefresh' array for processing
|
|
349
376
|
this.toRefresh.forEach(modelItem => {
|
|
350
377
|
// check if modelItem has boundControls - if so, call refresh() for each of them
|
|
351
378
|
const controlsToRefresh = modelItem.boundControls;
|
|
352
|
-
if(controlsToRefresh){
|
|
379
|
+
if (controlsToRefresh) {
|
|
353
380
|
controlsToRefresh.forEach(ctrl => {
|
|
354
381
|
ctrl.refresh();
|
|
355
382
|
});
|
|
356
383
|
}
|
|
357
384
|
|
|
358
385
|
// ### check if other controls depend on current modelItem
|
|
359
|
-
const mainGraph = this.getModel()
|
|
360
|
-
if(mainGraph && mainGraph.hasNode(modelItem.path)){
|
|
386
|
+
const { mainGraph } = this.getModel();
|
|
387
|
+
if (mainGraph && mainGraph.hasNode(modelItem.path)) {
|
|
361
388
|
const deps = this.getModel().mainGraph.dependentsOf(modelItem.path, false);
|
|
362
389
|
// ### iterate dependant modelItems and refresh all their boundControls
|
|
363
|
-
if(deps.length !== 0){
|
|
390
|
+
if (deps.length !== 0) {
|
|
364
391
|
deps.forEach(dep => {
|
|
365
392
|
// ### if changed modelItem has a 'facet' path we use the basePath that is the locationPath without facet name
|
|
366
393
|
const basePath = XPathUtil.getBasePath(dep);
|
|
367
394
|
const modelItemOfDep = this.getModel().modelItems.find(mip => mip.path === basePath);
|
|
368
395
|
// ### refresh all boundControls
|
|
369
|
-
modelItemOfDep.boundControls.forEach(control =>{
|
|
396
|
+
modelItemOfDep.boundControls.forEach(control => {
|
|
397
|
+
control.refresh();
|
|
398
|
+
});
|
|
370
399
|
});
|
|
371
400
|
needsRefresh = true;
|
|
372
401
|
}
|
|
373
402
|
}
|
|
374
403
|
});
|
|
375
404
|
this.toRefresh = [];
|
|
376
|
-
if(!needsRefresh){
|
|
405
|
+
if (!needsRefresh) {
|
|
377
406
|
console.log('skipping refresh - no dependants');
|
|
378
407
|
}
|
|
379
|
-
}else{
|
|
408
|
+
} else {
|
|
380
409
|
Fore.refreshChildren(this, true);
|
|
381
410
|
console.timeEnd('refreshChildren');
|
|
382
411
|
}
|
|
383
412
|
|
|
384
413
|
// ### refresh template expressions
|
|
385
|
-
if(this.initialRun || this.someInstanceDataStructureChanged){
|
|
414
|
+
if (this.initialRun || this.someInstanceDataStructureChanged) {
|
|
386
415
|
this._updateTemplateExpressions();
|
|
387
|
-
this.someInstanceDataStructureChanged = false; //reset
|
|
416
|
+
this.someInstanceDataStructureChanged = false; // reset
|
|
388
417
|
}
|
|
389
418
|
this._processTemplateExpressions();
|
|
390
419
|
|
|
391
420
|
console.timeEnd('refresh');
|
|
392
421
|
|
|
393
422
|
console.groupEnd();
|
|
394
|
-
console.log('### <<<<< dispatching refresh-done - end of UI update cycle >>>>>');
|
|
423
|
+
// console.log('### <<<<< dispatching refresh-done - end of UI update cycle >>>>>');
|
|
395
424
|
this.dispatchEvent(new CustomEvent('refresh-done'));
|
|
396
425
|
}
|
|
397
426
|
|
|
@@ -409,7 +438,7 @@ export class FxFore extends HTMLElement {
|
|
|
409
438
|
"(descendant-or-self::*/(text(), @*))[matches(.,'\\{.*\\}')] except descendant-or-self::fx-model/descendant-or-self::node()/(., @*)";
|
|
410
439
|
|
|
411
440
|
const tmplExpressions = evaluateXPathToNodes(search, this, this);
|
|
412
|
-
console.log('template expressions found ', tmplExpressions);
|
|
441
|
+
// console.log('template expressions found ', tmplExpressions);
|
|
413
442
|
|
|
414
443
|
if (!this.storedTemplateExpressions) {
|
|
415
444
|
this.storedTemplateExpressions = [];
|
|
@@ -434,7 +463,6 @@ export class FxFore extends HTMLElement {
|
|
|
434
463
|
|
|
435
464
|
// TODO: Should we clean up nodes that existed but are now gone?
|
|
436
465
|
this._processTemplateExpressions();
|
|
437
|
-
|
|
438
466
|
}
|
|
439
467
|
|
|
440
468
|
_processTemplateExpressions() {
|
|
@@ -446,7 +474,7 @@ export class FxFore extends HTMLElement {
|
|
|
446
474
|
}
|
|
447
475
|
}
|
|
448
476
|
|
|
449
|
-
// eslint-disable-next-line class-methods-use-this
|
|
477
|
+
// eslint-disable-next-line class-methods-use-this
|
|
450
478
|
_processTemplateExpression(exprObj) {
|
|
451
479
|
// console.log('processing template expression ', exprObj);
|
|
452
480
|
|
|
@@ -465,8 +493,6 @@ export class FxFore extends HTMLElement {
|
|
|
465
493
|
evaluateTemplateExpression(expr, node) {
|
|
466
494
|
if (expr === '{}') return;
|
|
467
495
|
const matches = expr.match(/{[^}]*}/g);
|
|
468
|
-
const namespaceContextNode =
|
|
469
|
-
node.nodeType === node.TEXT_NODE ? node.parentNode : node.ownerElement;
|
|
470
496
|
if (matches) {
|
|
471
497
|
matches.forEach(match => {
|
|
472
498
|
// console.log('match ', match);
|
|
@@ -509,6 +535,7 @@ export class FxFore extends HTMLElement {
|
|
|
509
535
|
this.evaluateTemplateExpression(replaced, node);
|
|
510
536
|
}
|
|
511
537
|
} catch (error) {
|
|
538
|
+
// console.log(error);
|
|
512
539
|
this.dispatchEvent(new CustomEvent('error', { detail: error }));
|
|
513
540
|
}
|
|
514
541
|
});
|
|
@@ -653,10 +680,10 @@ export class FxFore extends HTMLElement {
|
|
|
653
680
|
*/
|
|
654
681
|
async _initUI() {
|
|
655
682
|
console.log('### _initUI()');
|
|
656
|
-
|
|
683
|
+
if (!this.initialRun) return;
|
|
657
684
|
await this._lazyCreateInstance();
|
|
658
685
|
|
|
659
|
-
console.log('registering variables!');
|
|
686
|
+
// console.log('registering variables!');
|
|
660
687
|
const variables = new Map();
|
|
661
688
|
(function registerVariables(node) {
|
|
662
689
|
for (const child of node.children) {
|
|
@@ -668,11 +695,13 @@ export class FxFore extends HTMLElement {
|
|
|
668
695
|
})(this);
|
|
669
696
|
console.log('Found variables:', variables);
|
|
670
697
|
|
|
698
|
+
/*
|
|
671
699
|
const options = {
|
|
672
700
|
root: null,
|
|
673
701
|
rootMargin: '0px',
|
|
674
702
|
threshold: 0.3,
|
|
675
703
|
};
|
|
704
|
+
*/
|
|
676
705
|
|
|
677
706
|
await this.refresh();
|
|
678
707
|
// this.style.display='block'
|
|
@@ -681,10 +710,10 @@ export class FxFore extends HTMLElement {
|
|
|
681
710
|
|
|
682
711
|
this.ready = true;
|
|
683
712
|
this.initialRun = false;
|
|
684
|
-
console.log('###
|
|
685
|
-
console.log('
|
|
686
|
-
console.log('
|
|
687
|
-
|
|
713
|
+
console.log('### >>>>> dispatching ready >>>>>', this);
|
|
714
|
+
console.log('modelItems: ', this.getModel().modelItems);
|
|
715
|
+
console.log('### <<<<< FORE: form fully initialized...', this);
|
|
716
|
+
Fore.dispatch(this, 'ready', {});
|
|
688
717
|
}
|
|
689
718
|
|
|
690
719
|
registerLazyElement(element) {
|
|
@@ -709,9 +738,11 @@ export class FxFore extends HTMLElement {
|
|
|
709
738
|
}
|
|
710
739
|
|
|
711
740
|
_displayMessage(e) {
|
|
741
|
+
// console.log('_displayMessage',e);
|
|
712
742
|
const { level } = e.detail;
|
|
713
743
|
const msg = e.detail.message;
|
|
714
744
|
this._showMessage(level, msg);
|
|
745
|
+
e.stopPropagation();
|
|
715
746
|
}
|
|
716
747
|
|
|
717
748
|
_displayError(e) {
|
|
@@ -740,4 +771,6 @@ export class FxFore extends HTMLElement {
|
|
|
740
771
|
}
|
|
741
772
|
}
|
|
742
773
|
|
|
743
|
-
customElements.
|
|
774
|
+
if (!customElements.get('fx-fore')) {
|
|
775
|
+
customElements.define('fx-fore', FxFore);
|
|
776
|
+
}
|
package/src/fx-header.js
CHANGED