@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.
Files changed (63) hide show
  1. package/README.md +6 -27
  2. package/dist/fore-dev.js +43 -0
  3. package/dist/fore-dev.js.map +1 -0
  4. package/dist/fore.js +37 -0
  5. package/dist/fore.js.map +1 -0
  6. package/index.js +2 -1
  7. package/package.json +35 -39
  8. package/resources/fore.css +22 -54
  9. package/src/DependencyNotifyingDomFacade.js +5 -13
  10. package/src/ForeElementMixin.js +13 -20
  11. package/src/actions/abstract-action.js +14 -9
  12. package/src/actions/fx-action.js +6 -5
  13. package/src/actions/fx-append.js +8 -17
  14. package/src/actions/fx-confirm.js +3 -1
  15. package/src/actions/fx-delete.js +6 -3
  16. package/src/actions/fx-dispatch.js +9 -8
  17. package/src/actions/fx-hide.js +9 -6
  18. package/src/actions/fx-insert.js +27 -14
  19. package/src/actions/fx-message.js +3 -1
  20. package/src/actions/fx-refresh.js +11 -1
  21. package/src/actions/fx-replace.js +68 -0
  22. package/src/actions/fx-return.js +42 -0
  23. package/src/actions/fx-send.js +3 -1
  24. package/src/actions/fx-setvalue.js +58 -51
  25. package/src/actions/fx-show.js +8 -4
  26. package/src/actions/fx-toggle.js +13 -9
  27. package/src/actions/fx-update.js +3 -1
  28. package/src/dep_graph.js +1 -1
  29. package/src/drawdown.js +67 -82
  30. package/src/fore.js +141 -25
  31. package/src/functions/fx-function.js +11 -3
  32. package/src/fx-bind.js +39 -199
  33. package/src/fx-fore.js +101 -68
  34. package/src/fx-header.js +3 -1
  35. package/src/fx-instance.js +9 -1
  36. package/src/fx-model.js +31 -23
  37. package/src/fx-submission.js +73 -47
  38. package/src/fx-var.js +7 -4
  39. package/src/getInScopeContext.js +23 -16
  40. package/src/modelitem.js +4 -4
  41. package/src/relevance.js +65 -0
  42. package/src/ui/abstract-control.js +55 -35
  43. package/src/ui/fx-alert.js +7 -1
  44. package/src/ui/fx-case.js +3 -1
  45. package/src/ui/fx-container.js +4 -2
  46. package/src/ui/fx-control.js +283 -33
  47. package/src/ui/fx-dialog.js +50 -45
  48. package/src/ui/fx-group.js +3 -1
  49. package/src/ui/fx-hint.js +4 -1
  50. package/src/ui/fx-inspector.js +117 -17
  51. package/src/ui/fx-items.js +7 -5
  52. package/src/ui/fx-output.js +14 -5
  53. package/src/ui/fx-repeat.js +13 -26
  54. package/src/ui/fx-repeatitem.js +10 -4
  55. package/src/ui/fx-switch.js +3 -1
  56. package/src/ui/fx-trigger.js +3 -1
  57. package/src/xpath-evaluation.js +114 -102
  58. package/src/xpath-util.js +1 -5
  59. package/dist/fore-all.js +0 -140
  60. package/dist/fore-debug.js +0 -140
  61. package/src/.DS_Store +0 -0
  62. package/src/actions/.DS_Store +0 -0
  63. 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 = this.parentElement.closest('fx-bind[ref]');
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
- const touchedNodes = new Set();
518
- const domFacade = new DependencyNotifyingDomFacade(otherNode => touchedNodes.add(otherNode));
519
- this.nodeset.forEach(node => {
520
- evaluateXPathToString(propertyExpr, node, this, domFacade);
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.define('fx-bind', FxBind);
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
- animation: fadein .4s forwards;
78
- display:block;
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('FX-model');
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', (e) =>{
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
- addToRefresh(modelItem){
227
- const found = this.toRefresh.find(mi => mi.path === modelItem.path );
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
- .then(response => {
250
- const responseContentType = response.headers.get('content-type').toLowerCase();
251
- console.log('********** responseContentType *********', responseContentType);
252
- if (responseContentType.startsWith('text/html')) {
253
- // const htmlResponse = response.text();
254
- // return new DOMParser().parseFromString(htmlResponse, 'text/html');
255
- // return response.text();
256
- return response.text().then(result =>
257
- // console.log('xml ********', result);
258
- new DOMParser().parseFromString(result, 'text/html'),
259
- );
260
- }
261
- return 'done';
262
- })
263
- .then(data => {
264
- // const theFore = fxEvaluateXPathToFirstNode('//fx-fore', data.firstElementChild);
265
- const theFore = data.querySelector('fx-fore');
266
-
267
- // console.log('thefore', theFore)
268
- if(!theFore){
269
- this.dispatchEvent(new CustomEvent('error',{detail:{message: `Fore element not found in '${this.src}'. Maybe wrapped within 'template' element?`}}));
270
- }
271
- theFore.setAttribute('from-src', this.src);
272
- this.replaceWith(theFore);
273
- })
274
- .catch(error => {
275
- this.dispatchEvent(new CustomEvent('error',{detail:{message: `'${this.src}' not found or does not contain Fore element.`}}));
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(force) {
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().mainGraph;
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 =>{control.refresh()});
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('### <<<<< dispatching ready >>>>>');
685
- console.log('########## modelItems: ', this.getModel().modelItems);
686
- console.log('########## FORE: form fully initialized... ##########');
687
- this.dispatchEvent(new CustomEvent('ready', {}));
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.define('fx-fore', FxFore);
774
+ if (!customElements.get('fx-fore')) {
775
+ customElements.define('fx-fore', FxFore);
776
+ }
package/src/fx-header.js CHANGED
@@ -17,4 +17,6 @@ export class FxHeader extends foreElementMixin(HTMLElement) {
17
17
  this.shadowRoot.innerHTML = ``;
18
18
  }
19
19
  }
20
- customElements.define('fx-header', FxHeader);
20
+ if (!customElements.get('fx-header')) {
21
+ customElements.define('fx-header', FxHeader);
22
+ }