@jinntec/fore 2.1.1 → 2.3.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 +2 -2
- package/dist/fore-dev.js +2 -2
- package/dist/fore-dev.js.map +1 -1
- package/dist/fore.js +2 -2
- package/dist/fore.js.map +1 -1
- package/index.js +4 -2
- package/package.json +10 -38
- package/resources/fore.css +263 -262
- package/resources/vars.css +8 -0
- package/src/DependencyNotifyingDomFacade.js +1 -0
- package/src/ForeElementMixin.js +243 -228
- package/src/actions/abstract-action.js +407 -398
- package/src/actions/fx-action.js +6 -6
- package/src/actions/fx-append.js +1 -1
- package/src/actions/fx-call.js +63 -62
- package/src/actions/fx-confirm.js +11 -11
- package/src/actions/fx-construct-done.js +4 -4
- package/src/actions/fx-copy.js +36 -36
- package/src/actions/fx-delete.js +77 -79
- package/src/actions/fx-dispatch.js +14 -14
- package/src/actions/fx-hide.js +15 -15
- package/src/actions/fx-insert.js +9 -12
- package/src/actions/fx-insertchild.js +88 -0
- package/src/actions/fx-load.js +188 -185
- package/src/actions/fx-message.js +18 -19
- package/src/actions/fx-refresh.js +10 -10
- package/src/actions/fx-reload.js +16 -14
- package/src/actions/fx-replace.js +0 -1
- package/src/actions/fx-reset.js +31 -31
- package/src/actions/fx-send.js +59 -52
- package/src/actions/fx-setattribute.js +48 -49
- package/src/actions/fx-setfocus.js +54 -58
- package/src/actions/fx-setvalue.js +85 -81
- package/src/actions/fx-show.js +11 -11
- package/src/actions/fx-toggle.js +2 -2
- package/src/actions/fx-toggleboolean.js +38 -39
- package/src/actions/fx-unmodified.js +27 -0
- package/src/actions/fx-update.js +6 -6
- package/src/dep_graph.js +1 -1
- package/src/drawdown.js +23 -30
- package/src/events.js +19 -19
- package/src/fore.js +143 -125
- package/src/functions/common-function.js +24 -25
- package/src/functions/fx-function.js +6 -99
- package/src/functions/fx-functionlib.js +56 -0
- package/src/functions/registerFunction.js +112 -0
- package/src/fx-bind.js +19 -24
- package/src/fx-connection.js +226 -0
- package/src/fx-fore.js +844 -815
- package/src/fx-header.js +4 -4
- package/src/fx-instance.js +25 -29
- package/src/fx-model.js +405 -380
- package/src/fx-submission.js +399 -397
- package/src/fx-var.js +13 -12
- package/src/getInScopeContext.js +102 -89
- package/src/json-util.js +24 -24
- package/src/lab/fore-component.js +48 -52
- package/src/lab/instance-inspector.js +13 -16
- package/src/modelitem.js +48 -10
- package/src/relevance.js +12 -16
- package/src/tools/adi.js +858 -812
- package/src/tools/fx-action-log.js +377 -295
- package/src/tools/fx-devtools.js +210 -210
- package/src/tools/fx-dom-inspector.js +123 -122
- package/src/tools/fx-json-instance.js +262 -253
- package/src/tools/fx-log-item.js +6 -11
- package/src/tools/fx-log-settings.js +358 -301
- package/src/tools/fx-minimap.js +186 -177
- package/src/tools/helpers.js +1 -1
- package/src/ui/abstract-control.js +73 -53
- package/src/ui/fx-case.js +59 -7
- package/src/ui/fx-container.js +13 -14
- package/src/ui/fx-control.js +572 -538
- package/src/ui/fx-dialog.js +3 -3
- package/src/ui/fx-droptarget.js +3 -4
- package/src/ui/fx-group.js +4 -2
- package/src/ui/fx-hint.js +3 -0
- package/src/ui/fx-inspector.js +5 -5
- package/src/ui/fx-items.js +11 -11
- package/src/ui/fx-output.js +10 -12
- package/src/ui/fx-repeat-attributes.js +23 -27
- package/src/ui/fx-repeat.js +347 -344
- package/src/ui/fx-repeatitem.js +75 -68
- package/src/ui/fx-switch.js +39 -14
- package/src/ui/fx-trigger.js +4 -4
- package/src/withDraggability.js +193 -191
- package/src/xpath-evaluation.js +969 -958
- package/src/xpath-util.js +161 -134
package/src/ui/fx-repeat.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import './fx-repeatitem.js';
|
|
2
2
|
|
|
3
|
-
import {Fore} from '../fore.js';
|
|
4
|
-
import
|
|
5
|
-
import {evaluateXPath} from '../xpath-evaluation.js';
|
|
3
|
+
import { Fore } from '../fore.js';
|
|
4
|
+
import ForeElementMixin from '../ForeElementMixin.js';
|
|
5
|
+
import { evaluateXPath } from '../xpath-evaluation.js';
|
|
6
6
|
import getInScopeContext from '../getInScopeContext.js';
|
|
7
|
-
import {XPathUtil} from '../xpath-util.js';
|
|
8
|
-
import {
|
|
9
|
-
import {withDraggability} from '../withDraggability.js';
|
|
7
|
+
import { XPathUtil } from '../xpath-util.js';
|
|
8
|
+
import { withDraggability } from '../withDraggability.js';
|
|
10
9
|
|
|
11
10
|
// import {DependencyNotifyingDomFacade} from '../DependencyNotifyingDomFacade';
|
|
12
11
|
|
|
@@ -24,106 +23,109 @@ import {withDraggability} from '../withDraggability.js';
|
|
|
24
23
|
* @demo demo/todo.html
|
|
25
24
|
*
|
|
26
25
|
* todo: it should be seriously be considered to extend FxContainer instead but needs refactoring first.
|
|
26
|
+
* @extends {ForeElementMixin}
|
|
27
27
|
*/
|
|
28
|
-
export class FxRepeat extends withDraggability(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
28
|
+
export class FxRepeat extends withDraggability(ForeElementMixin, false) {
|
|
29
|
+
static get properties() {
|
|
30
|
+
return {
|
|
31
|
+
...super.properties,
|
|
32
|
+
index: {
|
|
33
|
+
type: Number,
|
|
34
|
+
},
|
|
35
|
+
template: {
|
|
36
|
+
type: Object,
|
|
37
|
+
},
|
|
38
|
+
focusOnCreate: {
|
|
39
|
+
type: String,
|
|
40
|
+
},
|
|
41
|
+
initDone: {
|
|
42
|
+
type: Boolean,
|
|
43
|
+
},
|
|
44
|
+
repeatIndex: {
|
|
45
|
+
type: Number,
|
|
46
|
+
},
|
|
47
|
+
nodeset: {
|
|
48
|
+
type: Array,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
constructor() {
|
|
54
|
+
super();
|
|
55
|
+
this.ref = '';
|
|
56
|
+
this.dataTemplate = [];
|
|
57
|
+
this.isDraggable = null;
|
|
58
|
+
this.dropTarget = null;
|
|
59
|
+
this.focusOnCreate = '';
|
|
60
|
+
this.initDone = false;
|
|
61
|
+
this.repeatIndex = 1;
|
|
62
|
+
this.nodeset = [];
|
|
63
|
+
this.inited = false;
|
|
64
|
+
this.index = 1;
|
|
65
|
+
this.repeatSize = 0;
|
|
66
|
+
this.attachShadow({ mode: 'open', delegatesFocus: true });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
get repeatSize() {
|
|
70
|
+
return this.querySelectorAll(':scope > fx-repeatitem').length;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
set repeatSize(size) {
|
|
74
|
+
this.size = size;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
setIndex(index) {
|
|
78
|
+
// console.log('new repeat index ', index);
|
|
79
|
+
this.index = index;
|
|
80
|
+
const rItems = this.querySelectorAll(':scope > fx-repeatitem');
|
|
81
|
+
this.applyIndex(rItems[this.index - 1]);
|
|
82
|
+
|
|
83
|
+
this.getOwnerForm().refresh(true);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
applyIndex(repeatItem) {
|
|
87
|
+
this._removeIndexMarker();
|
|
88
|
+
if (repeatItem) {
|
|
89
|
+
repeatItem.setAttribute('repeat-index', '');
|
|
51
90
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
get index() {
|
|
92
|
-
return parseInt(this.getAttribute('index'), 10);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
set index(idx) {
|
|
96
|
-
this.setAttribute('index', idx);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
_getRef() {
|
|
100
|
-
return this.getAttribute('ref');
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
connectedCallback() {
|
|
104
|
-
super.connectedCallback();
|
|
105
|
-
// console.log('connectedCallback',this);
|
|
106
|
-
// this.display = window.getComputedStyle(this, null).getPropertyValue("display");
|
|
107
|
-
this.ref = this.getAttribute('ref');
|
|
108
|
-
// this.ref = this._getRef();
|
|
109
|
-
// console.log('### fx-repeat connected ', this.id);
|
|
110
|
-
this.addEventListener('item-changed', e => {
|
|
111
|
-
const {item} = e.detail;
|
|
112
|
-
const idx = Array.from(this.children).indexOf(item);
|
|
113
|
-
this.applyIndex(this.children[idx]);
|
|
114
|
-
this.index = idx + 1;
|
|
115
|
-
});
|
|
116
|
-
// todo: review - this is just used by append action - event consolidation ?
|
|
117
|
-
document.addEventListener('index-changed', e => {
|
|
118
|
-
e.stopPropagation();
|
|
119
|
-
if (!e.target === this) return;
|
|
120
|
-
// const { item } = e.detail;
|
|
121
|
-
// const idx = Array.from(this.children).indexOf(item);
|
|
122
|
-
const {index} = e.detail;
|
|
123
|
-
this.index = parseInt(index, 10);
|
|
124
|
-
this.applyIndex(this.children[index - 1]);
|
|
125
|
-
});
|
|
126
|
-
/*
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
get index() {
|
|
94
|
+
return parseInt(this.getAttribute('index'), 10);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
set index(idx) {
|
|
98
|
+
this.setAttribute('index', idx);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
_getRef() {
|
|
102
|
+
return this.getAttribute('ref');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
connectedCallback() {
|
|
106
|
+
super.connectedCallback();
|
|
107
|
+
// console.log('connectedCallback',this);
|
|
108
|
+
// this.display = window.getComputedStyle(this, null).getPropertyValue("display");
|
|
109
|
+
this.ref = this.getAttribute('ref');
|
|
110
|
+
// this.ref = this._getRef();
|
|
111
|
+
// console.log('### fx-repeat connected ', this.id);
|
|
112
|
+
this.addEventListener('item-changed', e => {
|
|
113
|
+
const { item } = e.detail;
|
|
114
|
+
const idx = Array.from(this.children).indexOf(item);
|
|
115
|
+
// Warning: index is one-based
|
|
116
|
+
this.setIndex(idx + 1);
|
|
117
|
+
});
|
|
118
|
+
// todo: review - this is just used by append action - event consolidation ?
|
|
119
|
+
document.addEventListener('index-changed', e => {
|
|
120
|
+
e.stopPropagation();
|
|
121
|
+
if (!e.target === this) return;
|
|
122
|
+
// const { item } = e.detail;
|
|
123
|
+
// const idx = Array.from(this.children).indexOf(item);
|
|
124
|
+
const { index } = e.detail;
|
|
125
|
+
this.index = parseInt(index, 10);
|
|
126
|
+
this.applyIndex(this.children[index - 1]);
|
|
127
|
+
});
|
|
128
|
+
/*
|
|
127
129
|
document.addEventListener('insert', e => {
|
|
128
130
|
const nodes = e.detail.insertedNodes;
|
|
129
131
|
this.index = e.detail.position;
|
|
@@ -131,30 +133,30 @@ export class FxRepeat extends withDraggability(foreElementMixin(HTMLElement), fa
|
|
|
131
133
|
});
|
|
132
134
|
*/
|
|
133
135
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
136
|
+
// if (this.getOwnerForm().lazyRefresh) {
|
|
137
|
+
this.mutationObserver = new MutationObserver(mutations => {
|
|
138
|
+
// console.log('mutations', mutations);
|
|
139
|
+
|
|
140
|
+
if (mutations[0].type === 'childList') {
|
|
141
|
+
const added = mutations[0].addedNodes[0];
|
|
142
|
+
if (added) {
|
|
143
|
+
const instance = XPathUtil.resolveInstance(this, this.ref);
|
|
144
|
+
const path = XPathUtil.getPath(added, instance);
|
|
145
|
+
// console.log('path mutated', path);
|
|
146
|
+
// this.dispatch('path-mutated',{'path':path,'nodeset':this.nodeset,'index': this.index});
|
|
147
|
+
// this.index = index;
|
|
148
|
+
// const prev = mutations[0].previousSibling.previousElementSibling;
|
|
149
|
+
// const index = prev.index();
|
|
150
|
+
// this.applyIndex(this.index -1);
|
|
151
|
+
|
|
152
|
+
Fore.dispatch(this, 'path-mutated', { path, index: this.index });
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
// }
|
|
157
|
+
this.getOwnerForm().registerLazyElement(this);
|
|
156
158
|
|
|
157
|
-
|
|
159
|
+
const style = `
|
|
158
160
|
:host{
|
|
159
161
|
}
|
|
160
162
|
.fade-out-bottom {
|
|
@@ -166,68 +168,67 @@ export class FxRepeat extends withDraggability(foreElementMixin(HTMLElement), fa
|
|
|
166
168
|
animation: fade-out-bottom 0.7s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
|
|
167
169
|
}
|
|
168
170
|
`;
|
|
169
|
-
|
|
171
|
+
const html = `
|
|
170
172
|
<slot name="header"></slot>
|
|
171
173
|
<slot></slot>
|
|
172
174
|
`;
|
|
173
|
-
|
|
175
|
+
this.shadowRoot.innerHTML = `
|
|
174
176
|
<style>
|
|
175
177
|
${style}
|
|
176
178
|
</style>
|
|
177
179
|
${html}
|
|
178
180
|
`;
|
|
179
181
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
_createNewRepeatItem() {
|
|
185
|
-
const newItem = document.createElement('fx-repeatitem');
|
|
186
|
-
|
|
187
|
-
if (this.isDraggable) {
|
|
188
|
-
newItem.setAttribute('draggable', 'true');
|
|
189
|
-
newItem.setAttribute('tabindex', 0);
|
|
190
|
-
}
|
|
191
|
-
const clone = this._clone();
|
|
192
|
-
newItem.appendChild(clone);
|
|
193
|
-
|
|
194
|
-
return newItem;
|
|
195
|
-
}
|
|
182
|
+
// this.init();
|
|
183
|
+
}
|
|
196
184
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
console.log('##### repeat init ', this.id);
|
|
200
|
-
// if(!this.inited) this.init();
|
|
201
|
-
// does not use this.evalInContext as it is expecting a nodeset instead of single node
|
|
202
|
-
this._evalNodeset();
|
|
203
|
-
// console.log('##### ',this.id, this.nodeset);
|
|
185
|
+
_createNewRepeatItem() {
|
|
186
|
+
const newItem = document.createElement('fx-repeatitem');
|
|
204
187
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
188
|
+
if (this.isDraggable) {
|
|
189
|
+
newItem.setAttribute('draggable', 'true');
|
|
190
|
+
newItem.setAttribute('tabindex', 0);
|
|
191
|
+
}
|
|
192
|
+
const clone = this._clone();
|
|
193
|
+
newItem.appendChild(clone);
|
|
194
|
+
|
|
195
|
+
return newItem;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
init() {
|
|
199
|
+
// ### there must be a single 'template' child
|
|
200
|
+
console.log('##### repeat init ', this.id);
|
|
201
|
+
// if(!this.inited) this.init();
|
|
202
|
+
// does not use this.evalInContext as it is expecting a nodeset instead of single node
|
|
203
|
+
this._evalNodeset();
|
|
204
|
+
// console.log('##### ',this.id, this.nodeset);
|
|
205
|
+
|
|
206
|
+
this._initTemplate();
|
|
207
|
+
this._initRepeatItems();
|
|
208
|
+
|
|
209
|
+
this.setAttribute('index', this.index);
|
|
210
|
+
this.inited = true;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* repeat has no own modelItems
|
|
215
|
+
* @private
|
|
216
|
+
*/
|
|
217
|
+
_evalNodeset() {
|
|
218
|
+
// const inscope = this.getInScopeContext();
|
|
219
|
+
const inscope = getInScopeContext(this.getAttributeNode('ref') || this, this.ref);
|
|
220
|
+
// console.log('##### inscope ', inscope);
|
|
221
|
+
// console.log('##### ref ', this.ref);
|
|
222
|
+
// now we got a nodeset and attach MutationObserver to it
|
|
223
|
+
|
|
224
|
+
if (this.mutationObserver && inscope.nodeName) {
|
|
225
|
+
this.mutationObserver.observe(inscope, {
|
|
226
|
+
childList: true,
|
|
227
|
+
subtree: true,
|
|
228
|
+
});
|
|
210
229
|
}
|
|
211
230
|
|
|
212
|
-
|
|
213
|
-
* repeat has no own modelItems
|
|
214
|
-
* @private
|
|
215
|
-
*/
|
|
216
|
-
_evalNodeset() {
|
|
217
|
-
// const inscope = this.getInScopeContext();
|
|
218
|
-
const inscope = getInScopeContext(this.getAttributeNode('ref') || this, this.ref);
|
|
219
|
-
// console.log('##### inscope ', inscope);
|
|
220
|
-
// console.log('##### ref ', this.ref);
|
|
221
|
-
// now we got a nodeset and attach MutationObserver to it
|
|
222
|
-
|
|
223
|
-
if (this.mutationObserver && inscope.nodeName) {
|
|
224
|
-
this.mutationObserver.observe(inscope, {
|
|
225
|
-
childList: true,
|
|
226
|
-
subtree: true,
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/*
|
|
231
|
+
/*
|
|
231
232
|
this.touchedPaths = new Set();
|
|
232
233
|
const instance = XPathUtil.resolveInstance(this, this.ref);
|
|
233
234
|
const depTrackDomfacade = new DependencyNotifyingDomFacade((node) => {
|
|
@@ -235,203 +236,205 @@ export class FxRepeat extends withDraggability(foreElementMixin(HTMLElement), fa
|
|
|
235
236
|
});
|
|
236
237
|
const rawNodeset = evaluateXPath(this.ref, inscope, this, {}, {}, depTrackDomfacade );
|
|
237
238
|
*/
|
|
238
|
-
|
|
239
|
+
const rawNodeset = evaluateXPath(this.ref, inscope, this);
|
|
239
240
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
}
|
|
246
|
-
this.nodeset = rawNodeset;
|
|
241
|
+
// console.log('Touched!', this.ref, [...this.touchedPaths].join(', '));
|
|
242
|
+
if (rawNodeset.length === 1 && Array.isArray(rawNodeset[0])) {
|
|
243
|
+
// This XPath likely returned an XPath array. Just collapse to that array
|
|
244
|
+
this.nodeset = rawNodeset[0];
|
|
245
|
+
return;
|
|
247
246
|
}
|
|
247
|
+
this.nodeset = rawNodeset;
|
|
248
|
+
}
|
|
248
249
|
|
|
249
|
-
|
|
250
|
-
|
|
250
|
+
async refresh(force) {
|
|
251
|
+
// console.group('fx-repeat.refresh on', this.id);
|
|
251
252
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
253
|
+
if (!this.inited) this.init();
|
|
254
|
+
// console.time('repeat-refresh', this);
|
|
255
|
+
this._evalNodeset();
|
|
255
256
|
|
|
256
|
-
|
|
257
|
-
|
|
257
|
+
// ### register ourselves as boundControl
|
|
258
|
+
/*
|
|
258
259
|
const modelItem = this.getModelItem();
|
|
259
260
|
if (!modelItem.boundControls.includes(this)) {
|
|
260
261
|
modelItem.boundControls.push(this);
|
|
261
262
|
}
|
|
262
263
|
*/
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
const repeatItems = this.querySelectorAll(':scope > fx-repeatitem');
|
|
267
|
-
const repeatItemCount = repeatItems.length;
|
|
268
|
-
|
|
269
|
-
let nodeCount = 1;
|
|
270
|
-
if (Array.isArray(this.nodeset)) {
|
|
271
|
-
nodeCount = this.nodeset.length;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// const contextSize = this.nodeset.length;
|
|
275
|
-
const contextSize = nodeCount;
|
|
276
|
-
// todo: review - cant the context really never be smaller than the repeat count?
|
|
277
|
-
// todo: this code can be deprecated probably but check first
|
|
278
|
-
if (contextSize < repeatItemCount) {
|
|
279
|
-
for (let position = repeatItemCount; position > contextSize; position -= 1) {
|
|
280
|
-
// remove repeatitem
|
|
281
|
-
const itemToRemove = repeatItems[position - 1];
|
|
282
|
-
itemToRemove.parentNode.removeChild(itemToRemove);
|
|
283
|
-
this.getOwnerForm().unRegisterLazyElement(itemToRemove);
|
|
284
|
-
// this._fadeOut(itemToRemove);
|
|
285
|
-
// Fore.fadeOutElement(itemToRemove)
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
if (contextSize > repeatItemCount) {
|
|
290
|
-
for (let position = repeatItemCount + 1; position <= contextSize; position += 1) {
|
|
291
|
-
// add new repeatitem
|
|
292
|
-
|
|
293
|
-
const newItem = this._createNewRepeatItem();
|
|
294
|
-
|
|
295
|
-
this.appendChild(newItem);
|
|
296
|
-
this._initVariables(newItem);
|
|
264
|
+
// console.log('repeat refresh nodeset ', this.nodeset);
|
|
265
|
+
// console.log('repeatCount', this.repeatCount);
|
|
297
266
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
// Tell the owner form we might have new template expressions here
|
|
301
|
-
this.getOwnerForm().scanForNewTemplateExpressionsNextRefresh();
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// ### update nodeset of repeatitems
|
|
306
|
-
for (let position = 0; position < repeatItemCount; position += 1) {
|
|
307
|
-
const item = repeatItems[position];
|
|
308
|
-
this.getOwnerForm().registerLazyElement(item);
|
|
267
|
+
const repeatItems = this.querySelectorAll(':scope > fx-repeatitem');
|
|
268
|
+
const repeatItemCount = repeatItems.length;
|
|
309
269
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
// Fore.refreshChildren(clone,true);
|
|
316
|
-
const fore = this.getOwnerForm();
|
|
317
|
-
if (!fore.lazyRefresh || force) {
|
|
318
|
-
Fore.refreshChildren(this, force);
|
|
319
|
-
}
|
|
320
|
-
// this.style.display = 'block';
|
|
321
|
-
// this.style.display = this.display;
|
|
322
|
-
this.setIndex(this.index);
|
|
323
|
-
// console.timeEnd('repeat-refresh');
|
|
324
|
-
|
|
325
|
-
// this.replaceWith(clone);
|
|
326
|
-
|
|
327
|
-
// this.repeatCount = contextSize;
|
|
328
|
-
// console.log('repeatCount', this.repeatCount);
|
|
270
|
+
let nodeCount = 1;
|
|
271
|
+
if (Array.isArray(this.nodeset)) {
|
|
272
|
+
nodeCount = this.nodeset.length;
|
|
329
273
|
}
|
|
330
274
|
|
|
331
|
-
//
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
275
|
+
// const contextSize = this.nodeset.length;
|
|
276
|
+
const contextSize = nodeCount;
|
|
277
|
+
// todo: review - cant the context really never be smaller than the repeat count?
|
|
278
|
+
// todo: this code can be deprecated probably but check first
|
|
279
|
+
if (contextSize < repeatItemCount) {
|
|
280
|
+
for (let position = repeatItemCount; position > contextSize; position -= 1) {
|
|
281
|
+
// remove repeatitem
|
|
282
|
+
const itemToRemove = repeatItems[position - 1];
|
|
283
|
+
itemToRemove.parentNode.removeChild(itemToRemove);
|
|
284
|
+
this.getOwnerForm().unRegisterLazyElement(itemToRemove);
|
|
285
|
+
// this._fadeOut(itemToRemove);
|
|
286
|
+
// Fore.fadeOutElement(itemToRemove)
|
|
287
|
+
}
|
|
343
288
|
}
|
|
344
289
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
290
|
+
if (contextSize > repeatItemCount) {
|
|
291
|
+
for (let position = repeatItemCount + 1; position <= contextSize; position += 1) {
|
|
292
|
+
// add new repeatitem
|
|
348
293
|
|
|
349
|
-
|
|
350
|
-
el.style.display = this.display;
|
|
351
|
-
|
|
352
|
-
(function fade() {
|
|
353
|
-
// setTimeout(() => {
|
|
354
|
-
let val = parseFloat(el.style.opacity);
|
|
355
|
-
// eslint-disable-next-line no-cond-assign
|
|
356
|
-
if (!((val += 0.1) > 1)) {
|
|
357
|
-
el.style.opacity = val;
|
|
358
|
-
requestAnimationFrame(fade);
|
|
359
|
-
}
|
|
360
|
-
// }, 40);
|
|
361
|
-
})();
|
|
362
|
-
}
|
|
294
|
+
const newItem = this._createNewRepeatItem();
|
|
363
295
|
|
|
364
|
-
|
|
365
|
-
this.
|
|
366
|
-
// console.log('### init template for repeat ', this.id, this.template);
|
|
367
|
-
// todo: this.dropTarget not needed?
|
|
368
|
-
this.dropTarget = this.template.getAttribute('drop-target');
|
|
369
|
-
this.isDraggable = this.template.hasAttribute('draggable') ? this.template.getAttribute('draggable') : null;
|
|
370
|
-
|
|
371
|
-
if (this.template === null) {
|
|
372
|
-
// todo: catch this on form element
|
|
373
|
-
this.dispatchEvent(
|
|
374
|
-
new CustomEvent('no-template-error', {
|
|
375
|
-
composed: true,
|
|
376
|
-
bubbles: true,
|
|
377
|
-
detail: {message: `no template found for repeat:${this.id}`},
|
|
378
|
-
}),
|
|
379
|
-
);
|
|
380
|
-
}
|
|
296
|
+
this.appendChild(newItem);
|
|
297
|
+
this._initVariables(newItem);
|
|
381
298
|
|
|
382
|
-
|
|
299
|
+
newItem.nodeset = this.nodeset[position - 1];
|
|
300
|
+
newItem.index = position;
|
|
301
|
+
// Tell the owner form we might have new template expressions here
|
|
302
|
+
this.getOwnerForm().scanForNewTemplateExpressionsNextRefresh();
|
|
303
|
+
}
|
|
383
304
|
}
|
|
384
305
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
repeatItem.index = index + 1; // 1-based index
|
|
306
|
+
// ### update nodeset of repeatitems
|
|
307
|
+
for (let position = 0; position < repeatItemCount; position += 1) {
|
|
308
|
+
const item = repeatItems[position];
|
|
309
|
+
this.getOwnerForm().registerLazyElement(item);
|
|
390
310
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
this.applyIndex(repeatItem);
|
|
395
|
-
}
|
|
396
|
-
// console.log('*********repeat item created', repeatItem.nodeset)
|
|
397
|
-
Fore.dispatch(this, 'item-created', {nodeset: repeatItem.nodeset, pos: index + 1});
|
|
398
|
-
this._initVariables(repeatItem);
|
|
399
|
-
});
|
|
311
|
+
if (item.nodeset !== this.nodeset[position]) {
|
|
312
|
+
item.nodeset = this.nodeset[position];
|
|
313
|
+
}
|
|
400
314
|
}
|
|
401
315
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
for (const child of node.children) {
|
|
407
|
-
if ('setInScopeVariables' in child) {
|
|
408
|
-
child.setInScopeVariables(inScopeVariables);
|
|
409
|
-
}
|
|
410
|
-
registerVariables(child);
|
|
411
|
-
}
|
|
412
|
-
})(newRepeatItem);
|
|
316
|
+
// Fore.refreshChildren(clone,true);
|
|
317
|
+
const fore = this.getOwnerForm();
|
|
318
|
+
if (!fore.lazyRefresh || force) {
|
|
319
|
+
Fore.refreshChildren(this, force);
|
|
413
320
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
321
|
+
// this.style.display = 'block';
|
|
322
|
+
// this.style.display = this.display;
|
|
323
|
+
this.setIndex(this.index);
|
|
324
|
+
// console.timeEnd('repeat-refresh');
|
|
325
|
+
|
|
326
|
+
// this.replaceWith(clone);
|
|
327
|
+
|
|
328
|
+
// this.repeatCount = contextSize;
|
|
329
|
+
// console.log('repeatCount', this.repeatCount);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// eslint-disable-next-line class-methods-use-this
|
|
333
|
+
_fadeOut(el) {
|
|
334
|
+
el.style.opacity = 1;
|
|
335
|
+
|
|
336
|
+
(function fade() {
|
|
337
|
+
// eslint-disable-next-line no-cond-assign
|
|
338
|
+
if ((el.style.opacity -= 0.1) < 0) {
|
|
339
|
+
el.style.display = 'none';
|
|
340
|
+
} else {
|
|
341
|
+
requestAnimationFrame(fade);
|
|
342
|
+
}
|
|
343
|
+
})();
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// eslint-disable-next-line class-methods-use-this
|
|
347
|
+
_fadeIn(el) {
|
|
348
|
+
if (!el) return;
|
|
349
|
+
|
|
350
|
+
el.style.opacity = 0;
|
|
351
|
+
el.style.display = this.display;
|
|
352
|
+
|
|
353
|
+
(function fade() {
|
|
354
|
+
// setTimeout(() => {
|
|
355
|
+
let val = parseFloat(el.style.opacity);
|
|
356
|
+
// eslint-disable-next-line no-cond-assign
|
|
357
|
+
if (!((val += 0.1) > 1)) {
|
|
358
|
+
el.style.opacity = val;
|
|
359
|
+
requestAnimationFrame(fade);
|
|
360
|
+
}
|
|
361
|
+
// }, 40);
|
|
362
|
+
})();
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
_initTemplate() {
|
|
366
|
+
this.template = this.querySelector('template');
|
|
367
|
+
// console.log('### init template for repeat ', this.id, this.template);
|
|
368
|
+
// todo: this.dropTarget not needed?
|
|
369
|
+
this.dropTarget = this.template.getAttribute('drop-target');
|
|
370
|
+
this.isDraggable = this.template.hasAttribute('draggable')
|
|
371
|
+
? this.template.getAttribute('draggable')
|
|
372
|
+
: null;
|
|
373
|
+
|
|
374
|
+
if (this.template === null) {
|
|
375
|
+
// todo: catch this on form element
|
|
376
|
+
this.dispatchEvent(
|
|
377
|
+
new CustomEvent('no-template-error', {
|
|
378
|
+
composed: true,
|
|
379
|
+
bubbles: true,
|
|
380
|
+
detail: { message: `no template found for repeat:${this.id}` },
|
|
381
|
+
}),
|
|
382
|
+
);
|
|
420
383
|
}
|
|
421
384
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
item.removeAttribute('repeat-index');
|
|
425
|
-
});
|
|
426
|
-
}
|
|
385
|
+
this.shadowRoot.appendChild(this.template);
|
|
386
|
+
}
|
|
427
387
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
388
|
+
_initRepeatItems() {
|
|
389
|
+
this.nodeset.forEach((item, index) => {
|
|
390
|
+
const repeatItem = this._createNewRepeatItem();
|
|
391
|
+
repeatItem.nodeset = this.nodeset[index];
|
|
392
|
+
repeatItem.index = index + 1; // 1-based index
|
|
393
|
+
|
|
394
|
+
this.appendChild(repeatItem);
|
|
395
|
+
|
|
396
|
+
if (repeatItem.index === 1) {
|
|
397
|
+
this.applyIndex(repeatItem);
|
|
398
|
+
}
|
|
399
|
+
// console.log('*********repeat item created', repeatItem.nodeset)
|
|
400
|
+
Fore.dispatch(this, 'item-created', { nodeset: repeatItem.nodeset, pos: index + 1 });
|
|
401
|
+
this._initVariables(repeatItem);
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
_initVariables(newRepeatItem) {
|
|
406
|
+
const inScopeVariables = new Map(this.inScopeVariables);
|
|
407
|
+
newRepeatItem.setInScopeVariables(inScopeVariables);
|
|
408
|
+
(function registerVariables(node) {
|
|
409
|
+
for (const child of node.children) {
|
|
410
|
+
if ('setInScopeVariables' in child) {
|
|
411
|
+
child.setInScopeVariables(inScopeVariables);
|
|
412
|
+
}
|
|
413
|
+
registerVariables(child);
|
|
414
|
+
}
|
|
415
|
+
})(newRepeatItem);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
_clone() {
|
|
419
|
+
// const content = this.template.content.cloneNode(true);
|
|
420
|
+
this.template = this.shadowRoot.querySelector('template');
|
|
421
|
+
const content = this.template.content.cloneNode(true);
|
|
422
|
+
return document.importNode(content, true);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
_removeIndexMarker() {
|
|
426
|
+
Array.from(this.children).forEach(item => {
|
|
427
|
+
item.removeAttribute('repeat-index');
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
setInScopeVariables(inScopeVariables) {
|
|
432
|
+
// Repeats are interesting: the variables should be scoped per repeat item, they should not be
|
|
433
|
+
// able to see the variables in adjacent repeat items!
|
|
434
|
+
this.inScopeVariables = new Map(inScopeVariables);
|
|
435
|
+
}
|
|
433
436
|
}
|
|
434
437
|
|
|
435
438
|
if (!customElements.get('fx-repeat')) {
|
|
436
|
-
|
|
439
|
+
window.customElements.define('fx-repeat', FxRepeat);
|
|
437
440
|
}
|