@jinntec/fore 1.2.0 → 1.4.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.
Files changed (51) hide show
  1. package/dist/fore-dev.js +8 -8
  2. package/dist/fore-dev.js.map +1 -1
  3. package/dist/fore.js +7 -7
  4. package/dist/fore.js.map +1 -1
  5. package/index.js +1 -0
  6. package/package.json +2 -2
  7. package/resources/fore.css +100 -72
  8. package/src/ForeElementMixin.js +4 -0
  9. package/src/actions/abstract-action.js +102 -18
  10. package/src/actions/fx-action.js +9 -10
  11. package/src/actions/fx-append.js +1 -1
  12. package/src/actions/fx-confirm.js +3 -3
  13. package/src/actions/fx-copy.js +68 -0
  14. package/src/actions/fx-delete.js +53 -62
  15. package/src/actions/fx-dispatch.js +1 -1
  16. package/src/actions/fx-hide.js +4 -2
  17. package/src/actions/fx-insert.js +1 -1
  18. package/src/actions/fx-message.js +26 -2
  19. package/src/actions/fx-refresh.js +2 -2
  20. package/src/actions/fx-reload.js +30 -0
  21. package/src/actions/fx-replace.js +1 -1
  22. package/src/actions/fx-return.js +1 -1
  23. package/src/actions/fx-send.js +13 -3
  24. package/src/actions/fx-setfocus.js +33 -6
  25. package/src/actions/fx-setvalue.js +5 -5
  26. package/src/actions/fx-show.js +2 -1
  27. package/src/actions/fx-toggle.js +6 -1
  28. package/src/actions/fx-update.js +1 -1
  29. package/src/events.js +24 -0
  30. package/src/fore.js +128 -17
  31. package/src/fx-bind.js +6 -1
  32. package/src/fx-fore.js +93 -41
  33. package/src/fx-instance.js +95 -70
  34. package/src/fx-model.js +430 -441
  35. package/src/fx-submission.js +423 -405
  36. package/src/getInScopeContext.js +88 -82
  37. package/src/modelitem.js +5 -3
  38. package/src/relevance.js +1 -1
  39. package/src/ui/abstract-control.js +108 -22
  40. package/src/ui/fx-alert.js +0 -1
  41. package/src/ui/fx-container.js +22 -26
  42. package/src/ui/fx-control.js +84 -34
  43. package/src/ui/fx-group.js +5 -0
  44. package/src/ui/fx-inspector.js +5 -0
  45. package/src/ui/fx-output.js +14 -14
  46. package/src/ui/fx-repeat.js +2 -2
  47. package/src/ui/fx-repeatitem.js +5 -3
  48. package/src/ui/fx-switch.js +20 -8
  49. package/src/ui/fx-trigger.js +26 -19
  50. package/src/xpath-evaluation.js +49 -26
  51. package/src/xpath-util.js +26 -28
@@ -1,465 +1,483 @@
1
- import { Fore } from './fore.js';
2
- import { Relevance } from './relevance.js';
3
- import { foreElementMixin } from './ForeElementMixin.js';
4
- import { evaluateXPathToString, evaluateXPath } from './xpath-evaluation.js';
1
+ import {Fore} from './fore.js';
2
+ import {Relevance} from './relevance.js';
3
+ import {foreElementMixin} from './ForeElementMixin.js';
4
+ import {evaluateXPathToString, evaluateXPath} from './xpath-evaluation.js';
5
5
  import getInScopeContext from './getInScopeContext.js';
6
6
 
7
7
  /**
8
8
  * todo: validate='false'
9
9
  */
10
10
  export class FxSubmission extends foreElementMixin(HTMLElement) {
11
- constructor() {
12
- super();
13
- this.attachShadow({ mode: 'open' });
14
- }
11
+ constructor() {
12
+ super();
13
+ this.attachShadow({mode: 'open'});
14
+ }
15
15
 
16
- connectedCallback() {
17
- // this.style.display = 'none';
18
- this.methods = ['get', 'put', 'post', 'delete', 'head', 'urlencoded-post'];
16
+ connectedCallback() {
17
+ // this.style.display = 'none';
18
+ this.methods = ['get', 'put', 'post', 'delete', 'head', 'urlencoded-post'];
19
19
 
20
- this.model = this.parentNode;
20
+ this.model = this.parentNode;
21
21
 
22
- // ### initialize properties with defaults
23
- // if (!this.hasAttribute('id')) throw new Error('id is required');
24
- if (!this.hasAttribute('id')) console.warn('id is required');
25
- this.id = this.getAttribute('id');
22
+ // ### initialize properties with defaults
23
+ // if (!this.hasAttribute('id')) throw new Error('id is required');
24
+ if (!this.hasAttribute('id')) console.warn('id is required');
25
+ this.id = this.getAttribute('id');
26
26
 
27
- /** if present should be a existing instance id */
28
- this.instance = this.hasAttribute('instance') ? this.getAttribute('instance') : null;
27
+ /** if present should be a existing instance id */
28
+ this.instance = this.hasAttribute('instance') ? this.getAttribute('instance') : null;
29
29
 
30
- /** if present will determine XPath where to insert a response into when mode is 'replace' */
31
- this.into = this.hasAttribute('into') ? this.getAttribute('into') : null;
30
+ /** if present will determine XPath where to insert a response into when mode is 'replace' */
31
+ this.into = this.hasAttribute('into') ? this.getAttribute('into') : null;
32
32
 
33
- /** http method */
34
- this.method = this.hasAttribute('method') ? this.getAttribute('method') : 'get';
33
+ /** http method */
34
+ this.method = this.hasAttribute('method') ? this.getAttribute('method') : 'get';
35
35
 
36
- /** relevance processing - one of 'remove, keep or empty' */
37
- this.nonrelevant = this.hasAttribute('nonrelevant')
38
- ? this.getAttribute('nonrelevant')
39
- : 'remove';
36
+ /** relevance processing - one of 'remove, keep or empty' */
37
+ this.nonrelevant = this.hasAttribute('nonrelevant')
38
+ ? this.getAttribute('nonrelevant')
39
+ : 'remove';
40
40
 
41
- /** replace might be 'all', 'instance' or 'none' */
42
- this.replace = this.hasAttribute('replace') ? this.getAttribute('replace') : 'all';
41
+ /** replace might be 'all', 'instance' or 'none' */
42
+ this.replace = this.hasAttribute('replace') ? this.getAttribute('replace') : 'all';
43
43
 
44
- this.serialization = this.hasAttribute('serialization')
45
- ? this.getAttribute('serialization')
46
- : 'xml';
44
+ this.serialization = this.hasAttribute('serialization')
45
+ ? this.getAttribute('serialization')
46
+ : 'xml';
47
47
 
48
- // if (!this.hasAttribute('url')) throw new Error(`url is required for submission: ${this.id}`);
49
- if (!this.hasAttribute('url')) console.warn(`url is required for submission: ${this.id}`);
50
- this.url = this.getAttribute('url');
48
+ // if (!this.hasAttribute('url')) throw new Error(`url is required for submission: ${this.id}`);
49
+ if (!this.hasAttribute('url')) console.warn(`url is required for submission: ${this.id}`);
50
+ this.url = this.getAttribute('url');
51
51
 
52
- this.targetref = this.hasAttribute('targetref') ? this.getAttribute('targetref') : null;
52
+ this.targetref = this.hasAttribute('targetref') ? this.getAttribute('targetref') : null;
53
53
 
54
- this.mediatype = this.hasAttribute('mediatype')
55
- ? this.getAttribute('mediatype')
56
- : 'application/xml';
54
+ this.mediatype = this.hasAttribute('mediatype')
55
+ ? this.getAttribute('mediatype')
56
+ : 'application/xml';
57
57
 
58
- this.validate = this.getAttribute('validate') ? this.getAttribute('validate') : 'true';
59
- this.shadowRoot.innerHTML = this.renderHTML();
60
- }
58
+ this.validate = this.getAttribute('validate') ? this.getAttribute('validate') : 'true';
59
+ this.shadowRoot.innerHTML = this.renderHTML();
60
+ }
61
61
 
62
- // eslint-disable-next-line class-methods-use-this
63
- renderHTML() {
64
- return `
62
+ // eslint-disable-next-line class-methods-use-this
63
+ renderHTML() {
64
+ return `
65
65
  <slot></slot>
66
66
  `;
67
- }
68
-
69
- async submit() {
70
- await Fore.dispatch(this, 'submit', { submission: this });
71
- this._submit();
72
- }
73
-
74
- async _submit() {
75
- console.log('submitting....', this.getAttribute('id'));
76
- this.evalInContext();
77
- const model = this.getModel();
78
-
79
- model.recalculate();
80
-
81
- if (this.validate==='true') {
82
- const valid = model.revalidate();
83
- if (!valid) {
84
- console.log('validation failed. Bubmission stopped');
85
- // ### allow alerts to pop up
86
- // this.dispatch('submit-error', {});
87
- Fore.dispatch(this, 'submit-error', {});
88
- this.getModel().parentNode.refresh();
89
- return;
90
- }
91
- }
92
- console.log('model updated....');
93
- await this._serializeAndSend();
94
- }
95
-
96
- /**
97
- * resolves template expressions for a single attribute
98
- * @param expr the attribute value to evaluate
99
- * @param node the attribute node used for scoped resolution
100
- * @returns {*}
101
- * @private
102
- */
103
- _evaluateAttributeTemplateExpression(expr, node) {
104
- const matches = expr.match(/{[^}]*}/g);
105
- if (matches) {
106
- matches.forEach(match => {
107
- console.log('match ', match);
108
- const naked = match.substring(1, match.length - 1);
109
- const inscope = getInScopeContext(node, naked);
110
- const result = evaluateXPathToString(naked, inscope, this.getOwnerForm());
111
- const replaced = expr.replaceAll(match, result);
112
- console.log('replacing ', expr, ' with ', replaced);
113
- expr = replaced;
114
- });
115
- }
116
- return expr;
117
- }
118
-
119
- /**
120
- * sends the data after evaluating
121
- *
122
- * @private
123
- */
124
- async _serializeAndSend() {
125
- const resolvedUrl = this._evaluateAttributeTemplateExpression(this.url, this);
126
-
127
- const instance = this.getInstance();
128
- console.log('instance type', instance.type);
129
-
130
- let serialized;
131
- if (this.serialization === 'none') {
132
- serialized = undefined;
133
- } else {
134
- // const relevant = this.selectRelevant(instance.type);
135
- const relevant = Relevance.selectRelevant(this, instance.type);
136
- serialized = this._serialize(instance.type, relevant);
137
67
  }
138
68
 
139
- // let serialized = serializer.serializeToString(relevant);
140
- if (this.method.toLowerCase() === 'get') {
141
- serialized = undefined;
142
- }
143
- // console.log('data being send', serialized);
144
- // console.log('submitting data',serialized);
145
-
146
- // if (resolvedUrl === '#echo') {
147
- if (resolvedUrl.startsWith('#echo')) {
148
- let data = this._parse(serialized, instance);
149
- this._handleResponse(data);
150
- // this.dispatch('submit-done', {});
151
- Fore.dispatch(this, 'submit-done', {});
152
- return;
69
+ async submit() {
70
+ await Fore.dispatch(this, 'submit', {submission: this});
71
+ await this._submit();
153
72
  }
154
73
 
155
- if(resolvedUrl.startsWith('localStore:') && this.method === 'post'){
156
- // let data = this._parse(serialized, instance);
157
- const key = resolvedUrl.substring(resolvedUrl.indexOf(':')+1);
158
- localStorage.setItem(key,serialized);
159
- Fore.dispatch(this, 'submit-done', {});
160
- return;
74
+ async _submit() {
75
+ console.log('submitting....', this.getAttribute('id'));
76
+ this.evalInContext();
77
+ const model = this.getModel();
78
+
79
+ model.recalculate();
80
+
81
+ if (this.validate === 'true') {
82
+ const valid = model.revalidate();
83
+ if (!valid) {
84
+ console.log('validation failed. Submission stopped');
85
+ this.getOwnerForm().classList.add('submit-validation-failed');
86
+ // ### allow alerts to pop up
87
+ // this.dispatch('submit-error', {});
88
+ Fore.dispatch(this, 'submit-error', {});
89
+ this.getModel().parentNode.refresh(true);
90
+ return;
91
+ }
92
+ }
93
+ console.log('model updated....');
94
+ await this._serializeAndSend();
161
95
  }
162
96
 
163
- if(resolvedUrl.startsWith('localStore:') && (this.method === 'consume' || this.method === 'get')){
164
- // let data = this._parse(serialized, instance);
165
- this.replace = 'instance';
166
- const key = resolvedUrl.substring(resolvedUrl.indexOf(':')+1);
167
- const serialized = localStorage.getItem(key);
168
- if(!serialized){
169
- Fore.dispatch(this, 'submit-error', { message: `Error reading key ${key} from localstorage` });
170
- return;
171
- }
172
- let data = this._parse(serialized, instance);
173
- this._handleResponse(data);
174
- if(this.method === 'consume'){
175
- localStorage.removeItem(key);
176
- }
177
- Fore.dispatch(this, 'submit-done', {});
178
- return;
97
+ /**
98
+ * resolves template expressions for a single attribute
99
+ * @param expr the attribute value to evaluate
100
+ * @param node the attribute node used for scoped resolution
101
+ * @returns {*}
102
+ * @private
103
+ */
104
+ _evaluateAttributeTemplateExpression(expr, node) {
105
+ const matches = expr.match(/{[^}]*}/g);
106
+ if (matches) {
107
+ matches.forEach(match => {
108
+ console.log('match ', match);
109
+ const naked = match.substring(1, match.length - 1);
110
+ const inscope = getInScopeContext(node, naked);
111
+ const result = evaluateXPathToString(naked, inscope, this.getOwnerForm());
112
+ const replaced = expr.replaceAll(match, result);
113
+ console.log('replacing ', expr, ' with ', replaced);
114
+ expr = replaced;
115
+ });
116
+ }
117
+ return expr;
179
118
  }
180
119
 
181
- // ### setting headers
182
- const headers = this._getHeaders();
183
- console.log('headers', headers);
120
+ /**
121
+ * sends the data after evaluating
122
+ *
123
+ * @private
124
+ */
125
+ async _serializeAndSend() {
126
+ const resolvedUrl = this._evaluateAttributeTemplateExpression(this.url, this);
184
127
 
185
- // ### map urlencoded-post to post for fetch
186
- if (this.method === 'urlencoded-post') {
187
- this.method = 'post';
188
- }
128
+ const instance = this.getInstance();
129
+ console.log('instance type', instance.type);
189
130
 
190
- if (!this.methods.includes(this.method.toLowerCase())) {
191
- // this.dispatch('error', { message: `Unknown method ${this.method}` });
192
- Fore.dispatch(this, 'error', { message: `Unknown method ${this.method}` });
193
- return;
194
- }
195
- const response = await fetch(resolvedUrl, {
196
- method: this.method,
197
- mode: 'cors',
198
- credentials: 'include',
199
- headers,
200
- body: serialized,
201
- });
202
-
203
- if (!response.ok || response.status > 400) {
204
- // this.dispatch('submit-error', { message: `Error while submitting ${this.id}` });
205
- Fore.dispatch(this, 'submit-error', { message: `Error while submitting ${this.id}` });
206
- return;
207
- }
131
+ let serialized;
132
+ if (this.serialization === 'none') {
133
+ serialized = undefined;
134
+ } else {
135
+ // const relevant = this.selectRelevant(instance.type);
136
+ const relevant = Relevance.selectRelevant(this, instance.type);
137
+ serialized = this._serialize(instance.type, relevant);
138
+ }
208
139
 
209
- const contentType = response.headers.get('content-type').toLowerCase();
210
- if (
211
- contentType.startsWith('text/plain') ||
212
- contentType.startsWith('text/html') ||
213
- contentType.startsWith('text/markdown')
214
- ) {
215
- const text = await response.text();
216
- this._handleResponse(text);
217
- } else if (contentType.startsWith('application/json')) {
218
- const json = await response.json();
219
- this._handleResponse(json);
220
- } else if (contentType.startsWith('application/xml')) {
221
- const text = await response.text();
222
- const xml = new DOMParser().parseFromString(text, 'application/xml');
223
- this._handleResponse(xml);
224
- } else {
225
- const blob = await response.blob();
226
- this._handleResponse(blob);
227
- }
140
+ // let serialized = serializer.serializeToString(relevant);
141
+ if (this.method.toLowerCase() === 'get') {
142
+ serialized = undefined;
143
+ }
144
+ // console.log('data being send', serialized);
145
+ // console.log('submitting data',serialized);
146
+
147
+ // if (resolvedUrl === '#echo') {
148
+ if (resolvedUrl.startsWith('#echo')) {
149
+ const data = this._parse(serialized, instance);
150
+ this._handleResponse(data);
151
+ // this.dispatch('submit-done', {});
152
+ Fore.dispatch(this, 'submit-done', {});
153
+ return;
154
+ }
155
+
156
+ if (resolvedUrl.startsWith('localStore:')) {
157
+
158
+ if (this.method === 'get' || this.method === 'consume') {
159
+ // let data = this._parse(serialized, instance);
160
+ this.replace = 'instance';
161
+ const key = resolvedUrl.substring(resolvedUrl.indexOf(':') + 1);
162
+ const serialized = localStorage.getItem(key);
163
+ if (!serialized) {
164
+ Fore.dispatch(this, 'submit-error', {message: `Error reading key ${key} from localstorage`});
165
+ return;
166
+ }
167
+ let data = this._parse(serialized, instance);
168
+ this._handleResponse(data);
169
+ if (this.method === 'consume') {
170
+ localStorage.removeItem(key);
171
+ }
172
+ Fore.dispatch(this, 'submit-done', {});
173
+ }
174
+ if (this.method === 'post') {
175
+ // let data = this._parse(serialized, instance);
176
+ const key = resolvedUrl.substring(resolvedUrl.indexOf(':') + 1);
177
+ localStorage.setItem(key, serialized);
178
+ this._handleResponse(instance.instanceData);
179
+ Fore.dispatch(this, 'submit-done', {});
180
+ }
181
+ if (this.method === 'delete') {
182
+ const key = resolvedUrl.substring(resolvedUrl.indexOf(':') + 1);
183
+ localStorage.removeItem(key);
184
+ const newInst = new DOMParser().parseFromString('<data></data>', 'application/xml');
185
+ this._handleResponse(newInst);
186
+ Fore.dispatch(this, 'submit-done', {});
187
+ }
228
188
 
229
- // this.dispatch('submit-done', {});
230
- Fore.dispatch(this, 'submit-done', {});
231
- }
189
+ return;
190
+ }
232
191
 
233
- _parse(serialized, instance) {
234
- let data = null;
235
- if (serialized && instance.type === 'xml') {
236
- data = new DOMParser().parseFromString(serialized, 'application/xml');
237
- }
238
- if (serialized && instance.type === 'json') {
239
- data = JSON.parse(serialized);
240
- }
241
- return data;
242
- }
243
-
244
- _serialize(instanceType, relevantNodes) {
245
- if (this.method === 'urlencoded-post') {
246
- // this.method = 'post';
247
- const params = new URLSearchParams();
248
- // console.log('nodes to serialize', relevantNodes);
249
- Array.from(relevantNodes.children).forEach(child => {
250
- params.append(child.nodeName, child.textContent);
251
- });
252
- return params;
192
+ // ### setting headers
193
+ const headers = this._getHeaders();
194
+ console.log('headers', headers);
195
+
196
+ if (!this.methods.includes(this.method.toLowerCase())) {
197
+ // this.dispatch('error', { message: `Unknown method ${this.method}` });
198
+ Fore.dispatch(this, 'error', {message: `Unknown method ${this.method}`});
199
+ return;
200
+ }
201
+ try {
202
+ const response = await fetch(resolvedUrl, {
203
+ method: this.method,
204
+ mode: 'cors',
205
+ credentials: 'include',
206
+ headers,
207
+ body: serialized,
208
+ });
209
+
210
+ if (!response.ok || response.status > 400) {
211
+ // this.dispatch('submit-error', { message: `Error while submitting ${this.id}` });
212
+ Fore.dispatch(this, 'submit-error', {message: `Error while submitting ${this.id}`});
213
+ return;
214
+ }
215
+
216
+ const contentType = response.headers.get('content-type').toLowerCase();
217
+ if (
218
+ contentType.startsWith('text/plain') ||
219
+ contentType.startsWith('text/html') ||
220
+ contentType.startsWith('text/markdown')
221
+ ) {
222
+ const text = await response.text();
223
+ this._handleResponse(text);
224
+ } else if (contentType.startsWith('application/json')) {
225
+ const json = await response.json();
226
+ this._handleResponse(json);
227
+ } else if (contentType.startsWith('application/xml')) {
228
+ const text = await response.text();
229
+ const xml = new DOMParser().parseFromString(text, 'application/xml');
230
+ this._handleResponse(xml);
231
+ } else {
232
+ const blob = await response.blob();
233
+ this._handleResponse(blob);
234
+ }
235
+
236
+ // this.dispatch('submit-done', {});
237
+ Fore.dispatch(this, 'submit-done', {});
238
+ } catch (error) {
239
+ Fore.dispatch(this, 'submit-error', {error: error.message});
240
+ }
253
241
  }
254
- if (instanceType === 'xml') {
255
- const serializer = new XMLSerializer();
256
- return serializer.serializeToString(relevantNodes);
242
+
243
+ _parse(serialized, instance) {
244
+ let data = null;
245
+ if (serialized && instance.type === 'xml') {
246
+ data = new DOMParser().parseFromString(serialized, 'application/xml');
247
+ }
248
+ if (serialized && instance.type === 'json') {
249
+ data = JSON.parse(serialized);
250
+ }
251
+ return data;
257
252
  }
258
- if (instanceType === 'json') {
259
- // console.warn('JSON serialization is not yet supported')
260
- return JSON.stringify(relevantNodes);
253
+
254
+ _serialize(instanceType, relevantNodes) {
255
+ if (this.serialization === 'application/x-www-form-urlencoded') {
256
+ // this.method = 'post';
257
+ const params = new URLSearchParams();
258
+ // console.log('nodes to serialize', relevantNodes);
259
+ Array.from(relevantNodes.children).forEach(child => {
260
+ params.append(child.nodeName, child.textContent);
261
+ });
262
+ return params;
263
+ }
264
+ if (instanceType === 'xml') {
265
+ const serializer = new XMLSerializer();
266
+ return serializer.serializeToString(relevantNodes);
267
+ }
268
+ if (instanceType === 'json') {
269
+ // console.warn('JSON serialization is not yet supported')
270
+ return JSON.stringify(relevantNodes);
271
+ }
272
+ throw new Error('unknown instance type ', instanceType);
261
273
  }
262
- throw new Error('unknown instance type ', instanceType);
263
- }
264
-
265
- _getHeaders() {
266
- const headers = new Headers();
267
-
268
- // ### set content-type header according to type of instance
269
- const instance = this.getInstance();
270
- const contentType = Fore.getContentType(instance, this.method);
271
- headers.append('Content-Type', contentType);
272
- // ### needed to overwrite browsers' setting of 'Accept' header
273
- if (headers.has('Accept')) {
274
- headers.delete('Accept');
274
+
275
+ _getHeaders() {
276
+ const headers = new Headers();
277
+
278
+ // ### set content-type header according to type of instance
279
+ const instance = this.getInstance();
280
+ const contentType = Fore.getContentType(instance, this.serialization);
281
+ headers.append('Content-Type', contentType);
282
+ // ### needed to overwrite browsers' setting of 'Accept' header
283
+ if (headers.has('Accept')) {
284
+ headers.delete('Accept');
285
+ }
286
+ // headers.append('Accept', 'application/xml');
287
+
288
+ // ### add header defined by fx-header elements
289
+ const headerElems = this.querySelectorAll('fx-header');
290
+ Array.from(headerElems).forEach(header => {
291
+ const {name} = header;
292
+ const val = header.getValue();
293
+ headers.append(name, val);
294
+ });
295
+ return headers;
275
296
  }
276
- // headers.append('Accept', 'application/xml');
277
-
278
- // ### add header defined by fx-header elements
279
- const headerElems = this.querySelectorAll('fx-header');
280
- Array.from(headerElems).forEach(header => {
281
- const { name } = header;
282
- const val = header.getValue();
283
- headers.append(name, val);
284
- });
285
- return headers;
286
- }
287
-
288
- _getUrlExpr() {
289
- return this.storedTemplateExpressions.find(stored => stored.node.nodeName === 'url');
290
- }
291
-
292
- _getTargetInstance() {
293
- let targetInstance;
294
- if (this.instance) {
295
- targetInstance = this.model.getInstance(this.instance);
296
- } else {
297
- targetInstance = this.model.getInstance('default');
297
+
298
+ _getUrlExpr() {
299
+ return this.storedTemplateExpressions.find(stored => stored.node.nodeName === 'url');
298
300
  }
299
- if (!targetInstance) {
300
- throw new Error(`target instance not found: ${targetInstance}`);
301
+
302
+ _getTargetInstance() {
303
+ let targetInstance;
304
+ if (this.instance) {
305
+ targetInstance = this.model.getInstance(this.instance);
306
+ } else {
307
+ targetInstance = this.model.getInstance('default');
308
+ }
309
+ if (!targetInstance) {
310
+ throw new Error(`target instance not found: ${targetInstance}`);
311
+ }
312
+ return targetInstance;
301
313
  }
302
- return targetInstance;
303
- }
304
-
305
- /**
306
- * handles replacement of instance data from response data.
307
- *
308
- * Please note that data might be
309
- * @param data
310
- * @private
311
- */
312
- _handleResponse(data) {
313
- console.log('_handleResponse ', data);
314
314
 
315
- /*
316
- // ### responses need to be handled depending on their type.
317
- if(this.type === 'json'){
315
+ /**
316
+ * handles replacement of instance data from response data.
317
+ *
318
+ * Please note that data might be
319
+ * @param data
320
+ * @private
321
+ */
322
+ _handleResponse(data) {
323
+ console.log('_handleResponse ', data);
318
324
 
319
- }
320
- */
321
-
322
- if (this.replace === 'instance') {
323
- const targetInstance = this._getTargetInstance();
324
- if (targetInstance) {
325
- if (this.targetref) {
326
- const [theTarget] = evaluateXPath(
327
- this.targetref,
328
- targetInstance.instanceData.firstElementChild,
329
- this,
330
- );
331
- console.log('theTarget', theTarget);
332
- const clone = data.firstElementChild;
333
- const parent = theTarget.parentNode;
334
- parent.replaceChild(clone, theTarget);
335
- console.log('finally ', parent);
336
- } else if (this.into) {
337
- const [theTarget] = evaluateXPath(
338
- this.into,
339
- targetInstance.instanceData.firstElementChild,
340
- this,
341
- );
342
- console.log('theTarget', theTarget);
343
- theTarget.innerHTML = data;
344
- } else {
345
- const instanceData = data;
346
- targetInstance.instanceData = instanceData;
347
- console.log('### replaced instance ', this.getModel().instances);
348
- console.log('### replaced instance ', targetInstance.instanceData);
325
+ /*
326
+ // ### responses need to be handled depending on their type.
327
+ if(this.type === 'json'){
328
+
329
+ }
330
+ */
331
+
332
+ if (this.replace === 'instance') {
333
+ const targetInstance = this._getTargetInstance();
334
+ if (targetInstance) {
335
+ if (this.targetref) {
336
+ const [theTarget] = evaluateXPath(
337
+ this.targetref,
338
+ targetInstance.instanceData.firstElementChild,
339
+ this,
340
+ );
341
+ console.log('theTarget', theTarget);
342
+ const clone = data.firstElementChild;
343
+ const parent = theTarget.parentNode;
344
+ parent.replaceChild(clone, theTarget);
345
+ console.log('finally ', parent);
346
+ } else if (this.into) {
347
+ const [theTarget] = evaluateXPath(
348
+ this.into,
349
+ targetInstance.instanceData.firstElementChild,
350
+ this,
351
+ );
352
+ console.log('theTarget', theTarget);
353
+ if (data.nodeType === Node.DOCUMENT_NODE) {
354
+ theTarget.appendChild(data.firstElementChild);
355
+ } else {
356
+ theTarget.innerHTML = data;
357
+ }
358
+ } else {
359
+ const instanceData = data;
360
+ targetInstance.instanceData = instanceData;
361
+ console.log('### replaced instance ', this.getModel().instances);
362
+ console.log('### replaced instance ', targetInstance.instanceData);
363
+ }
364
+
365
+ // Skip any refreshes if the model is not yet inited
366
+ if (this.model.inited) {
367
+ this.model.updateModel(); // force update
368
+ this.getOwnerForm().refresh(true);
369
+ }
370
+ } else {
371
+ throw new Error(`target instance not found: ${targetInstance}`);
372
+ }
349
373
  }
350
374
 
351
- this.model.updateModel(); // force update
352
- this.getOwnerForm().refresh(true);
353
- } else {
354
- throw new Error(`target instance not found: ${targetInstance}`);
355
- }
375
+ if (this.replace === 'all') {
376
+ document.getElementsByTagName('html')[0].innerHTML = data;
377
+ }
378
+ if (this.replace === 'target') {
379
+ const target = this.getAttribute('target');
380
+ const targetNode = document.querySelector(target);
381
+ targetNode.innerHTML = data;
382
+ }
383
+ if (this.replace === 'redirect') {
384
+ window.location.href = data;
385
+ }
356
386
  }
357
387
 
358
- if (this.replace === 'all') {
359
- document.getElementsByTagName('html')[0].innerHTML = data;
360
- }
361
- if (this.replace === 'target') {
362
- const target = this.getAttribute('target');
363
- const targetNode = document.querySelector(target);
364
- targetNode.innerHTML = data;
365
- }
366
- if (this.replace === 'redirect') {
367
- window.location.href = data;
388
+ /**
389
+ * select relevant nodes
390
+ *
391
+ * @returns {*}
392
+ */
393
+ /*
394
+ selectRelevant(type) {
395
+ console.log('selectRelevant' ,type)
396
+ switch (type){
397
+ case 'xml':
398
+ return this._relevantXmlNodes();
399
+ default:
400
+ console.warn(`relevance selection not supported for type:${this.type}`);
401
+ return this.nodeset;
402
+ }
368
403
  }
369
- }
370
-
371
- /**
372
- * select relevant nodes
373
- *
374
- * @returns {*}
375
- */
376
- /*
377
- selectRelevant(type) {
378
- console.log('selectRelevant' ,type)
379
- switch (type){
380
- case 'xml':
381
- return this._relevantXmlNodes();
382
- default:
383
- console.warn(`relevance selection not supported for type:${this.type}`);
404
+ */
405
+
406
+ // todo: support for 'empty'
407
+ /*
408
+ _relevantXmlNodes() {
409
+ // ### no relevance selection - current nodeset is used 'as-is'
410
+ if (this.nonrelevant === 'keep') {
384
411
  return this.nodeset;
385
- }
386
- }
387
- */
388
-
389
- // todo: support for 'empty'
390
- /*
391
- _relevantXmlNodes() {
392
- // ### no relevance selection - current nodeset is used 'as-is'
393
- if (this.nonrelevant === 'keep') {
394
- return this.nodeset;
395
- }
412
+ }
396
413
 
397
- // first check if nodeset of submission is relevant - otherwise bail out
398
- const mi = this.getModel().getModelItem(this.nodeset);
399
- if (mi && !mi.relevant) return null;
414
+ // first check if nodeset of submission is relevant - otherwise bail out
415
+ const mi = this.getModel().getModelItem(this.nodeset);
416
+ if (mi && !mi.relevant) return null;
400
417
 
401
- const doc = new DOMParser().parseFromString('<data></data>', 'application/xml');
402
- const root = doc.firstElementChild;
418
+ const doc = new DOMParser().parseFromString('<data></data>', 'application/xml');
419
+ const root = doc.firstElementChild;
403
420
 
404
- if (this.nodeset.children.length === 0 && this._isRelevant(this.nodeset)) {
405
- return this.nodeset;
421
+ if (this.nodeset.children.length === 0 && this._isRelevant(this.nodeset)) {
422
+ return this.nodeset;
423
+ }
424
+ return this._filterRelevant(this.nodeset, root);
406
425
  }
407
- return this._filterRelevant(this.nodeset, root);
408
- }
409
- */
410
-
411
- /*
412
- _filterRelevant(node, result) {
413
- const { childNodes } = node;
414
- Array.from(childNodes).forEach(n => {
415
- if (this._isRelevant(n)) {
416
- const clone = n.cloneNode(false);
417
- result.appendChild(clone);
418
- const { attributes } = n;
419
- if (attributes) {
420
- Array.from(attributes).forEach(attr => {
421
- if (this._isRelevant(attr)) {
422
- clone.setAttribute(attr.nodeName, attr.value);
423
- } else if (this.nonrelevant === 'empty') {
424
- clone.setAttribute(attr.nodeName, '');
425
- } else {
426
- clone.removeAttribute(attr.nodeName);
427
- }
428
- });
426
+ */
427
+
428
+ /*
429
+ _filterRelevant(node, result) {
430
+ const { childNodes } = node;
431
+ Array.from(childNodes).forEach(n => {
432
+ if (this._isRelevant(n)) {
433
+ const clone = n.cloneNode(false);
434
+ result.appendChild(clone);
435
+ const { attributes } = n;
436
+ if (attributes) {
437
+ Array.from(attributes).forEach(attr => {
438
+ if (this._isRelevant(attr)) {
439
+ clone.setAttribute(attr.nodeName, attr.value);
440
+ } else if (this.nonrelevant === 'empty') {
441
+ clone.setAttribute(attr.nodeName, '');
442
+ } else {
443
+ clone.removeAttribute(attr.nodeName);
444
+ }
445
+ });
446
+ }
447
+ return this._filterRelevant(n, clone);
429
448
  }
430
- return this._filterRelevant(n, clone);
431
- }
432
- return null;
433
- });
434
- return result;
435
- }
436
- */
437
-
438
- /*
439
- _isRelevant(node) {
440
- const mi = this.getModel().getModelItem(node);
441
- if (!mi || mi.relevant) {
442
- return true;
449
+ return null;
450
+ });
451
+ return result;
443
452
  }
444
- return false;
445
- }
446
- */
453
+ */
447
454
 
448
- _handleError() {
449
- // this.dispatch('submit-error', {});
450
- Fore.dispatch(this, 'submit-error', {});
451
455
  /*
452
- console.log('ERRRORRRRR');
453
- this.dispatchEvent(
454
- new CustomEvent('submit-error', {
455
- composed: true,
456
- bubbles: true,
457
- detail: {},
458
- }),
459
- );
460
- */
461
- }
456
+ _isRelevant(node) {
457
+ const mi = this.getModel().getModelItem(node);
458
+ if (!mi || mi.relevant) {
459
+ return true;
460
+ }
461
+ return false;
462
+ }
463
+ */
464
+
465
+ _handleError() {
466
+ // this.dispatch('submit-error', {});
467
+ Fore.dispatch(this, 'submit-error', {});
468
+ /*
469
+ console.log('ERRRORRRRR');
470
+ this.dispatchEvent(
471
+ new CustomEvent('submit-error', {
472
+ composed: true,
473
+ bubbles: true,
474
+ detail: {},
475
+ }),
476
+ );
477
+ */
478
+ }
462
479
  }
480
+
463
481
  if (!customElements.get('fx-submission')) {
464
- customElements.define('fx-submission', FxSubmission);
482
+ customElements.define('fx-submission', FxSubmission);
465
483
  }