@schukai/monster 3.53.0 → 3.55.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/package.json +1 -1
  3. package/source/components/datatable/datasource/rest.mjs +358 -309
  4. package/source/components/datatable/datatable/header.mjs +8 -0
  5. package/source/components/datatable/datatable.mjs +606 -557
  6. package/source/components/datatable/embedded-pagination.mjs +50 -62
  7. package/source/components/datatable/filter/util.mjs +122 -0
  8. package/source/components/datatable/filter.mjs +893 -708
  9. package/source/components/datatable/pagination.mjs +335 -310
  10. package/source/components/datatable/status.mjs +248 -0
  11. package/source/components/datatable/style/datatable.pcss +1 -0
  12. package/source/components/datatable/style/embedded-pagination.pcss +59 -2
  13. package/source/components/datatable/style/filter.pcss +4 -0
  14. package/source/components/datatable/style/pagination.pcss +28 -4
  15. package/source/components/datatable/style/status.pcss +42 -0
  16. package/source/components/datatable/stylesheet/column-bar.mjs +1 -1
  17. package/source/components/datatable/stylesheet/datatable.mjs +1 -1
  18. package/source/components/datatable/stylesheet/filter-button.mjs +1 -1
  19. package/source/components/datatable/stylesheet/filter.mjs +1 -1
  20. package/source/components/datatable/stylesheet/pagination.mjs +1 -1
  21. package/source/components/datatable/stylesheet/status.mjs +27 -0
  22. package/source/components/form/action-button.mjs +1 -1
  23. package/source/components/form/api-button.mjs +1 -1
  24. package/source/components/form/button-bar.mjs +1 -1
  25. package/source/components/form/button.mjs +1 -1
  26. package/source/components/form/confirm-button.mjs +1 -1
  27. package/source/components/form/context-error.mjs +275 -0
  28. package/source/components/form/context-help.mjs +5 -5
  29. package/source/components/form/form.mjs +2 -2
  30. package/source/components/form/message-state-button.mjs +2 -2
  31. package/source/components/form/popper-button.mjs +7 -4
  32. package/source/components/form/popper.mjs +317 -309
  33. package/source/components/form/reload.mjs +1 -1
  34. package/source/components/form/select.mjs +9 -3
  35. package/source/components/form/shadow-reload.mjs +1 -1
  36. package/source/components/form/state-button.mjs +2 -1
  37. package/source/components/form/style/context-error.pcss +32 -0
  38. package/source/components/form/style/context-help.pcss +22 -5
  39. package/source/components/form/stylesheet/context-error.mjs +27 -0
  40. package/source/components/form/stylesheet/context-help.mjs +1 -1
  41. package/source/components/form/stylesheet/select.mjs +1 -1
  42. package/source/components/form/stylesheet/tabs.mjs +1 -1
  43. package/source/components/form/tabs.mjs +757 -707
  44. package/source/components/form/template.mjs +1 -1
  45. package/source/components/form/tree-select.mjs +1 -1
  46. package/source/components/host/collapse.mjs +22 -5
  47. package/source/components/host/config-manager.mjs +39 -2
  48. package/source/components/host/host.mjs +14 -0
  49. package/source/components/host/stylesheet/call-button.mjs +1 -1
  50. package/source/components/host/stylesheet/overlay.mjs +1 -1
  51. package/source/components/host/stylesheet/toggle-button.mjs +1 -1
  52. package/source/components/host/util.mjs +6 -1
  53. package/source/components/notify/stylesheet/message.mjs +1 -1
  54. package/source/components/stylesheet/icons.mjs +1 -1
  55. package/source/data/transformer.mjs +39 -42
  56. package/source/dom/customelement.mjs +1 -1
  57. package/source/dom/updater.mjs +700 -688
  58. package/source/dom/util.mjs +42 -0
  59. package/source/i18n/providers/embed.mjs +3 -3
  60. package/source/monster.mjs +6 -0
  61. package/source/text/formatter.mjs +2 -2
  62. package/source/types/observer.mjs +1 -1
  63. package/source/types/version.mjs +1 -1
  64. package/source/util/sleep.mjs +18 -0
  65. package/test/cases/components/form/button.mjs +2 -1
  66. package/test/cases/components/form/select.mjs +1 -1
  67. package/test/cases/components/form/tree-select.mjs +1 -1
  68. package/test/cases/data/transformer.mjs +2 -2
  69. package/test/cases/dom/updater.mjs +67 -46
  70. package/test/cases/monster.mjs +1 -1
  71. package/test/web/test.html +2 -2
  72. package/test/web/tests.js +18 -13
@@ -3,25 +3,25 @@
3
3
  * SPDX-License-Identifier: AGPL-3.0
4
4
  */
5
5
 
6
- import { addAttributeToken } from "../../../dom/attributes.mjs";
7
- import { ATTRIBUTE_ERRORMESSAGE } from "../../../dom/constants.mjs";
8
- import { Datasource, dataSourceSymbol } from "../datasource.mjs";
9
- import { DatasourceStyleSheet } from "../stylesheet/datasource.mjs";
10
- import { instanceSymbol } from "../../../constants.mjs";
6
+ import {addAttributeToken} from "../../../dom/attributes.mjs";
7
+ import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs";
8
+ import {Datasource, dataSourceSymbol} from "../datasource.mjs";
9
+ import {DatasourceStyleSheet} from "../stylesheet/datasource.mjs";
10
+ import {instanceSymbol} from "../../../constants.mjs";
11
11
  import {
12
- assembleMethodSymbol,
13
- registerCustomElement,
12
+ assembleMethodSymbol,
13
+ registerCustomElement,
14
14
  } from "../../../dom/customelement.mjs";
15
- import { RestAPI } from "../../../data/datasource/server/restapi.mjs";
16
- import { Formatter } from "../../../text/formatter.mjs";
17
- import { clone } from "../../../util/clone.mjs";
18
- import { validateBoolean } from "../../../types/validate.mjs";
19
- import { findElementWithIdUpwards } from "../../../dom/util.mjs";
20
- import { Observer } from "../../../types/observer.mjs";
21
- import { Pathfinder } from "../../../data/pathfinder.mjs";
22
- import { fireCustomEvent } from "../../../dom/events.mjs";
15
+ import {RestAPI} from "../../../data/datasource/server/restapi.mjs";
16
+ import {Formatter} from "../../../text/formatter.mjs";
17
+ import {clone} from "../../../util/clone.mjs";
18
+ import {validateBoolean} from "../../../types/validate.mjs";
19
+ import {findElementWithIdUpwards} from "../../../dom/util.mjs";
20
+ import {Observer} from "../../../types/observer.mjs";
21
+ import {Pathfinder} from "../../../data/pathfinder.mjs";
22
+ import {fireCustomEvent} from "../../../dom/events.mjs";
23
23
 
24
- export { Rest };
24
+ export {Rest};
25
25
 
26
26
  /**
27
27
  * @private
@@ -34,7 +34,7 @@ const intersectionObserverHandlerSymbol = Symbol("intersectionObserverHandler");
34
34
  * @type {symbol}
35
35
  */
36
36
  const intersectionObserverObserverSymbol = Symbol(
37
- "intersectionObserverObserver",
37
+ "intersectionObserverObserver",
38
38
  );
39
39
 
40
40
  /**
@@ -63,322 +63,371 @@ const filterObserverSymbol = Symbol("filterObserver");
63
63
  * @summary A rest api datasource
64
64
  */
65
65
  class Rest extends Datasource {
66
- /**
67
- * the constructor of the class
68
- */
69
- constructor() {
70
- super();
71
- this[dataSourceSymbol] = new RestAPI();
72
- }
73
-
74
- /**
75
- * This method is called by the `instanceof` operator.
76
- * @returns {symbol}
77
- */
78
- static get [instanceSymbol]() {
79
- return Symbol.for("@schukai/monster/components/datasource/rest@@instance");
80
- }
81
-
82
- /**
83
- * To set the options via the html tag the attribute `data-monster-options` must be used.
84
- * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
85
- *
86
- * The individual configuration values can be found in the table.
87
- *
88
- * @property {Object} templates Template definitions
89
- * @property {string} templates.main Main template
90
- * @property {Object} features Feature definitions
91
- * @property {boolean} features.autoInit If true, the component is initialized automatically
92
- * @property {Object} read Read configuration
93
- * @property {string} read.url The url of the rest api
94
- * @property {string} read.method The method of the rest api
95
- * @property {Object} read.parameters The parameters of the rest api
96
- * @property {Object} read.parameters.filter The filter of the rest api
97
- * @property {Object} read.parameters.orderBy The order by of the rest api
98
- * @property {Object} read.parameters.page The page of the rest api
99
- * @property {Object} write Write configuration
100
- */
101
- get defaults() {
102
- const restOptions = new RestAPI().defaults;
103
-
104
- restOptions.read.parameters = {
105
- filter: undefined,
106
- oderBy: undefined,
107
- page: "1",
108
- };
109
-
110
- return Object.assign({}, super.defaults, restOptions, {
111
- templates: {
112
- main: getTemplate(),
113
- },
114
-
115
- features: {
116
- autoInit: true,
117
- filter: false,
118
- },
119
-
120
- autoInit: {
121
- intersectionObserver: false,
122
- oneTime: true,
123
- },
124
-
125
- filter: {
126
- id: undefined,
127
- },
128
-
129
- response: {
130
- errorMessagePath: "sys.message",
131
- },
132
- });
133
- }
134
-
135
- /**
136
- *
137
- * @param {string} page
138
- * @param {string} query
139
- * @param {string} orderBy
140
- * @returns {Monster.Components.Datatable.Datasource.Rest}
141
- */
142
- setParameters({ page, query, orderBy }) {
143
- const parameters = this.getOption("read.parameters");
144
- if (query !== undefined) {
145
- parameters.query = `${query}`;
146
- parameters.page = "1";
147
- }
148
-
149
- // after a query the page is set to 1, so if the page is not set, it is set to 1
150
- if (page !== undefined) parameters.page = `${page}`;
151
- if (orderBy !== undefined) parameters.order = `${orderBy}`;
152
- this.setOption("read.parameters", parameters);
153
- return this;
154
- }
155
-
156
- /**
157
- *
158
- * @return {Monster.Components.Form.Form}
159
- */
160
- [assembleMethodSymbol]() {
161
- super[assembleMethodSymbol]();
162
-
163
- initEventHandler.call(this);
164
- initAutoInit.call(this);
165
- }
166
-
167
- /**
168
- * @deprecated 2023-06-25
169
- * @returns {Promise<never>|*}
170
- */
171
- reload() {
172
- return this.fetch();
173
- }
174
-
175
- /**
176
- * Fetches the data from the rest api
177
- * @returns {Promise<never>|*}
178
- */
179
- fetch() {
180
- const opt = clone(this.getOption("read"));
181
- this[dataSourceSymbol].setOption("read", opt);
182
-
183
- let url = this.getOption("read.url");
184
- const formatter = new Formatter(this.getOption("read.parameters"));
185
-
186
- if (!url) {
187
- return Promise.reject(new Error("No url defined"));
188
- }
189
-
190
- url = formatter.format(url);
191
-
192
- this[dataSourceSymbol].setOption("read.url", url);
193
- return this[dataSourceSymbol].read();
194
- }
195
-
196
- /**
197
- *
198
- * @return {CSSStyleSheet[]}
199
- */
200
- static getCSSStyleSheet() {
201
- return [DatasourceStyleSheet];
202
- }
203
-
204
- /**
205
- * @private
206
- * @return {string}
207
- */
208
- static getTag() {
209
- return "monster-datasource-rest";
210
- }
211
-
212
- /**
213
- * This method activates the intersection observer manually.
214
- * For this purpose, the option `autoInit.intersectionObserver` must be set to `false`.
215
- *
216
- * @returns {Monster.Components.Datatable.Datasource.Rest}
217
- */
218
- initIntersectionObserver() {
219
- initIntersectionObserver.call(this);
220
- return this;
221
- }
222
-
223
- /**
224
- * @private
225
- */
226
- connectedCallback() {
227
- super.connectedCallback();
228
-
229
- setTimeout(() => {
230
- if (this.getOption("features.filter", false) === true) {
231
- initFilter.call(this);
232
- }
233
- }, 0);
234
- }
235
-
236
- /**
237
- * @private
238
- */
239
- disconnectedCallback() {
240
- super.disconnectedCallback();
241
- removeFilter.call(this);
242
- }
66
+ /**
67
+ * the constructor of the class
68
+ */
69
+ constructor() {
70
+ super();
71
+ this[dataSourceSymbol] = new RestAPI();
72
+ }
73
+
74
+ /**
75
+ * This method is called by the `instanceof` operator.
76
+ * @returns {symbol}
77
+ */
78
+ static get [instanceSymbol]() {
79
+ return Symbol.for("@schukai/monster/components/datasource/rest@@instance");
80
+ }
81
+
82
+ /**
83
+ * To set the options via the html tag the attribute `data-monster-options` must be used.
84
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
85
+ *
86
+ * The individual configuration values can be found in the table.
87
+ *
88
+ * @property {Object} templates Template definitions
89
+ * @property {string} templates.main Main template
90
+ * @property {Object} features Feature definitions
91
+ * @property {boolean} features.autoInit If true, the component is initialized automatically
92
+ * @property {boolean} features.filter If true, the component is initialized automatically
93
+ * @property {Object} autoInit Auto init definitions
94
+ * @property {boolean} autoInit.intersectionObserver If true, the intersection observer is initialized automatically
95
+ * @property {boolean} autoInit.oneTime If true, the intersection observer is initialized only once
96
+ * @property {Object} filter Filter definitions
97
+ * @property {string} filter.id The id of the filter control
98
+ * @property {Object} datatable Datatable definitions
99
+ * @property {string} datatable.id The id of the datatable control
100
+ * @property {Object} response Response definitions
101
+ * @property {string} response.errorMessagePath The path to the error message in the response
102
+ * @property {Object} read Read configuration
103
+ * @property {string} read.url The url of the rest api
104
+ * @property {string} read.method The method of the rest api
105
+ * @property {Object} read.parameters The parameters of the rest api
106
+ * @property {Object} read.parameters.filter The filter of the rest api
107
+ * @property {Object} read.parameters.orderBy The order by of the rest api
108
+ * @property {Object} read.parameters.page The page of the rest api
109
+ * @property {Object} write Write configuration
110
+
111
+ */
112
+ get defaults() {
113
+ const restOptions = new RestAPI().defaults;
114
+
115
+ restOptions.read.parameters = {
116
+ filter: undefined,
117
+ oderBy: undefined,
118
+ page: "1",
119
+ };
120
+
121
+ return Object.assign({}, super.defaults, restOptions, {
122
+ templates: {
123
+ main: getTemplate(),
124
+ },
125
+
126
+ features: {
127
+ autoInit: true,
128
+ filter: false,
129
+ },
130
+
131
+ autoInit: {
132
+ intersectionObserver: false,
133
+ oneTime: true,
134
+ },
135
+
136
+ filter: {
137
+ id: undefined,
138
+ },
139
+
140
+ datatable: {
141
+ id: undefined,
142
+ },
143
+
144
+ response: {
145
+ errorMessagePath: "sys.message",
146
+ },
147
+ });
148
+ }
149
+
150
+ /**
151
+ *
152
+ * @param {string} page
153
+ * @param {string} query
154
+ * @param {string} orderBy
155
+ * @returns {Monster.Components.Datatable.Datasource.Rest}
156
+ */
157
+ setParameters({page, query, orderBy}) {
158
+ const parameters = this.getOption("read.parameters");
159
+ if (query !== undefined) {
160
+ parameters.query = `${query}`;
161
+ parameters.page = "1";
162
+ }
163
+
164
+ // after a query the page is set to 1, so if the page is not set, it is set to 1
165
+ if (page !== undefined) parameters.page = `${page}`;
166
+ if (orderBy !== undefined) parameters.order = `${orderBy}`;
167
+ this.setOption("read.parameters", parameters);
168
+ return this;
169
+ }
170
+
171
+ /**
172
+ *
173
+ * @return {Monster.Components.Form.Form}
174
+ */
175
+ [assembleMethodSymbol]() {
176
+ super[assembleMethodSymbol]();
177
+
178
+ initEventHandler.call(this);
179
+ initAutoInit.call(this);
180
+ }
181
+
182
+ /**
183
+ * @deprecated 2023-06-25
184
+ * @returns {Promise<never>|*}
185
+ */
186
+ reload() {
187
+ return this.fetch();
188
+ }
189
+
190
+ /**
191
+ * Fetches the data from the rest api
192
+ * @returns {Promise<never>|*}
193
+ */
194
+ fetch() {
195
+ const self = this;
196
+ const opt = clone(this.getOption("read"));
197
+ this[dataSourceSymbol].setOption("read", opt);
198
+
199
+ let url = this.getOption("read.url");
200
+ const formatter = new Formatter(this.getOption("read.parameters"));
201
+
202
+ if (!url) {
203
+ return Promise.reject(new Error("No url defined"));
204
+ }
205
+
206
+ url = formatter.format(url);
207
+
208
+ this[dataSourceSymbol].setOption("read.url", url);
209
+
210
+ return new Promise((resolve, reject) => {
211
+
212
+ fireCustomEvent(self, "monster-datasource-fetch", {
213
+ datasource: self,
214
+ });
215
+
216
+ setTimeout(() => {
217
+ self[dataSourceSymbol].read().then((response) => {
218
+ fireCustomEvent(self, "monster-datasource-fetched", {
219
+ datasource: self,
220
+ });
221
+
222
+ resolve(response);
223
+
224
+ })
225
+ .catch((error) => {
226
+ fireCustomEvent(self, "monster-datasource-error", {
227
+ error: error,
228
+ });
229
+
230
+ addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, error.toString());
231
+ reject(error);
232
+
233
+ });
234
+ },0);
235
+
236
+ });
237
+
238
+
239
+ }
240
+
241
+ /**
242
+ *
243
+ * @return {CSSStyleSheet[]}
244
+ */
245
+ static getCSSStyleSheet() {
246
+ return [DatasourceStyleSheet];
247
+ }
248
+
249
+ /**
250
+ * @private
251
+ * @return {string}
252
+ */
253
+ static getTag() {
254
+ return "monster-datasource-rest";
255
+ }
256
+
257
+ /**
258
+ * This method activates the intersection observer manually.
259
+ * For this purpose, the option `autoInit.intersectionObserver` must be set to `false`.
260
+ *
261
+ * @returns {Monster.Components.Datatable.Datasource.Rest}
262
+ */
263
+ initIntersectionObserver() {
264
+ initIntersectionObserver.call(this);
265
+ return this;
266
+ }
267
+
268
+ /**
269
+ * @private
270
+ */
271
+ connectedCallback() {
272
+ super.connectedCallback();
273
+
274
+ setTimeout(() => {
275
+ if (this.getOption("features.filter", false) === true) {
276
+ initFilter.call(this);
277
+ }
278
+ }, 0);
279
+ }
280
+
281
+ /**
282
+ * @private
283
+ */
284
+ disconnectedCallback() {
285
+ super.disconnectedCallback();
286
+ removeFilter.call(this);
287
+ }
243
288
  }
244
289
 
245
290
  /**
246
291
  * @private
247
292
  */
248
293
  function removeFilter() {
249
- const filterID = this.getOption("filter.id", undefined);
250
- if (!filterID) return;
294
+ const filterID = this.getOption("filter.id", undefined);
295
+ if (!filterID) return;
251
296
 
252
- const filterControl = findElementWithIdUpwards(this, filterID);
297
+ const filterControl = findElementWithIdUpwards(this, filterID);
253
298
 
254
- if (filterControl && this[filterObserverSymbol]) {
255
- filterControl?.detachObserver(this[filterObserverSymbol]);
256
- }
299
+ if (filterControl && this[filterObserverSymbol]) {
300
+ filterControl?.detachObserver(this[filterObserverSymbol]);
301
+ }
257
302
  }
258
303
 
304
+
259
305
  /**
260
306
  * @private
261
307
  */
262
308
  function initFilter() {
263
- const filterID = this.getOption("filter.id", undefined);
264
-
265
- if (!filterID)
266
- throw new Error("filter feature is enabled but no filter id is defined");
267
-
268
- const filterControl = findElementWithIdUpwards(this, filterID);
269
- if (!filterControl)
270
- throw new Error(
271
- "filter feature is enabled but no filter control with id " +
272
- filterID +
273
- " is found",
274
- );
275
-
276
- this[filterObserverSymbol] = new Observer(() => {
277
- const query = filterControl.getOption("query", undefined);
278
- this.setParameters({ query: query });
279
- this.fetch()
280
- .then(() => {
281
- this.dispatchEvent(new CustomEvent("reload", { bubbles: true }));
282
- filterControl?.showSuccess();
283
- })
284
- .catch((e) => {
285
- this.dispatchEvent(
286
- new CustomEvent("error", { bubbles: true, detail: e }),
287
- );
288
-
289
- const response = e?.getResponse();
290
- if (response && response.status === 400) {
291
- response
292
- .json()
293
- .then((json) => {
294
- const path = new Pathfinder(json);
295
- const error = path.getVia(
296
- this.getOption("response.errorMessagePath"),
297
- );
298
- if (error) {
299
- filterControl?.showFailureMessage(error);
300
- return;
301
- }
302
-
303
- filterControl?.showFailureMessage(e.message);
304
- })
305
- .catch((e) => {
306
- filterControl?.showFailureMessage(e.message);
307
- });
308
- } else {
309
- filterControl?.showFailureMessage(e.message);
310
- }
311
- });
312
- });
313
-
314
- filterControl.attachObserver(this[filterObserverSymbol]);
309
+ const filterID = this.getOption("filter.id", undefined);
310
+
311
+ if (!filterID)
312
+ throw new Error("filter feature is enabled but no filter id is defined");
313
+
314
+ const filterControl = findElementWithIdUpwards(this, filterID);
315
+ if (!filterControl)
316
+ throw new Error(
317
+ "filter feature is enabled but no filter control with id " +
318
+ filterID +
319
+ " is found",
320
+ );
321
+
322
+ this[filterObserverSymbol] = new Observer(() => {
323
+
324
+ const query = filterControl.getOption("query", undefined);
325
+ this.setParameters({query: query});
326
+ this.fetch()
327
+ .then((response) => {
328
+
329
+ if(!(response instanceof Response) ){
330
+ throw new Error("Response is not an instance of Response");
331
+ }
332
+
333
+ if (response?.ok === true) {
334
+ this.dispatchEvent(new CustomEvent("reload", {bubbles: true}));
335
+ filterControl?.showSuccess();
336
+ }
337
+
338
+ response
339
+ .json()
340
+ .then((json) => {
341
+ const path = new Pathfinder(json);
342
+ const error = path.getVia(
343
+ this.getOption("response.errorMessagePath"),
344
+ );
345
+ if (error) {
346
+ filterControl?.showFailureMessage(error);
347
+ return;
348
+ }
349
+
350
+ filterControl?.showFailureMessage(e.message);
351
+ })
352
+ .catch((e) => {
353
+ filterControl?.showFailureMessage(e.message);
354
+ });
355
+
356
+
357
+ })
358
+ .catch((e) => {
359
+ this.dispatchEvent(
360
+ new CustomEvent("error", {bubbles: true, detail: e}),
361
+ );
362
+
363
+ if (!(e instanceof Error)) {
364
+ e = new Error(e);
365
+ }
366
+
367
+ filterControl?.showFailureMessage(e.message);
368
+ return Promise.reject(e);
369
+
370
+ });
371
+ });
372
+
373
+ filterControl.attachObserver(this[filterObserverSymbol]);
315
374
  }
316
375
 
317
376
  /**
318
377
  * @private
319
378
  */
320
379
  function initAutoInit() {
321
- const autoInit = this.getOption("features.autoInit");
322
- validateBoolean(autoInit);
323
-
324
- if (autoInit !== true) return;
325
-
326
- if (this.getOption("autoInit.intersectionObserver") === true) {
327
- initIntersectionObserver.call(this);
328
- return;
329
- }
330
-
331
- setTimeout(() => {
332
- this.fetch()
333
- .then(() => {
334
- fireCustomEvent(this, "monster-datasource-fetched", {
335
- datasource: this,
336
- });
337
- })
338
- .catch((error) => {
339
- fireCustomEvent(this, "monster-datasource-error", {
340
- error: error,
341
- });
342
-
343
- addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, String(error));
344
- });
345
- }, 0);
380
+ const autoInit = this.getOption("features.autoInit");
381
+ validateBoolean(autoInit);
382
+
383
+ if (autoInit !== true) return;
384
+
385
+ if (this.getOption("autoInit.intersectionObserver") === true) {
386
+ initIntersectionObserver.call(this);
387
+ return;
388
+ }
389
+
390
+ setTimeout(() => {
391
+ this.fetch().catch(() => {
392
+
393
+ });
394
+ }, 0);
346
395
  }
347
396
 
348
397
  function initEventHandler() {
349
- this[intersectionObserverHandlerSymbol] = (entries) => {
350
- entries.forEach((entry) => {
351
- if (entry.isIntersecting) {
352
- if (entry.intersectionRatio > 0) {
353
- this.fetch();
354
- }
355
-
356
- // only load once
357
- if (
358
- this.getOption("autoInit.oneTime") === true &&
359
- this[intersectionObserverObserverSymbol] !== undefined
360
- ) {
361
- this[intersectionObserverObserverSymbol].unobserve(this);
362
- }
363
- }
364
- });
365
- };
398
+ this[intersectionObserverHandlerSymbol] = (entries) => {
399
+ entries.forEach((entry) => {
400
+ if (entry.isIntersecting) {
401
+ if (entry.intersectionRatio > 0) {
402
+ this.fetch();
403
+ }
404
+
405
+ // only load once
406
+ if (
407
+ this.getOption("autoInit.oneTime") === true &&
408
+ this[intersectionObserverObserverSymbol] !== undefined
409
+ ) {
410
+ this[intersectionObserverObserverSymbol].unobserve(this);
411
+ }
412
+ }
413
+ });
414
+ };
366
415
  }
367
416
 
368
417
  function initIntersectionObserver() {
369
- this.classList.add("intersection-observer");
370
-
371
- const options = {
372
- root: null,
373
- rootMargin: "0px",
374
- threshold: 0.1,
375
- };
376
-
377
- this[intersectionObserverObserverSymbol] = new IntersectionObserver(
378
- this[intersectionObserverHandlerSymbol],
379
- options,
380
- );
381
- this[intersectionObserverObserverSymbol].observe(this);
418
+ this.classList.add("intersection-observer");
419
+
420
+ const options = {
421
+ root: null,
422
+ rootMargin: "0px",
423
+ threshold: 0.1,
424
+ };
425
+
426
+ this[intersectionObserverObserverSymbol] = new IntersectionObserver(
427
+ this[intersectionObserverHandlerSymbol],
428
+ options,
429
+ );
430
+ this[intersectionObserverObserverSymbol].observe(this);
382
431
  }
383
432
 
384
433
  /**
@@ -386,8 +435,8 @@ function initIntersectionObserver() {
386
435
  * @return {string}
387
436
  */
388
437
  function getTemplate() {
389
- // language=HTML
390
- return `
438
+ // language=HTML
439
+ return `
391
440
  <slot></slot>`;
392
441
  }
393
442