@jinntec/fore 1.3.0 → 1.5.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/dist/fore-dev.js +8 -8
- package/dist/fore-dev.js.map +1 -1
- package/dist/fore.js +7 -7
- package/dist/fore.js.map +1 -1
- package/index.js +1 -0
- package/package.json +1 -1
- package/resources/fore.css +6 -1
- package/src/ForeElementMixin.js +4 -0
- package/src/actions/abstract-action.js +117 -48
- package/src/actions/fx-action.js +9 -9
- package/src/actions/fx-append.js +1 -1
- package/src/actions/fx-confirm.js +1 -1
- package/src/actions/fx-copy.js +68 -0
- package/src/actions/fx-delete.js +1 -1
- package/src/actions/fx-dispatch.js +1 -1
- package/src/actions/fx-hide.js +1 -1
- package/src/actions/fx-insert.js +1 -1
- package/src/actions/fx-message.js +1 -1
- package/src/actions/fx-refresh.js +2 -2
- package/src/actions/fx-reload.js +1 -1
- package/src/actions/fx-replace.js +1 -1
- package/src/actions/fx-return.js +1 -1
- package/src/actions/fx-send.js +2 -2
- package/src/actions/fx-setfocus.js +1 -1
- package/src/actions/fx-setvalue.js +1 -1
- package/src/actions/fx-show.js +1 -1
- package/src/actions/fx-toggle.js +1 -1
- package/src/actions/fx-update.js +1 -1
- package/src/fore.js +59 -10
- package/src/fx-bind.js +5 -0
- package/src/fx-fore.js +92 -35
- package/src/fx-instance.js +70 -70
- package/src/fx-model.js +12 -17
- package/src/fx-submission.js +420 -416
- package/src/getInScopeContext.js +19 -5
- package/src/modelitem.js +3 -1
- package/src/ui/abstract-control.js +1 -1
- package/src/ui/fx-control.js +2 -2
- package/src/ui/fx-repeat-attributes.js +442 -0
- package/src/ui/fx-repeat.js +8 -0
- package/src/ui/fx-switch.js +9 -1
- package/src/ui/fx-trigger.js +19 -18
- package/src/xpath-evaluation.js +21 -9
- package/src/xpath-util.js +13 -28
package/src/getInScopeContext.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {evaluateXPathToFirstNode} from './xpath-evaluation.js';
|
|
1
|
+
import { evaluateXPathToFirstNode } from './xpath-evaluation.js';
|
|
2
2
|
import {Fore} from './fore.js';
|
|
3
3
|
|
|
4
4
|
import {XPathUtil} from './xpath-util.js';
|
|
@@ -52,10 +52,8 @@ function _getInitialContext(node, ref) {
|
|
|
52
52
|
}
|
|
53
53
|
return model.getDefaultInstance().getDefaultContext();
|
|
54
54
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
return [];
|
|
55
|
+
// should always return default context if all other fails
|
|
56
|
+
return model.getDefaultInstance().getDefaultContext();
|
|
59
57
|
}
|
|
60
58
|
|
|
61
59
|
export default function getInScopeContext(node, ref) {
|
|
@@ -81,6 +79,22 @@ export default function getInScopeContext(node, ref) {
|
|
|
81
79
|
return repeatItem.nodeset;
|
|
82
80
|
}
|
|
83
81
|
|
|
82
|
+
// ### check for repeatitems created by fx-repeat-attributes - this could possibly be unified with standard repeats
|
|
83
|
+
// const repeatItemFromAttrs = Fore.getClosest('.fx-repeatitem', parentElement);
|
|
84
|
+
// const repeatItemFromAttrs = Fore.getClosest('.fx-repeatitem', parentElement);
|
|
85
|
+
const repeatItemFromAttrs = parentElement.closest('.fx-repeatitem');
|
|
86
|
+
|
|
87
|
+
if (repeatItemFromAttrs) {
|
|
88
|
+
// ### determine correct inscopecontext by determining the index of the repeatitem in its parent list and
|
|
89
|
+
// ### using that as an index on the repeat nodeset
|
|
90
|
+
const parent = repeatItemFromAttrs.parentNode;
|
|
91
|
+
const index = Array.from(parent.children).indexOf(repeatItemFromAttrs);
|
|
92
|
+
|
|
93
|
+
// ### fetching nodeset from fx-repeat-attributes element
|
|
94
|
+
const repeatFromAttributes = Fore.getClosest('fx-repeat-attributes', parentElement);
|
|
95
|
+
return repeatFromAttributes.nodeset[index];
|
|
96
|
+
}
|
|
97
|
+
|
|
84
98
|
if (parentElement.hasAttribute('context')) {
|
|
85
99
|
const initialContext = _getInitialContext(parentElement.parentNode, ref);
|
|
86
100
|
const contextAttr = parentElement.getAttribute('context');
|
package/src/modelitem.js
CHANGED
|
@@ -257,7 +257,7 @@ export default class AbstractControl extends foreElementMixin(HTMLElement) {
|
|
|
257
257
|
const alert = this.querySelector('fx-alert');
|
|
258
258
|
|
|
259
259
|
const mi = this.getModelItem();
|
|
260
|
-
console.log('late modelItem', mi);
|
|
260
|
+
// console.log('late modelItem', mi);
|
|
261
261
|
if (this.isValid() !== this.modelItem.constraint) {
|
|
262
262
|
if (this.modelItem.constraint) {
|
|
263
263
|
// if (alert) alert.style.display = 'none';
|
package/src/ui/fx-control.js
CHANGED
|
@@ -482,7 +482,7 @@ export default class FxControl extends XfAbstractControl {
|
|
|
482
482
|
if (nodeset.length) {
|
|
483
483
|
// console.log('nodeset', nodeset);
|
|
484
484
|
const fragment = document.createDocumentFragment();
|
|
485
|
-
console.time('offscreen');
|
|
485
|
+
// console.time('offscreen');
|
|
486
486
|
/*
|
|
487
487
|
Array.from(nodeset).forEach(node => {
|
|
488
488
|
// console.log('#### node', node);
|
|
@@ -504,7 +504,7 @@ export default class FxControl extends XfAbstractControl {
|
|
|
504
504
|
this.updateEntry(newEntry, node);
|
|
505
505
|
});
|
|
506
506
|
this.template.parentNode.appendChild(fragment);
|
|
507
|
-
console.timeEnd('offscreen');
|
|
507
|
+
// console.timeEnd('offscreen');
|
|
508
508
|
} else {
|
|
509
509
|
const newEntry = this.createEntry();
|
|
510
510
|
this.template.parentNode.appendChild(newEntry);
|
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
import { Fore } from '../fore.js';
|
|
2
|
+
import { evaluateXPath } from '../xpath-evaluation.js';
|
|
3
|
+
import getInScopeContext from '../getInScopeContext.js';
|
|
4
|
+
import { XPathUtil } from '../xpath-util.js';
|
|
5
|
+
import {foreElementMixin} from "../ForeElementMixin.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* `fx-repeat`
|
|
9
|
+
*
|
|
10
|
+
* Repeats its template for each node in its' bound nodeset.
|
|
11
|
+
*
|
|
12
|
+
* Template is a standard HTML `<template>` element. Once instanciated the template
|
|
13
|
+
* is moved to the shadowDOM of the repeat for safe re-use.
|
|
14
|
+
*
|
|
15
|
+
*
|
|
16
|
+
*
|
|
17
|
+
* @customElement
|
|
18
|
+
* @demo demo/todo.html
|
|
19
|
+
*
|
|
20
|
+
* todo: it should be seriously be considered to extend FxContainer instead but needs refactoring first.
|
|
21
|
+
*/
|
|
22
|
+
export class FxRepeatAttributes extends foreElementMixin(HTMLElement) {
|
|
23
|
+
static get properties() {
|
|
24
|
+
return {
|
|
25
|
+
...super.properties,
|
|
26
|
+
index: {
|
|
27
|
+
type: Number,
|
|
28
|
+
},
|
|
29
|
+
template: {
|
|
30
|
+
type: Object,
|
|
31
|
+
},
|
|
32
|
+
focusOnCreate: {
|
|
33
|
+
type: String,
|
|
34
|
+
},
|
|
35
|
+
initDone: {
|
|
36
|
+
type: Boolean,
|
|
37
|
+
},
|
|
38
|
+
repeatIndex: {
|
|
39
|
+
type: Number,
|
|
40
|
+
},
|
|
41
|
+
repeatSize:{
|
|
42
|
+
type:Number,
|
|
43
|
+
},
|
|
44
|
+
nodeset: {
|
|
45
|
+
type: Array,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
constructor() {
|
|
51
|
+
super();
|
|
52
|
+
this.ref = '';
|
|
53
|
+
this.dataTemplate = [];
|
|
54
|
+
this.focusOnCreate = '';
|
|
55
|
+
this.initDone = false;
|
|
56
|
+
this.repeatIndex = 1;
|
|
57
|
+
this.nodeset = [];
|
|
58
|
+
this.inited = false;
|
|
59
|
+
this.host= {};
|
|
60
|
+
this.index = 1;
|
|
61
|
+
this.repeatSize = 0;
|
|
62
|
+
this.attachShadow({ mode: 'open', delegatesFocus: true });
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
get repeatSize() {
|
|
66
|
+
return this.querySelectorAll(':scope > .fx-repeatitem').length;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
set repeatSize(size) {
|
|
70
|
+
super.repeatSize = size;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
setIndex(index) {
|
|
75
|
+
// console.log('new repeat index ', index);
|
|
76
|
+
this.index = index;
|
|
77
|
+
const refd = this.querySelector('[data-ref]');
|
|
78
|
+
const rItems = refd.querySelectorAll(':scope > *');
|
|
79
|
+
this.applyIndex(rItems[this.index - 1]);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
applyIndex(repeatItem) {
|
|
83
|
+
this._removeIndexMarker();
|
|
84
|
+
if (repeatItem) {
|
|
85
|
+
repeatItem.setAttribute('repeat-index', '');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
get index() {
|
|
90
|
+
return this.getAttribute('index');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
set index(idx) {
|
|
94
|
+
this.setAttribute('index', idx);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
_getRepeatedItems(){
|
|
98
|
+
const refd = this.querySelector('[data-ref]');
|
|
99
|
+
return refd.children;
|
|
100
|
+
}
|
|
101
|
+
async connectedCallback() {
|
|
102
|
+
console.log('connectedCallback',this);
|
|
103
|
+
// this.display = window.getComputedStyle(this, null).getPropertyValue("display");
|
|
104
|
+
this.ref = this.getAttribute('ref');
|
|
105
|
+
// this.ref = this._getRef();
|
|
106
|
+
// console.log('### fx-repeat connected ', this.id);
|
|
107
|
+
this.addEventListener('item-changed', e => {
|
|
108
|
+
console.log('handle index event ', e);
|
|
109
|
+
const { item } = e.detail;
|
|
110
|
+
const repeatedItems = this._getRepeatedItems();
|
|
111
|
+
const idx = Array.from(repeatedItems).indexOf(item);
|
|
112
|
+
this.applyIndex(repeatedItems[idx]);
|
|
113
|
+
this.index = idx + 1;
|
|
114
|
+
});
|
|
115
|
+
// todo: review - this is just used by append action - event consolidation ?
|
|
116
|
+
document.addEventListener('index-changed', e => {
|
|
117
|
+
e.stopPropagation();
|
|
118
|
+
if (!e.target === this) return;
|
|
119
|
+
console.log('handle index event ', e);
|
|
120
|
+
// const { item } = e.detail;
|
|
121
|
+
// const idx = Array.from(this.children).indexOf(item);
|
|
122
|
+
const { index } = e.detail;
|
|
123
|
+
this.index = Number(index);
|
|
124
|
+
this.applyIndex(this.children[index - 1]);
|
|
125
|
+
});
|
|
126
|
+
/*
|
|
127
|
+
document.addEventListener('insert', e => {
|
|
128
|
+
const nodes = e.detail.insertedNodes;
|
|
129
|
+
this.index = e.detail.position;
|
|
130
|
+
console.log('insert catched', nodes, this.index);
|
|
131
|
+
});
|
|
132
|
+
*/
|
|
133
|
+
|
|
134
|
+
// if (this.getOwnerForm().lazyRefresh) {
|
|
135
|
+
this.mutationObserver = new MutationObserver(mutations => {
|
|
136
|
+
console.log('mutations', mutations);
|
|
137
|
+
|
|
138
|
+
if (mutations[0].type === 'childList') {
|
|
139
|
+
const added = mutations[0].addedNodes[0];
|
|
140
|
+
if (added) {
|
|
141
|
+
const path = XPathUtil.getPath(added);
|
|
142
|
+
console.log('path mutated', path);
|
|
143
|
+
// this.dispatch('path-mutated',{'path':path,'nodeset':this.nodeset,'index': this.index});
|
|
144
|
+
// this.index = index;
|
|
145
|
+
// const prev = mutations[0].previousSibling.previousElementSibling;
|
|
146
|
+
// const index = prev.index();
|
|
147
|
+
// this.applyIndex(this.index -1);
|
|
148
|
+
|
|
149
|
+
Fore.dispatch(this, 'path-mutated', { path, index: this.index });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
// }
|
|
154
|
+
this.getOwnerForm().registerLazyElement(this);
|
|
155
|
+
|
|
156
|
+
const style = `
|
|
157
|
+
:host{
|
|
158
|
+
}
|
|
159
|
+
.fade-out-bottom {
|
|
160
|
+
-webkit-animation: fade-out-bottom 0.7s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
|
|
161
|
+
animation: fade-out-bottom 0.7s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
|
|
162
|
+
}
|
|
163
|
+
.fade-out-bottom {
|
|
164
|
+
-webkit-animation: fade-out-bottom 0.7s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
|
|
165
|
+
animation: fade-out-bottom 0.7s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
|
|
166
|
+
}
|
|
167
|
+
`;
|
|
168
|
+
const html = `
|
|
169
|
+
<slot></slot>
|
|
170
|
+
`;
|
|
171
|
+
this.shadowRoot.innerHTML = `
|
|
172
|
+
<style>
|
|
173
|
+
${style}
|
|
174
|
+
</style>
|
|
175
|
+
${html}
|
|
176
|
+
`;
|
|
177
|
+
|
|
178
|
+
// this.init();
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async init() {
|
|
182
|
+
// ### there must be a single 'template' child
|
|
183
|
+
|
|
184
|
+
const inited = new Promise(resolve => {
|
|
185
|
+
console.log('##### repeat-attributes init ', this.id);
|
|
186
|
+
// if(!this.inited) this.init();
|
|
187
|
+
// does not use this.evalInContext as it is expecting a nodeset instead of single node
|
|
188
|
+
this._evalNodeset();
|
|
189
|
+
// console.log('##### ',this.id, this.nodeset);
|
|
190
|
+
|
|
191
|
+
this._initTemplate();
|
|
192
|
+
// this._initRepeatItems();
|
|
193
|
+
|
|
194
|
+
this.setAttribute('index', this.index);
|
|
195
|
+
this.inited = true;
|
|
196
|
+
resolve('done');
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
return inited;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
_getRef(){
|
|
203
|
+
return this.getAttribute('ref');
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* repeat has no own modelItems
|
|
208
|
+
* @private
|
|
209
|
+
*/
|
|
210
|
+
_evalNodeset() {
|
|
211
|
+
// const inscope = this.getInScopeContext();
|
|
212
|
+
const inscope = getInScopeContext(this.getAttributeNode('ref') || this, this.ref);
|
|
213
|
+
// console.log('##### inscope ', inscope);
|
|
214
|
+
// console.log('##### ref ', this.ref);
|
|
215
|
+
// now we got a nodeset and attach MutationObserver to it
|
|
216
|
+
|
|
217
|
+
if (this.mutationObserver && inscope.nodeName) {
|
|
218
|
+
this.mutationObserver.observe(inscope, {
|
|
219
|
+
childList: true,
|
|
220
|
+
subtree: true,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const rawNodeset = evaluateXPath(this.ref, inscope, this);
|
|
225
|
+
if (rawNodeset.length === 1 && Array.isArray(rawNodeset[0])) {
|
|
226
|
+
// This XPath likely returned an XPath array. Just collapse to that array
|
|
227
|
+
this.nodeset = rawNodeset[0];
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
this.nodeset = rawNodeset;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async refresh(force) {
|
|
234
|
+
// console.group('fx-repeat.refresh on', this.id);
|
|
235
|
+
|
|
236
|
+
if (!this.inited) this.init();
|
|
237
|
+
console.time('repeat-refresh', this);
|
|
238
|
+
this._evalNodeset();
|
|
239
|
+
// console.log('repeat refresh nodeset ', this.nodeset);
|
|
240
|
+
|
|
241
|
+
let repeatItems = this.querySelectorAll('.fx-repeatitem');
|
|
242
|
+
let repeatItemCount = repeatItems.length;
|
|
243
|
+
|
|
244
|
+
let nodeCount = 1;
|
|
245
|
+
if (Array.isArray(this.nodeset)) {
|
|
246
|
+
nodeCount = this.nodeset.length;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// const contextSize = this.nodeset.length;
|
|
250
|
+
const contextSize = nodeCount;
|
|
251
|
+
// todo: review - cant the context really never be smaller than the repeat count?
|
|
252
|
+
// todo: this code can be deprecated probably but check first
|
|
253
|
+
if (contextSize < repeatItemCount) {
|
|
254
|
+
for (let position = repeatItemCount; position > contextSize; position -= 1) {
|
|
255
|
+
// remove repeatitem
|
|
256
|
+
const itemToRemove = repeatItems[position - 1];
|
|
257
|
+
itemToRemove.parentNode.removeChild(itemToRemove);
|
|
258
|
+
this.getOwnerForm().unRegisterLazyElement(itemToRemove);
|
|
259
|
+
// this._fadeOut(itemToRemove);
|
|
260
|
+
// Fore.fadeOutElement(itemToRemove)
|
|
261
|
+
this.getOwnerForm().someInstanceDataStructureChanged = true;
|
|
262
|
+
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (contextSize > repeatItemCount) {
|
|
267
|
+
for (let position = repeatItemCount + 1; position <= contextSize; position += 1) {
|
|
268
|
+
// add new repeatitem
|
|
269
|
+
|
|
270
|
+
const clonedTemplate = this._clone();
|
|
271
|
+
|
|
272
|
+
// ### cloned templates are always appended to the binding element - the one having the data-ref
|
|
273
|
+
const bindingElement = this.querySelector('[data-ref]');
|
|
274
|
+
bindingElement.appendChild(clonedTemplate);
|
|
275
|
+
clonedTemplate.classList.add('fx-repeatitem');
|
|
276
|
+
clonedTemplate.setAttribute('index',position);
|
|
277
|
+
|
|
278
|
+
clonedTemplate.addEventListener('click', this._dispatchIndexChange);
|
|
279
|
+
// this.addEventListener('focusin', this._handleFocus);
|
|
280
|
+
clonedTemplate.addEventListener('focusin', this._dispatchIndexChange);
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
// this._initVariables(clonedTemplate);
|
|
284
|
+
|
|
285
|
+
// newItem.nodeset = this.nodeset[position - 1];
|
|
286
|
+
// newItem.index = position;
|
|
287
|
+
this.getOwnerForm().someInstanceDataStructureChanged = true;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// ### update nodeset of repeatitems
|
|
292
|
+
repeatItems = this.querySelectorAll(':scope > .fx-repeatitem');
|
|
293
|
+
repeatItemCount = repeatItems.length;
|
|
294
|
+
|
|
295
|
+
for (let position = 0; position < repeatItemCount; position += 1) {
|
|
296
|
+
const item = repeatItems[position];
|
|
297
|
+
this.getOwnerForm().registerLazyElement(item);
|
|
298
|
+
|
|
299
|
+
if (item.nodeset !== this.nodeset[position]) {
|
|
300
|
+
item.nodeset = this.nodeset[position];
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Fore.refreshChildren(clone,true);
|
|
305
|
+
const fore = this.getOwnerForm();
|
|
306
|
+
if (!fore.lazyRefresh || force) {
|
|
307
|
+
Fore.refreshChildren(this, force);
|
|
308
|
+
}
|
|
309
|
+
// this.style.display = 'block';
|
|
310
|
+
// this.style.display = this.display;
|
|
311
|
+
this.setIndex(this.index);
|
|
312
|
+
console.timeEnd('repeat-refresh');
|
|
313
|
+
|
|
314
|
+
console.groupEnd();
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
_dispatchIndexChange() {
|
|
318
|
+
// console.log('_dispatchIndexChange on index ', this.index);
|
|
319
|
+
this.dispatchEvent(
|
|
320
|
+
new CustomEvent('item-changed', { composed: false, bubbles: true, detail: { item: this , index:this.index } }),
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// eslint-disable-next-line class-methods-use-this
|
|
325
|
+
_fadeOut(el) {
|
|
326
|
+
el.style.opacity = 1;
|
|
327
|
+
|
|
328
|
+
(function fade() {
|
|
329
|
+
// eslint-disable-next-line no-cond-assign
|
|
330
|
+
if ((el.style.opacity -= 0.1) < 0) {
|
|
331
|
+
el.style.display = 'none';
|
|
332
|
+
} else {
|
|
333
|
+
requestAnimationFrame(fade);
|
|
334
|
+
}
|
|
335
|
+
})();
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// eslint-disable-next-line class-methods-use-this
|
|
339
|
+
_fadeIn(el) {
|
|
340
|
+
if (!el) return;
|
|
341
|
+
|
|
342
|
+
el.style.opacity = 0;
|
|
343
|
+
el.style.display = this.display;
|
|
344
|
+
|
|
345
|
+
(function fade() {
|
|
346
|
+
// setTimeout(() => {
|
|
347
|
+
let val = parseFloat(el.style.opacity);
|
|
348
|
+
// eslint-disable-next-line no-cond-assign
|
|
349
|
+
if (!((val += 0.1) > 1)) {
|
|
350
|
+
el.style.opacity = val;
|
|
351
|
+
requestAnimationFrame(fade);
|
|
352
|
+
}
|
|
353
|
+
// }, 40);
|
|
354
|
+
})();
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
async _initTemplate() {
|
|
358
|
+
// const shadowTemplate = this.shadowRoot.querySelector('template');
|
|
359
|
+
// console.log('shadowtempl ', shadowTemplate);
|
|
360
|
+
|
|
361
|
+
// const defaultSlot = this.shadowRoot.querySelector('slot');
|
|
362
|
+
// todo: this is still weak - should handle that better maybe by an explicit slot?
|
|
363
|
+
// this.template = this.firstElementChild;
|
|
364
|
+
this.template = this.querySelector('template');
|
|
365
|
+
console.log('### init template for repeat ', this.id, this.template);
|
|
366
|
+
|
|
367
|
+
if (this.template === null) {
|
|
368
|
+
// console.error('### no template found for this repeat:', this.id);
|
|
369
|
+
// todo: catch this on form element
|
|
370
|
+
this.dispatchEvent(
|
|
371
|
+
new CustomEvent('no-template-error', {
|
|
372
|
+
composed: true,
|
|
373
|
+
bubbles: true,
|
|
374
|
+
detail: { message: `no template found for repeat:${this.id}` },
|
|
375
|
+
}),
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
this.shadowRoot.appendChild(this.template);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/*
|
|
383
|
+
_initRepeatItems() {
|
|
384
|
+
console.log('_initRepeatItems', this.nodeset);
|
|
385
|
+
// const model = this.getModel();
|
|
386
|
+
// this.textContent = '';
|
|
387
|
+
Array.from(this.nodeset).forEach((item, index) => {
|
|
388
|
+
|
|
389
|
+
const clone = this._clone();
|
|
390
|
+
this.appendChild(clone);
|
|
391
|
+
/!*
|
|
392
|
+
this.appendChild(repeatItem);
|
|
393
|
+
|
|
394
|
+
if (item.index === 1) {
|
|
395
|
+
this.applyIndex(item);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
this._initVariables(item);
|
|
399
|
+
*!/
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
*/
|
|
403
|
+
|
|
404
|
+
_initVariables(newRepeatItem) {
|
|
405
|
+
const inScopeVariables = new Map(this.inScopeVariables);
|
|
406
|
+
newRepeatItem.setInScopeVariables(inScopeVariables);
|
|
407
|
+
(function registerVariables(node) {
|
|
408
|
+
for (const child of node.children) {
|
|
409
|
+
if ('setInScopeVariables' in child) {
|
|
410
|
+
child.setInScopeVariables(inScopeVariables);
|
|
411
|
+
}
|
|
412
|
+
registerVariables(child);
|
|
413
|
+
}
|
|
414
|
+
})(newRepeatItem);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
_clone() {
|
|
418
|
+
// const content = this.template.content.cloneNode(true);
|
|
419
|
+
this.template = this.shadowRoot.querySelector('template');
|
|
420
|
+
// this.template = this.querySelector('template');
|
|
421
|
+
// const content = this.template.content.cloneNode(true);
|
|
422
|
+
// return document.importNode(content, true);
|
|
423
|
+
return this.template.content.firstElementChild.cloneNode(true);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
_removeIndexMarker() {
|
|
427
|
+
const refd = this.querySelector('[data-ref]');
|
|
428
|
+
Array.from(refd.children).forEach(item => {
|
|
429
|
+
item.removeAttribute('repeat-index');
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
setInScopeVariables(inScopeVariables) {
|
|
434
|
+
// Repeats are interesting: the variables should be scoped per repeat item, they should not be
|
|
435
|
+
// able to see the variables in adjacent repeat items!
|
|
436
|
+
this.inScopeVariables = new Map(inScopeVariables);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
if (!customElements.get('fx-repeat-attributes')) {
|
|
441
|
+
window.customElements.define('fx-repeat-attributes', FxRepeatAttributes);
|
|
442
|
+
}
|
package/src/ui/fx-repeat.js
CHANGED
|
@@ -90,9 +90,15 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
|
|
|
90
90
|
this.setAttribute('index', idx);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
_getRef(){
|
|
94
|
+
return this.getAttribute('ref');
|
|
95
|
+
}
|
|
96
|
+
|
|
93
97
|
connectedCallback() {
|
|
98
|
+
console.log('connectedCallback',this);
|
|
94
99
|
// this.display = window.getComputedStyle(this, null).getPropertyValue("display");
|
|
95
100
|
this.ref = this.getAttribute('ref');
|
|
101
|
+
// this.ref = this._getRef();
|
|
96
102
|
// console.log('### fx-repeat connected ', this.id);
|
|
97
103
|
this.addEventListener('item-changed', e => {
|
|
98
104
|
console.log('handle index event ', e);
|
|
@@ -164,6 +170,8 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
|
|
|
164
170
|
</style>
|
|
165
171
|
${html}
|
|
166
172
|
`;
|
|
173
|
+
|
|
174
|
+
// this.init();
|
|
167
175
|
}
|
|
168
176
|
|
|
169
177
|
init() {
|
package/src/ui/fx-switch.js
CHANGED
|
@@ -5,7 +5,6 @@ import { FxContainer } from './fx-container.js';
|
|
|
5
5
|
* `fx-switch`
|
|
6
6
|
* a container allowing to switch between fx-case elements
|
|
7
7
|
*
|
|
8
|
-
* * todo: implement
|
|
9
8
|
* @customElement
|
|
10
9
|
*/
|
|
11
10
|
class FxSwitch extends FxContainer {
|
|
@@ -45,9 +44,13 @@ class FxSwitch extends FxContainer {
|
|
|
45
44
|
Array.from(cases).forEach(caseElem => {
|
|
46
45
|
const name = caseElem.getAttribute('name');
|
|
47
46
|
if (name === this.modelItem.value) {
|
|
47
|
+
Fore.dispatch(caseElem,'select',{});
|
|
48
48
|
caseElem.classList.add('selected-case');
|
|
49
49
|
selectedCase = caseElem;
|
|
50
50
|
} else {
|
|
51
|
+
if(caseElem.classList.contains('selected-case')){
|
|
52
|
+
Fore.dispatch(caseElem,'deselect',{});
|
|
53
|
+
}
|
|
51
54
|
caseElem.classList.remove('selected-case');
|
|
52
55
|
}
|
|
53
56
|
});
|
|
@@ -56,6 +59,7 @@ class FxSwitch extends FxContainer {
|
|
|
56
59
|
// if none is selected select the first as default
|
|
57
60
|
if (!selectedCase) {
|
|
58
61
|
selectedCase = cases[0];
|
|
62
|
+
Fore.dispatch(selectedCase,'select',{});
|
|
59
63
|
selectedCase.classList.add('selected-case');
|
|
60
64
|
}
|
|
61
65
|
}
|
|
@@ -69,9 +73,13 @@ class FxSwitch extends FxContainer {
|
|
|
69
73
|
if (caseElement === c) {
|
|
70
74
|
// eslint-disable-next-line no-param-reassign
|
|
71
75
|
c.classList.add('selected-case');
|
|
76
|
+
Fore.dispatch(c,'select',{});
|
|
72
77
|
this.refresh();
|
|
73
78
|
} else {
|
|
74
79
|
// eslint-disable-next-line no-param-reassign
|
|
80
|
+
if(c.classList.contains('selected-case')){
|
|
81
|
+
Fore.dispatch(c,'deselect',{});
|
|
82
|
+
}
|
|
75
83
|
c.classList.remove('selected-case');
|
|
76
84
|
}
|
|
77
85
|
});
|
package/src/ui/fx-trigger.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import XfAbstractControl from './abstract-control.js';
|
|
2
|
-
import {leadingDebounce} from
|
|
2
|
+
import { leadingDebounce } from '../events.js';
|
|
3
3
|
|
|
4
4
|
export class FxTrigger extends XfAbstractControl {
|
|
5
5
|
connectedCallback() {
|
|
@@ -28,14 +28,18 @@ export class FxTrigger extends XfAbstractControl {
|
|
|
28
28
|
|
|
29
29
|
const element = elements[0];
|
|
30
30
|
|
|
31
|
-
if(this.debounceDelay){
|
|
31
|
+
if (this.debounceDelay) {
|
|
32
32
|
this.addEventListener(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
'click',
|
|
34
|
+
leadingDebounce(
|
|
35
|
+
this,
|
|
36
|
+
e => {
|
|
37
|
+
this.performActions(e);
|
|
38
|
+
},
|
|
39
|
+
this.debounceDelay,
|
|
40
|
+
),
|
|
37
41
|
);
|
|
38
|
-
}else{
|
|
42
|
+
} else {
|
|
39
43
|
element.addEventListener('click', e => this.performActions(e));
|
|
40
44
|
}
|
|
41
45
|
this.widget = element;
|
|
@@ -63,7 +67,7 @@ export class FxTrigger extends XfAbstractControl {
|
|
|
63
67
|
}
|
|
64
68
|
|
|
65
69
|
async updateWidgetValue() {
|
|
66
|
-
console.log('trigger update', this);
|
|
70
|
+
// console.log('trigger update', this);
|
|
67
71
|
return null;
|
|
68
72
|
}
|
|
69
73
|
|
|
@@ -88,17 +92,14 @@ export class FxTrigger extends XfAbstractControl {
|
|
|
88
92
|
// Update all child variables, but only once
|
|
89
93
|
this.querySelectorAll('fx-var').forEach(variableElement => variableElement.refresh());
|
|
90
94
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
// child.execute(e);
|
|
98
|
-
}
|
|
95
|
+
for (let i = 0; i < this.children.length; i += 1) {
|
|
96
|
+
const child = this.children[i];
|
|
97
|
+
if (typeof child.execute === 'function') {
|
|
98
|
+
// eslint-disable-next-line no-await-in-loop
|
|
99
|
+
await child.execute(e);
|
|
100
|
+
// child.execute(e);
|
|
99
101
|
}
|
|
100
|
-
}
|
|
101
|
-
forLoop();
|
|
102
|
+
}
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
/*
|