@jinntec/fore 2.5.0 → 2.6.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 +34261 -9
- package/dist/fore.js +34123 -9
- package/index.js +1 -1
- package/package.json +1 -1
- package/resources/fore.css +29 -0
- package/src/DataObserver.js +181 -0
- package/src/DependentXPathQueries.js +32 -0
- package/src/ForeElementMixin.js +289 -260
- package/src/actions/abstract-action.js +24 -24
- package/src/actions/fx-append.js +2 -0
- package/src/actions/fx-delete.js +14 -2
- package/src/actions/fx-hide.js +1 -1
- package/src/actions/fx-insert.js +47 -41
- package/src/actions/fx-load.js +7 -2
- package/src/actions/fx-setvalue.js +104 -86
- package/src/actions/fx-show.js +4 -2
- package/src/fore.js +40 -23
- package/src/fx-fore.js +92 -93
- package/src/fx-submission.js +28 -23
- package/src/getInScopeContext.js +1 -0
- package/src/modelitem.js +107 -96
- package/src/ui/UIElement.js +91 -0
- package/src/ui/abstract-control.js +10 -7
- package/src/ui/fx-container.js +5 -3
- package/src/ui/fx-control-menu.js +198 -0
- package/src/ui/fx-control.js +61 -17
- package/src/ui/fx-dialog.js +2 -2
- package/src/ui/fx-group.js +14 -0
- package/src/ui/fx-repeat.js +33 -3
- package/src/xpath-util.js +284 -256
- package/dist/fore-dev.js.map +0 -1
- package/dist/fore.js.map +0 -1
- package/src/ui/fx-select.js +0 -89
package/src/fx-fore.js
CHANGED
|
@@ -247,6 +247,8 @@ export class FxFore extends HTMLElement {
|
|
|
247
247
|
// this.mergePartial = this.hasAttribute('merge-partial')? true:false;
|
|
248
248
|
this.mergePartial = false;
|
|
249
249
|
this.createNodes = this.hasAttribute('create-nodes') ? true : false;
|
|
250
|
+
this._localNamesWithChanges = new Set();
|
|
251
|
+
this.setAttribute('role', 'form'); // set aria role
|
|
250
252
|
}
|
|
251
253
|
|
|
252
254
|
connectedCallback() {
|
|
@@ -388,6 +390,16 @@ export class FxFore extends HTMLElement {
|
|
|
388
390
|
}
|
|
389
391
|
}
|
|
390
392
|
|
|
393
|
+
/**
|
|
394
|
+
* Signal something happened with an element with the given local name. This will be used in the
|
|
395
|
+
* next (non-forceful) refresh to detect whether a component (usually a repeat) should update
|
|
396
|
+
*
|
|
397
|
+
* @param {string} localNameOfElement
|
|
398
|
+
*/
|
|
399
|
+
signalChangeToElement(localNameOfElement) {
|
|
400
|
+
this._localNamesWithChanges.add(localNameOfElement);
|
|
401
|
+
}
|
|
402
|
+
|
|
391
403
|
/**
|
|
392
404
|
* Raise a flag that there might be new template expressions under some node. This happens with
|
|
393
405
|
* repeats updating (new repeat items can have new template expressions) or switches changing their case (new case = new raw HTML)
|
|
@@ -502,89 +514,26 @@ export class FxFore extends HTMLElement {
|
|
|
502
514
|
* @param {(boolean|{reason:'index-function'})} [force]fx-fore
|
|
503
515
|
*/
|
|
504
516
|
async refresh(force) {
|
|
505
|
-
/*
|
|
506
|
-
|
|
507
|
-
if (!changedPaths) {
|
|
508
|
-
changedPaths = this.toRefresh.map(item => item.path);
|
|
509
|
-
} else {
|
|
510
|
-
this.toRefresh.push(
|
|
511
|
-
...changedPaths
|
|
512
|
-
.map(
|
|
513
|
-
path =>
|
|
514
|
-
this.getModel()
|
|
515
|
-
.modelItems
|
|
516
|
-
.find(item => item.path === path)
|
|
517
|
-
)
|
|
518
|
-
.filter(Boolean)
|
|
519
|
-
);
|
|
520
|
-
|
|
521
|
-
for(const changedPath of changedPaths) {
|
|
522
|
-
for (const repeat of this.querySelectorAll('fx-repeat')) {
|
|
523
|
-
if (repeat.closest('fx-fore') !== this) {
|
|
524
|
-
continue;
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
if (repeat.touchedPaths && repeat.touchedPaths.has(changedPath)) {
|
|
528
|
-
// Make a temporary model-item-like structure for this
|
|
529
|
-
this.toRefresh.push({
|
|
530
|
-
path: changedPath,
|
|
531
|
-
boundControls: [repeat]
|
|
532
|
-
});
|
|
533
|
-
|
|
534
|
-
console.log('Found a repeat to update!!!', repeat)
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
*/
|
|
540
517
|
if (this.isRefreshing) {
|
|
541
518
|
return;
|
|
542
519
|
}
|
|
520
|
+
|
|
521
|
+
if (force !== true && this._localNamesWithChanges.size > 0) {
|
|
522
|
+
force = {
|
|
523
|
+
...(force || { reason: undefined }),
|
|
524
|
+
elementLocalnamesWithChanges: Array.from(this._localNamesWithChanges),
|
|
525
|
+
};
|
|
526
|
+
this._localNamesWithChanges.clear();
|
|
527
|
+
}
|
|
528
|
+
|
|
543
529
|
this.isRefreshing = true;
|
|
544
|
-
// console.log(`### <<<<< refresh() on '${this.id}' >>>>>`);
|
|
545
530
|
|
|
546
531
|
// refresh () {
|
|
547
532
|
// ### refresh Fore UI elements
|
|
548
533
|
// if (!this.initialRun && this.toRefresh.length !== 0) {
|
|
534
|
+
// if (!this.initialRun && this.toRefresh.length !== 0) {
|
|
549
535
|
if (!force && !this.initialRun && this.toRefresh.length !== 0) {
|
|
550
|
-
|
|
551
|
-
let needsRefresh = false;
|
|
552
|
-
|
|
553
|
-
// ### after recalculation the changed modelItems are copied to 'toRefresh' array for processing
|
|
554
|
-
this.toRefresh.forEach(modelItem => {
|
|
555
|
-
// check if modelItem has boundControls - if so, call refresh() for each of them
|
|
556
|
-
const controlsToRefresh = modelItem.boundControls;
|
|
557
|
-
if (controlsToRefresh) {
|
|
558
|
-
controlsToRefresh.forEach(ctrl => {
|
|
559
|
-
ctrl.refresh(force);
|
|
560
|
-
});
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
// ### check if other controls depend on current modelItem
|
|
564
|
-
const { mainGraph } = this.getModel();
|
|
565
|
-
if (mainGraph && mainGraph.hasNode(modelItem.path)) {
|
|
566
|
-
const deps = this.getModel().mainGraph.dependentsOf(modelItem.path, false);
|
|
567
|
-
// ### iterate dependant modelItems and refresh all their boundControls
|
|
568
|
-
if (deps.length !== 0) {
|
|
569
|
-
deps.forEach(dep => {
|
|
570
|
-
// ### if changed modelItem has a 'facet' path we use the basePath that is the locationPath without facet name
|
|
571
|
-
const basePath = XPathUtil.getBasePath(dep);
|
|
572
|
-
const modelItemOfDep = this.getModel().modelItems.find(mip => mip.path === basePath);
|
|
573
|
-
// ### refresh all boundControls
|
|
574
|
-
modelItemOfDep.boundControls.forEach(control => {
|
|
575
|
-
control.refresh(force);
|
|
576
|
-
});
|
|
577
|
-
});
|
|
578
|
-
needsRefresh = true;
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
});
|
|
582
|
-
this.toRefresh = [];
|
|
583
|
-
/*
|
|
584
|
-
if (!needsRefresh) {
|
|
585
|
-
console.log('no dependants to refresh');
|
|
586
|
-
}
|
|
587
|
-
*/
|
|
536
|
+
this.refreshChanged(force);
|
|
588
537
|
} else {
|
|
589
538
|
// ### resetting visited state for controls to refresh
|
|
590
539
|
/*
|
|
@@ -595,13 +544,15 @@ export class FxFore extends HTMLElement {
|
|
|
595
544
|
*/
|
|
596
545
|
|
|
597
546
|
if (this.inited) {
|
|
547
|
+
console.log(`### <<<<< refresh() on '${this.id}' >>>>>`);
|
|
548
|
+
|
|
598
549
|
Fore.refreshChildren(this, force);
|
|
599
550
|
}
|
|
600
551
|
// console.timeEnd('refreshChildren');
|
|
601
552
|
}
|
|
602
553
|
|
|
603
554
|
// ### refresh template expressions
|
|
604
|
-
if (this.initialRun || this._scanForNewTemplateExpressionsNextRefresh) {
|
|
555
|
+
if (force || this.initialRun || this._scanForNewTemplateExpressionsNextRefresh) {
|
|
605
556
|
this._updateTemplateExpressions();
|
|
606
557
|
this._scanForNewTemplateExpressionsNextRefresh = false; // reset
|
|
607
558
|
}
|
|
@@ -641,12 +592,49 @@ export class FxFore extends HTMLElement {
|
|
|
641
592
|
for (const subFore of subFores) {
|
|
642
593
|
// subFore.refresh(false, changedPaths);
|
|
643
594
|
if (subFore.ready) {
|
|
644
|
-
|
|
595
|
+
// Do an unconditional hard refresh: there might be changes that are relevant
|
|
596
|
+
await subFore.refresh(true);
|
|
645
597
|
}
|
|
646
598
|
}
|
|
647
599
|
this.isRefreshing = false;
|
|
648
600
|
}
|
|
649
601
|
|
|
602
|
+
refreshChanged(force) {
|
|
603
|
+
console.log('toRefresh', this.toRefresh);
|
|
604
|
+
let needsRefresh = false;
|
|
605
|
+
|
|
606
|
+
// ### after recalculation the changed modelItems are copied to 'toRefresh' array for processing
|
|
607
|
+
this.toRefresh.forEach(modelItem => {
|
|
608
|
+
// check if modelItem has boundControls - if so, call refresh() for each of them
|
|
609
|
+
const controlsToRefresh = modelItem.boundControls;
|
|
610
|
+
if (controlsToRefresh) {
|
|
611
|
+
controlsToRefresh.forEach(ctrl => {
|
|
612
|
+
ctrl.refresh(force);
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
// ### check if other controls depend on current modelItem
|
|
617
|
+
const { mainGraph } = this.getModel();
|
|
618
|
+
if (mainGraph && mainGraph.hasNode(modelItem.path)) {
|
|
619
|
+
const deps = this.getModel().mainGraph.dependentsOf(modelItem.path, false);
|
|
620
|
+
// ### iterate dependant modelItems and refresh all their boundControls
|
|
621
|
+
if (deps.length !== 0) {
|
|
622
|
+
deps.forEach(dep => {
|
|
623
|
+
// ### if changed modelItem has a 'facet' path we use the basePath that is the locationPath without facet name
|
|
624
|
+
const basePath = XPathUtil.getBasePath(dep);
|
|
625
|
+
const modelItemOfDep = this.getModel().modelItems.find(mip => mip.path === basePath);
|
|
626
|
+
// ### refresh all boundControls
|
|
627
|
+
modelItemOfDep.boundControls.forEach(control => {
|
|
628
|
+
control.refresh(force);
|
|
629
|
+
});
|
|
630
|
+
});
|
|
631
|
+
needsRefresh = true;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
});
|
|
635
|
+
this.toRefresh = [];
|
|
636
|
+
}
|
|
637
|
+
|
|
650
638
|
/**
|
|
651
639
|
* entry point for processing of template expression enclosed in '{}' brackets.
|
|
652
640
|
*
|
|
@@ -1018,20 +1006,30 @@ export class FxFore extends HTMLElement {
|
|
|
1018
1006
|
*/
|
|
1019
1007
|
initData(root = this) {
|
|
1020
1008
|
// const created = new Promise(resolve => {
|
|
1021
|
-
console.log('INIT');
|
|
1022
|
-
const boundControls = Array.from(root.querySelectorAll('[ref]:not(fx-model *),fx-repeatitem'));
|
|
1009
|
+
// console.log('INIT');
|
|
1010
|
+
// const boundControls = Array.from(root.querySelectorAll('[ref]:not(fx-model *),fx-repeatitem'));
|
|
1011
|
+
|
|
1012
|
+
const boundControls = Array.from(
|
|
1013
|
+
root.querySelectorAll(
|
|
1014
|
+
'fx-control[ref],fx-upload[ref],fx-group[ref],fx-repeat[ref], fx-switch[ref]',
|
|
1015
|
+
),
|
|
1016
|
+
);
|
|
1023
1017
|
if (root.matches('fx-repeatitem')) {
|
|
1024
1018
|
boundControls.unshift(root);
|
|
1025
1019
|
}
|
|
1026
1020
|
// console.log('_initD', boundControls);
|
|
1027
1021
|
for (let i = 0; i < boundControls.length; i++) {
|
|
1028
|
-
const
|
|
1029
|
-
|
|
1022
|
+
const bound = boundControls[i];
|
|
1023
|
+
|
|
1024
|
+
/*
|
|
1025
|
+
ignore bound elements that are enclosed with a control like <select> or <fx-items> and repeated items
|
|
1026
|
+
*/
|
|
1027
|
+
if (!bound.matches('fx-repeatitem') && !bound.parentNode.closest('fx-control')) {
|
|
1030
1028
|
// Repeat items are dumb. They do not respond to evalInContext
|
|
1031
|
-
|
|
1029
|
+
bound.evalInContext();
|
|
1032
1030
|
}
|
|
1033
1031
|
let ownerDoc;
|
|
1034
|
-
if (
|
|
1032
|
+
if (bound.nodeset !== null) {
|
|
1035
1033
|
// console.log('Node exists', control.nodeset);
|
|
1036
1034
|
continue;
|
|
1037
1035
|
}
|
|
@@ -1042,7 +1040,7 @@ export class FxFore extends HTMLElement {
|
|
|
1042
1040
|
|
|
1043
1041
|
// Previous control can either be an ancestor of us, or a previous node, which can be a sibling, or a child of a sibling.
|
|
1044
1042
|
// First: parent
|
|
1045
|
-
if (previousControl.contains(
|
|
1043
|
+
if (previousControl.contains(bound)) {
|
|
1046
1044
|
// Parent is here.
|
|
1047
1045
|
// console.log('insert into', control,previousControl);
|
|
1048
1046
|
// console.log('insert into nodeset', control.nodeset);
|
|
@@ -1050,7 +1048,7 @@ export class FxFore extends HTMLElement {
|
|
|
1050
1048
|
// console.log('parentNodeset', parentNodeset);
|
|
1051
1049
|
|
|
1052
1050
|
// const parentModelItemNode = parentModelItem.node;
|
|
1053
|
-
const ref =
|
|
1051
|
+
const ref = bound.ref;
|
|
1054
1052
|
// const newElement = parentModelItemNode.ownerDocument.createElement(ref);
|
|
1055
1053
|
if (parentNodeset.querySelector(`[ref="${ref}"]`)) {
|
|
1056
1054
|
console.log(`Node with ref "${ref}" already exists.`);
|
|
@@ -1061,8 +1059,8 @@ export class FxFore extends HTMLElement {
|
|
|
1061
1059
|
|
|
1062
1060
|
// Plonk it in at the start!
|
|
1063
1061
|
parentNodeset.insertBefore(newElement, parentNodeset.firstChild);
|
|
1064
|
-
|
|
1065
|
-
console.log('CREATED child', newElement);
|
|
1062
|
+
bound.evalInContext();
|
|
1063
|
+
// console.log('CREATED child', newElement);
|
|
1066
1064
|
// console.log('new control evaluated to ', control.nodeset);
|
|
1067
1065
|
// Done!
|
|
1068
1066
|
continue;
|
|
@@ -1070,7 +1068,7 @@ export class FxFore extends HTMLElement {
|
|
|
1070
1068
|
// console.log('previousControl', previousControl);
|
|
1071
1069
|
// console.log('control', control);
|
|
1072
1070
|
// Is previousControl a sibling or a descendant of a logical sibling? Keep looking backwards until we share parents!
|
|
1073
|
-
const ourParent = XPathUtil.getParentBindingElement(
|
|
1071
|
+
const ourParent = XPathUtil.getParentBindingElement(bound);
|
|
1074
1072
|
// console.log('ourParent', ourParent);
|
|
1075
1073
|
let siblingControl = null;
|
|
1076
1074
|
/*
|
|
@@ -1093,8 +1091,9 @@ export class FxFore extends HTMLElement {
|
|
|
1093
1091
|
throw new Error('Unexpected! there must be a sibling right?');
|
|
1094
1092
|
}
|
|
1095
1093
|
// console.log('sibling', siblingControl);
|
|
1094
|
+
// todo: review: should this not just be inscopeContext?
|
|
1096
1095
|
const parentNodeset = ourParent.nodeset;
|
|
1097
|
-
const ref =
|
|
1096
|
+
const ref = bound.ref;
|
|
1098
1097
|
let referenceNodeset = siblingControl.nodeset;
|
|
1099
1098
|
const newElement = this._createNodes(ref, parentNodeset);
|
|
1100
1099
|
|
|
@@ -1110,9 +1109,9 @@ export class FxFore extends HTMLElement {
|
|
|
1110
1109
|
console.log('control ref', control.ref);
|
|
1111
1110
|
console.log('control new element parent', newElement.parentNode.nodeName);
|
|
1112
1111
|
*/
|
|
1113
|
-
|
|
1112
|
+
bound.evalInContext();
|
|
1114
1113
|
// console.log('new control evaluated to ', control.nodeset);
|
|
1115
|
-
console.log('CREATED sibling', newElement);
|
|
1114
|
+
// console.log('CREATED sibling', newElement);
|
|
1116
1115
|
}
|
|
1117
1116
|
// console.log('DATA', this.getModel().getDefaultContext());
|
|
1118
1117
|
}
|
|
@@ -1126,16 +1125,16 @@ export class FxFore extends HTMLElement {
|
|
|
1126
1125
|
console.log(`Node already exists for ref: ${ref}`);
|
|
1127
1126
|
return existingNode;
|
|
1128
1127
|
}
|
|
1129
|
-
*/
|
|
1130
1128
|
console.log(`creating new node for ref: ${ref}`);
|
|
1129
|
+
*/
|
|
1131
1130
|
let newElement;
|
|
1132
1131
|
if (ref.includes('/')) {
|
|
1133
1132
|
// multi-step ref expressions
|
|
1134
|
-
newElement = XPathUtil.
|
|
1133
|
+
newElement = XPathUtil.createNodesFromXPath(ref, referenceNode.ownerDocument, this);
|
|
1135
1134
|
// console.log('new subtree', newElement);
|
|
1136
1135
|
return newElement;
|
|
1137
1136
|
} else {
|
|
1138
|
-
return XPathUtil.
|
|
1137
|
+
return XPathUtil.createNodesFromXPath(ref, referenceNode.ownerDocument, this);
|
|
1139
1138
|
}
|
|
1140
1139
|
}
|
|
1141
1140
|
|
package/src/fx-submission.js
CHANGED
|
@@ -84,8 +84,8 @@ export class FxSubmission extends ForeElementMixin {
|
|
|
84
84
|
|
|
85
85
|
async _submit() {
|
|
86
86
|
console.info(
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
`%csubmitting #${this.id}`,
|
|
88
|
+
'background:yellow; color:black; padding:.5rem; display:inline-block; white-space: nowrap; border-radius:0.3rem;width:100%;',
|
|
89
89
|
);
|
|
90
90
|
|
|
91
91
|
this.evalInContext();
|
|
@@ -100,7 +100,7 @@ export class FxSubmission extends ForeElementMixin {
|
|
|
100
100
|
this.getOwnerForm().classList.add('submit-validation-failed');
|
|
101
101
|
// ### allow alerts to pop up
|
|
102
102
|
// this.dispatch('submit-error', {});
|
|
103
|
-
Fore.dispatch(this, 'submit-error', {});
|
|
103
|
+
Fore.dispatch(this, 'submit-error', { status: 0, message: 'validation failed' });
|
|
104
104
|
this.getModel().parentNode.refresh(true);
|
|
105
105
|
return;
|
|
106
106
|
}
|
|
@@ -183,6 +183,7 @@ export class FxSubmission extends ForeElementMixin {
|
|
|
183
183
|
const serialized = localStorage.getItem(key);
|
|
184
184
|
if (!serialized) {
|
|
185
185
|
Fore.dispatch(this, 'submit-error', {
|
|
186
|
+
status: 400,
|
|
186
187
|
message: `Error reading key ${key} from localstorage`,
|
|
187
188
|
});
|
|
188
189
|
this.parameters.clear();
|
|
@@ -237,11 +238,14 @@ export class FxSubmission extends ForeElementMixin {
|
|
|
237
238
|
if (!response.ok || response.status > 400) {
|
|
238
239
|
// this.dispatch('submit-error', { message: `Error while submitting ${this.id}` });
|
|
239
240
|
console.info(
|
|
240
|
-
|
|
241
|
-
|
|
241
|
+
`%csubmit-error #${this.id}`,
|
|
242
|
+
'background:red; color:black; padding:.5rem; display:inline-block; white-space: nowrap; border-radius:0.3rem;width:100%;',
|
|
242
243
|
);
|
|
243
244
|
|
|
244
|
-
Fore.dispatch(this, 'submit-error', {
|
|
245
|
+
Fore.dispatch(this, 'submit-error', {
|
|
246
|
+
status: response.status,
|
|
247
|
+
message: `Error during submit ${this.id}`,
|
|
248
|
+
});
|
|
245
249
|
return;
|
|
246
250
|
}
|
|
247
251
|
|
|
@@ -264,15 +268,14 @@ export class FxSubmission extends ForeElementMixin {
|
|
|
264
268
|
// this.dispatch('submit-done', {});
|
|
265
269
|
// console.log(`### <<<<< ${this.id} submit-done >>>>>`);
|
|
266
270
|
Fore.dispatch(this, 'submit-done', {});
|
|
267
|
-
/*
|
|
271
|
+
/*
|
|
268
272
|
console.info(
|
|
269
273
|
`%csubmit-done #${this.id}`,
|
|
270
274
|
'background:green; color:white; padding:.5rem; display:inline-block; white-space: nowrap; border-radius:0.3rem;width:100%;',
|
|
271
275
|
);
|
|
272
276
|
*/
|
|
273
|
-
|
|
274
277
|
} catch (error) {
|
|
275
|
-
Fore.dispatch(this, 'submit-error', { error: error.message });
|
|
278
|
+
Fore.dispatch(this, 'submit-error', { status: 500, error: error.message });
|
|
276
279
|
} finally {
|
|
277
280
|
this.parameters.clear();
|
|
278
281
|
const download = document.querySelector('[download]');
|
|
@@ -395,26 +398,27 @@ export class FxSubmission extends ForeElementMixin {
|
|
|
395
398
|
if (this.replace === 'instance') {
|
|
396
399
|
if (targetInstance) {
|
|
397
400
|
if (this.targetref) {
|
|
398
|
-
|
|
399
401
|
const [theTarget] = evaluateXPath(
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
402
|
+
this.targetref,
|
|
403
|
+
targetInstance.instanceData.firstElementChild,
|
|
404
|
+
this,
|
|
403
405
|
);
|
|
404
406
|
console.log('theTarget', theTarget);
|
|
405
|
-
if(
|
|
407
|
+
if (
|
|
408
|
+
this.responseMediatype === 'application/xml' ||
|
|
409
|
+
this.responseMediatype === 'text/html'
|
|
410
|
+
) {
|
|
406
411
|
const clone = data.firstElementChild;
|
|
407
412
|
const parent = theTarget.parentNode;
|
|
408
413
|
parent.replaceChild(clone, theTarget);
|
|
409
414
|
console.log('finally ', parent);
|
|
410
415
|
}
|
|
411
|
-
if(this.responseMediatype.startsWith('text/')){
|
|
416
|
+
if (this.responseMediatype.startsWith('text/')) {
|
|
412
417
|
theTarget.textContent = data;
|
|
413
418
|
}
|
|
414
|
-
if(this.responseMediatype === 'application/json'){
|
|
415
|
-
console.warn('targetref is not supported for application/json responses')
|
|
419
|
+
if (this.responseMediatype === 'application/json') {
|
|
420
|
+
console.warn('targetref is not supported for application/json responses');
|
|
416
421
|
}
|
|
417
|
-
|
|
418
422
|
} else if (this.into) {
|
|
419
423
|
const [theTarget] = evaluateXPath(
|
|
420
424
|
this.into,
|
|
@@ -471,11 +475,10 @@ export class FxSubmission extends ForeElementMixin {
|
|
|
471
475
|
const target = this._getProperty('target');
|
|
472
476
|
const targetNode = document.querySelector(target);
|
|
473
477
|
if (targetNode) {
|
|
474
|
-
|
|
475
|
-
if(contentType.startsWith('text/html')){
|
|
478
|
+
if (contentType.startsWith('text/html')) {
|
|
476
479
|
targetNode.innerHTML = data;
|
|
477
480
|
}
|
|
478
|
-
if(this.responseMediatype.startsWith('image/svg')){
|
|
481
|
+
if (this.responseMediatype.startsWith('image/svg')) {
|
|
479
482
|
const parser = new DOMParser();
|
|
480
483
|
const svgDoc = parser.parseFromString(data, 'image/svg+xml');
|
|
481
484
|
|
|
@@ -493,10 +496,11 @@ export class FxSubmission extends ForeElementMixin {
|
|
|
493
496
|
}
|
|
494
497
|
}
|
|
495
498
|
|
|
499
|
+
/*
|
|
496
500
|
_handleError() {
|
|
497
501
|
// this.dispatch('submit-error', {});
|
|
498
502
|
Fore.dispatch(this, 'submit-error', {});
|
|
499
|
-
|
|
503
|
+
/!*
|
|
500
504
|
console.log('ERRRORRRRR');
|
|
501
505
|
this.dispatchEvent(
|
|
502
506
|
new CustomEvent('submit-error', {
|
|
@@ -505,8 +509,9 @@ export class FxSubmission extends ForeElementMixin {
|
|
|
505
509
|
detail: {},
|
|
506
510
|
}),
|
|
507
511
|
);
|
|
508
|
-
|
|
512
|
+
*!/
|
|
509
513
|
}
|
|
514
|
+
*/
|
|
510
515
|
|
|
511
516
|
/*
|
|
512
517
|
mergeNodes(node1, node2) {
|
package/src/getInScopeContext.js
CHANGED
|
@@ -69,6 +69,7 @@ function _getInitialContext(node, ref) {
|
|
|
69
69
|
export default function getInScopeContext(node, ref) {
|
|
70
70
|
// console.log('getInScopeContext', ref, node);
|
|
71
71
|
|
|
72
|
+
//todo: check for multi-step pathes
|
|
72
73
|
const parentElement = _getElement(node);
|
|
73
74
|
// console.log('getInScopeContext parent', parentElement);
|
|
74
75
|
|
package/src/modelitem.js
CHANGED
|
@@ -6,116 +6,127 @@
|
|
|
6
6
|
* Each bound node in an instance has exactly one ModelItem associated with it.
|
|
7
7
|
*/
|
|
8
8
|
export class ModelItem {
|
|
9
|
-
/**
|
|
10
|
-
*
|
|
11
|
-
* @param {string} path calculated normalized path expression linking to data
|
|
12
|
-
* @param {string} ref relative binding expression
|
|
13
|
-
* @param {boolean} readonly - boolean to signal readonly/readwrite state
|
|
14
|
-
* @param {boolean} relevant - boolean to signal relevant/non-relevant state
|
|
15
|
-
* @param {boolean} required - boolean to signal required/optional state
|
|
16
|
-
* @param {boolean} constraint - boolean boolean to signal valid/invalid state
|
|
17
|
-
* @param {string} type - string expression to set a datatype
|
|
18
|
-
* @param {Node} node - the node the 'ref' expression is referring to
|
|
19
|
-
* @param {import('./fx-bind').FxBind} bind - the fx-bind element having created this modelItem
|
|
20
|
-
* @param {string} instance - the fx-instance id having created this modelItem
|
|
21
|
-
*/
|
|
22
|
-
constructor(path, ref, readonly, relevant, required, constraint, type, node, bind,instance) {
|
|
23
9
|
/**
|
|
24
|
-
*
|
|
10
|
+
*
|
|
11
|
+
* @param {string} path calculated normalized path expression linking to data
|
|
12
|
+
* @param {string} ref relative binding expression
|
|
13
|
+
* @param {boolean} readonly - boolean to signal readonly/readwrite state
|
|
14
|
+
* @param {boolean} relevant - boolean to signal relevant/non-relevant state
|
|
15
|
+
* @param {boolean} required - boolean to signal required/optional state
|
|
16
|
+
* @param {boolean} constraint - boolean boolean to signal valid/invalid state
|
|
17
|
+
* @param {string} type - string expression to set a datatype
|
|
18
|
+
* @param {Node} node - the node the 'ref' expression is referring to
|
|
19
|
+
* @param {import('./fx-bind').FxBind} bind - the fx-bind element having created this modelItem
|
|
20
|
+
* @param {string} instance - the fx-instance id having created this modelItem
|
|
25
21
|
*/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
22
|
+
constructor(
|
|
23
|
+
path,
|
|
24
|
+
ref,
|
|
25
|
+
readonly,
|
|
26
|
+
relevant,
|
|
27
|
+
required,
|
|
28
|
+
constraint,
|
|
29
|
+
type,
|
|
30
|
+
node,
|
|
31
|
+
bind,
|
|
32
|
+
instance,
|
|
33
|
+
) {
|
|
34
|
+
/**
|
|
35
|
+
* @type {string}
|
|
36
|
+
*/
|
|
37
|
+
this.path = path;
|
|
38
|
+
/**
|
|
39
|
+
* @type {string}
|
|
40
|
+
*/
|
|
41
|
+
this.ref = ref;
|
|
42
|
+
/**
|
|
43
|
+
* @type {boolean}
|
|
44
|
+
*/
|
|
45
|
+
this.constraint = constraint;
|
|
46
|
+
/**
|
|
47
|
+
* @type {boolean}
|
|
48
|
+
*/
|
|
49
|
+
this.readonly = readonly;
|
|
50
|
+
/**
|
|
51
|
+
* @type {boolean}
|
|
52
|
+
*/
|
|
53
|
+
this.relevant = relevant;
|
|
54
|
+
/**
|
|
55
|
+
* @type {boolean}
|
|
56
|
+
*/
|
|
57
|
+
this.required = required;
|
|
58
|
+
/**
|
|
59
|
+
* @type {string}
|
|
60
|
+
*/
|
|
61
|
+
this.type = type;
|
|
62
|
+
/**
|
|
63
|
+
* @type {Node}
|
|
64
|
+
*/
|
|
65
|
+
this.node = node;
|
|
66
|
+
/**
|
|
67
|
+
* @type {import('./fx-bind').FxBind}
|
|
68
|
+
*/
|
|
69
|
+
this.bind = bind;
|
|
70
|
+
this.changed = false;
|
|
71
|
+
/**
|
|
72
|
+
* @type {import('./ui/fx-alert').FxAlert[]}
|
|
73
|
+
*/
|
|
74
|
+
this.alerts = [];
|
|
75
|
+
/**
|
|
76
|
+
* @type {import('./ui/abstract-control').default[]}
|
|
77
|
+
*/
|
|
78
|
+
this.boundControls = [];
|
|
79
|
+
// this.value = this._getValue();
|
|
80
|
+
this.instanceId = instance;
|
|
81
|
+
}
|
|
71
82
|
|
|
72
|
-
|
|
83
|
+
/*
|
|
73
84
|
get ref(){
|
|
74
85
|
return this.bind.ref;
|
|
75
86
|
}
|
|
76
87
|
*/
|
|
77
88
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
89
|
+
get value() {
|
|
90
|
+
if (!this.node) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
if (!this.node.nodeType) return this.node;
|
|
83
94
|
|
|
84
|
-
|
|
85
|
-
|
|
95
|
+
if (this.node.nodeType === Node.ATTRIBUTE_NODE) {
|
|
96
|
+
return this.node.nodeValue;
|
|
97
|
+
}
|
|
98
|
+
return this.node.textContent;
|
|
86
99
|
}
|
|
87
|
-
return this.node.textContent;
|
|
88
|
-
}
|
|
89
100
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
101
|
+
/**
|
|
102
|
+
* @param {Node} newVal
|
|
103
|
+
*/
|
|
104
|
+
set value(newVal) {
|
|
105
|
+
// console.log('modelitem.setvalue oldVal', this.value);
|
|
106
|
+
// console.log('modelitem.setvalue newVal', newVal);
|
|
96
107
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
if (newVal.nodeType === Node.DOCUMENT_NODE) {
|
|
109
|
+
this.node.replaceWith(newVal.firstElementChild);
|
|
110
|
+
this.node = newVal.firstElementChild;
|
|
111
|
+
// this.node.appendChild(newVal.firstElementChild);
|
|
112
|
+
} else if (newVal.nodeType === Node.ELEMENT_NODE) {
|
|
113
|
+
this.node.replaceWith(newVal);
|
|
114
|
+
this.node = newVal;
|
|
115
|
+
// this.node.appendChild(newVal);
|
|
116
|
+
} else if (this.node.nodeType === Node.ATTRIBUTE_NODE) {
|
|
117
|
+
this.node.nodeValue = newVal;
|
|
118
|
+
} else {
|
|
119
|
+
this.node.textContent = newVal;
|
|
120
|
+
}
|
|
109
121
|
}
|
|
110
|
-
}
|
|
111
122
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
123
|
+
addAlert(alert) {
|
|
124
|
+
if (!this.alerts.includes(alert)) {
|
|
125
|
+
this.alerts.push(alert);
|
|
126
|
+
}
|
|
115
127
|
}
|
|
116
|
-
}
|
|
117
128
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
129
|
+
cleanAlerts() {
|
|
130
|
+
this.alerts = [];
|
|
131
|
+
}
|
|
121
132
|
}
|