@jinntec/fore 1.7.2 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -7
- package/dist/fore-dev.js +2 -2
- package/dist/fore-dev.js.map +1 -1
- package/dist/fore.js +2 -2
- package/dist/fore.js.map +1 -1
- package/index.js +1 -0
- package/package.json +7 -2
- package/src/actions/fx-call.js +74 -0
- package/src/fx-fore.js +25 -5
- package/src/fx-instance.js +14 -5
- package/src/fx-submission.js +54 -146
- package/src/ui/fx-control.js +17 -6
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jinntec/fore",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Fore - declarative user interfaces in plain HTML",
|
|
5
5
|
"module": "./index.js",
|
|
6
6
|
"publishConfig": {
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"fontoxpath": "^3.30.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
+
"@types/cypress": "^1.1.3",
|
|
37
38
|
"@babel/plugin-proposal-class-properties": "^7.17.12",
|
|
38
39
|
"@open-wc/building-rollup": "^2.0.1",
|
|
39
40
|
"@open-wc/eslint-config": "^7.0.0",
|
|
@@ -47,6 +48,7 @@
|
|
|
47
48
|
"@rollup/plugin-strip": "^2.1.0",
|
|
48
49
|
"@skypack/package-check": "^0.2.2",
|
|
49
50
|
"@webcomponents/webcomponentsjs": "^2.6.0",
|
|
51
|
+
"cypress": "^13.3.0",
|
|
50
52
|
"deepmerge": "^4.2.2",
|
|
51
53
|
"es-dev-server": "^2.1.0",
|
|
52
54
|
"eslint": "^8.16.0",
|
|
@@ -82,7 +84,10 @@
|
|
|
82
84
|
"start:build": "cd dist && es-dev-server --open",
|
|
83
85
|
"build": "rimraf dist && rollup -c rollup.config.js",
|
|
84
86
|
"start": "es-dev-server --app-index doc/index.html --node-resolve --watch --open",
|
|
85
|
-
"
|
|
87
|
+
"preversion": "npm run test",
|
|
88
|
+
"prepare": "npm run build",
|
|
89
|
+
"install-demos": "npm i && cd demo && npm i",
|
|
90
|
+
"start-cypress": "es-dev-server --app-index doc/index.html --node-resolve"
|
|
86
91
|
},
|
|
87
92
|
"keywords": [
|
|
88
93
|
"Fore",
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import '../fx-model.js';
|
|
2
|
+
import {AbstractAction} from './abstract-action.js';
|
|
3
|
+
import {evaluateXPath, evaluateXPathToString} from "../xpath-evaluation.js";
|
|
4
|
+
import {Fore} from "../fore";
|
|
5
|
+
import getInScopeContext from "../getInScopeContext";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* `fx-call`
|
|
9
|
+
*
|
|
10
|
+
* @customElement
|
|
11
|
+
*/
|
|
12
|
+
export default class FxCall extends AbstractAction {
|
|
13
|
+
static get properties() {
|
|
14
|
+
return {
|
|
15
|
+
...super.properties,
|
|
16
|
+
action: {
|
|
17
|
+
type: String,
|
|
18
|
+
},
|
|
19
|
+
fn: {
|
|
20
|
+
type: String,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
constructor() {
|
|
26
|
+
super();
|
|
27
|
+
this.action = '';
|
|
28
|
+
this.fn = '';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
connectedCallback() {
|
|
32
|
+
if (super.connectedCallback) {
|
|
33
|
+
super.connectedCallback();
|
|
34
|
+
}
|
|
35
|
+
if (this.hasAttribute('action')) {
|
|
36
|
+
this.action = this.getAttribute('action');
|
|
37
|
+
} else if(this.hasAttribute('function')){
|
|
38
|
+
this.fn = this.getAttribute('function');
|
|
39
|
+
|
|
40
|
+
}else{
|
|
41
|
+
throw new Error('fx-call must specify an "action" or "function" attribute');
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async perform() {
|
|
46
|
+
super.perform();
|
|
47
|
+
if(this.action){
|
|
48
|
+
await this._callAction();
|
|
49
|
+
}
|
|
50
|
+
// execute function
|
|
51
|
+
if(this.fn){
|
|
52
|
+
this._callFunction();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* find action and execute it
|
|
58
|
+
*/
|
|
59
|
+
async _callAction(){
|
|
60
|
+
const action = document.querySelector(`#${this.action}`);
|
|
61
|
+
if(action){
|
|
62
|
+
await action.perform();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
_callFunction(){
|
|
67
|
+
const inscope = getInScopeContext(this, 'instance()',this);
|
|
68
|
+
evaluateXPath(this.fn, inscope, this);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!customElements.get('fx-call')) {
|
|
73
|
+
window.customElements.define('fx-call', FxCall);
|
|
74
|
+
}
|
package/src/fx-fore.js
CHANGED
|
@@ -29,6 +29,12 @@ export class FxFore extends HTMLElement {
|
|
|
29
29
|
|
|
30
30
|
static get properties() {
|
|
31
31
|
return {
|
|
32
|
+
/**
|
|
33
|
+
* ignore certain nodes for template expression search
|
|
34
|
+
*/
|
|
35
|
+
ignoreExpressions:{
|
|
36
|
+
type: String
|
|
37
|
+
},
|
|
32
38
|
/**
|
|
33
39
|
* merge-partial
|
|
34
40
|
*/
|
|
@@ -173,8 +179,8 @@ export class FxFore extends HTMLElement {
|
|
|
173
179
|
|
|
174
180
|
<jinn-toast id="message" gravity="bottom" position="left"></jinn-toast>
|
|
175
181
|
<jinn-toast id="sticky" gravity="bottom" position="left" duration="-1" close="true" data-class="sticky-message"></jinn-toast>
|
|
176
|
-
<jinn-toast id="error" text="error" duration="-1" data-class="error" close="true" position="
|
|
177
|
-
<jinn-toast id="warn" text="warning" duration="
|
|
182
|
+
<jinn-toast id="error" text="error" duration="-1" data-class="error" close="true" position="right" gravity="top" escape-markup="false"></jinn-toast>
|
|
183
|
+
<jinn-toast id="warn" text="warning" duration="5000" data-class="warning" position="left" gravity="top"></jinn-toast>
|
|
178
184
|
<slot id="default"></slot>
|
|
179
185
|
<slot name="messages"></slot>
|
|
180
186
|
<div id="modalMessage" class="overlay">
|
|
@@ -225,6 +231,7 @@ export class FxFore extends HTMLElement {
|
|
|
225
231
|
// e.stopImmediatePropagation();
|
|
226
232
|
},true);
|
|
227
233
|
*/
|
|
234
|
+
this.ignoreExpressions = this.hasAttribute('ignore-expressions') ? this.getAttribute('ignore-expressions'): null;
|
|
228
235
|
|
|
229
236
|
this.lazyRefresh = this.hasAttribute('refresh-on-view');
|
|
230
237
|
if (this.lazyRefresh) {
|
|
@@ -254,6 +261,10 @@ export class FxFore extends HTMLElement {
|
|
|
254
261
|
return;
|
|
255
262
|
}
|
|
256
263
|
|
|
264
|
+
if(this.ignoreExpressions){
|
|
265
|
+
this.ignoredNodes = Array.from(this.querySelectorAll(this.ignoreExpressions));
|
|
266
|
+
}
|
|
267
|
+
|
|
257
268
|
const children = event.target.assignedElements();
|
|
258
269
|
let modelElement = children.find(
|
|
259
270
|
modelElem => modelElem.nodeName.toUpperCase() === 'FX-MODEL',
|
|
@@ -547,7 +558,9 @@ export class FxFore extends HTMLElement {
|
|
|
547
558
|
const expr = this._getTemplateExpression(node);
|
|
548
559
|
|
|
549
560
|
// console.log('storedTemplateExpressionByNode', this.storedTemplateExpressionByNode);
|
|
550
|
-
|
|
561
|
+
if(expr){
|
|
562
|
+
this.storedTemplateExpressionByNode.set(node, expr);
|
|
563
|
+
}
|
|
551
564
|
});
|
|
552
565
|
// console.log('stored template expressions ', this.storedTemplateExpressionByNode);
|
|
553
566
|
|
|
@@ -629,6 +642,13 @@ export class FxFore extends HTMLElement {
|
|
|
629
642
|
|
|
630
643
|
// eslint-disable-next-line class-methods-use-this
|
|
631
644
|
_getTemplateExpression(node) {
|
|
645
|
+
if(this.ignoredNodes){
|
|
646
|
+
if(node.nodeType === Node.ATTRIBUTE_NODE){
|
|
647
|
+
node = node.ownerElement;
|
|
648
|
+
}
|
|
649
|
+
const found = this.ignoredNodes.find( (n) => n.contains(node));
|
|
650
|
+
if(found) return null;
|
|
651
|
+
}
|
|
632
652
|
if (node.nodeType === Node.ATTRIBUTE_NODE) {
|
|
633
653
|
return node.value;
|
|
634
654
|
}
|
|
@@ -920,9 +940,9 @@ export class FxFore extends HTMLElement {
|
|
|
920
940
|
this.shadowRoot.getElementById('messageContent').innerText = msg;
|
|
921
941
|
// this.shadowRoot.getElementById('modalMessage').open();
|
|
922
942
|
this.shadowRoot.getElementById('modalMessage').classList.add('show');
|
|
923
|
-
} else if (level === 'sticky') {
|
|
943
|
+
} else if (level === 'sticky' || level === 'error' || level === 'warn') {
|
|
924
944
|
// const notification = this.$.modeless;
|
|
925
|
-
this.shadowRoot.querySelector(
|
|
945
|
+
this.shadowRoot.querySelector(`#${level}`).showToast(msg);
|
|
926
946
|
} else {
|
|
927
947
|
const toast = this.shadowRoot.querySelector('#message');
|
|
928
948
|
toast.showToast(msg);
|
package/src/fx-instance.js
CHANGED
|
@@ -20,8 +20,7 @@ async function handleResponse(response) {
|
|
|
20
20
|
);
|
|
21
21
|
}
|
|
22
22
|
if (
|
|
23
|
-
responseContentType.startsWith('text/
|
|
24
|
-
responseContentType.startsWith('text/markdown')
|
|
23
|
+
responseContentType.startsWith('text/')
|
|
25
24
|
) {
|
|
26
25
|
// console.log("********** inside res plain *********");
|
|
27
26
|
return response.text();
|
|
@@ -53,6 +52,7 @@ export class FxInstance extends HTMLElement {
|
|
|
53
52
|
this.attachShadow({ mode: 'open' });
|
|
54
53
|
this.originalInstance = null;
|
|
55
54
|
this.partialInstance = null;
|
|
55
|
+
this.credentials = '';
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
connectedCallback() {
|
|
@@ -67,6 +67,13 @@ export class FxInstance extends HTMLElement {
|
|
|
67
67
|
this.id = 'default';
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
this.credentials = this.hasAttribute('credentials')
|
|
71
|
+
? this.getAttribute('credentials')
|
|
72
|
+
: 'same-origin';
|
|
73
|
+
if (!['same-origin', 'include', 'omit'].includes(this.credentials)) {
|
|
74
|
+
console.error(`fx-submission: the value of credentials is not valid. Expected 'same-origin', 'include' or 'omit' but got '${this.credentials}'`, this);
|
|
75
|
+
}
|
|
76
|
+
|
|
70
77
|
if (this.hasAttribute('type')) {
|
|
71
78
|
this.type = this.getAttribute('type');
|
|
72
79
|
} else {
|
|
@@ -207,6 +214,10 @@ export class FxInstance extends HTMLElement {
|
|
|
207
214
|
this.instanceData = {};
|
|
208
215
|
this.originalInstance = [...this.instanceData];
|
|
209
216
|
}
|
|
217
|
+
if(this.type === 'text'){
|
|
218
|
+
this.instanceData = '';
|
|
219
|
+
this.originalInstance = '';
|
|
220
|
+
}
|
|
210
221
|
}
|
|
211
222
|
|
|
212
223
|
async _loadData() {
|
|
@@ -240,10 +251,8 @@ export class FxInstance extends HTMLElement {
|
|
|
240
251
|
try {
|
|
241
252
|
const response = await fetch(url, {
|
|
242
253
|
method: 'GET',
|
|
243
|
-
|
|
254
|
+
credentials: this.credentials,
|
|
244
255
|
mode: 'cors',
|
|
245
|
-
credentials: 'include',
|
|
246
|
-
*/
|
|
247
256
|
headers: {
|
|
248
257
|
'Content-Type': contentType,
|
|
249
258
|
},
|
package/src/fx-submission.js
CHANGED
|
@@ -12,6 +12,7 @@ export class FxSubmission extends foreElementMixin(HTMLElement) {
|
|
|
12
12
|
constructor() {
|
|
13
13
|
super();
|
|
14
14
|
this.attachShadow({mode: 'open'});
|
|
15
|
+
this.credentials = '';
|
|
15
16
|
this.parameters = new Map();
|
|
16
17
|
}
|
|
17
18
|
|
|
@@ -56,6 +57,12 @@ export class FxSubmission extends foreElementMixin(HTMLElement) {
|
|
|
56
57
|
: 'application/xml';
|
|
57
58
|
|
|
58
59
|
this.validate = this.getAttribute('validate') ? this.getAttribute('validate') : 'true';
|
|
60
|
+
this.credentials = this.hasAttribute('credentials')
|
|
61
|
+
? this.getAttribute('credentials')
|
|
62
|
+
: 'same-origin';
|
|
63
|
+
if (!['same-origin', 'include', 'omit'].includes(this.credentials)) {
|
|
64
|
+
console.error(`fx-submission: the value of credentials is not valid. Expected 'same-origin', 'include' or 'omit' but got '${this.credentials}'`, this);
|
|
65
|
+
}
|
|
59
66
|
this.shadowRoot.innerHTML = this.renderHTML();
|
|
60
67
|
}
|
|
61
68
|
|
|
@@ -96,9 +103,8 @@ export class FxSubmission extends foreElementMixin(HTMLElement) {
|
|
|
96
103
|
_getProperty(attrName){
|
|
97
104
|
if(this.parameters.has(attrName)){
|
|
98
105
|
return this.parameters.get(attrName);
|
|
99
|
-
} else {
|
|
100
|
-
return this.getAttribute(attrName);
|
|
101
106
|
}
|
|
107
|
+
return this.getAttribute(attrName);
|
|
102
108
|
}
|
|
103
109
|
|
|
104
110
|
/**
|
|
@@ -191,10 +197,8 @@ export class FxSubmission extends foreElementMixin(HTMLElement) {
|
|
|
191
197
|
try {
|
|
192
198
|
const response = await fetch(resolvedUrl, {
|
|
193
199
|
method: this.method,
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
credentials: 'include',
|
|
197
|
-
*/
|
|
200
|
+
credentials: this.credentials,
|
|
201
|
+
mode:'cors',
|
|
198
202
|
headers,
|
|
199
203
|
body: serialized,
|
|
200
204
|
});
|
|
@@ -207,9 +211,7 @@ export class FxSubmission extends foreElementMixin(HTMLElement) {
|
|
|
207
211
|
|
|
208
212
|
const contentType = response.headers.get('content-type').toLowerCase();
|
|
209
213
|
if (
|
|
210
|
-
contentType.startsWith('text/
|
|
211
|
-
contentType.startsWith('text/html') ||
|
|
212
|
-
contentType.startsWith('text/markdown')
|
|
214
|
+
contentType.startsWith('text/')
|
|
213
215
|
) {
|
|
214
216
|
const text = await response.text();
|
|
215
217
|
this._handleResponse(text, resolvedUrl,contentType);
|
|
@@ -231,6 +233,10 @@ export class FxSubmission extends foreElementMixin(HTMLElement) {
|
|
|
231
233
|
Fore.dispatch(this, 'submit-error', {error: error.message});
|
|
232
234
|
} finally {
|
|
233
235
|
this.parameters.clear();
|
|
236
|
+
const download = document.querySelector('[download]');
|
|
237
|
+
if(download){
|
|
238
|
+
document.body.removeChild(download);
|
|
239
|
+
}
|
|
234
240
|
}
|
|
235
241
|
}
|
|
236
242
|
|
|
@@ -242,6 +248,9 @@ export class FxSubmission extends foreElementMixin(HTMLElement) {
|
|
|
242
248
|
if (serialized && instance.getAttribute('type') === 'json') {
|
|
243
249
|
data = JSON.parse(serialized);
|
|
244
250
|
}
|
|
251
|
+
if (serialized && instance.getAttribute('type') === 'text') {
|
|
252
|
+
data = serialized;
|
|
253
|
+
}
|
|
245
254
|
return data;
|
|
246
255
|
}
|
|
247
256
|
|
|
@@ -263,6 +272,9 @@ export class FxSubmission extends foreElementMixin(HTMLElement) {
|
|
|
263
272
|
// console.warn('JSON serialization is not yet supported')
|
|
264
273
|
return JSON.stringify(relevantNodes);
|
|
265
274
|
}
|
|
275
|
+
if (instanceType === 'text') {
|
|
276
|
+
return relevantNodes;
|
|
277
|
+
}
|
|
266
278
|
throw new Error('unknown instance type ', instanceType);
|
|
267
279
|
}
|
|
268
280
|
|
|
@@ -393,11 +405,26 @@ export class FxSubmission extends foreElementMixin(HTMLElement) {
|
|
|
393
405
|
}
|
|
394
406
|
}
|
|
395
407
|
|
|
408
|
+
if (this.replace === 'download') {
|
|
409
|
+
const target = this._getProperty('target');
|
|
410
|
+
const downloadLink = document.createElement('a');
|
|
411
|
+
downloadLink.setAttribute('download',target);
|
|
412
|
+
downloadLink.setAttribute('href',`data:${contentType},${data}`);
|
|
413
|
+
document.body.appendChild(downloadLink);
|
|
414
|
+
downloadLink.click();
|
|
415
|
+
}
|
|
396
416
|
if (this.replace === 'all') {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
417
|
+
const target = this._getProperty('target');
|
|
418
|
+
if(target && target === '_blank'){
|
|
419
|
+
const win = window.open("", "_blank");
|
|
420
|
+
win.document.write(`<pre>${data}</pre>`);
|
|
421
|
+
win.document.close();
|
|
422
|
+
}else{
|
|
423
|
+
document.open();
|
|
424
|
+
document.write(data);
|
|
425
|
+
document.close();
|
|
426
|
+
window.location.href = resolvedUrl;
|
|
427
|
+
}
|
|
401
428
|
// document.getElementsByTagName('html')[0].innerHTML = data;
|
|
402
429
|
}
|
|
403
430
|
if (this.replace === 'target' && contentType.startsWith('text/html')) {
|
|
@@ -415,51 +442,22 @@ export class FxSubmission extends foreElementMixin(HTMLElement) {
|
|
|
415
442
|
}
|
|
416
443
|
}
|
|
417
444
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
}
|
|
432
|
-
*/
|
|
433
|
-
|
|
434
|
-
/*
|
|
435
|
-
_mergeNodes(node1, node2) {
|
|
436
|
-
const childNodes1 = node1.childNodes;
|
|
437
|
-
const childNodes2 = node2.childNodes;
|
|
438
|
-
|
|
439
|
-
for (let i = 0; i < childNodes2.length; i++) {
|
|
440
|
-
const child2 = childNodes2[i];
|
|
441
|
-
let nodeMerged = false;
|
|
442
|
-
|
|
443
|
-
if (child2.nodeType === 1) { // Element Node
|
|
444
|
-
for (let j = 0; j < childNodes1.length; j++) {
|
|
445
|
-
const child1 = childNodes1[j];
|
|
446
|
-
if (child1.nodeType === 1 && child1.tagName === child2.tagName) {
|
|
447
|
-
this._mergeNodes(child1, child2);
|
|
448
|
-
nodeMerged = true;
|
|
449
|
-
break;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
if (!nodeMerged) {
|
|
455
|
-
const clonedNode = child2.cloneNode(true);
|
|
456
|
-
node1.appendChild(clonedNode);
|
|
457
|
-
}
|
|
458
|
-
}
|
|
445
|
+
_handleError() {
|
|
446
|
+
// this.dispatch('submit-error', {});
|
|
447
|
+
Fore.dispatch(this, 'submit-error', {});
|
|
448
|
+
/*
|
|
449
|
+
console.log('ERRRORRRRR');
|
|
450
|
+
this.dispatchEvent(
|
|
451
|
+
new CustomEvent('submit-error', {
|
|
452
|
+
composed: true,
|
|
453
|
+
bubbles: true,
|
|
454
|
+
detail: {},
|
|
455
|
+
}),
|
|
456
|
+
);
|
|
457
|
+
*/
|
|
459
458
|
}
|
|
460
|
-
*/
|
|
461
459
|
|
|
462
|
-
/*
|
|
460
|
+
/*
|
|
463
461
|
mergeNodes(node1, node2) {
|
|
464
462
|
// Overwrite attributes in node1 with values from node2
|
|
465
463
|
for (const { name, value } of node2.attributes) {
|
|
@@ -490,97 +488,7 @@ export class FxSubmission extends foreElementMixin(HTMLElement) {
|
|
|
490
488
|
});
|
|
491
489
|
}
|
|
492
490
|
*/
|
|
493
|
-
/**
|
|
494
|
-
* select relevant nodes
|
|
495
|
-
*
|
|
496
|
-
* @returns {*}
|
|
497
|
-
*/
|
|
498
|
-
/*
|
|
499
|
-
selectRelevant(type) {
|
|
500
|
-
console.log('selectRelevant' ,type)
|
|
501
|
-
switch (type){
|
|
502
|
-
case 'xml':
|
|
503
|
-
return this._relevantXmlNodes();
|
|
504
|
-
default:
|
|
505
|
-
console.warn(`relevance selection not supported for type:${this.type}`);
|
|
506
|
-
return this.nodeset;
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
*/
|
|
510
|
-
|
|
511
|
-
// todo: support for 'empty'
|
|
512
|
-
/*
|
|
513
|
-
_relevantXmlNodes() {
|
|
514
|
-
// ### no relevance selection - current nodeset is used 'as-is'
|
|
515
|
-
if (this.nonrelevant === 'keep') {
|
|
516
|
-
return this.nodeset;
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
// first check if nodeset of submission is relevant - otherwise bail out
|
|
520
|
-
const mi = this.getModel().getModelItem(this.nodeset);
|
|
521
|
-
if (mi && !mi.relevant) return null;
|
|
522
|
-
|
|
523
|
-
const doc = new DOMParser().parseFromString('<data></data>', 'application/xml');
|
|
524
|
-
const root = doc.firstElementChild;
|
|
525
|
-
|
|
526
|
-
if (this.nodeset.children.length === 0 && this._isRelevant(this.nodeset)) {
|
|
527
|
-
return this.nodeset;
|
|
528
|
-
}
|
|
529
|
-
return this._filterRelevant(this.nodeset, root);
|
|
530
|
-
}
|
|
531
|
-
*/
|
|
532
|
-
|
|
533
|
-
/*
|
|
534
|
-
_filterRelevant(node, result) {
|
|
535
|
-
const { childNodes } = node;
|
|
536
|
-
Array.from(childNodes).forEach(n => {
|
|
537
|
-
if (this._isRelevant(n)) {
|
|
538
|
-
const clone = n.cloneNode(false);
|
|
539
|
-
result.appendChild(clone);
|
|
540
|
-
const { attributes } = n;
|
|
541
|
-
if (attributes) {
|
|
542
|
-
Array.from(attributes).forEach(attr => {
|
|
543
|
-
if (this._isRelevant(attr)) {
|
|
544
|
-
clone.setAttribute(attr.nodeName, attr.value);
|
|
545
|
-
} else if (this.nonrelevant === 'empty') {
|
|
546
|
-
clone.setAttribute(attr.nodeName, '');
|
|
547
|
-
} else {
|
|
548
|
-
clone.removeAttribute(attr.nodeName);
|
|
549
|
-
}
|
|
550
|
-
});
|
|
551
|
-
}
|
|
552
|
-
return this._filterRelevant(n, clone);
|
|
553
|
-
}
|
|
554
|
-
return null;
|
|
555
|
-
});
|
|
556
|
-
return result;
|
|
557
|
-
}
|
|
558
|
-
*/
|
|
559
491
|
|
|
560
|
-
/*
|
|
561
|
-
_isRelevant(node) {
|
|
562
|
-
const mi = this.getModel().getModelItem(node);
|
|
563
|
-
if (!mi || mi.relevant) {
|
|
564
|
-
return true;
|
|
565
|
-
}
|
|
566
|
-
return false;
|
|
567
|
-
}
|
|
568
|
-
*/
|
|
569
|
-
|
|
570
|
-
_handleError() {
|
|
571
|
-
// this.dispatch('submit-error', {});
|
|
572
|
-
Fore.dispatch(this, 'submit-error', {});
|
|
573
|
-
/*
|
|
574
|
-
console.log('ERRRORRRRR');
|
|
575
|
-
this.dispatchEvent(
|
|
576
|
-
new CustomEvent('submit-error', {
|
|
577
|
-
composed: true,
|
|
578
|
-
bubbles: true,
|
|
579
|
-
detail: {},
|
|
580
|
-
}),
|
|
581
|
-
);
|
|
582
|
-
*/
|
|
583
|
-
}
|
|
584
492
|
}
|
|
585
493
|
|
|
586
494
|
if (!customElements.get('fx-submission')) {
|
package/src/ui/fx-control.js
CHANGED
|
@@ -43,6 +43,9 @@ export default class FxControl extends XfAbstractControl {
|
|
|
43
43
|
static get properties() {
|
|
44
44
|
return {
|
|
45
45
|
...XfAbstractControl.properties,
|
|
46
|
+
credentials:{
|
|
47
|
+
type: String
|
|
48
|
+
},
|
|
46
49
|
initial: {
|
|
47
50
|
type: Boolean
|
|
48
51
|
}
|
|
@@ -74,6 +77,13 @@ export default class FxControl extends XfAbstractControl {
|
|
|
74
77
|
}
|
|
75
78
|
`;
|
|
76
79
|
|
|
80
|
+
this.credentials = this.hasAttribute('credentials')
|
|
81
|
+
? this.getAttribute('credentials')
|
|
82
|
+
: 'same-origin';
|
|
83
|
+
if (!['same-origin', 'include', 'omit'].includes(this.credentials)) {
|
|
84
|
+
console.error(`fx-submission: the value of credentials is not valid. Expected 'same-origin', 'include' or 'omit' but got '${this.credentials}'`, this);
|
|
85
|
+
}
|
|
86
|
+
|
|
77
87
|
this.shadowRoot.innerHTML = `
|
|
78
88
|
<style>
|
|
79
89
|
${style}
|
|
@@ -369,7 +379,7 @@ export default class FxControl extends XfAbstractControl {
|
|
|
369
379
|
}
|
|
370
380
|
|
|
371
381
|
// ### when there's a url Fore is used as widget and will be loaded from external file
|
|
372
|
-
if (this.url && !this.loaded) {
|
|
382
|
+
if (this.url && !this.loaded && this.modelItem.relevant) {
|
|
373
383
|
// ### evaluate initial data if necessary
|
|
374
384
|
|
|
375
385
|
if (this.initial) {
|
|
@@ -417,10 +427,8 @@ export default class FxControl extends XfAbstractControl {
|
|
|
417
427
|
try {
|
|
418
428
|
const response = await fetch(this.url, {
|
|
419
429
|
method: 'GET',
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
credentials: 'include',
|
|
423
|
-
*/
|
|
430
|
+
credentials: this.credentials,
|
|
431
|
+
mode: 'cors',
|
|
424
432
|
headers: {
|
|
425
433
|
'Content-Type': 'text/html',
|
|
426
434
|
},
|
|
@@ -446,9 +454,12 @@ export default class FxControl extends XfAbstractControl {
|
|
|
446
454
|
'model-construct-done',
|
|
447
455
|
e => {
|
|
448
456
|
const defaultInst = imported.querySelector('fx-instance');
|
|
449
|
-
if (this.
|
|
457
|
+
if (this.initial) {
|
|
450
458
|
const doc = new DOMParser().parseFromString('<data></data>', 'application/xml');
|
|
451
459
|
// Note: Clone the input to prevent the inner fore from editing the outer node
|
|
460
|
+
// Also update the `initialNode` to make sure we have an up-to-date version
|
|
461
|
+
this.initialNode = evaluateXPathToFirstNode(this.initial, this.nodeset, this);
|
|
462
|
+
|
|
452
463
|
doc.firstElementChild.appendChild(this.initialNode.cloneNode(true));
|
|
453
464
|
defaultInst.setInstanceData(doc);
|
|
454
465
|
}
|