@jinntec/fore 1.2.0 → 1.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/dist/fore-dev.js +8 -8
- package/dist/fore-dev.js.map +1 -1
- package/dist/fore.js +7 -7
- package/dist/fore.js.map +1 -1
- package/index.js +1 -0
- package/package.json +2 -2
- package/resources/fore.css +95 -72
- package/src/actions/abstract-action.js +48 -6
- package/src/actions/fx-action.js +1 -2
- package/src/actions/fx-confirm.js +2 -2
- package/src/actions/fx-delete.js +53 -62
- package/src/actions/fx-hide.js +3 -1
- package/src/actions/fx-message.js +25 -1
- package/src/actions/fx-reload.js +30 -0
- package/src/actions/fx-send.js +11 -1
- package/src/actions/fx-setfocus.js +32 -5
- package/src/actions/fx-setvalue.js +4 -4
- package/src/actions/fx-show.js +1 -0
- package/src/actions/fx-toggle.js +5 -0
- package/src/events.js +24 -0
- package/src/fore.js +71 -8
- package/src/fx-bind.js +1 -1
- package/src/fx-fore.js +65 -14
- package/src/fx-instance.js +33 -8
- package/src/fx-model.js +435 -441
- package/src/fx-submission.js +76 -62
- package/src/getInScopeContext.js +91 -83
- package/src/modelitem.js +2 -2
- package/src/relevance.js +1 -1
- package/src/ui/abstract-control.js +108 -22
- package/src/ui/fx-alert.js +0 -1
- package/src/ui/fx-container.js +22 -26
- package/src/ui/fx-control.js +84 -34
- package/src/ui/fx-group.js +5 -0
- package/src/ui/fx-inspector.js +5 -0
- package/src/ui/fx-output.js +14 -14
- package/src/ui/fx-repeat.js +2 -2
- package/src/ui/fx-repeatitem.js +5 -3
- package/src/ui/fx-switch.js +11 -7
- package/src/ui/fx-trigger.js +15 -9
- package/src/xpath-evaluation.js +28 -17
- package/src/xpath-util.js +13 -0
|
@@ -3,7 +3,7 @@ import {resolveId} from "../xpath-evaluation";
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* `fx-setfocus`
|
|
6
|
-
* Set the focus to a target control.
|
|
6
|
+
* Set the focus to a target control optionally selecting eventual value in case a `select` attribute is given.
|
|
7
7
|
*
|
|
8
8
|
* @customElement
|
|
9
9
|
*/
|
|
@@ -16,22 +16,49 @@ export class FxSetfocus extends AbstractAction {
|
|
|
16
16
|
perform() {
|
|
17
17
|
console.log('setting focus', this.control);
|
|
18
18
|
// super.perform();
|
|
19
|
-
|
|
20
|
-
// const targetElement = resolveId(this.control, this);
|
|
21
19
|
const selector = '#'+this.control;
|
|
22
|
-
|
|
20
|
+
|
|
21
|
+
let targetElement = this.getOwnerForm().querySelector(selector);;
|
|
22
|
+
|
|
23
|
+
// ### focus action is itself hosted within a repeat
|
|
24
|
+
const parentIItem = this.closest('fx-repeatitem');
|
|
25
|
+
if(parentIItem){
|
|
26
|
+
console.log('parentRepeat',parentIItem);
|
|
27
|
+
targetElement = parentIItem.querySelector(selector);
|
|
28
|
+
this._focus(targetElement);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ### the target element is hosted within a repeat
|
|
23
33
|
const repeatitem = targetElement.closest('fx-repeatitem, .fx-repeatitem');
|
|
24
34
|
if(repeatitem){
|
|
25
35
|
// targetElement is repeated
|
|
26
36
|
// get the active repeatitem (only for fx-repeat for now - todo: support repeat attributes
|
|
27
37
|
const repeat = repeatitem.parentNode;
|
|
28
38
|
targetElement = repeat.querySelector('[repeat-index] ' + selector);
|
|
39
|
+
}
|
|
29
40
|
|
|
41
|
+
this._focus(targetElement);
|
|
42
|
+
if(this.hasAttribute('select')){
|
|
43
|
+
this._select(targetElement);
|
|
30
44
|
}
|
|
31
|
-
targetElement.getWidget().focus();
|
|
32
45
|
}
|
|
46
|
+
|
|
47
|
+
_focus(targetElement){
|
|
48
|
+
if(targetElement){
|
|
49
|
+
targetElement.getWidget().focus();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
_select(targetElement){
|
|
54
|
+
if(targetElement){
|
|
55
|
+
targetElement.getWidget().select();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
33
59
|
}
|
|
34
60
|
|
|
61
|
+
|
|
35
62
|
if (!customElements.get('fx-setfocus')) {
|
|
36
63
|
window.customElements.define('fx-setfocus', FxSetfocus);
|
|
37
64
|
}
|
|
@@ -52,16 +52,17 @@ export default class FxSetvalue extends AbstractAction {
|
|
|
52
52
|
}
|
|
53
53
|
console.log('value', value);
|
|
54
54
|
if (value.nodeType === Node.ATTRIBUTE_NODE) {
|
|
55
|
-
console.log('value', value.nodeValue);
|
|
55
|
+
// console.log('value', value.nodeValue);
|
|
56
56
|
value = value.nodeValue;
|
|
57
57
|
}
|
|
58
58
|
const mi = this.getModelItem();
|
|
59
59
|
this.setValue(mi, value);
|
|
60
|
+
// todo: check this again - logically needsUpate should be set but makes tests fail
|
|
61
|
+
// this.needsUpdate = true;
|
|
62
|
+
|
|
60
63
|
}
|
|
61
64
|
|
|
62
65
|
setValue(modelItem, newVal) {
|
|
63
|
-
console.log('setvalue[1] ', modelItem, newVal);
|
|
64
|
-
|
|
65
66
|
const item = modelItem;
|
|
66
67
|
if (!item) return;
|
|
67
68
|
|
|
@@ -69,7 +70,6 @@ export default class FxSetvalue extends AbstractAction {
|
|
|
69
70
|
item.value = newVal;
|
|
70
71
|
this.getModel().changed.push(modelItem);
|
|
71
72
|
this.needsUpdate = true;
|
|
72
|
-
console.log('setvalue[2] ', item, newVal);
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
}
|
package/src/actions/fx-show.js
CHANGED
package/src/actions/fx-toggle.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AbstractAction } from './abstract-action.js';
|
|
2
|
+
import {Fore} from "../fore";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* `fx-toggle`
|
|
@@ -24,6 +25,10 @@ class FxToggle extends AbstractAction {
|
|
|
24
25
|
if (this.case) {
|
|
25
26
|
const ownerForm = this.getOwnerForm();
|
|
26
27
|
const caseElement = ownerForm.querySelector(`#${this.case}`);
|
|
28
|
+
if(!caseElement){
|
|
29
|
+
Fore.dispatch(this, 'error', { message: `fx-case id not found: ${this.case}` });
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
27
32
|
const fxSwitch = caseElement.parentNode;
|
|
28
33
|
fxSwitch.toggle(caseElement);
|
|
29
34
|
}
|
package/src/events.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export function leadingDebounce(caller, func, timeout = 300){
|
|
2
|
+
console.log('debouncing', func);
|
|
3
|
+
let timer;
|
|
4
|
+
return (...args) => {
|
|
5
|
+
if (!timer) {
|
|
6
|
+
func.apply(caller, args);
|
|
7
|
+
}
|
|
8
|
+
clearTimeout(timer);
|
|
9
|
+
timer = setTimeout(() => {
|
|
10
|
+
timer = undefined;
|
|
11
|
+
return null;
|
|
12
|
+
}, timeout);
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function debounce(caller, func, timeout = 300) {
|
|
17
|
+
let timer;
|
|
18
|
+
return (...args) => {
|
|
19
|
+
clearTimeout(timer);
|
|
20
|
+
timer = setTimeout(() => {
|
|
21
|
+
func.apply(caller, args);
|
|
22
|
+
}, timeout);
|
|
23
|
+
};
|
|
24
|
+
}
|
package/src/fore.js
CHANGED
|
@@ -11,6 +11,7 @@ export class Fore {
|
|
|
11
11
|
|
|
12
12
|
static get ACTION_ELEMENTS() {
|
|
13
13
|
return [
|
|
14
|
+
'FX-ACTION',
|
|
14
15
|
'FX-DELETE',
|
|
15
16
|
'FX-DISPATCH',
|
|
16
17
|
'FX-HIDE',
|
|
@@ -21,6 +22,7 @@ export class Fore {
|
|
|
21
22
|
'FX-RECALCULATE',
|
|
22
23
|
'FX-REFRESH',
|
|
23
24
|
'FX-RENEW',
|
|
25
|
+
'FX-RELOAD',
|
|
24
26
|
'FX-REPLACE',
|
|
25
27
|
'FX-RESET',
|
|
26
28
|
'FX-RETAIN',
|
|
@@ -64,16 +66,12 @@ export class Fore {
|
|
|
64
66
|
return [
|
|
65
67
|
'FX-ALERT',
|
|
66
68
|
'FX-CONTROL',
|
|
67
|
-
'FX-BUTTON',
|
|
68
|
-
'FX-CONTROL',
|
|
69
69
|
'FX-DIALOG',
|
|
70
70
|
'FX-FILENAME',
|
|
71
71
|
'FX-MEDIATYPE',
|
|
72
72
|
'FX-GROUP',
|
|
73
73
|
'FX-HINT',
|
|
74
|
-
'FX-INPUT',
|
|
75
74
|
'FX-ITEMS',
|
|
76
|
-
'FX-LABEL',
|
|
77
75
|
'FX-OUTPUT',
|
|
78
76
|
'FX-RANGE',
|
|
79
77
|
'FX-REPEAT',
|
|
@@ -89,6 +87,16 @@ export class Fore {
|
|
|
89
87
|
];
|
|
90
88
|
}
|
|
91
89
|
|
|
90
|
+
static get MODEL_ELEMENTS(){
|
|
91
|
+
return [
|
|
92
|
+
'FX-BIND',
|
|
93
|
+
'FX-FUNCTION',
|
|
94
|
+
'FX-MODEL',
|
|
95
|
+
'FX-INSTANCE',
|
|
96
|
+
'FX-SUBMISSION',
|
|
97
|
+
];
|
|
98
|
+
}
|
|
99
|
+
|
|
92
100
|
static isUiElement(elementName) {
|
|
93
101
|
const found = Fore.UI_ELEMENTS.includes(elementName);
|
|
94
102
|
if (found) {
|
|
@@ -133,7 +141,7 @@ export class Fore {
|
|
|
133
141
|
if (Fore.isUiElement(element.nodeName) && typeof element.refresh === 'function') {
|
|
134
142
|
// console.log('refreshing', element, element?.ref);
|
|
135
143
|
// console.log('refreshing ',element);
|
|
136
|
-
element.refresh();
|
|
144
|
+
element.refresh(force);
|
|
137
145
|
} else if (element.nodeName.toUpperCase() !== 'FX-MODEL') {
|
|
138
146
|
Fore.refreshChildren(element, force);
|
|
139
147
|
}
|
|
@@ -145,6 +153,61 @@ export class Fore {
|
|
|
145
153
|
return refreshed;
|
|
146
154
|
}
|
|
147
155
|
|
|
156
|
+
static copyDom(inputElement){
|
|
157
|
+
console.time('convert');
|
|
158
|
+
const target = new DOMParser().parseFromString('<fx-fore></fx-fore>', 'text/html');
|
|
159
|
+
console.log('copyDom new doc',target);
|
|
160
|
+
console.log('copyDom new body',target.body);
|
|
161
|
+
console.log('copyDom new body',target.querySelector('fx-fore'));
|
|
162
|
+
const newFore = target.querySelector('fx-fore');
|
|
163
|
+
this.convertFromSimple(inputElement,newFore);
|
|
164
|
+
newFore.removeAttribute('convert');
|
|
165
|
+
console.log('converted', newFore);
|
|
166
|
+
return newFore;
|
|
167
|
+
console.timeEnd('convert');
|
|
168
|
+
}
|
|
169
|
+
static convertFromSimple(startElement,targetElement){
|
|
170
|
+
const children = startElement.childNodes;
|
|
171
|
+
if (children) {
|
|
172
|
+
Array.from(children).forEach(node => {
|
|
173
|
+
const lookFor = `FX-${node.nodeName.toUpperCase()}`;
|
|
174
|
+
if (Fore.MODEL_ELEMENTS.includes(lookFor)
|
|
175
|
+
|| Fore.UI_ELEMENTS.includes(lookFor)
|
|
176
|
+
|| Fore.ACTION_ELEMENTS.includes(lookFor)
|
|
177
|
+
) {
|
|
178
|
+
const conv = targetElement.ownerDocument.createElement(lookFor);
|
|
179
|
+
console.log('conv', node, conv);
|
|
180
|
+
targetElement.appendChild(conv);
|
|
181
|
+
Fore.copyAttributes(node,conv);
|
|
182
|
+
Fore.convertFromSimple(node,conv);
|
|
183
|
+
} else{
|
|
184
|
+
|
|
185
|
+
if(node.nodeType === Node.TEXT_NODE){
|
|
186
|
+
const copied = targetElement.ownerDocument.createTextNode(node.textContent);
|
|
187
|
+
targetElement.appendChild(copied);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if(node.nodeType === Node.ELEMENT_NODE){
|
|
191
|
+
const copied = targetElement.ownerDocument.createElement(node.nodeName);
|
|
192
|
+
targetElement.appendChild(copied);
|
|
193
|
+
Fore.copyAttributes(node,targetElement);
|
|
194
|
+
Fore.convertFromSimple(node,copied);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
static copyAttributes(source, target) {
|
|
202
|
+
return Array.from(source.attributes).forEach(attribute => {
|
|
203
|
+
target.setAttribute(
|
|
204
|
+
attribute.nodeName,
|
|
205
|
+
attribute.nodeValue,
|
|
206
|
+
);
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
|
|
148
211
|
/**
|
|
149
212
|
* Alternative to `closest` that respects subcontrol boundaries
|
|
150
213
|
*/
|
|
@@ -168,8 +231,8 @@ export class Fore {
|
|
|
168
231
|
* @param instance an fx-instance element
|
|
169
232
|
* @returns {string|null}
|
|
170
233
|
*/
|
|
171
|
-
static getContentType(instance,
|
|
172
|
-
if (
|
|
234
|
+
static getContentType(instance, contentType) {
|
|
235
|
+
if (contentType === 'application/x-www-form-urlencoded') {
|
|
173
236
|
return 'application/x-www-form-urlencoded; charset=UTF-8';
|
|
174
237
|
}
|
|
175
238
|
if (instance.type === 'xml') {
|
|
@@ -228,7 +291,7 @@ export class Fore {
|
|
|
228
291
|
bubbles: true,
|
|
229
292
|
detail,
|
|
230
293
|
});
|
|
231
|
-
console.
|
|
294
|
+
console.info('dispatching', event.type, target);
|
|
232
295
|
target.dispatchEvent(event);
|
|
233
296
|
}
|
|
234
297
|
|
package/src/fx-bind.js
CHANGED
|
@@ -61,7 +61,7 @@ export class FxBind extends foreElementMixin(HTMLElement) {
|
|
|
61
61
|
*/
|
|
62
62
|
init(model) {
|
|
63
63
|
this.model = model;
|
|
64
|
-
console.log('init binding ', this);
|
|
64
|
+
// console.log('init binding ', this);
|
|
65
65
|
this.instanceId = this._getInstanceId();
|
|
66
66
|
this.bindType = this.getModel().getInstance(this.instanceId).type;
|
|
67
67
|
// console.log('binding type ', this.bindType);
|
package/src/fx-fore.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import {Fore} from './fore.js';
|
|
2
2
|
import './fx-instance.js';
|
|
3
|
-
import './fx-model.js';
|
|
3
|
+
import {FxModel} from './fx-model.js';
|
|
4
4
|
import '@jinntec/jinn-toast';
|
|
5
|
-
import {evaluateXPathToNodes, evaluateXPathToString} from './xpath-evaluation.js';
|
|
5
|
+
import {evaluateXPathToBoolean, evaluateXPathToNodes, evaluateXPathToString} from './xpath-evaluation.js';
|
|
6
6
|
import getInScopeContext from './getInScopeContext.js';
|
|
7
7
|
import {XPathUtil} from './xpath-util.js';
|
|
8
|
+
import {AbstractAction} from "./actions/abstract-action";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Main class for Fore.Outermost container element for each Fore application.
|
|
@@ -181,6 +182,8 @@ export class FxFore extends HTMLElement {
|
|
|
181
182
|
}
|
|
182
183
|
|
|
183
184
|
connectedCallback() {
|
|
185
|
+
this.style.visibility = 'hidden';
|
|
186
|
+
|
|
184
187
|
/*
|
|
185
188
|
document.addEventListener('ready', (e) =>{
|
|
186
189
|
if(e.target !== this){
|
|
@@ -218,6 +221,14 @@ export class FxFore extends HTMLElement {
|
|
|
218
221
|
|
|
219
222
|
const slot = this.shadowRoot.querySelector('slot');
|
|
220
223
|
slot.addEventListener('slotchange', event => {
|
|
224
|
+
|
|
225
|
+
// preliminary addition for auto-conversion of non-prefixed element into prefixed elements. See fore.js
|
|
226
|
+
if(this.hasAttribute('convert')){
|
|
227
|
+
this.replaceWith(Fore.copyDom(this));
|
|
228
|
+
// Fore.copyDom(this);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
|
|
221
232
|
const children = event.target.assignedElements();
|
|
222
233
|
let modelElement = children.find(
|
|
223
234
|
modelElem => modelElem.nodeName.toUpperCase() === 'FX-MODEL',
|
|
@@ -228,9 +239,11 @@ export class FxFore extends HTMLElement {
|
|
|
228
239
|
modelElement = generatedModel;
|
|
229
240
|
}
|
|
230
241
|
if (!modelElement.inited) {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
242
|
+
console.info(
|
|
243
|
+
`%cFore is processing URL ${window.location.href}`,
|
|
244
|
+
"background:#64b5f6; color:white; padding:1rem; display:inline-block; white-space: nowrap; border-radius:0.3rem;width:100%;",
|
|
245
|
+
);
|
|
246
|
+
|
|
234
247
|
if (this.src) {
|
|
235
248
|
console.log('########## FORE: loaded from ... ', this.src, '##########');
|
|
236
249
|
}
|
|
@@ -239,7 +252,7 @@ export class FxFore extends HTMLElement {
|
|
|
239
252
|
this.model = modelElement;
|
|
240
253
|
});
|
|
241
254
|
this.addEventListener('path-mutated', e => {
|
|
242
|
-
console.log('path-mutated event received', e.detail.path, e.detail.index);
|
|
255
|
+
// console.log('path-mutated event received', e.detail.path, e.detail.index);
|
|
243
256
|
this.someInstanceDataStructureChanged = true;
|
|
244
257
|
});
|
|
245
258
|
}
|
|
@@ -375,7 +388,8 @@ export class FxFore extends HTMLElement {
|
|
|
375
388
|
|
|
376
389
|
async refresh(force) {
|
|
377
390
|
// refresh () {
|
|
378
|
-
console.
|
|
391
|
+
console.info('%crefresh','font-style: italic; background: #8bc34a; color:white; padding:0.3rem 5rem 0.3rem 0.3rem; display:block; width:100%;');
|
|
392
|
+
console.group('refresh', force);
|
|
379
393
|
|
|
380
394
|
console.time('refresh');
|
|
381
395
|
|
|
@@ -393,7 +407,7 @@ export class FxFore extends HTMLElement {
|
|
|
393
407
|
const controlsToRefresh = modelItem.boundControls;
|
|
394
408
|
if (controlsToRefresh) {
|
|
395
409
|
controlsToRefresh.forEach(ctrl => {
|
|
396
|
-
ctrl.refresh();
|
|
410
|
+
ctrl.refresh(force);
|
|
397
411
|
});
|
|
398
412
|
}
|
|
399
413
|
|
|
@@ -409,7 +423,7 @@ export class FxFore extends HTMLElement {
|
|
|
409
423
|
const modelItemOfDep = this.getModel().modelItems.find(mip => mip.path === basePath);
|
|
410
424
|
// ### refresh all boundControls
|
|
411
425
|
modelItemOfDep.boundControls.forEach(control => {
|
|
412
|
-
control.refresh();
|
|
426
|
+
control.refresh(force);
|
|
413
427
|
});
|
|
414
428
|
});
|
|
415
429
|
needsRefresh = true;
|
|
@@ -418,7 +432,7 @@ export class FxFore extends HTMLElement {
|
|
|
418
432
|
});
|
|
419
433
|
this.toRefresh = [];
|
|
420
434
|
if (!needsRefresh) {
|
|
421
|
-
console.log('
|
|
435
|
+
console.log('no dependants to refresh');
|
|
422
436
|
}
|
|
423
437
|
} else {
|
|
424
438
|
Fore.refreshChildren(this, true);
|
|
@@ -437,6 +451,8 @@ export class FxFore extends HTMLElement {
|
|
|
437
451
|
console.groupEnd();
|
|
438
452
|
// console.log('### <<<<< dispatching refresh-done - end of UI update cycle >>>>>');
|
|
439
453
|
// this.dispatchEvent(new CustomEvent('refresh-done'));
|
|
454
|
+
// this.initialRun = false;
|
|
455
|
+
this.style.visibility='visible';
|
|
440
456
|
Fore.dispatch(this, 'refresh-done', {});
|
|
441
457
|
}
|
|
442
458
|
|
|
@@ -449,9 +465,8 @@ export class FxFore extends HTMLElement {
|
|
|
449
465
|
* @private
|
|
450
466
|
*/
|
|
451
467
|
_updateTemplateExpressions() {
|
|
452
|
-
// Note the fact we're going over HTML here: therefore the `html` prefix.
|
|
453
468
|
const search =
|
|
454
|
-
"(descendant-or-self
|
|
469
|
+
"(descendant-or-self::*!(text(), @*))[contains(., '{')][substring-after(., '{') => contains('}')][not(ancestor-or-self::fx-model)]";
|
|
455
470
|
|
|
456
471
|
const tmplExpressions = evaluateXPathToNodes(search, this, this);
|
|
457
472
|
// console.log('template expressions found ', tmplExpressions);
|
|
@@ -557,6 +572,38 @@ export class FxFore extends HTMLElement {
|
|
|
557
572
|
* @private
|
|
558
573
|
*/
|
|
559
574
|
_handleModelConstructDone() {
|
|
575
|
+
/*
|
|
576
|
+
listening on beforeunload after model is constructed - this is to be able to evaluate a condition on the data
|
|
577
|
+
that specifies whether or not to show confirmation.
|
|
578
|
+
*/
|
|
579
|
+
if(this.hasAttribute('show-confirmation')){
|
|
580
|
+
const condition = this.getAttribute('show-confirmation');
|
|
581
|
+
if(condition
|
|
582
|
+
&& condition !== 'show-confirmation'
|
|
583
|
+
&& condition !== 'true'
|
|
584
|
+
&& condition !== ''){
|
|
585
|
+
window.addEventListener('beforeunload', event => {
|
|
586
|
+
const mustDisplay = evaluateXPathToBoolean(showConfirm, this.getModel().getDefaultContext(), this)
|
|
587
|
+
if(mustDisplay){
|
|
588
|
+
console.log('have to display confirmation')
|
|
589
|
+
return event.returnValue = 'are you sure';
|
|
590
|
+
}
|
|
591
|
+
event.preventDefault();
|
|
592
|
+
console.log('do not display confirmation')
|
|
593
|
+
})
|
|
594
|
+
}else{
|
|
595
|
+
window.addEventListener('beforeunload', event => {
|
|
596
|
+
// if(AbstractAction.dataChanged){
|
|
597
|
+
if(FxModel.dataChanged){
|
|
598
|
+
console.log('have to display confirmation')
|
|
599
|
+
return event.returnValue = 'are you sure';
|
|
600
|
+
}
|
|
601
|
+
event.preventDefault();
|
|
602
|
+
console.log('do not display confirmation')
|
|
603
|
+
})
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
560
607
|
this._initUI();
|
|
561
608
|
}
|
|
562
609
|
|
|
@@ -708,9 +755,13 @@ export class FxFore extends HTMLElement {
|
|
|
708
755
|
this.ready = true;
|
|
709
756
|
this.initialRun = false;
|
|
710
757
|
// console.log('### >>>>> dispatching ready >>>>>', this);
|
|
711
|
-
console.log('### modelItems: ', this.getModel().modelItems);
|
|
712
|
-
console.log('### <<<<< FORE: form fully initialized...', this);
|
|
758
|
+
// console.log('### modelItems: ', this.getModel().modelItems);
|
|
713
759
|
Fore.dispatch(this, 'ready', {});
|
|
760
|
+
console.info(
|
|
761
|
+
`%cPage Initialization done`,
|
|
762
|
+
"background:#64b5f6; color:white; padding:1rem; display:block; white-space: nowrap; border-radius:0.3rem;width:100%;",
|
|
763
|
+
);
|
|
764
|
+
console.log('dataChanged', FxModel.dataChanged);
|
|
714
765
|
}
|
|
715
766
|
|
|
716
767
|
registerLazyElement(element) {
|
package/src/fx-instance.js
CHANGED
|
@@ -84,14 +84,14 @@ export class FxInstance extends HTMLElement {
|
|
|
84
84
|
*/
|
|
85
85
|
getInstanceData() {
|
|
86
86
|
if (!this.instanceData) {
|
|
87
|
-
this.
|
|
87
|
+
this.createInstanceData();
|
|
88
88
|
}
|
|
89
89
|
return this.instanceData;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
setInstanceData(data) {
|
|
93
93
|
if (!data) {
|
|
94
|
-
this.
|
|
94
|
+
this.createInstanceData();
|
|
95
95
|
return;
|
|
96
96
|
}
|
|
97
97
|
this.instanceData = data;
|
|
@@ -142,7 +142,7 @@ export class FxInstance extends HTMLElement {
|
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
|
|
145
|
+
createInstanceData() {
|
|
146
146
|
if (this.type === 'xml') {
|
|
147
147
|
// const doc = new DOMParser().parseFromString('<data data-id="default"></data>', 'application/xml');
|
|
148
148
|
const doc = new DOMParser().parseFromString('<data></data>', 'application/xml');
|
|
@@ -157,6 +157,31 @@ export class FxInstance extends HTMLElement {
|
|
|
157
157
|
const url = `${this.src}`;
|
|
158
158
|
const contentType = Fore.getContentType(this, 'get');
|
|
159
159
|
|
|
160
|
+
if(url.startsWith('localStore')){
|
|
161
|
+
const key = url.substring(url.indexOf(':')+1);
|
|
162
|
+
|
|
163
|
+
const doc = new DOMParser().parseFromString('<data></data>', 'application/xml');
|
|
164
|
+
const root = doc.firstElementChild;
|
|
165
|
+
this.instanceData = doc;
|
|
166
|
+
|
|
167
|
+
if(!key){
|
|
168
|
+
console.warn('no key specified for localStore');
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const serialized = localStorage.getItem(key);
|
|
173
|
+
if(!serialized){
|
|
174
|
+
console.warn(`Data for key ${key} cannot be found`);
|
|
175
|
+
this._useInlineData();
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const data = new DOMParser().parseFromString(serialized, 'application/xml');
|
|
179
|
+
// let data = this._parse(serialized, instance);
|
|
180
|
+
// root.appendChild(data);
|
|
181
|
+
doc.firstElementChild.replaceWith(data.firstElementChild);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
160
185
|
await fetch(url, {
|
|
161
186
|
method: 'GET',
|
|
162
187
|
mode: 'cors',
|
|
@@ -168,12 +193,12 @@ export class FxInstance extends HTMLElement {
|
|
|
168
193
|
.then(response => {
|
|
169
194
|
const { status } = response;
|
|
170
195
|
if (status >= 400) {
|
|
171
|
-
console.log('response status', status);
|
|
196
|
+
// console.log('response status', status);
|
|
172
197
|
alert(`response status: ${status} - failed to load data for '${this.src}' - stopping.`);
|
|
173
198
|
throw new Error(`failed to load data - status: ${status}`);
|
|
174
199
|
}
|
|
175
200
|
const responseContentType = response.headers.get('content-type').toLowerCase();
|
|
176
|
-
console.log('********** responseContentType *********', responseContentType);
|
|
201
|
+
// console.log('********** responseContentType *********', responseContentType);
|
|
177
202
|
if (responseContentType.startsWith('text/html')) {
|
|
178
203
|
// const htmlResponse = response.text();
|
|
179
204
|
// return new DOMParser().parseFromString(htmlResponse, 'text/html');
|
|
@@ -205,7 +230,7 @@ export class FxInstance extends HTMLElement {
|
|
|
205
230
|
.then(data => {
|
|
206
231
|
if (data.nodeType) {
|
|
207
232
|
this.instanceData = data;
|
|
208
|
-
console.log('instanceData loaded: ', this.instanceData);
|
|
233
|
+
console.log('instanceData loaded: ', this.id, this.instanceData);
|
|
209
234
|
return;
|
|
210
235
|
}
|
|
211
236
|
this.instanceData = data;
|
|
@@ -231,12 +256,12 @@ export class FxInstance extends HTMLElement {
|
|
|
231
256
|
// console.log('innerHTML ', this.innerHTML);
|
|
232
257
|
const instanceData = new DOMParser().parseFromString(this.innerHTML, 'application/xml');
|
|
233
258
|
|
|
234
|
-
console.log('fx-instance init id:', this.id);
|
|
259
|
+
// console.log('fx-instance init id:', this.id);
|
|
235
260
|
this.instanceData = instanceData;
|
|
236
261
|
// console.log('instanceData ', this.instanceData);
|
|
237
262
|
// console.log('instanceData ', this.instanceData.firstElementChild);
|
|
238
263
|
|
|
239
|
-
console.log('fx-instance data: ', this.instanceData);
|
|
264
|
+
// console.log('fx-instance data: ', this.instanceData);
|
|
240
265
|
// this.instanceData.firstElementChild.setAttribute('id', this.id);
|
|
241
266
|
// todo: move innerHTML out to shadowDOM (for later reset)
|
|
242
267
|
} else if (this.type === 'json') {
|