@schukai/monster 3.70.0 → 3.71.1
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/CHANGELOG.md +17 -0
- package/README.md +1 -8
- package/package.json +1 -1
- package/source/components/datatable/datasource/rest.mjs +410 -404
- package/source/components/datatable/save-button.mjs +0 -8
- package/source/components/form/form.mjs +0 -7
- package/source/data/datasource/server/restapi.mjs +12 -3
- package/source/data/datasource/server.mjs +118 -74
- package/source/data/diff.mjs +1 -1
- package/test/cases/data/diff.mjs +37 -0
- package/test/web/test.html +0 -6
|
@@ -12,25 +12,27 @@
|
|
|
12
12
|
* SPDX-License-Identifier: AGPL-3.0
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
15
|
+
import {diff} from "../../../data/diff.mjs";
|
|
16
|
+
import {addAttributeToken} from "../../../dom/attributes.mjs";
|
|
17
|
+
import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs";
|
|
18
|
+
import {isArray} from "../../../types/is.mjs";
|
|
19
|
+
import {Datasource, dataSourceSymbol} from "../datasource.mjs";
|
|
20
|
+
import {DatasourceStyleSheet} from "../stylesheet/datasource.mjs";
|
|
21
|
+
import {instanceSymbol} from "../../../constants.mjs";
|
|
20
22
|
import {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
assembleMethodSymbol,
|
|
24
|
+
registerCustomElement,
|
|
23
25
|
} from "../../../dom/customelement.mjs";
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
26
|
+
import {RestAPI} from "../../../data/datasource/server/restapi.mjs";
|
|
27
|
+
import {Formatter} from "../../../text/formatter.mjs";
|
|
28
|
+
import {clone} from "../../../util/clone.mjs";
|
|
29
|
+
import {validateBoolean} from "../../../types/validate.mjs";
|
|
30
|
+
import {findElementWithIdUpwards} from "../../../dom/util.mjs";
|
|
31
|
+
import {Observer} from "../../../types/observer.mjs";
|
|
32
|
+
import {Pathfinder} from "../../../data/pathfinder.mjs";
|
|
33
|
+
import {fireCustomEvent} from "../../../dom/events.mjs";
|
|
32
34
|
|
|
33
|
-
export {
|
|
35
|
+
export {Rest};
|
|
34
36
|
|
|
35
37
|
/**
|
|
36
38
|
* @private
|
|
@@ -44,7 +46,7 @@ const intersectionObserverHandlerSymbol = Symbol("intersectionObserverHandler");
|
|
|
44
46
|
* @type {symbol}
|
|
45
47
|
*/
|
|
46
48
|
const rawDataSymbol = Symbol.for(
|
|
47
|
-
|
|
49
|
+
"@schukai/monster/data/datasource/server/restapi/rawdata",
|
|
48
50
|
);
|
|
49
51
|
|
|
50
52
|
/**
|
|
@@ -52,7 +54,7 @@ const rawDataSymbol = Symbol.for(
|
|
|
52
54
|
* @type {symbol}
|
|
53
55
|
*/
|
|
54
56
|
const intersectionObserverObserverSymbol = Symbol(
|
|
55
|
-
|
|
57
|
+
"intersectionObserverObserver",
|
|
56
58
|
);
|
|
57
59
|
|
|
58
60
|
/**
|
|
@@ -81,23 +83,23 @@ const filterObserverSymbol = Symbol("filterObserver");
|
|
|
81
83
|
* @summary A rest api datasource
|
|
82
84
|
*/
|
|
83
85
|
class Rest extends Datasource {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
86
|
+
/**
|
|
87
|
+
* the constructor of the class
|
|
88
|
+
*/
|
|
89
|
+
constructor() {
|
|
90
|
+
super();
|
|
91
|
+
this[dataSourceSymbol] = new RestAPI();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* This method is called by the `instanceof` operator.
|
|
96
|
+
* @returns {symbol}
|
|
97
|
+
*/
|
|
98
|
+
static get [instanceSymbol]() {
|
|
99
|
+
return Symbol.for("@schukai/monster/components/datasource/rest@@instance");
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
101
103
|
* To set the options via the html tag the attribute `data-monster-options` must be used.
|
|
102
104
|
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
|
103
105
|
*
|
|
@@ -128,405 +130,409 @@ class Rest extends Datasource {
|
|
|
128
130
|
* @property {Object} write Write configuration
|
|
129
131
|
|
|
130
132
|
*/
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
133
|
+
get defaults() {
|
|
134
|
+
const restOptions = new RestAPI().defaults;
|
|
135
|
+
|
|
136
|
+
restOptions.read.parameters = {
|
|
137
|
+
filter: undefined,
|
|
138
|
+
oderBy: undefined,
|
|
139
|
+
page: "1",
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
return Object.assign({}, super.defaults, restOptions, {
|
|
143
|
+
templates: {
|
|
144
|
+
main: getTemplate(),
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
features: {
|
|
148
|
+
autoInit: false,
|
|
149
|
+
filter: false,
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
autoInit: {
|
|
153
|
+
intersectionObserver: false,
|
|
154
|
+
oneTime: true,
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
filter: {
|
|
158
|
+
id: undefined,
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
datatable: {
|
|
162
|
+
id: undefined,
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
response: {
|
|
166
|
+
path: {
|
|
167
|
+
message: "sys.message",
|
|
168
|
+
code: "sys.code",
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
*
|
|
176
|
+
* @param {string} page
|
|
177
|
+
* @param {string} query
|
|
178
|
+
* @param {string} orderBy
|
|
179
|
+
* @returns {Monster.Components.Datatable.Datasource.Rest}
|
|
180
|
+
*/
|
|
181
|
+
setParameters({page, query, orderBy}) {
|
|
182
|
+
const parameters = this.getOption("read.parameters");
|
|
183
|
+
if (query !== undefined) {
|
|
184
|
+
parameters.query = `${query}`;
|
|
185
|
+
parameters.page = "1";
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// after a query the page is set to 1, so if the page is not set, it is set to 1
|
|
189
|
+
if (page !== undefined) parameters.page = `${page}`;
|
|
190
|
+
if (orderBy !== undefined) parameters.order = `${orderBy}`;
|
|
191
|
+
this.setOption("read.parameters", parameters);
|
|
192
|
+
return this;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* @return {void}
|
|
197
|
+
*/
|
|
198
|
+
[assembleMethodSymbol]() {
|
|
199
|
+
super[assembleMethodSymbol]();
|
|
200
|
+
|
|
201
|
+
initEventHandler.call(this);
|
|
202
|
+
initAutoInit.call(this);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* @deprecated 2023-06-25
|
|
207
|
+
* @returns {Promise<never>|*}
|
|
208
|
+
*/
|
|
209
|
+
reload() {
|
|
210
|
+
return this.fetch();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Fetches the data from the rest api
|
|
215
|
+
* @returns {Promise<never>|*}
|
|
216
|
+
*/
|
|
217
|
+
fetch() {
|
|
218
|
+
const opt = clone(this.getOption("read"));
|
|
219
|
+
this[dataSourceSymbol].setOption("read", opt);
|
|
220
|
+
|
|
221
|
+
let url = this.getOption("read.url");
|
|
222
|
+
const formatter = new Formatter(this.getOption("read.parameters"));
|
|
223
|
+
|
|
224
|
+
if (!url) {
|
|
225
|
+
return Promise.reject(new Error("No url defined"));
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
url = formatter.format(url);
|
|
229
|
+
|
|
230
|
+
this[dataSourceSymbol].setOption("read.url", url);
|
|
231
|
+
|
|
232
|
+
return new Promise((resolve, reject) => {
|
|
233
|
+
fireCustomEvent(this, "monster-datasource-fetch", {
|
|
234
|
+
datasource: this,
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
setTimeout(() => {
|
|
238
|
+
this[dataSourceSymbol]
|
|
239
|
+
.read()
|
|
240
|
+
.then((response) => {
|
|
241
|
+
fireCustomEvent(this, "monster-datasource-fetched", {
|
|
242
|
+
datasource: this,
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
resolve(response);
|
|
246
|
+
})
|
|
247
|
+
.catch((error) => {
|
|
248
|
+
fireCustomEvent(this, "monster-datasource-error", {
|
|
249
|
+
error: error,
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error.toString());
|
|
253
|
+
reject(error);
|
|
254
|
+
});
|
|
255
|
+
}, 0);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
*
|
|
261
|
+
* @return {CSSStyleSheet[]}
|
|
262
|
+
*/
|
|
263
|
+
static getCSSStyleSheet() {
|
|
264
|
+
return [DatasourceStyleSheet];
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* @private
|
|
269
|
+
* @return {string}
|
|
270
|
+
*/
|
|
271
|
+
static getTag() {
|
|
272
|
+
return "monster-datasource-rest";
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* This method activates the intersection observer manually.
|
|
277
|
+
* For this purpose, the option `autoInit.intersectionObserver` must be set to `false`.
|
|
278
|
+
*
|
|
279
|
+
* @returns {Monster.Components.Datatable.Datasource.Rest}
|
|
280
|
+
*/
|
|
281
|
+
initIntersectionObserver() {
|
|
282
|
+
initIntersectionObserver.call(this);
|
|
283
|
+
return this;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* @private
|
|
288
|
+
*/
|
|
289
|
+
connectedCallback() {
|
|
290
|
+
super.connectedCallback();
|
|
291
|
+
|
|
292
|
+
setTimeout(() => {
|
|
293
|
+
if (this.getOption("features.filter", false) === true) {
|
|
294
|
+
initFilter.call(this);
|
|
295
|
+
}
|
|
296
|
+
}, 0);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* @private
|
|
301
|
+
*/
|
|
302
|
+
disconnectedCallback() {
|
|
303
|
+
super.disconnectedCallback();
|
|
304
|
+
removeFilter.call(this);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* @returns {Promise<never>|*}
|
|
309
|
+
*/
|
|
310
|
+
read() {
|
|
311
|
+
return this.fetch();
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Fetches the data from the rest api
|
|
316
|
+
* @returns {Promise<never>|*}
|
|
317
|
+
*/
|
|
318
|
+
write() {
|
|
319
|
+
const opt = clone(this.getOption("write"));
|
|
320
|
+
this[dataSourceSymbol].setOption("write", opt);
|
|
321
|
+
|
|
322
|
+
let url = this.getOption("write.url");
|
|
323
|
+
const formatter = new Formatter(this.getOption("write.parameters"));
|
|
324
|
+
|
|
325
|
+
if (!url) {
|
|
326
|
+
return Promise.reject(new Error("No url defined"));
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
url = formatter.format(url);
|
|
330
|
+
|
|
331
|
+
this[dataSourceSymbol].setOption("write.url", url);
|
|
332
|
+
|
|
333
|
+
return new Promise((resolve, reject) => {
|
|
334
|
+
fireCustomEvent(this, "monster-datasource-fetch", {
|
|
335
|
+
datasource: this,
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
setTimeout(() => {
|
|
339
|
+
this[dataSourceSymbol]
|
|
340
|
+
.write()
|
|
341
|
+
.then((response) => {
|
|
342
|
+
fireCustomEvent(this, "monster-datasource-fetched", {
|
|
343
|
+
datasource: this,
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
resolve(response);
|
|
347
|
+
})
|
|
348
|
+
.catch((error) => {
|
|
349
|
+
fireCustomEvent(this, "monster-datasource-error", {
|
|
350
|
+
error: error,
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error.toString());
|
|
354
|
+
reject(error);
|
|
355
|
+
});
|
|
356
|
+
}, 0);
|
|
357
|
+
});
|
|
358
|
+
}
|
|
354
359
|
}
|
|
355
360
|
|
|
356
361
|
/**
|
|
357
362
|
* @private
|
|
358
363
|
*/
|
|
359
364
|
function removeFilter() {
|
|
360
|
-
|
|
361
|
-
|
|
365
|
+
const filterID = this.getOption("filter.id", undefined);
|
|
366
|
+
if (!filterID) return;
|
|
362
367
|
|
|
363
|
-
|
|
368
|
+
const filterControl = findElementWithIdUpwards(this, filterID);
|
|
364
369
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
370
|
+
if (filterControl && this[filterObserverSymbol]) {
|
|
371
|
+
filterControl?.detachObserver(this[filterObserverSymbol]);
|
|
372
|
+
}
|
|
368
373
|
}
|
|
369
374
|
|
|
370
375
|
/**
|
|
371
376
|
* @private
|
|
372
377
|
*/
|
|
373
378
|
function initFilter() {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
379
|
+
const filterID = this.getOption("filter.id", undefined);
|
|
380
|
+
|
|
381
|
+
if (!filterID)
|
|
382
|
+
throw new Error("filter feature is enabled but no filter id is defined");
|
|
383
|
+
|
|
384
|
+
const filterControl = findElementWithIdUpwards(this, filterID);
|
|
385
|
+
if (!filterControl)
|
|
386
|
+
throw new Error(
|
|
387
|
+
"filter feature is enabled but no filter control with id " +
|
|
388
|
+
filterID +
|
|
389
|
+
" is found",
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
this[filterObserverSymbol] = new Observer(() => {
|
|
393
|
+
const query = filterControl.getOption("query");
|
|
394
|
+
if (query === undefined) {
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
this.setParameters({query: query});
|
|
398
|
+
this.fetch()
|
|
399
|
+
.then((response) => {
|
|
400
|
+
if (!(response instanceof Response)) {
|
|
401
|
+
throw new Error("Response is not an instance of Response");
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (response?.ok === true) {
|
|
405
|
+
this.dispatchEvent(new CustomEvent("reload", {bubbles: true}));
|
|
406
|
+
filterControl?.showSuccess();
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (response.bodyUsed === true) {
|
|
410
|
+
return handleIntersectionObserver.call(
|
|
411
|
+
this,
|
|
412
|
+
response[rawDataSymbol],
|
|
413
|
+
response,
|
|
414
|
+
filterControl,
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
response
|
|
419
|
+
.text()
|
|
420
|
+
.then((jsonAsText) => {
|
|
421
|
+
let json;
|
|
422
|
+
try {
|
|
423
|
+
json = JSON.parse(jsonAsText);
|
|
424
|
+
} catch (e) {
|
|
425
|
+
const message = e instanceof Error ? e.message : `${e}`;
|
|
426
|
+
filterControl?.showFailureMessage(message);
|
|
427
|
+
return Promise.reject(e);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
return handleIntersectionObserver.call(
|
|
431
|
+
this,
|
|
432
|
+
json,
|
|
433
|
+
response,
|
|
434
|
+
filterControl,
|
|
435
|
+
);
|
|
436
|
+
})
|
|
437
|
+
.catch((e) => {
|
|
438
|
+
filterControl?.showFailureMessage(e.message);
|
|
439
|
+
});
|
|
440
|
+
})
|
|
441
|
+
.catch((e) => {
|
|
442
|
+
this.dispatchEvent(
|
|
443
|
+
new CustomEvent("error", {bubbles: true, detail: e}),
|
|
444
|
+
);
|
|
445
|
+
|
|
446
|
+
if (!(e instanceof Error)) {
|
|
447
|
+
e = new Error(e);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
filterControl?.showFailureMessage(e.message);
|
|
451
|
+
return Promise.reject(e);
|
|
452
|
+
});
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
filterControl.attachObserver(this[filterObserverSymbol]);
|
|
451
456
|
}
|
|
452
457
|
|
|
453
458
|
function handleIntersectionObserver(json, response, filterControl) {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
459
|
+
const path = new Pathfinder(json);
|
|
460
|
+
|
|
461
|
+
const codePath = this.getOption("response.path.code");
|
|
462
|
+
|
|
463
|
+
if (path.exists(codePath)) {
|
|
464
|
+
const code = `${path.getVia(codePath)}`;
|
|
465
|
+
if (code && code === "200") {
|
|
466
|
+
filterControl?.showSuccess();
|
|
467
|
+
return Promise.resolve(response);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
const messagePath = this.getOption("response.path.message");
|
|
471
|
+
if (path.exists(messagePath)) {
|
|
472
|
+
const message = path.getVia(messagePath);
|
|
473
|
+
filterControl?.showFailureMessage(message);
|
|
474
|
+
return Promise.reject(new Error(message));
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
return Promise.reject(new Error("Response code is not 200"));
|
|
478
|
+
}
|
|
474
479
|
}
|
|
475
480
|
|
|
476
481
|
/**
|
|
477
482
|
* @private
|
|
478
483
|
*/
|
|
479
484
|
function initAutoInit() {
|
|
480
|
-
|
|
481
|
-
const autoInit = this.getOption("features.autoInit");
|
|
482
|
-
validateBoolean(autoInit);
|
|
483
485
|
|
|
484
|
-
|
|
486
|
+
const autoInit = this.getOption("features.autoInit");
|
|
487
|
+
validateBoolean(autoInit);
|
|
488
|
+
|
|
489
|
+
if (autoInit !== true) return;
|
|
485
490
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
491
|
+
if (this.getOption("autoInit.intersectionObserver") === true) {
|
|
492
|
+
initIntersectionObserver.call(this);
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
490
495
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
496
|
+
setTimeout(() => {
|
|
497
|
+
this.fetch().catch(() => {
|
|
498
|
+
});
|
|
499
|
+
}, 0);
|
|
494
500
|
}
|
|
495
501
|
|
|
496
502
|
function initEventHandler() {
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
503
|
+
this[intersectionObserverHandlerSymbol] = (entries) => {
|
|
504
|
+
entries.forEach((entry) => {
|
|
505
|
+
if (entry.isIntersecting) {
|
|
506
|
+
if (entry.intersectionRatio > 0) {
|
|
507
|
+
this.fetch();
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// only load once
|
|
511
|
+
if (
|
|
512
|
+
this.getOption("autoInit.oneTime") === true &&
|
|
513
|
+
this[intersectionObserverObserverSymbol] !== undefined
|
|
514
|
+
) {
|
|
515
|
+
this[intersectionObserverObserverSymbol].unobserve(this);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
};
|
|
514
520
|
}
|
|
515
521
|
|
|
516
522
|
function initIntersectionObserver() {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
523
|
+
this.classList.add("intersection-observer");
|
|
524
|
+
|
|
525
|
+
const options = {
|
|
526
|
+
root: null,
|
|
527
|
+
rootMargin: "0px",
|
|
528
|
+
threshold: 0.1,
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
this[intersectionObserverObserverSymbol] = new IntersectionObserver(
|
|
532
|
+
this[intersectionObserverHandlerSymbol],
|
|
533
|
+
options,
|
|
534
|
+
);
|
|
535
|
+
this[intersectionObserverObserverSymbol].observe(this);
|
|
530
536
|
}
|
|
531
537
|
|
|
532
538
|
/**
|
|
@@ -534,8 +540,8 @@ function initIntersectionObserver() {
|
|
|
534
540
|
* @return {string}
|
|
535
541
|
*/
|
|
536
542
|
function getTemplate() {
|
|
537
|
-
|
|
538
|
-
|
|
543
|
+
// language=HTML
|
|
544
|
+
return `
|
|
539
545
|
<slot></slot>`;
|
|
540
546
|
}
|
|
541
547
|
|