@jinntec/fore 1.0.0-1 → 1.0.0-4

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 (43) hide show
  1. package/README.md +20 -1
  2. package/dist/fore-all.js +10 -10
  3. package/dist/fore-debug.js +140 -0
  4. package/index.js +8 -0
  5. package/package.json +7 -6
  6. package/resources/{vars.css → fore-styles.css} +292 -0
  7. package/src/DependencyNotifyingDomFacade.js +9 -1
  8. package/src/ForeElementMixin.js +25 -17
  9. package/src/actions/abstract-action.js +8 -7
  10. package/src/actions/fx-action.js +6 -1
  11. package/src/actions/fx-dispatch.js +10 -2
  12. package/src/actions/fx-hide.js +23 -0
  13. package/src/actions/fx-insert.js +9 -9
  14. package/src/actions/fx-send.js +1 -1
  15. package/src/actions/fx-setvalue.js +2 -4
  16. package/src/actions/fx-show.js +23 -0
  17. package/src/dep_graph.js +9 -0
  18. package/src/drawdown.js +172 -0
  19. package/src/fore.js +56 -3
  20. package/src/fx-bind.js +20 -17
  21. package/src/fx-fore.js +297 -33
  22. package/src/fx-instance.js +27 -6
  23. package/src/fx-model.js +182 -37
  24. package/src/fx-submission.js +29 -7
  25. package/src/fx-var.js +43 -0
  26. package/src/getInScopeContext.js +28 -7
  27. package/src/modelitem.js +1 -0
  28. package/src/ui/abstract-control.js +17 -4
  29. package/src/ui/fx-alert.js +16 -20
  30. package/src/ui/fx-container.js +9 -4
  31. package/src/ui/fx-control.js +76 -39
  32. package/src/ui/fx-dialog.js +68 -0
  33. package/src/ui/fx-inspector.js +44 -0
  34. package/src/ui/fx-items.js +120 -0
  35. package/src/ui/fx-output.js +50 -12
  36. package/src/ui/fx-repeat.js +83 -16
  37. package/src/ui/fx-repeatitem.js +11 -4
  38. package/src/ui/fx-trigger.js +3 -0
  39. package/src/xpath-evaluation.js +372 -135
  40. package/src/xpath-util.js +52 -12
  41. package/dist/fore.js +0 -2
  42. package/resources/fore.css +0 -86
  43. package/resources/toastify.css +0 -87
@@ -4,6 +4,7 @@ import { Fore } from '../fore.js';
4
4
  import { foreElementMixin } from '../ForeElementMixin.js';
5
5
  import { evaluateXPath } from '../xpath-evaluation.js';
6
6
  import getInScopeContext from '../getInScopeContext.js';
7
+ import {XPathUtil} from "../xpath-util";
7
8
 
8
9
  /**
9
10
  * `fx-repeat`
@@ -88,6 +89,7 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
88
89
  }
89
90
 
90
91
  connectedCallback() {
92
+ // this.display = window.getComputedStyle(this, null).getPropertyValue("display");
91
93
  this.ref = this.getAttribute('ref');
92
94
  // console.log('### fx-repeat connected ', this.id);
93
95
  this.addEventListener('item-changed', e => {
@@ -114,16 +116,37 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
114
116
  console.log('insert catched', nodes, this.index);
115
117
  });
116
118
 
119
+ // if (this.getOwnerForm().lazyRefresh) {
120
+ this.mutationObserver = new MutationObserver(mutations => {
121
+ console.log('mutations', mutations);
122
+
123
+ if(mutations[0].type === "childList"){
124
+ const added = mutations[0].addedNodes[0];
125
+ if(added){
126
+ const path = XPathUtil.getPath(added);
127
+ console.log('path mutated',path);
128
+ // this.dispatch('path-mutated',{'path':path,'nodeset':this.nodeset,'index': this.index});
129
+ this.dispatch('path-mutated',{'path':path,'index': this.index});
130
+ }
131
+
132
+ }
133
+ });
134
+ // }
135
+ this.getOwnerForm().registerLazyElement(this);
136
+
137
+
117
138
  const style = `
118
- .fade-out-bottom {
119
- -webkit-animation: fade-out-bottom 0.7s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
120
- animation: fade-out-bottom 0.7s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
121
- }
122
- .fade-out-bottom {
123
- -webkit-animation: fade-out-bottom 0.7s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
124
- animation: fade-out-bottom 0.7s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
125
- }
126
- `;
139
+ :host{
140
+ }
141
+ .fade-out-bottom {
142
+ -webkit-animation: fade-out-bottom 0.7s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
143
+ animation: fade-out-bottom 0.7s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
144
+ }
145
+ .fade-out-bottom {
146
+ -webkit-animation: fade-out-bottom 0.7s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
147
+ animation: fade-out-bottom 0.7s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
148
+ }
149
+ `;
127
150
  const html = `
128
151
  <slot name="header"></slot>
129
152
  <slot></slot>
@@ -157,9 +180,17 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
157
180
  */
158
181
  _evalNodeset() {
159
182
  // const inscope = this.getInScopeContext();
160
- const inscope = getInScopeContext(this, this.ref);
183
+ const inscope = getInScopeContext(this.getAttributeNode('ref') || this, this.ref);
161
184
  // console.log('##### inscope ', inscope);
162
185
  // console.log('##### ref ', this.ref);
186
+ // now we got a nodeset and attach MutationObserver to it
187
+
188
+ if (this.mutationObserver && inscope.nodeName) {
189
+ this.mutationObserver.observe(inscope, {
190
+ childList: true,
191
+ subtree: true,
192
+ });
193
+ }
163
194
 
164
195
  const seq = evaluateXPath(this.ref, inscope, this.getOwnerForm());
165
196
  // const seq = evaluateXPathToNodes(this.ref, inscope, this.getOwnerForm());
@@ -188,12 +219,13 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
188
219
  throw new Error(`Unexpected result of repeat nodeset: ${seq}`);
189
220
  }
190
221
 
191
- async refresh() {
192
- console.group('fx-repeat.refresh on', this.id);
222
+ async refresh(force) {
223
+ // console.group('fx-repeat.refresh on', this.id);
193
224
 
194
225
  if (!this.inited) this.init();
226
+ console.time('repeat-refresh', this);
195
227
  this._evalNodeset();
196
- console.log('repeat refresh nodeset ', this.nodeset);
228
+ // console.log('repeat refresh nodeset ', this.nodeset);
197
229
  // console.log('repeatCount', this.repeatCount);
198
230
 
199
231
  const repeatItems = this.querySelectorAll(':scope > fx-repeatitem');
@@ -213,7 +245,7 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
213
245
  // remove repeatitem
214
246
  const itemToRemove = repeatItems[position - 1];
215
247
  itemToRemove.parentNode.removeChild(itemToRemove);
216
-
248
+ this.getOwnerForm().unRegisterLazyElement(itemToRemove);
217
249
  // this._fadeOut(itemToRemove);
218
250
  // Fore.fadeOutElement(itemToRemove)
219
251
  }
@@ -228,6 +260,8 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
228
260
  newItem.appendChild(clonedTemplate);
229
261
  this.appendChild(newItem);
230
262
 
263
+ this._initVariables(newItem);
264
+
231
265
  newItem.nodeset = this.nodeset[position - 1];
232
266
  newItem.index = position;
233
267
  }
@@ -236,13 +270,25 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
236
270
  // ### update nodeset of repeatitems
237
271
  for (let position = 0; position < repeatItemCount; position += 1) {
238
272
  const item = repeatItems[position];
273
+ this.getOwnerForm().registerLazyElement(item);
274
+
239
275
  if (item.nodeset !== this.nodeset[position]) {
240
276
  item.nodeset = this.nodeset[position];
241
277
  }
242
278
  }
243
279
 
244
- Fore.refreshChildren(this);
280
+ // Fore.refreshChildren(clone,true);
281
+ const fore = this.getOwnerForm();
282
+ if (!fore.lazyRefresh || force) {
283
+ Fore.refreshChildren(this, force);
284
+ }
285
+ // this.style.display = 'block';
286
+ // this.style.display = this.display;
245
287
  this.setIndex(this.index);
288
+ console.timeEnd('repeat-refresh');
289
+
290
+ // this.replaceWith(clone);
291
+
246
292
  // this.repeatCount = contextSize;
247
293
  // console.log('repeatCount', this.repeatCount);
248
294
  console.groupEnd();
@@ -289,7 +335,7 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
289
335
  // todo: this is still weak - should handle that better maybe by an explicit slot?
290
336
  // this.template = this.firstElementChild;
291
337
  this.template = this.querySelector('template');
292
- console.log('### init template for repeat ', this.id, this.template);
338
+ // console.log('### init template for repeat ', this.id, this.template);
293
339
 
294
340
  if (this.template === null) {
295
341
  // console.error('### no template found for this repeat:', this.id);
@@ -321,9 +367,24 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
321
367
  if (repeatItem.index === 1) {
322
368
  this.applyIndex(repeatItem);
323
369
  }
370
+
371
+ this._initVariables(repeatItem);
324
372
  });
325
373
  }
326
374
 
375
+ _initVariables(newRepeatItem) {
376
+ const inScopeVariables = new Map(this.inScopeVariables);
377
+ newRepeatItem.setInScopeVariables(inScopeVariables);
378
+ (function registerVariables(node) {
379
+ for (const child of node.children) {
380
+ if ('setInScopeVariables' in child) {
381
+ child.setInScopeVariables(inScopeVariables);
382
+ }
383
+ registerVariables(child);
384
+ }
385
+ })(newRepeatItem);
386
+ }
387
+
327
388
  _clone() {
328
389
  // const content = this.template.content.cloneNode(true);
329
390
  this.template = this.shadowRoot.querySelector('template');
@@ -336,6 +397,12 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
336
397
  item.removeAttribute('repeat-index');
337
398
  });
338
399
  }
400
+
401
+ setInScopeVariables(inScopeVariables) {
402
+ // Repeats are interesting: the variables should be scoped per repeat item, they should not be
403
+ // able to see the variables in adjacent repeat items!
404
+ this.inScopeVariables = new Map(inScopeVariables);
405
+ }
339
406
  }
340
407
 
341
408
  window.customElements.define('fx-repeat', FxRepeat);
@@ -22,7 +22,8 @@ export class FxRepeatitem extends foreElementMixin(HTMLElement) {
22
22
  this.inited = false;
23
23
 
24
24
  this.addEventListener('click', this._dispatchIndexChange);
25
- this.addEventListener('focusin', this._handleFocus);
25
+ // this.addEventListener('focusin', this._handleFocus);
26
+ this.addEventListener('focusin', this._dispatchIndexChange);
26
27
 
27
28
  this.attachShadow({ mode: 'open', delegatesFocus: true });
28
29
  }
@@ -30,7 +31,12 @@ export class FxRepeatitem extends foreElementMixin(HTMLElement) {
30
31
  _handleFocus() {
31
32
  this.parentNode.setIndex(this.index);
32
33
  // TODO: do this somewhere else, somewhere more central
33
- this.closest('fx-fore').refresh();
34
+
35
+ /**
36
+ * todo: resolve - this is problematic as it triggers a lot of unneeded refreshes but it needed
37
+ * when you want to support activating the right repeatitem when the user tabs through controls.
38
+ */
39
+ // this.closest('fx-fore').refresh();
34
40
  }
35
41
 
36
42
  _dispatchIndexChange() {
@@ -52,6 +58,7 @@ export class FxRepeatitem extends foreElementMixin(HTMLElement) {
52
58
  this.shadowRoot.innerHTML = `
53
59
  ${html}
54
60
  `;
61
+ this.getOwnerForm().registerLazyElement(this);
55
62
  }
56
63
 
57
64
  disconnectedCallback() {
@@ -72,7 +79,7 @@ export class FxRepeatitem extends foreElementMixin(HTMLElement) {
72
79
  return this.getModelItem()[this.index];
73
80
  }
74
81
 
75
- refresh() {
82
+ refresh(force) {
76
83
  // console.log('refresh repeatitem: ',this.nodeset);
77
84
  // console.log('refresh repeatitem nodeset: ',this.nodeset);
78
85
  this.modelItem = this.getModel().getModelItem(this.nodeset);
@@ -94,7 +101,7 @@ export class FxRepeatitem extends foreElementMixin(HTMLElement) {
94
101
  }
95
102
  */
96
103
 
97
- Fore.refreshChildren(this);
104
+ Fore.refreshChildren(this, force);
98
105
  }
99
106
  }
100
107
 
@@ -80,6 +80,9 @@ export class FxTrigger extends XfAbstractControl {
80
80
  repeatedItem.click();
81
81
  }
82
82
 
83
+ // Update all child variables, but only once
84
+ this.querySelectorAll('fx-var').forEach(variableElement => variableElement.refresh());
85
+
83
86
  const forLoop = async () => {
84
87
  for (let i = 0; i < this.children.length; i += 1) {
85
88
  const child = this.children[i];