@jinntec/fore 1.10.1 → 1.10.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.
- 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/package.json +1 -1
- package/src/actions/fx-toggle.js +1 -0
- package/src/fore.js +0 -222
- package/src/fx-bind.js +26 -6
- package/src/fx-fore.js +22 -21
- package/src/fx-model.js +13 -2
- package/src/ui/fx-container.js +0 -1
- package/src/ui/fx-switch.js +63 -40
- package/src/xpath-evaluation.js +10 -27
package/package.json
CHANGED
package/src/actions/fx-toggle.js
CHANGED
|
@@ -23,6 +23,7 @@ class FxToggle extends AbstractAction {
|
|
|
23
23
|
super.perform();
|
|
24
24
|
if (this.case) {
|
|
25
25
|
const ownerForm = this.getOwnerForm();
|
|
26
|
+
// todo: id resolution!!!
|
|
26
27
|
const caseElement = ownerForm.querySelector(`#${this.case}`);
|
|
27
28
|
if(!caseElement){
|
|
28
29
|
Fore.dispatch(this, 'error', { message: `fx-case id not found: ${this.case}` });
|
package/src/fore.js
CHANGED
|
@@ -18,228 +18,6 @@ export class Fore {
|
|
|
18
18
|
|
|
19
19
|
static TYPE_DEFAULT = 'xs:string';
|
|
20
20
|
|
|
21
|
-
/**
|
|
22
|
-
* recursively walks along a template instance that contains all nodes relevant for editing and
|
|
23
|
-
* applying all nodes being present in partial instance onto it.
|
|
24
|
-
*
|
|
25
|
-
* @param start
|
|
26
|
-
* @param partial
|
|
27
|
-
* @returns {*}
|
|
28
|
-
* @private
|
|
29
|
-
*/
|
|
30
|
-
static combine(start, partial, foreElement,expr){
|
|
31
|
-
if(!start) return;
|
|
32
|
-
|
|
33
|
-
const appended = false;
|
|
34
|
-
// ### get the path of the current element
|
|
35
|
-
let path = evaluateXPath('path()',start,foreElement)[0];
|
|
36
|
-
if(expr){
|
|
37
|
-
path = expr;
|
|
38
|
-
}
|
|
39
|
-
// const attrMap = new Map();
|
|
40
|
-
console.log('########process path', XPathUtil.shortenPath(path));
|
|
41
|
-
const predicates = Fore.buildPredicates(start);
|
|
42
|
-
// console.log('########process search', path);
|
|
43
|
-
// ### search the path in the partial instance
|
|
44
|
-
const toMerge = evaluateXPathToFirstNode( path,partial,foreElement);
|
|
45
|
-
if(expr){
|
|
46
|
-
console.log('skipped one - new toMerge', toMerge);
|
|
47
|
-
}
|
|
48
|
-
// console.log('tomerge node', toMerge);
|
|
49
|
-
// if(toMerge.length === 1){}
|
|
50
|
-
if(toMerge){
|
|
51
|
-
// console.log('merging nodes', toMerge);
|
|
52
|
-
const mergeAttrs = Fore.buildPredicates(toMerge);
|
|
53
|
-
if(predicates === mergeAttrs) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
// console.log('####### attr maps', attrMap, toMergeAttrMap);
|
|
57
|
-
// console.log('########process merge attrs', mergeAttrs);
|
|
58
|
-
if(start.getAttribute('type') !== toMerge.getAttribute('type') ){
|
|
59
|
-
console.log('###### element type attr not matching', start, toMerge);
|
|
60
|
-
const nextSibling = start.nextElementSibling;
|
|
61
|
-
if(nextSibling && nextSibling.nodeName === start.nodeName){
|
|
62
|
-
console.log('nextSibling', nextSibling, XPathUtil.shortenPath(path));
|
|
63
|
-
console.log('start', start, XPathUtil.shortenPath(path));
|
|
64
|
-
Fore.combine(start,partial,foreElement,path);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// ### iterate the attributes of the template node
|
|
69
|
-
// if(attrMap === toMergeAttrMap){
|
|
70
|
-
// if(start.attributes){
|
|
71
|
-
Array.from(start.attributes).forEach(attr => {
|
|
72
|
-
// ### if the template attribute has a matching attribute in partial...
|
|
73
|
-
if (toMerge.hasAttribute(attr.nodeName)) {
|
|
74
|
-
if (attr.nodeName !== 'xmlns') {
|
|
75
|
-
// console.log('overwrite attr', attr);
|
|
76
|
-
const toMergeAttr = toMerge.getAttribute(attr.nodeName);
|
|
77
|
-
// if (attr.nodeValue !== toMergeAttr.nodeValue) {
|
|
78
|
-
// ### apply the attribute value from partial to template
|
|
79
|
-
if(toMergeAttr){
|
|
80
|
-
start.setAttribute(attr.nodeName, toMergeAttr)
|
|
81
|
-
}
|
|
82
|
-
// }
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
// }
|
|
87
|
-
}else{
|
|
88
|
-
console.log('###### element in template but not in partial',start);
|
|
89
|
-
const nextSibling = start.nextElementSibling;
|
|
90
|
-
if(nextSibling && nextSibling.nodeName === start.nodeName){
|
|
91
|
-
Fore.combine(nextSibling,partial,foreElement,path);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
// ### if we don't have children we still might have text
|
|
95
|
-
if(toMerge.children.length === 0){
|
|
96
|
-
const toMergeText = toMerge.textContent;
|
|
97
|
-
if(toMergeText){
|
|
98
|
-
start.textContent = toMergeText;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// ### if the template node does not have children but the partial has then copy them over
|
|
103
|
-
if(start.children.length === 0 && toMerge.children.length !== 0){
|
|
104
|
-
const mergeChildren = Array.from(toMerge.children);
|
|
105
|
-
mergeChildren.forEach(child => {
|
|
106
|
-
start.append(child);
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// ### recurse
|
|
112
|
-
if(start.children){
|
|
113
|
-
Array.from(start.children).forEach(element => {
|
|
114
|
-
/*
|
|
115
|
-
console.log('stepping into element', element);
|
|
116
|
-
if(element.getAttribute('type') !== toMerge.getAttribute('type')){
|
|
117
|
-
// console.log('###### element in template but not in partial');
|
|
118
|
-
// const nextSibling = start.nextElementSibling;
|
|
119
|
-
const nextSibling = element.nextElementSibling;
|
|
120
|
-
if(nextSibling && nextSibling.nodeName === toMerge.nodeName){
|
|
121
|
-
console.log('nextSibling', nextSibling, XPathUtil.shortenPath(path));
|
|
122
|
-
Fore.combine(nextSibling,partial,foreElement,path);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
*/
|
|
126
|
-
return Fore.combine(element, partial,foreElement,null);
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
return start;
|
|
132
|
-
}
|
|
133
|
-
/*
|
|
134
|
-
static combine(start, partial, foreElement,expr){
|
|
135
|
-
if(!start) return;
|
|
136
|
-
// ### get the path of the current element
|
|
137
|
-
let path = evaluateXPath('path()',start,foreElement)[0];
|
|
138
|
-
if(expr){
|
|
139
|
-
path = expr;
|
|
140
|
-
}
|
|
141
|
-
// const attrMap = new Map();
|
|
142
|
-
console.log('########process path', XPathUtil.shortenPath(path));
|
|
143
|
-
const predicates = Fore.buildPredicates(start);
|
|
144
|
-
/!*
|
|
145
|
-
if(predicates){
|
|
146
|
-
path = path.substring(1, path.lastIndexOf('['));
|
|
147
|
-
}
|
|
148
|
-
path += Fore.buildPredicates(start);
|
|
149
|
-
*!/
|
|
150
|
-
// console.log('########process search', path);
|
|
151
|
-
// ### search the path in the partial instance
|
|
152
|
-
const toMerge = evaluateXPathToFirstNode( path,partial,foreElement);
|
|
153
|
-
|
|
154
|
-
// console.log('tomerge node', toMerge);
|
|
155
|
-
// if(toMerge.length === 1){}
|
|
156
|
-
if(toMerge){
|
|
157
|
-
// console.log('merging nodes', toMerge);
|
|
158
|
-
const mergeAttrs = Fore.buildPredicates(toMerge);
|
|
159
|
-
if(predicates === mergeAttrs) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
// console.log('####### attr maps', attrMap, toMergeAttrMap);
|
|
163
|
-
// console.log('########process merge attrs', mergeAttrs);
|
|
164
|
-
/!*
|
|
165
|
-
if(toMerge.getAttribute('type') !== start.getAttribute('type')){
|
|
166
|
-
// console.log('###### element in template but not in partial');
|
|
167
|
-
// const nextSibling = start.nextElementSibling;
|
|
168
|
-
const nextSibling = start.nextElementSibling;
|
|
169
|
-
if(nextSibling && nextSibling.nodeName === start.nodeName){
|
|
170
|
-
console.log('nextSibling', nextSibling, XPathUtil.shortenPath(path));
|
|
171
|
-
Fore.combine(nextSibling,partial,foreElement,path);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
*!/
|
|
175
|
-
|
|
176
|
-
// ### iterate the attributes of the template node
|
|
177
|
-
// if(attrMap === toMergeAttrMap){
|
|
178
|
-
// if(start.attributes){
|
|
179
|
-
Array.from(start.attributes).forEach(attr => {
|
|
180
|
-
// ### if the template attribute has a matching attribute in partial...
|
|
181
|
-
if (toMerge.hasAttribute(attr.nodeName)) {
|
|
182
|
-
if (attr.nodeName !== 'xmlns') {
|
|
183
|
-
// console.log('overwrite attr', attr);
|
|
184
|
-
const toMergeAttr = toMerge.getAttribute(attr.nodeName);
|
|
185
|
-
// if (attr.nodeValue !== toMergeAttr.nodeValue) {
|
|
186
|
-
// ### apply the attribute value from partial to template
|
|
187
|
-
if(toMergeAttr){
|
|
188
|
-
start.setAttribute(attr.nodeName, toMergeAttr)
|
|
189
|
-
}
|
|
190
|
-
// }
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
// }
|
|
195
|
-
}else{
|
|
196
|
-
console.log('###### element in template but not in partial',start);
|
|
197
|
-
const nextSibling = start.nextElementSibling;
|
|
198
|
-
if(nextSibling && nextSibling.nodeName === start.nodeName){
|
|
199
|
-
Fore.combine(nextSibling,partial,foreElement,path);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
// ### if we don't have children we still might have text
|
|
203
|
-
if(toMerge.children.length === 0){
|
|
204
|
-
const toMergeText = toMerge.textContent;
|
|
205
|
-
if(toMergeText){
|
|
206
|
-
start.textContent = toMergeText;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// ### if the template node does not have children but the partial has then copy them over
|
|
211
|
-
if(start.children.length === 0 && toMerge.children.length !== 0){
|
|
212
|
-
const mergeChildren = Array.from(toMerge.children);
|
|
213
|
-
mergeChildren.forEach(child => {
|
|
214
|
-
start.append(child);
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// ### recurse
|
|
220
|
-
if(start.children){
|
|
221
|
-
Array.from(start.children).forEach(element => {
|
|
222
|
-
/!*
|
|
223
|
-
console.log('stepping into element', element);
|
|
224
|
-
if(element.getAttribute('type') !== toMerge.getAttribute('type')){
|
|
225
|
-
// console.log('###### element in template but not in partial');
|
|
226
|
-
// const nextSibling = start.nextElementSibling;
|
|
227
|
-
const nextSibling = element.nextElementSibling;
|
|
228
|
-
if(nextSibling && nextSibling.nodeName === toMerge.nodeName){
|
|
229
|
-
console.log('nextSibling', nextSibling, XPathUtil.shortenPath(path));
|
|
230
|
-
Fore.combine(nextSibling,partial,foreElement,path);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
*!/
|
|
234
|
-
return Fore.combine(element, partial,foreElement);
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
return start;
|
|
240
|
-
}
|
|
241
|
-
*/
|
|
242
|
-
|
|
243
21
|
static buildPredicates(node){
|
|
244
22
|
let attrPredicate='';
|
|
245
23
|
Array.from(node.attributes).forEach(attr =>{
|
package/src/fx-bind.js
CHANGED
|
@@ -63,7 +63,7 @@ export class FxBind extends foreElementMixin(HTMLElement) {
|
|
|
63
63
|
init(model) {
|
|
64
64
|
this.model = model;
|
|
65
65
|
// console.log('init binding ', this);
|
|
66
|
-
this.
|
|
66
|
+
this._getInstanceId();
|
|
67
67
|
this.bindType = this.getModel().getInstance(this.instanceId).type;
|
|
68
68
|
// console.log('binding type ', this.bindType);
|
|
69
69
|
|
|
@@ -399,20 +399,40 @@ export class FxBind extends foreElementMixin(HTMLElement) {
|
|
|
399
399
|
return result;
|
|
400
400
|
}
|
|
401
401
|
|
|
402
|
-
|
|
402
|
+
/**
|
|
403
|
+
* return the instance id this bind is associated with. Resolves upwards in binds to either find an expr containing
|
|
404
|
+
* and instance() function or if not found return 'default'.
|
|
405
|
+
* @private
|
|
406
|
+
*/
|
|
403
407
|
_getInstanceId() {
|
|
404
408
|
const bindExpr = this.getBindingExpr();
|
|
405
409
|
// console.log('_getInstanceId bindExpr ', bindExpr);
|
|
406
410
|
if (bindExpr.startsWith('instance(')) {
|
|
407
411
|
this.instanceId = XPathUtil.getInstanceId(bindExpr);
|
|
408
|
-
return
|
|
412
|
+
return;
|
|
409
413
|
}
|
|
410
|
-
if
|
|
411
|
-
|
|
414
|
+
if(!this.instanceId && this.parentNode.nodeName === 'FX-BIND'){
|
|
415
|
+
let parent = this.parentNode;
|
|
416
|
+
while(parent && !this.instanceId){
|
|
417
|
+
const ref = parent.getBindingExpr();
|
|
418
|
+
if (ref.startsWith('instance(')) {
|
|
419
|
+
this.instanceId = XPathUtil.getInstanceId(ref);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
if(parent.parentNode.nodeName !== 'FX-BIND'){
|
|
423
|
+
this.instanceId = 'default';
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
parent = parent.parentNode;
|
|
427
|
+
}
|
|
412
428
|
}
|
|
413
|
-
|
|
429
|
+
this.instanceId = 'default';
|
|
414
430
|
}
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
|
|
415
434
|
}
|
|
435
|
+
|
|
416
436
|
if (!customElements.get('fx-bind')) {
|
|
417
437
|
customElements.define('fx-bind', FxBind);
|
|
418
438
|
}
|
package/src/fx-fore.js
CHANGED
|
@@ -768,30 +768,31 @@ export class FxFore extends HTMLElement {
|
|
|
768
768
|
*/
|
|
769
769
|
async _lazyCreateInstance() {
|
|
770
770
|
const model = this.querySelector('fx-model');
|
|
771
|
-
// Inherit shared models from the parent component
|
|
772
771
|
|
|
772
|
+
// ##### lazy creation should NOT take place if there's a parent Fore using shared instances
|
|
773
773
|
const parentFore = this.parentNode.closest('fx-fore');
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
}
|
|
779
|
-
this.getModel().updateModel();
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
if (model.instances.length === 0) {
|
|
784
|
-
// console.log('### lazy creation of instance');
|
|
785
|
-
const generatedInstance = document.createElement('fx-instance');
|
|
786
|
-
model.appendChild(generatedInstance);
|
|
774
|
+
if(parentFore){
|
|
775
|
+
const shared = parentFore.getModel().instances.filter(shared => shared.hasAttribute('shared'));
|
|
776
|
+
if(shared.length !==0) return;
|
|
777
|
+
}
|
|
787
778
|
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
779
|
+
// still need to catch just in case...
|
|
780
|
+
try{
|
|
781
|
+
if (model.instances.length === 0) {
|
|
782
|
+
// console.log('### lazy creation of instance');
|
|
783
|
+
const generatedInstance = document.createElement('fx-instance');
|
|
784
|
+
model.appendChild(generatedInstance);
|
|
785
|
+
|
|
786
|
+
const generated = document.implementation.createDocument(null, 'data', null);
|
|
787
|
+
// const newData = this._generateInstance(this, generated.firstElementChild);
|
|
788
|
+
this._generateInstance(this, generated.firstElementChild);
|
|
789
|
+
generatedInstance.instanceData = generated;
|
|
790
|
+
model.instances.push(generatedInstance);
|
|
791
|
+
// console.log('generatedInstance ', this.getModel().getDefaultInstanceData());
|
|
792
|
+
Fore.dispatch(this,'instance-loaded',{instance:this});
|
|
793
|
+
}
|
|
794
|
+
}catch (e) {
|
|
795
|
+
console.warn('lazyCreateInstance created an error attempting to create a document', e.message);
|
|
795
796
|
}
|
|
796
797
|
}
|
|
797
798
|
|
package/src/fx-model.js
CHANGED
|
@@ -30,6 +30,7 @@ export class FxModel extends HTMLElement {
|
|
|
30
30
|
this.modelConstructed = false;
|
|
31
31
|
this.attachShadow({mode: 'open'});
|
|
32
32
|
this.computes = 0;
|
|
33
|
+
this.fore = {};
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
get formElement() {
|
|
@@ -49,6 +50,7 @@ export class FxModel extends HTMLElement {
|
|
|
49
50
|
}, {once: true});
|
|
50
51
|
|
|
51
52
|
this.skipUpdate = false;
|
|
53
|
+
this.fore = this.parentNode;
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
static lazyCreateModelItem(model, ref, node) {
|
|
@@ -400,7 +402,7 @@ export class FxModel extends HTMLElement {
|
|
|
400
402
|
modelItem.required = compute;
|
|
401
403
|
this.formElement.addToRefresh(modelItem); // let fore know that modelItem needs refresh
|
|
402
404
|
if (!modelItem.node.textContent) {
|
|
403
|
-
console.log('
|
|
405
|
+
console.log('node is required but has no value ', XPathUtil.getDocPath(modelItem.node));
|
|
404
406
|
valid = false;
|
|
405
407
|
}
|
|
406
408
|
// if (!compute) valid = false;
|
|
@@ -458,7 +460,16 @@ export class FxModel extends HTMLElement {
|
|
|
458
460
|
// console.log('instances array ',Array.from(this.instances));
|
|
459
461
|
|
|
460
462
|
const instArray = Array.from(this.instances);
|
|
461
|
-
|
|
463
|
+
let found = instArray.find(inst => inst.id === id);
|
|
464
|
+
if(!found) {
|
|
465
|
+
const parentFore = this.fore.parentNode.closest('fx-fore');
|
|
466
|
+
if (parentFore) {
|
|
467
|
+
console.log('shared instances from parent', this.parentNode.id);
|
|
468
|
+
const parentInstances = parentFore.getModel().instances;
|
|
469
|
+
const shared = parentInstances.filter(shared => shared.hasAttribute('shared'));
|
|
470
|
+
found = shared.find(found => found.id === id);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
462
473
|
if(!found){
|
|
463
474
|
// return this.getDefaultInstance(); // if id is not found always defaults to first in doc order
|
|
464
475
|
Fore.dispatch(this, 'error', {
|
package/src/ui/fx-container.js
CHANGED
package/src/ui/fx-switch.js
CHANGED
|
@@ -18,7 +18,10 @@ class FxSwitch extends FxContainer {
|
|
|
18
18
|
constructor() {
|
|
19
19
|
super();
|
|
20
20
|
this.formerCase = {};
|
|
21
|
+
this.selectedCase = null;
|
|
22
|
+
this.cases = null;
|
|
21
23
|
}
|
|
24
|
+
|
|
22
25
|
connectedCallback() {
|
|
23
26
|
if (super.connectedCallback) {
|
|
24
27
|
super.connectedCallback();
|
|
@@ -37,63 +40,83 @@ class FxSwitch extends FxContainer {
|
|
|
37
40
|
</style>
|
|
38
41
|
${html}
|
|
39
42
|
`;
|
|
43
|
+
this.cases = [];
|
|
44
|
+
this.formerCase=null;
|
|
40
45
|
}
|
|
41
46
|
|
|
42
47
|
async refresh(force) {
|
|
43
48
|
super.refresh();
|
|
44
49
|
// console.log('refresh on switch ');
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
if(this.cases.length === 0){
|
|
51
|
+
this.cases = Array.from(this.querySelectorAll(':scope > fx-case'));
|
|
52
|
+
}
|
|
53
|
+
|
|
47
54
|
if (this.isBound()) {
|
|
48
|
-
|
|
49
|
-
const name = caseElem.getAttribute('name');
|
|
50
|
-
if (name === this.modelItem?.value) {
|
|
51
|
-
Fore.dispatch(caseElem,'select',{});
|
|
52
|
-
caseElem.classList.add('selected-case');
|
|
53
|
-
selectedCase = caseElem;
|
|
54
|
-
} else {
|
|
55
|
-
if(caseElem.classList.contains('selected-case')){
|
|
56
|
-
Fore.dispatch(caseElem,'deselect',{});
|
|
57
|
-
}
|
|
58
|
-
caseElem.classList.remove('selected-case');
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
} else {
|
|
62
|
-
selectedCase = this.querySelector(':scope > .selected-case');
|
|
63
|
-
// if none is selected select the first as default
|
|
64
|
-
if (!selectedCase) {
|
|
65
|
-
selectedCase = cases[0]; // if nothing is selected use the first case
|
|
66
|
-
Fore.dispatch(selectedCase,'select',{});
|
|
67
|
-
selectedCase.classList.add('selected-case');
|
|
68
|
-
}
|
|
55
|
+
this._handleBoundSwitch();
|
|
69
56
|
}
|
|
70
|
-
if(this.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
v.classList.remove('visited');
|
|
74
|
-
});
|
|
57
|
+
if(!this.selectedCase){
|
|
58
|
+
this.selectedCase = this.cases[0]; // first is always default
|
|
59
|
+
this.toggle(this.selectedCase);
|
|
75
60
|
}
|
|
76
61
|
|
|
77
|
-
Fore.refreshChildren(selectedCase,force);
|
|
78
|
-
this.formerCase = selectedCase;
|
|
62
|
+
Fore.refreshChildren(this.selectedCase,force);
|
|
79
63
|
}
|
|
80
64
|
|
|
65
|
+
_dispatchEvents(){
|
|
66
|
+
if(this.formerCase && this.formerCase !== this.selectedCase){
|
|
67
|
+
Fore.dispatch(this.formerCase,'deselect',{});
|
|
68
|
+
}
|
|
69
|
+
if(this.selectedCase.classList.contains('selected-case')){
|
|
70
|
+
Fore.dispatch(this.selectedCase,'select',{});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
_resetVisited(){
|
|
75
|
+
const visited = this.selectedCase.querySelectorAll('.visited');
|
|
76
|
+
Array.from(visited).forEach(v =>{
|
|
77
|
+
v.classList.remove('visited');
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* handles switches being bound. If modelItem value matches the 'name' attribute that case will be toggled.
|
|
83
|
+
* @private
|
|
84
|
+
*/
|
|
85
|
+
_handleBoundSwitch() {
|
|
86
|
+
Array.from(this.cases).forEach(caseElem => {
|
|
87
|
+
const name = caseElem.getAttribute('name');
|
|
88
|
+
if (name === this.modelItem?.value) {
|
|
89
|
+
this.toggle(caseElem);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Activates a fx-case element by switching CSS classes.
|
|
96
|
+
* Dispatches 'select' and 'deselect' events as appropriate.
|
|
97
|
+
*
|
|
98
|
+
* @param caseElement the fx-case element to activate
|
|
99
|
+
*/
|
|
81
100
|
toggle(caseElement) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
101
|
+
this.formerCase = this.selectedCase;
|
|
102
|
+
this.selectedCase = caseElement;
|
|
103
|
+
Array.from(this.cases).forEach(c => {
|
|
104
|
+
if (c === this.selectedCase) {
|
|
105
|
+
c.classList.remove('deselected-case');
|
|
86
106
|
c.classList.add('selected-case');
|
|
87
|
-
|
|
88
|
-
this.refresh();
|
|
107
|
+
c.inert = false;
|
|
89
108
|
} else {
|
|
90
|
-
// eslint-disable-next-line no-param-reassign
|
|
91
|
-
if(c.classList.contains('selected-case')){
|
|
92
|
-
Fore.dispatch(c,'deselect',{});
|
|
93
|
-
}
|
|
94
109
|
c.classList.remove('selected-case');
|
|
110
|
+
c.classList.add('deselected-case');
|
|
111
|
+
c.inert = true;
|
|
112
|
+
this._resetVisited();
|
|
95
113
|
}
|
|
96
114
|
});
|
|
115
|
+
|
|
116
|
+
if(this.selectedCase !== caseElement){
|
|
117
|
+
this.selectedCase = caseElement;
|
|
118
|
+
}
|
|
119
|
+
this._dispatchEvents();
|
|
97
120
|
}
|
|
98
121
|
}
|
|
99
122
|
|
package/src/xpath-evaluation.js
CHANGED
|
@@ -444,11 +444,10 @@ export function evaluateXPath(xpath, contextNode, formElement, variables = {}, o
|
|
|
444
444
|
*/
|
|
445
445
|
export function evaluateXPath(xpath, contextNode, formElement, variables = {}, options={}) {
|
|
446
446
|
try{
|
|
447
|
-
console.log('evaluateXPath',xpath);
|
|
448
447
|
const namespaceResolver = createNamespaceResolverForNode(xpath, contextNode, formElement);
|
|
449
448
|
const variablesInScope = getVariablesInScope(formElement);
|
|
450
449
|
|
|
451
|
-
|
|
450
|
+
const result = fxEvaluateXPath(
|
|
452
451
|
xpath,
|
|
453
452
|
contextNode,
|
|
454
453
|
null,
|
|
@@ -465,6 +464,8 @@ export function evaluateXPath(xpath, contextNode, formElement, variables = {}, o
|
|
|
465
464
|
language: options.language || evaluateXPath.XPATH_3_1
|
|
466
465
|
},
|
|
467
466
|
);
|
|
467
|
+
// console.log('evaluateXPath',xpath, result);
|
|
468
|
+
return result;
|
|
468
469
|
}catch (e){
|
|
469
470
|
formElement.dispatchEvent(new CustomEvent('error', {
|
|
470
471
|
composed: false,
|
|
@@ -506,7 +507,7 @@ export function evaluateXPathToFirstNode(xpath, contextNode, formElement) {
|
|
|
506
507
|
try{
|
|
507
508
|
const namespaceResolver = createNamespaceResolverForNode(xpath, contextNode, formElement);
|
|
508
509
|
const variablesInScope = getVariablesInScope(formElement);
|
|
509
|
-
|
|
510
|
+
const result = fxEvaluateXPathToFirstNode(xpath, contextNode, null, variablesInScope, {
|
|
510
511
|
defaultFunctionNamespaceURI: XFORMS_NAMESPACE_URI,
|
|
511
512
|
moduleImports: {
|
|
512
513
|
xf: XFORMS_NAMESPACE_URI,
|
|
@@ -515,6 +516,8 @@ export function evaluateXPathToFirstNode(xpath, contextNode, formElement) {
|
|
|
515
516
|
functionNameResolver,
|
|
516
517
|
namespaceResolver,
|
|
517
518
|
});
|
|
519
|
+
// console.log('evaluateXPathToFirstNode',xpath, result);
|
|
520
|
+
return result;
|
|
518
521
|
} catch (e){
|
|
519
522
|
formElement.dispatchEvent(new CustomEvent('error', {
|
|
520
523
|
composed: false,
|
|
@@ -542,7 +545,7 @@ export function evaluateXPathToNodes(xpath, contextNode, formElement) {
|
|
|
542
545
|
const namespaceResolver = createNamespaceResolverForNode(xpath, contextNode, formElement);
|
|
543
546
|
const variablesInScope = getVariablesInScope(formElement);
|
|
544
547
|
|
|
545
|
-
|
|
548
|
+
const result = fxEvaluateXPathToNodes(xpath, contextNode, null, variablesInScope, {
|
|
546
549
|
currentContext: {formElement},
|
|
547
550
|
functionNameResolver,
|
|
548
551
|
moduleImports: {
|
|
@@ -550,6 +553,8 @@ export function evaluateXPathToNodes(xpath, contextNode, formElement) {
|
|
|
550
553
|
},
|
|
551
554
|
namespaceResolver,
|
|
552
555
|
});
|
|
556
|
+
// console.log('evaluateXPathToNodes',xpath, result);
|
|
557
|
+
return result;
|
|
553
558
|
}catch (e){
|
|
554
559
|
formElement.dispatchEvent(new CustomEvent('error', {
|
|
555
560
|
composed: false,
|
|
@@ -982,7 +987,7 @@ const instance = (dynamicContext, string) => {
|
|
|
982
987
|
bubbles: true,
|
|
983
988
|
detail: {
|
|
984
989
|
origin: 'functions',
|
|
985
|
-
message: `
|
|
990
|
+
message: `Instance not found '${localName}'`,
|
|
986
991
|
level:'Error'
|
|
987
992
|
},
|
|
988
993
|
}));
|
|
@@ -995,28 +1000,6 @@ const instance = (dynamicContext, string) => {
|
|
|
995
1000
|
return null;
|
|
996
1001
|
}
|
|
997
1002
|
return context;
|
|
998
|
-
|
|
999
|
-
/*
|
|
1000
|
-
const inst = string
|
|
1001
|
-
? formElement.getModel().getInstance(string)
|
|
1002
|
-
: formElement.getModel().getDefaultInstance();
|
|
1003
|
-
*/
|
|
1004
|
-
|
|
1005
|
-
/*
|
|
1006
|
-
const inst = string
|
|
1007
|
-
? resolveId(string, formElement, 'fx-instance')
|
|
1008
|
-
: formElement.querySelector(`fx-instance`);
|
|
1009
|
-
|
|
1010
|
-
if (lookup) {
|
|
1011
|
-
const context = lookup.getDefaultContext();
|
|
1012
|
-
if (!context) {
|
|
1013
|
-
debugger;
|
|
1014
|
-
return null;
|
|
1015
|
-
}
|
|
1016
|
-
return context;
|
|
1017
|
-
}
|
|
1018
|
-
return null;
|
|
1019
|
-
*/
|
|
1020
1003
|
};
|
|
1021
1004
|
|
|
1022
1005
|
registerCustomXPathFunction(
|