@jinntec/fore 1.0.0-0 → 1.0.0-3

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.
@@ -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,14 @@ 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
228
  // console.log('repeat refresh nodeset ', this.nodeset);
229
+ // console.log('repeatCount', this.repeatCount);
197
230
 
198
231
  const repeatItems = this.querySelectorAll(':scope > fx-repeatitem');
199
232
  const repeatItemCount = repeatItems.length;
@@ -212,8 +245,9 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
212
245
  // remove repeatitem
213
246
  const itemToRemove = repeatItems[position - 1];
214
247
  itemToRemove.parentNode.removeChild(itemToRemove);
215
-
248
+ this.getOwnerForm().unRegisterLazyElement(itemToRemove);
216
249
  // this._fadeOut(itemToRemove);
250
+ // Fore.fadeOutElement(itemToRemove)
217
251
  }
218
252
  }
219
253
 
@@ -226,6 +260,8 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
226
260
  newItem.appendChild(clonedTemplate);
227
261
  this.appendChild(newItem);
228
262
 
263
+ this._initVariables(newItem);
264
+
229
265
  newItem.nodeset = this.nodeset[position - 1];
230
266
  newItem.index = position;
231
267
  }
@@ -234,14 +270,27 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
234
270
  // ### update nodeset of repeatitems
235
271
  for (let position = 0; position < repeatItemCount; position += 1) {
236
272
  const item = repeatItems[position];
273
+ this.getOwnerForm().registerLazyElement(item);
274
+
237
275
  if (item.nodeset !== this.nodeset[position]) {
238
276
  item.nodeset = this.nodeset[position];
239
277
  }
240
278
  }
241
279
 
242
- this._fadeIn(repeatItems[this.index - 1]);
243
- 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;
244
287
  this.setIndex(this.index);
288
+ console.timeEnd('repeat-refresh');
289
+
290
+ // this.replaceWith(clone);
291
+
292
+ // this.repeatCount = contextSize;
293
+ // console.log('repeatCount', this.repeatCount);
245
294
  console.groupEnd();
246
295
  }
247
296
 
@@ -286,7 +335,7 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
286
335
  // todo: this is still weak - should handle that better maybe by an explicit slot?
287
336
  // this.template = this.firstElementChild;
288
337
  this.template = this.querySelector('template');
289
- console.log('### init template for repeat ', this.id, this.template);
338
+ // console.log('### init template for repeat ', this.id, this.template);
290
339
 
291
340
  if (this.template === null) {
292
341
  // console.error('### no template found for this repeat:', this.id);
@@ -318,9 +367,24 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
318
367
  if (repeatItem.index === 1) {
319
368
  this.applyIndex(repeatItem);
320
369
  }
370
+
371
+ this._initVariables(repeatItem);
321
372
  });
322
373
  }
323
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
+
324
388
  _clone() {
325
389
  // const content = this.template.content.cloneNode(true);
326
390
  this.template = this.shadowRoot.querySelector('template');
@@ -333,6 +397,12 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
333
397
  item.removeAttribute('repeat-index');
334
398
  });
335
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
+ }
336
406
  }
337
407
 
338
408
  window.customElements.define('fx-repeat', FxRepeat);
@@ -22,13 +22,21 @@ 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
  }
29
30
 
30
31
  _handleFocus() {
31
32
  this.parentNode.setIndex(this.index);
33
+ // TODO: do this somewhere else, somewhere more central
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();
32
40
  }
33
41
 
34
42
  _dispatchIndexChange() {
@@ -50,6 +58,7 @@ export class FxRepeatitem extends foreElementMixin(HTMLElement) {
50
58
  this.shadowRoot.innerHTML = `
51
59
  ${html}
52
60
  `;
61
+ this.getOwnerForm().registerLazyElement(this);
53
62
  }
54
63
 
55
64
  disconnectedCallback() {
@@ -70,14 +79,18 @@ export class FxRepeatitem extends foreElementMixin(HTMLElement) {
70
79
  return this.getModelItem()[this.index];
71
80
  }
72
81
 
73
- refresh() {
82
+ refresh(force) {
74
83
  // console.log('refresh repeatitem: ',this.nodeset);
75
84
  // console.log('refresh repeatitem nodeset: ',this.nodeset);
76
85
  this.modelItem = this.getModel().getModelItem(this.nodeset);
77
86
 
78
87
  if (this.modelItem && !this.modelItem.relevant) {
88
+ // await Fore.fadeOutElement(this)
79
89
  this.style.display = 'none';
80
90
  } else {
91
+ // if(this.hasAttribute('repeat-index')){
92
+ // Fore.fadeInElement(this);
93
+ // }
81
94
  this.style.display = this.display;
82
95
  }
83
96
 
@@ -88,7 +101,7 @@ export class FxRepeatitem extends foreElementMixin(HTMLElement) {
88
101
  }
89
102
  */
90
103
 
91
- Fore.refreshChildren(this);
104
+ Fore.refreshChildren(this, force);
92
105
  }
93
106
  }
94
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];