@jinntec/fore 2.6.0 → 2.7.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 +4470 -2643
- package/dist/fore.js +4415 -2620
- package/index.js +2 -0
- package/package.json +10 -4
- package/resources/fore.css +2 -6
- package/src/DependencyNotifyingDomFacade.js +27 -21
- package/src/ForeElementMixin.js +282 -277
- package/src/actions/abstract-action.js +7 -12
- package/src/actions/fx-append.js +23 -2
- package/src/actions/fx-call.js +2 -2
- package/src/actions/fx-delete.js +54 -29
- package/src/actions/fx-insert.js +23 -15
- package/src/actions/fx-refresh.js +15 -5
- package/src/actions/fx-replace.js +18 -3
- package/src/actions/fx-reset.js +6 -0
- package/src/actions/fx-send.js +10 -7
- package/src/actions/fx-setattribute.js +12 -0
- package/src/actions/fx-setfocus.js +11 -8
- package/src/actions/fx-setvalue.js +93 -93
- package/src/actions/fx-toggle.js +1 -1
- package/src/extract-predicate-deps.js +57 -0
- package/src/extractPredicateDependencies.js +36 -0
- package/src/fore.js +41 -16
- package/src/fx-bind.js +128 -23
- package/src/fx-connection.js +24 -7
- package/src/fx-fore.js +506 -259
- package/src/fx-instance.js +9 -11
- package/src/fx-model.js +154 -65
- package/src/fx-submission.js +19 -30
- package/src/fx-var.js +5 -0
- package/src/getInScopeContext.js +7 -8
- package/src/modelitem.js +247 -112
- package/src/tools/fx-action-log.js +21 -19
- package/src/tools/fx-log-settings.js +4 -2
- package/src/ui/TemplateExpression.js +12 -0
- package/src/ui/UIElement.js +125 -10
- package/src/ui/abstract-control.js +5 -0
- package/src/ui/fx-case.js +15 -3
- package/src/ui/fx-container.js +5 -0
- package/src/ui/fx-control-menu.js +23 -14
- package/src/ui/fx-control.js +55 -15
- package/src/ui/fx-items.js +10 -4
- package/src/ui/fx-repeat-attributes.js +111 -35
- package/src/ui/fx-repeat.js +332 -85
- package/src/ui/fx-repeat.updated.js +821 -0
- package/src/ui/fx-repeatitem.js +23 -20
- package/src/ui/fx-switch.js +5 -3
- package/src/ui/fx-upload.js +36 -40
- package/src/ui/repeat-base.js +532 -0
- package/src/withDraggability.js +8 -4
- package/src/xpath-evaluation.js +26 -8
- package/src/xpath-path.js +79 -0
- package/src/xpath-util.js +357 -289
|
@@ -2,8 +2,9 @@ import { Fore } from '../fore.js';
|
|
|
2
2
|
import { evaluateXPath } from '../xpath-evaluation.js';
|
|
3
3
|
import getInScopeContext from '../getInScopeContext.js';
|
|
4
4
|
import { XPathUtil } from '../xpath-util.js';
|
|
5
|
-
import ForeElementMixin from '../ForeElementMixin.js';
|
|
6
5
|
import { withDraggability } from '../withDraggability.js';
|
|
6
|
+
import { getPath } from '../xpath-path.js';
|
|
7
|
+
import { RepeatBase } from './repeat-base.js';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* `fx-repeat`
|
|
@@ -20,7 +21,7 @@ import { withDraggability } from '../withDraggability.js';
|
|
|
20
21
|
*
|
|
21
22
|
* todo: it should be seriously be considered to extend FxContainer instead but needs refactoring first.
|
|
22
23
|
*/
|
|
23
|
-
export class FxRepeatAttributes extends withDraggability(
|
|
24
|
+
export class FxRepeatAttributes extends withDraggability(RepeatBase, false) {
|
|
24
25
|
static get properties() {
|
|
25
26
|
return {
|
|
26
27
|
...super.properties,
|
|
@@ -62,8 +63,23 @@ export class FxRepeatAttributes extends withDraggability(ForeElementMixin, false
|
|
|
62
63
|
this.index = 1;
|
|
63
64
|
this.repeatSize = 0;
|
|
64
65
|
this.attachShadow({ mode: 'open', delegatesFocus: true });
|
|
66
|
+
/**
|
|
67
|
+
* @type {Map<Element, Node>} A lookup from a repeat item to the node it has associated
|
|
68
|
+
*/
|
|
69
|
+
this._contextItemByRepeatItem = new Map();
|
|
65
70
|
}
|
|
66
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Get the context node for the given repeat item
|
|
74
|
+
*
|
|
75
|
+
* @param {Element} repeatItem
|
|
76
|
+
* @returns {Node} The node (if any) that is the active item for this repeat item
|
|
77
|
+
*/
|
|
78
|
+
getContextForRepeatItem(repeatItem) {
|
|
79
|
+
return this._contextItemByRepeatItem.get(repeatItem);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/*
|
|
67
83
|
get repeatSize() {
|
|
68
84
|
return this.querySelectorAll(':scope > .fx-repeatitem').length;
|
|
69
85
|
}
|
|
@@ -71,22 +87,66 @@ export class FxRepeatAttributes extends withDraggability(ForeElementMixin, false
|
|
|
71
87
|
set repeatSize(size) {
|
|
72
88
|
super.repeatSize = size;
|
|
73
89
|
}
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
async init() {
|
|
93
|
+
// ### there must be a single 'template' child
|
|
94
|
+
|
|
95
|
+
const inited = new Promise(resolve => {
|
|
96
|
+
// console.log('##### repeat-attributes init ', this.id);
|
|
97
|
+
// if(!this.inited) this.init();
|
|
98
|
+
// does not use this.evalInContext as it is expecting a nodeset instead of single node
|
|
99
|
+
this._evalNodeset();
|
|
100
|
+
// console.log('##### ',this.id, this.nodeset);
|
|
101
|
+
|
|
102
|
+
this._initTemplate();
|
|
103
|
+
// this._initRepeatItems();
|
|
104
|
+
|
|
105
|
+
this.setAttribute('index', this.index);
|
|
106
|
+
this.inited = true;
|
|
107
|
+
resolve('done');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
return inited;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
_deleteHandler(deleted) {
|
|
114
|
+
super._deleteHandler(deleted);
|
|
115
|
+
const refd = this.querySelector('[data-ref]');
|
|
116
|
+
const rItems = refd ? refd.querySelectorAll(':scope > .fx-repeatitem') : [];
|
|
117
|
+
|
|
118
|
+
for (let i = 0; i < Math.min(this.nodeset.length, rItems.length); ++i) {
|
|
119
|
+
this._contextItemByRepeatItem.set(rItems[i], this.nodeset[i]);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
74
122
|
|
|
75
123
|
setIndex(index) {
|
|
76
|
-
// console.log('new repeat index ', index);
|
|
77
|
-
this.index = index;
|
|
78
124
|
const refd = this.querySelector('[data-ref]');
|
|
79
|
-
const rItems = refd.querySelectorAll(':scope >
|
|
80
|
-
|
|
125
|
+
const rItems = refd ? refd.querySelectorAll(':scope > .fx-repeatitem') : [];
|
|
126
|
+
const size = rItems.length;
|
|
127
|
+
|
|
128
|
+
const clamped = size === 0 ? 0 : Math.max(1, Math.min(index, size));
|
|
129
|
+
this.index = clamped;
|
|
130
|
+
|
|
131
|
+
if (size > 0) {
|
|
132
|
+
this.applyIndex(rItems[this.index - 1]);
|
|
133
|
+
} else {
|
|
134
|
+
this._removeIndexMarker(); // nothing selected
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
this.setAttribute('index', String(this.index));
|
|
81
138
|
}
|
|
82
139
|
|
|
140
|
+
/*
|
|
83
141
|
applyIndex(repeatItem) {
|
|
84
142
|
this._removeIndexMarker();
|
|
85
143
|
if (repeatItem) {
|
|
86
144
|
repeatItem.setAttribute('repeat-index', '');
|
|
87
145
|
}
|
|
88
146
|
}
|
|
147
|
+
*/
|
|
89
148
|
|
|
149
|
+
/*
|
|
90
150
|
get index() {
|
|
91
151
|
return parseInt(this.getAttribute('index'), 10);
|
|
92
152
|
}
|
|
@@ -94,6 +154,7 @@ export class FxRepeatAttributes extends withDraggability(ForeElementMixin, false
|
|
|
94
154
|
set index(idx) {
|
|
95
155
|
this.setAttribute('index', idx);
|
|
96
156
|
}
|
|
157
|
+
*/
|
|
97
158
|
|
|
98
159
|
_getRepeatedItems() {
|
|
99
160
|
const refd = this.querySelector('[data-ref]');
|
|
@@ -101,6 +162,7 @@ export class FxRepeatAttributes extends withDraggability(ForeElementMixin, false
|
|
|
101
162
|
}
|
|
102
163
|
|
|
103
164
|
async connectedCallback() {
|
|
165
|
+
super.connectedCallback();
|
|
104
166
|
// console.log('connectedCallback',this);
|
|
105
167
|
// this.display = window.getComputedStyle(this, null).getPropertyValue("display");
|
|
106
168
|
this.ref = this.getAttribute('ref');
|
|
@@ -111,7 +173,8 @@ export class FxRepeatAttributes extends withDraggability(ForeElementMixin, false
|
|
|
111
173
|
const { item } = e.detail;
|
|
112
174
|
const repeatedItems = this._getRepeatedItems();
|
|
113
175
|
const idx = Array.from(repeatedItems).indexOf(item);
|
|
114
|
-
this.
|
|
176
|
+
this.setIndex(idx + 1);
|
|
177
|
+
// this.applyIndex(repeatedItems[idx]);
|
|
115
178
|
this.index = idx + 1;
|
|
116
179
|
});
|
|
117
180
|
// todo: review - this is just used by append action - event consolidation ?
|
|
@@ -120,15 +183,7 @@ export class FxRepeatAttributes extends withDraggability(ForeElementMixin, false
|
|
|
120
183
|
if (!e.target === this) return;
|
|
121
184
|
const { index } = e.detail;
|
|
122
185
|
this.index = Number(index);
|
|
123
|
-
this.applyIndex(this.children[index - 1]);
|
|
124
|
-
});
|
|
125
|
-
/*
|
|
126
|
-
document.addEventListener('insert', e => {
|
|
127
|
-
const nodes = e.detail.insertedNodes;
|
|
128
|
-
this.index = e.detail.position;
|
|
129
|
-
console.log('insert catched', nodes, this.index);
|
|
130
186
|
});
|
|
131
|
-
*/
|
|
132
187
|
|
|
133
188
|
// if (this.getOwnerForm().lazyRefresh) {
|
|
134
189
|
this.mutationObserver = new MutationObserver(mutations => {
|
|
@@ -136,7 +191,7 @@ export class FxRepeatAttributes extends withDraggability(ForeElementMixin, false
|
|
|
136
191
|
const added = mutations[0].addedNodes[0];
|
|
137
192
|
if (added) {
|
|
138
193
|
const instance = XPathUtil.resolveInstance(this, this.ref);
|
|
139
|
-
const path =
|
|
194
|
+
const path = getPath(added, instance);
|
|
140
195
|
// this.dispatch('path-mutated',{'path':path,'nodeset':this.nodeset,'index': this.index});
|
|
141
196
|
// this.index = index;
|
|
142
197
|
// const prev = mutations[0].previousSibling.previousElementSibling;
|
|
@@ -196,6 +251,10 @@ export class FxRepeatAttributes extends withDraggability(ForeElementMixin, false
|
|
|
196
251
|
return inited;
|
|
197
252
|
}
|
|
198
253
|
|
|
254
|
+
getRepeatItems() {
|
|
255
|
+
return Array.from(this.querySelectorAll(':scope [data-ref] > .fx-repeatitem'));
|
|
256
|
+
}
|
|
257
|
+
|
|
199
258
|
_getRef() {
|
|
200
259
|
return this.getAttribute('ref');
|
|
201
260
|
}
|
|
@@ -248,6 +307,7 @@ export class FxRepeatAttributes extends withDraggability(ForeElementMixin, false
|
|
|
248
307
|
// remove repeatitem
|
|
249
308
|
const itemToRemove = repeatItems[position - 1];
|
|
250
309
|
itemToRemove.parentNode.removeChild(itemToRemove);
|
|
310
|
+
this._contextItemByRepeatItem.delete(itemToRemove);
|
|
251
311
|
this.getOwnerForm().unRegisterLazyElement(itemToRemove);
|
|
252
312
|
// this._fadeOut(itemToRemove);
|
|
253
313
|
// Fore.fadeOutElement(itemToRemove)
|
|
@@ -259,29 +319,15 @@ export class FxRepeatAttributes extends withDraggability(ForeElementMixin, false
|
|
|
259
319
|
for (let position = repeatItemCount + 1; position <= contextSize; position += 1) {
|
|
260
320
|
// add new repeatitem
|
|
261
321
|
|
|
262
|
-
const clonedTemplate = this.
|
|
322
|
+
const clonedTemplate = this._createNewRepeatItem(position, this.nodeset[position - 1]);
|
|
263
323
|
if (!clonedTemplate) return;
|
|
264
324
|
|
|
265
|
-
// ### cloned templates are always appended to the binding element - the one having the data-ref
|
|
266
|
-
const bindingElement = this.querySelector('[data-ref]');
|
|
267
|
-
bindingElement.appendChild(clonedTemplate);
|
|
268
|
-
clonedTemplate.classList.add('fx-repeatitem');
|
|
269
|
-
clonedTemplate.setAttribute('index', position);
|
|
270
|
-
|
|
271
|
-
clonedTemplate.addEventListener('click', this._dispatchIndexChange);
|
|
272
|
-
// this.addEventListener('focusin', this._handleFocus);
|
|
273
|
-
clonedTemplate.addEventListener('focusin', this._dispatchIndexChange);
|
|
274
|
-
|
|
275
|
-
// this._initVariables(clonedTemplate);
|
|
276
|
-
|
|
277
|
-
// newItem.nodeset = this.nodeset[position - 1];
|
|
278
|
-
// newItem.index = position;
|
|
279
325
|
this.getOwnerForm().someInstanceDataStructureChanged = true;
|
|
280
326
|
}
|
|
281
327
|
}
|
|
282
328
|
|
|
283
329
|
// ### update nodeset of repeatitems
|
|
284
|
-
repeatItems = this.querySelectorAll('
|
|
330
|
+
repeatItems = this.querySelectorAll('.fx-repeatitem');
|
|
285
331
|
repeatItemCount = repeatItems.length;
|
|
286
332
|
|
|
287
333
|
for (let position = 0; position < repeatItemCount; position += 1) {
|
|
@@ -291,6 +337,8 @@ export class FxRepeatAttributes extends withDraggability(ForeElementMixin, false
|
|
|
291
337
|
if (item.nodeset !== this.nodeset[position]) {
|
|
292
338
|
item.nodeset = this.nodeset[position];
|
|
293
339
|
}
|
|
340
|
+
|
|
341
|
+
this._contextItemByRepeatItem.set(item, this.nodeset[position]);
|
|
294
342
|
}
|
|
295
343
|
|
|
296
344
|
// Fore.refreshChildren(clone,true);
|
|
@@ -385,10 +433,38 @@ export class FxRepeatAttributes extends withDraggability(ForeElementMixin, false
|
|
|
385
433
|
})(newRepeatItem);
|
|
386
434
|
}
|
|
387
435
|
|
|
388
|
-
|
|
436
|
+
/**
|
|
437
|
+
* @override
|
|
438
|
+
*
|
|
439
|
+
* @param {number} insertionIndex - the one-based index of where to insert the new node
|
|
440
|
+
* @param {Node} node - The node related to this new repeat item
|
|
441
|
+
*
|
|
442
|
+
* @returns {HTMLElement}
|
|
443
|
+
*/
|
|
444
|
+
_createNewRepeatItem(insertionIndex, node) {
|
|
389
445
|
this.template = this.shadowRoot.querySelector('template');
|
|
390
|
-
if (!this.template) return;
|
|
391
|
-
|
|
446
|
+
if (!this.template) return null;
|
|
447
|
+
const newNode = /** @type {HTMLElement} */ (
|
|
448
|
+
this.template.content.firstElementChild.cloneNode(true)
|
|
449
|
+
);
|
|
450
|
+
|
|
451
|
+
// ### cloned templates are always appended to the binding element - the one having the data-ref
|
|
452
|
+
const bindingElement = this.querySelector('[data-ref]');
|
|
453
|
+
|
|
454
|
+
const repeatItems = bindingElement.querySelectorAll('.fx-repeatitem');
|
|
455
|
+
|
|
456
|
+
const beforeNode = repeatItems[insertionIndex - 1] ?? null; // Null appends by default
|
|
457
|
+
bindingElement.insertBefore(newNode, beforeNode);
|
|
458
|
+
newNode.classList.add('fx-repeatitem');
|
|
459
|
+
// newNode.setAttribute('index', `${insertionIndex}`);
|
|
460
|
+
|
|
461
|
+
newNode.addEventListener('click', this._dispatchIndexChange);
|
|
462
|
+
// this.addEventListener('focusin', this._handleFocus);
|
|
463
|
+
newNode.addEventListener('focusin', this._dispatchIndexChange);
|
|
464
|
+
|
|
465
|
+
this._contextItemByRepeatItem.set(newNode, node);
|
|
466
|
+
|
|
467
|
+
return newNode;
|
|
392
468
|
}
|
|
393
469
|
|
|
394
470
|
_removeIndexMarker() {
|