@jinntec/fore 1.0.0-3 → 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 +25 -34
- package/dist/fore-dev.js +43 -0
- package/dist/fore-dev.js.map +1 -0
- package/dist/fore.js +36 -1
- package/dist/fore.js.map +1 -0
- package/index.js +3 -0
- package/package.json +34 -38
- package/resources/fore.css +35 -50
- package/src/DependencyNotifyingDomFacade.js +10 -16
- package/src/ForeElementMixin.js +25 -18
- package/src/actions/abstract-action.js +17 -9
- package/src/actions/fx-action.js +6 -4
- 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 +10 -6
- package/src/actions/fx-insert.js +49 -39
- 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 +15 -10
- package/src/actions/fx-update.js +3 -1
- package/src/dep_graph.js +4 -2
- package/src/drawdown.js +67 -82
- package/src/fore.js +158 -11
- package/src/functions/fx-function.js +11 -3
- package/src/fx-bind.js +42 -202
- package/src/fx-fore.js +105 -70
- 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 +37 -11
- 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 +7 -1
- package/src/ui/fx-control.js +283 -33
- package/src/ui/fx-dialog.js +54 -40
- 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 +8 -8
- package/src/ui/fx-output.js +14 -5
- package/src/ui/fx-repeat.js +33 -41
- 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 +121 -131
- package/src/xpath-util.js +14 -7
- package/dist/fore-all.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-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;
|
|
@@ -152,6 +155,7 @@ export class FxFore extends HTMLElement {
|
|
|
152
155
|
|
|
153
156
|
const html = `
|
|
154
157
|
<jinn-toast id="message" gravity="bottom" position="left"></jinn-toast>
|
|
158
|
+
<jinn-toast id="sticky" gravity="bottom" position="left" duration="-1" close="true" data-class="sticky-message"></jinn-toast>
|
|
155
159
|
<jinn-toast id="error" text="error" duration="-1" data-class="error" close="true" position="left" gravity="bottom"></jinn-toast>
|
|
156
160
|
<slot></slot>
|
|
157
161
|
<div id="modalMessage" class="overlay">
|
|
@@ -177,6 +181,25 @@ export class FxFore extends HTMLElement {
|
|
|
177
181
|
}
|
|
178
182
|
|
|
179
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
|
+
|
|
180
203
|
this.lazyRefresh = this.hasAttribute('refresh-on-view');
|
|
181
204
|
if (this.lazyRefresh) {
|
|
182
205
|
const options = {
|
|
@@ -187,10 +210,10 @@ export class FxFore extends HTMLElement {
|
|
|
187
210
|
this.intersectionObserver = new IntersectionObserver(this.handleIntersect, options);
|
|
188
211
|
}
|
|
189
212
|
|
|
190
|
-
this.src = this.hasAttribute('src')? this.getAttribute('src'):null;
|
|
191
|
-
if(this.src){
|
|
213
|
+
this.src = this.hasAttribute('src') ? this.getAttribute('src') : null;
|
|
214
|
+
if (this.src) {
|
|
192
215
|
this._loadFromSrc();
|
|
193
|
-
return
|
|
216
|
+
return;
|
|
194
217
|
}
|
|
195
218
|
|
|
196
219
|
const slot = this.shadowRoot.querySelector('slot');
|
|
@@ -200,7 +223,7 @@ export class FxFore extends HTMLElement {
|
|
|
200
223
|
modelElem => modelElem.nodeName.toUpperCase() === 'FX-MODEL',
|
|
201
224
|
);
|
|
202
225
|
if (!modelElement) {
|
|
203
|
-
const generatedModel = document.createElement('
|
|
226
|
+
const generatedModel = document.createElement('fx-model');
|
|
204
227
|
this.appendChild(generatedModel);
|
|
205
228
|
modelElement = generatedModel;
|
|
206
229
|
}
|
|
@@ -208,23 +231,22 @@ export class FxFore extends HTMLElement {
|
|
|
208
231
|
console.log(
|
|
209
232
|
`########## FORE: kick off processing for ... ${window.location.href} ##########`,
|
|
210
233
|
);
|
|
211
|
-
if(this.src){
|
|
234
|
+
if (this.src) {
|
|
212
235
|
console.log('########## FORE: loaded from ... ', this.src, '##########');
|
|
213
236
|
}
|
|
214
237
|
modelElement.modelConstruct();
|
|
215
238
|
}
|
|
216
239
|
this.model = modelElement;
|
|
217
240
|
});
|
|
218
|
-
this.addEventListener('path-mutated',
|
|
241
|
+
this.addEventListener('path-mutated', e => {
|
|
219
242
|
console.log('path-mutated event received', e.detail.path, e.detail.index);
|
|
220
243
|
this.someInstanceDataStructureChanged = true;
|
|
221
244
|
});
|
|
222
245
|
}
|
|
223
246
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
if(!found){
|
|
247
|
+
addToRefresh(modelItem) {
|
|
248
|
+
const found = this.toRefresh.find(mi => mi.path === modelItem.path);
|
|
249
|
+
if (!found) {
|
|
228
250
|
this.toRefresh.push(modelItem);
|
|
229
251
|
}
|
|
230
252
|
}
|
|
@@ -236,7 +258,7 @@ export class FxFore extends HTMLElement {
|
|
|
236
258
|
* @private
|
|
237
259
|
*/
|
|
238
260
|
_loadFromSrc() {
|
|
239
|
-
console.log('########## loading Fore from ',this.src
|
|
261
|
+
console.log('########## loading Fore from ', this.src, '##########');
|
|
240
262
|
fetch(this.src, {
|
|
241
263
|
method: 'GET',
|
|
242
264
|
mode: 'cors',
|
|
@@ -245,34 +267,40 @@ export class FxFore extends HTMLElement {
|
|
|
245
267
|
'Content-Type': 'text/html',
|
|
246
268
|
},
|
|
247
269
|
})
|
|
248
|
-
|
|
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
|
-
|
|
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.`,
|
|
275
302
|
});
|
|
303
|
+
});
|
|
276
304
|
}
|
|
277
305
|
|
|
278
306
|
/**
|
|
@@ -331,7 +359,7 @@ export class FxFore extends HTMLElement {
|
|
|
331
359
|
* AVT:
|
|
332
360
|
*
|
|
333
361
|
*/
|
|
334
|
-
async refresh(
|
|
362
|
+
async refresh() {
|
|
335
363
|
// refresh () {
|
|
336
364
|
console.group('### refresh');
|
|
337
365
|
|
|
@@ -339,58 +367,60 @@ export class FxFore extends HTMLElement {
|
|
|
339
367
|
|
|
340
368
|
// ### refresh Fore UI elements
|
|
341
369
|
console.time('refreshChildren');
|
|
342
|
-
console.log('toRefresh',this.toRefresh);
|
|
370
|
+
console.log('toRefresh', this.toRefresh);
|
|
343
371
|
|
|
344
|
-
if(!this.initialRun && this.toRefresh.length !== 0){
|
|
372
|
+
if (!this.initialRun && this.toRefresh.length !== 0) {
|
|
345
373
|
let needsRefresh = false;
|
|
346
374
|
|
|
347
375
|
// ### after recalculation the changed modelItems are copied to 'toRefresh' array for processing
|
|
348
376
|
this.toRefresh.forEach(modelItem => {
|
|
349
377
|
// check if modelItem has boundControls - if so, call refresh() for each of them
|
|
350
378
|
const controlsToRefresh = modelItem.boundControls;
|
|
351
|
-
if(controlsToRefresh){
|
|
379
|
+
if (controlsToRefresh) {
|
|
352
380
|
controlsToRefresh.forEach(ctrl => {
|
|
353
381
|
ctrl.refresh();
|
|
354
382
|
});
|
|
355
383
|
}
|
|
356
384
|
|
|
357
385
|
// ### check if other controls depend on current modelItem
|
|
358
|
-
const mainGraph = this.getModel()
|
|
359
|
-
if(mainGraph && mainGraph.hasNode(modelItem.path)){
|
|
386
|
+
const { mainGraph } = this.getModel();
|
|
387
|
+
if (mainGraph && mainGraph.hasNode(modelItem.path)) {
|
|
360
388
|
const deps = this.getModel().mainGraph.dependentsOf(modelItem.path, false);
|
|
361
389
|
// ### iterate dependant modelItems and refresh all their boundControls
|
|
362
|
-
if(deps.length !== 0){
|
|
390
|
+
if (deps.length !== 0) {
|
|
363
391
|
deps.forEach(dep => {
|
|
364
392
|
// ### if changed modelItem has a 'facet' path we use the basePath that is the locationPath without facet name
|
|
365
393
|
const basePath = XPathUtil.getBasePath(dep);
|
|
366
394
|
const modelItemOfDep = this.getModel().modelItems.find(mip => mip.path === basePath);
|
|
367
395
|
// ### refresh all boundControls
|
|
368
|
-
modelItemOfDep.boundControls.forEach(control =>{
|
|
396
|
+
modelItemOfDep.boundControls.forEach(control => {
|
|
397
|
+
control.refresh();
|
|
398
|
+
});
|
|
369
399
|
});
|
|
370
400
|
needsRefresh = true;
|
|
371
401
|
}
|
|
372
402
|
}
|
|
373
403
|
});
|
|
374
404
|
this.toRefresh = [];
|
|
375
|
-
if(!needsRefresh){
|
|
405
|
+
if (!needsRefresh) {
|
|
376
406
|
console.log('skipping refresh - no dependants');
|
|
377
407
|
}
|
|
378
|
-
}else{
|
|
408
|
+
} else {
|
|
379
409
|
Fore.refreshChildren(this, true);
|
|
380
410
|
console.timeEnd('refreshChildren');
|
|
381
411
|
}
|
|
382
412
|
|
|
383
413
|
// ### refresh template expressions
|
|
384
|
-
if(this.initialRun || this.someInstanceDataStructureChanged){
|
|
414
|
+
if (this.initialRun || this.someInstanceDataStructureChanged) {
|
|
385
415
|
this._updateTemplateExpressions();
|
|
386
|
-
this.someInstanceDataStructureChanged = false; //reset
|
|
416
|
+
this.someInstanceDataStructureChanged = false; // reset
|
|
387
417
|
}
|
|
388
418
|
this._processTemplateExpressions();
|
|
389
419
|
|
|
390
420
|
console.timeEnd('refresh');
|
|
391
421
|
|
|
392
422
|
console.groupEnd();
|
|
393
|
-
console.log('### <<<<< dispatching refresh-done - end of UI update cycle >>>>>');
|
|
423
|
+
// console.log('### <<<<< dispatching refresh-done - end of UI update cycle >>>>>');
|
|
394
424
|
this.dispatchEvent(new CustomEvent('refresh-done'));
|
|
395
425
|
}
|
|
396
426
|
|
|
@@ -408,7 +438,7 @@ export class FxFore extends HTMLElement {
|
|
|
408
438
|
"(descendant-or-self::*/(text(), @*))[matches(.,'\\{.*\\}')] except descendant-or-self::fx-model/descendant-or-self::node()/(., @*)";
|
|
409
439
|
|
|
410
440
|
const tmplExpressions = evaluateXPathToNodes(search, this, this);
|
|
411
|
-
console.log('template expressions found ', tmplExpressions);
|
|
441
|
+
// console.log('template expressions found ', tmplExpressions);
|
|
412
442
|
|
|
413
443
|
if (!this.storedTemplateExpressions) {
|
|
414
444
|
this.storedTemplateExpressions = [];
|
|
@@ -433,7 +463,6 @@ export class FxFore extends HTMLElement {
|
|
|
433
463
|
|
|
434
464
|
// TODO: Should we clean up nodes that existed but are now gone?
|
|
435
465
|
this._processTemplateExpressions();
|
|
436
|
-
|
|
437
466
|
}
|
|
438
467
|
|
|
439
468
|
_processTemplateExpressions() {
|
|
@@ -445,7 +474,7 @@ export class FxFore extends HTMLElement {
|
|
|
445
474
|
}
|
|
446
475
|
}
|
|
447
476
|
|
|
448
|
-
// eslint-disable-next-line class-methods-use-this
|
|
477
|
+
// eslint-disable-next-line class-methods-use-this
|
|
449
478
|
_processTemplateExpression(exprObj) {
|
|
450
479
|
// console.log('processing template expression ', exprObj);
|
|
451
480
|
|
|
@@ -464,8 +493,6 @@ export class FxFore extends HTMLElement {
|
|
|
464
493
|
evaluateTemplateExpression(expr, node) {
|
|
465
494
|
if (expr === '{}') return;
|
|
466
495
|
const matches = expr.match(/{[^}]*}/g);
|
|
467
|
-
const namespaceContextNode =
|
|
468
|
-
node.nodeType === node.TEXT_NODE ? node.parentNode : node.ownerElement;
|
|
469
496
|
if (matches) {
|
|
470
497
|
matches.forEach(match => {
|
|
471
498
|
// console.log('match ', match);
|
|
@@ -508,6 +535,7 @@ export class FxFore extends HTMLElement {
|
|
|
508
535
|
this.evaluateTemplateExpression(replaced, node);
|
|
509
536
|
}
|
|
510
537
|
} catch (error) {
|
|
538
|
+
// console.log(error);
|
|
511
539
|
this.dispatchEvent(new CustomEvent('error', { detail: error }));
|
|
512
540
|
}
|
|
513
541
|
});
|
|
@@ -652,10 +680,10 @@ export class FxFore extends HTMLElement {
|
|
|
652
680
|
*/
|
|
653
681
|
async _initUI() {
|
|
654
682
|
console.log('### _initUI()');
|
|
655
|
-
|
|
683
|
+
if (!this.initialRun) return;
|
|
656
684
|
await this._lazyCreateInstance();
|
|
657
685
|
|
|
658
|
-
console.log('registering variables!');
|
|
686
|
+
// console.log('registering variables!');
|
|
659
687
|
const variables = new Map();
|
|
660
688
|
(function registerVariables(node) {
|
|
661
689
|
for (const child of node.children) {
|
|
@@ -667,22 +695,25 @@ export class FxFore extends HTMLElement {
|
|
|
667
695
|
})(this);
|
|
668
696
|
console.log('Found variables:', variables);
|
|
669
697
|
|
|
698
|
+
/*
|
|
670
699
|
const options = {
|
|
671
700
|
root: null,
|
|
672
701
|
rootMargin: '0px',
|
|
673
702
|
threshold: 0.3,
|
|
674
703
|
};
|
|
704
|
+
*/
|
|
675
705
|
|
|
676
706
|
await this.refresh();
|
|
677
707
|
// this.style.display='block'
|
|
678
708
|
this.classList.add('fx-ready');
|
|
709
|
+
document.body.classList.add('fx-ready');
|
|
679
710
|
|
|
680
711
|
this.ready = true;
|
|
681
712
|
this.initialRun = false;
|
|
682
|
-
console.log('###
|
|
683
|
-
console.log('
|
|
684
|
-
console.log('
|
|
685
|
-
|
|
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', {});
|
|
686
717
|
}
|
|
687
718
|
|
|
688
719
|
registerLazyElement(element) {
|
|
@@ -707,9 +738,11 @@ export class FxFore extends HTMLElement {
|
|
|
707
738
|
}
|
|
708
739
|
|
|
709
740
|
_displayMessage(e) {
|
|
741
|
+
// console.log('_displayMessage',e);
|
|
710
742
|
const { level } = e.detail;
|
|
711
743
|
const msg = e.detail.message;
|
|
712
744
|
this._showMessage(level, msg);
|
|
745
|
+
e.stopPropagation();
|
|
713
746
|
}
|
|
714
747
|
|
|
715
748
|
_displayError(e) {
|
|
@@ -728,9 +761,9 @@ export class FxFore extends HTMLElement {
|
|
|
728
761
|
this.shadowRoot.getElementById('messageContent').innerText = msg;
|
|
729
762
|
// this.shadowRoot.getElementById('modalMessage').open();
|
|
730
763
|
this.shadowRoot.getElementById('modalMessage').classList.add('show');
|
|
731
|
-
} else if (level === '
|
|
764
|
+
} else if (level === 'sticky') {
|
|
732
765
|
// const notification = this.$.modeless;
|
|
733
|
-
this.shadowRoot.querySelector('#
|
|
766
|
+
this.shadowRoot.querySelector('#sticky').showToast(msg);
|
|
734
767
|
} else {
|
|
735
768
|
const toast = this.shadowRoot.querySelector('#message');
|
|
736
769
|
toast.showToast(msg);
|
|
@@ -738,4 +771,6 @@ export class FxFore extends HTMLElement {
|
|
|
738
771
|
}
|
|
739
772
|
}
|
|
740
773
|
|
|
741
|
-
customElements.
|
|
774
|
+
if (!customElements.get('fx-fore')) {
|
|
775
|
+
customElements.define('fx-fore', FxFore);
|
|
776
|
+
}
|
package/src/fx-header.js
CHANGED
package/src/fx-instance.js
CHANGED
|
@@ -166,6 +166,12 @@ export class FxInstance extends HTMLElement {
|
|
|
166
166
|
},
|
|
167
167
|
})
|
|
168
168
|
.then(response => {
|
|
169
|
+
const { status } = response;
|
|
170
|
+
if (status >= 400) {
|
|
171
|
+
console.log('response status', status);
|
|
172
|
+
alert(`response status: ${status} - failed to load data for '${this.src}' - stopping.`);
|
|
173
|
+
throw new Error(`failed to load data - status: ${status}`);
|
|
174
|
+
}
|
|
169
175
|
const responseContentType = response.headers.get('content-type').toLowerCase();
|
|
170
176
|
console.log('********** responseContentType *********', responseContentType);
|
|
171
177
|
if (responseContentType.startsWith('text/html')) {
|
|
@@ -257,4 +263,6 @@ export class FxInstance extends HTMLElement {
|
|
|
257
263
|
console.log('_handleResponse ', loader.lastError);
|
|
258
264
|
}
|
|
259
265
|
}
|
|
260
|
-
customElements.
|
|
266
|
+
if (!customElements.get('fx-instance')) {
|
|
267
|
+
customElements.define('fx-instance', FxInstance);
|
|
268
|
+
}
|
package/src/fx-model.js
CHANGED
|
@@ -35,11 +35,11 @@ export class FxModel extends HTMLElement {
|
|
|
35
35
|
<slot></slot>
|
|
36
36
|
`;
|
|
37
37
|
|
|
38
|
-
this.addEventListener('model-construct-done',
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
});
|
|
38
|
+
this.addEventListener('model-construct-done', () => {
|
|
39
|
+
this.modelConstructed = true;
|
|
40
|
+
// console.log('model-construct-done fired ', this.modelConstructed);
|
|
41
|
+
// console.log('model-construct-done fired ', e.detail.model.instances);
|
|
42
|
+
},{ once: true });
|
|
43
43
|
|
|
44
44
|
this.skipUpdate = false;
|
|
45
45
|
}
|
|
@@ -95,8 +95,15 @@ export class FxModel extends HTMLElement {
|
|
|
95
95
|
*
|
|
96
96
|
*/
|
|
97
97
|
modelConstruct() {
|
|
98
|
-
console.log('### <<<<< dispatching model-construct >>>>>');
|
|
99
|
-
this.dispatchEvent(new CustomEvent('model-construct', { detail: this }));
|
|
98
|
+
// console.log('### <<<<< dispatching model-construct >>>>>');
|
|
99
|
+
// this.dispatchEvent(new CustomEvent('model-construct', { detail: this }));
|
|
100
|
+
this.dispatchEvent(
|
|
101
|
+
new CustomEvent('model-construct', {
|
|
102
|
+
composed: false,
|
|
103
|
+
bubbles: true,
|
|
104
|
+
detail: { model: this },
|
|
105
|
+
}),
|
|
106
|
+
);
|
|
100
107
|
|
|
101
108
|
console.time('instance-loading');
|
|
102
109
|
const instances = this.querySelectorAll('fx-instance');
|
|
@@ -109,14 +116,14 @@ export class FxModel extends HTMLElement {
|
|
|
109
116
|
|
|
110
117
|
Promise.all(promises).then(() => {
|
|
111
118
|
this.instances = Array.from(instances);
|
|
112
|
-
console.log('_modelConstruct this.instances ', this.instances);
|
|
119
|
+
// console.log('_modelConstruct this.instances ', this.instances);
|
|
113
120
|
this.updateModel();
|
|
114
121
|
this.inited = true;
|
|
115
122
|
|
|
116
|
-
console.log('### <<<<< dispatching model-construct-done >>>>>');
|
|
123
|
+
// console.log('### <<<<< dispatching model-construct-done >>>>>');
|
|
117
124
|
this.dispatchEvent(
|
|
118
125
|
new CustomEvent('model-construct-done', {
|
|
119
|
-
composed:
|
|
126
|
+
composed: false,
|
|
120
127
|
bubbles: true,
|
|
121
128
|
detail: { model: this },
|
|
122
129
|
}),
|
|
@@ -127,7 +134,7 @@ export class FxModel extends HTMLElement {
|
|
|
127
134
|
// ### if there's no instance one will created
|
|
128
135
|
this.dispatchEvent(
|
|
129
136
|
new CustomEvent('model-construct-done', {
|
|
130
|
-
composed:
|
|
137
|
+
composed: false,
|
|
131
138
|
bubbles: true,
|
|
132
139
|
detail: { model: this },
|
|
133
140
|
}),
|
|
@@ -146,32 +153,32 @@ export class FxModel extends HTMLElement {
|
|
|
146
153
|
* update action triggering the update cycle
|
|
147
154
|
*/
|
|
148
155
|
updateModel() {
|
|
149
|
-
console.time('updateModel');
|
|
156
|
+
// console.time('updateModel');
|
|
150
157
|
this.rebuild();
|
|
151
|
-
if(this.skipUpdate) return;
|
|
158
|
+
if (this.skipUpdate) return;
|
|
152
159
|
this.recalculate();
|
|
153
160
|
this.revalidate();
|
|
154
|
-
console.timeEnd('updateModel');
|
|
161
|
+
// console.timeEnd('updateModel');
|
|
155
162
|
}
|
|
156
163
|
|
|
157
164
|
rebuild() {
|
|
158
165
|
console.group('### rebuild');
|
|
159
166
|
console.time('rebuild');
|
|
160
|
-
this.mainGraph = new DepGraph(false); //do: should be moved down below binds.length check but causes errors in tests.
|
|
167
|
+
this.mainGraph = new DepGraph(false); // do: should be moved down below binds.length check but causes errors in tests.
|
|
161
168
|
this.modelItems = [];
|
|
162
169
|
|
|
163
170
|
// trigger recursive initialization of the fx-bind elements
|
|
164
171
|
const binds = this.querySelectorAll('fx-model > fx-bind');
|
|
165
|
-
if(binds.length === 0
|
|
166
|
-
console.log('skipped model update');
|
|
172
|
+
if (binds.length === 0) {
|
|
173
|
+
// console.log('skipped model update');
|
|
167
174
|
this.skipUpdate = true;
|
|
168
|
-
return
|
|
175
|
+
return;
|
|
169
176
|
}
|
|
170
177
|
|
|
171
178
|
binds.forEach(bind => {
|
|
172
179
|
bind.init(this);
|
|
173
180
|
});
|
|
174
|
-
console.timeEnd('rebuild');
|
|
181
|
+
// console.timeEnd('rebuild');
|
|
175
182
|
|
|
176
183
|
// console.log(`dependencies of a `, this.mainGraph.dependenciesOf("/Q{}data[1]/Q{}a[1]:required"));
|
|
177
184
|
// console.log(`dependencies of b `, this.mainGraph.dependenciesOf("/Q{}data[1]/Q{}b[1]:required"));
|
|
@@ -208,7 +215,7 @@ export class FxModel extends HTMLElement {
|
|
|
208
215
|
this.subgraph.addNode(modelItem.path, modelItem.node);
|
|
209
216
|
// const dependents = this.mainGraph.dependantsOf(modelItem.path, false);
|
|
210
217
|
// this._addSubgraphDependencies(modelItem.path);
|
|
211
|
-
if (this.mainGraph.hasNode(modelItem.path)) {
|
|
218
|
+
if (this.mainGraph && this.mainGraph.hasNode(modelItem.path)) {
|
|
212
219
|
// const dependents = this.mainGraph.directDependantsOf(modelItem.path)
|
|
213
220
|
|
|
214
221
|
const all = this.mainGraph.dependantsOf(modelItem.path, false);
|
|
@@ -238,7 +245,7 @@ export class FxModel extends HTMLElement {
|
|
|
238
245
|
// ### compute the subgraph
|
|
239
246
|
const ordered = this.subgraph.overallOrder(false);
|
|
240
247
|
ordered.forEach(path => {
|
|
241
|
-
if (this.mainGraph.hasNode(path)) {
|
|
248
|
+
if (this.mainGraph && this.mainGraph.hasNode(path)) {
|
|
242
249
|
const node = this.mainGraph.getNodeData(path);
|
|
243
250
|
this.compute(node, path);
|
|
244
251
|
}
|
|
@@ -445,5 +452,6 @@ export class FxModel extends HTMLElement {
|
|
|
445
452
|
return result;
|
|
446
453
|
}
|
|
447
454
|
}
|
|
448
|
-
|
|
449
|
-
customElements.define('fx-model', FxModel);
|
|
455
|
+
if (!customElements.get('fx-model')) {
|
|
456
|
+
customElements.define('fx-model', FxModel);
|
|
457
|
+
}
|