@schukai/monster 4.38.4 → 4.38.5
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 +12 -0
- package/package.json +1 -1
- package/source/components/datatable/filter.mjs +1339 -1342
- package/source/components/datatable/save-button.mjs +331 -331
- package/source/components/form/select.mjs +2851 -2851
- package/source/components/form/toggle-switch.mjs +359 -359
- package/source/components/style/property.css +265 -261
- package/source/dom/updater.mjs +842 -838
- package/source/i18n/translations.mjs +206 -206
- package/source/types/observer.mjs +127 -132
- package/source/types/version.mjs +1 -1
- package/test/cases/dom/updater.mjs +639 -626
- package/test/cases/monster.mjs +1 -1
- package/test/web/test.html +2 -2
- package/test/web/tests.js +513 -452
@@ -14,18 +14,18 @@
|
|
14
14
|
|
15
15
|
import { instanceSymbol } from "../../constants.mjs";
|
16
16
|
import {
|
17
|
-
|
18
|
-
|
17
|
+
findTargetElementFromEvent,
|
18
|
+
fireCustomEvent,
|
19
19
|
} from "../../dom/events.mjs";
|
20
20
|
import {
|
21
|
-
|
22
|
-
|
21
|
+
findElementWithIdUpwards,
|
22
|
+
findElementWithSelectorUpwards,
|
23
23
|
} from "../../dom/util.mjs";
|
24
24
|
import {
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
assembleMethodSymbol,
|
26
|
+
CustomElement,
|
27
|
+
getSlottedElements,
|
28
|
+
registerCustomElement,
|
29
29
|
} from "../../dom/customelement.mjs";
|
30
30
|
import { ID } from "../../types/id.mjs";
|
31
31
|
import { Settings } from "./filter/settings.mjs";
|
@@ -33,11 +33,11 @@ import { FilterStyleSheet } from "./stylesheet/filter.mjs";
|
|
33
33
|
import { getDocument, getWindow } from "../../dom/util.mjs";
|
34
34
|
import { getGlobal } from "../../types/global.mjs";
|
35
35
|
import {
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
isInstance,
|
37
|
+
isFunction,
|
38
|
+
isObject,
|
39
|
+
isArray,
|
40
|
+
isString,
|
41
41
|
} from "../../types/is.mjs";
|
42
42
|
import { Host } from "../host/host.mjs";
|
43
43
|
import { addAttributeToken } from "../../dom/attributes.mjs";
|
@@ -47,17 +47,17 @@ import { Formatter } from "../../text/formatter.mjs";
|
|
47
47
|
import { generateRangeComparisonExpression } from "../../text/util.mjs";
|
48
48
|
|
49
49
|
import {
|
50
|
-
|
51
|
-
|
50
|
+
parseBracketedKeyValueHash,
|
51
|
+
createBracketedKeyValueHash,
|
52
52
|
} from "../../text/bracketed-key-value-hash.mjs";
|
53
53
|
import { ThemeStyleSheet } from "../stylesheet/theme.mjs";
|
54
54
|
import { SpaceStyleSheet } from "../stylesheet/space.mjs";
|
55
55
|
import { FormStyleSheet } from "../stylesheet/form.mjs";
|
56
56
|
|
57
57
|
import {
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
getStoredFilterConfigKey,
|
59
|
+
getFilterConfigKey,
|
60
|
+
parseDateInput,
|
61
61
|
} from "./filter/util.mjs";
|
62
62
|
|
63
63
|
import "./filter/select.mjs";
|
@@ -110,7 +110,7 @@ const filterControlElementSymbol = Symbol("filterControlElement");
|
|
110
110
|
* @type {symbol}
|
111
111
|
*/
|
112
112
|
const filterSaveActionButtonElementSymbol = Symbol(
|
113
|
-
|
113
|
+
"filterSaveActionButtonElement",
|
114
114
|
);
|
115
115
|
|
116
116
|
/**
|
@@ -170,241 +170,241 @@ const hashChangeSymbol = Symbol("hashChange");
|
|
170
170
|
* @summary The Filter component is used to show and handle the filter values.
|
171
171
|
*/
|
172
172
|
class Filter extends CustomElement {
|
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
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
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
|
-
|
173
|
+
/**
|
174
|
+
*
|
175
|
+
*/
|
176
|
+
constructor() {
|
177
|
+
super();
|
178
|
+
this[settingsSymbol] = new Settings();
|
179
|
+
|
180
|
+
// debounce the hash change event if doSearch is called by click the search button
|
181
|
+
this[hashChangeSymbol] = 0;
|
182
|
+
}
|
183
|
+
|
184
|
+
/**
|
185
|
+
* This method is called by the `instanceof` operator.
|
186
|
+
* @return {symbol}
|
187
|
+
*/
|
188
|
+
static get [instanceSymbol]() {
|
189
|
+
return Symbol.for("@schukai/monster/components/filter@@instance");
|
190
|
+
}
|
191
|
+
|
192
|
+
/**
|
193
|
+
*
|
194
|
+
* @param {string} message
|
195
|
+
* @return {Filter}
|
196
|
+
*/
|
197
|
+
showFailureMessage(message) {
|
198
|
+
this[searchButtonElementSymbol].setState(
|
199
|
+
"failed",
|
200
|
+
this.getOption("timeouts.message", 4000),
|
201
|
+
);
|
202
|
+
this[searchButtonElementSymbol]
|
203
|
+
.setMessage(message.toString())
|
204
|
+
.showMessage(this.getOption("timeouts.message", 4000));
|
205
|
+
return this;
|
206
|
+
}
|
207
|
+
|
208
|
+
/**
|
209
|
+
*
|
210
|
+
* @return {Filter}
|
211
|
+
*/
|
212
|
+
resetFailureMessage() {
|
213
|
+
this[searchButtonElementSymbol].hideMessage();
|
214
|
+
this[searchButtonElementSymbol].removeState();
|
215
|
+
return this;
|
216
|
+
}
|
217
|
+
|
218
|
+
/**
|
219
|
+
*
|
220
|
+
* @return {Filter}
|
221
|
+
*/
|
222
|
+
showSuccess() {
|
223
|
+
this[searchButtonElementSymbol].setState(
|
224
|
+
"successful",
|
225
|
+
this.getOption("timeouts.message", 4000),
|
226
|
+
);
|
227
|
+
return this;
|
228
|
+
}
|
229
|
+
|
230
|
+
/**
|
231
|
+
* To set the options via the HTML tag, the attribute `data-monster-options` must be used.
|
232
|
+
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
233
|
+
*
|
234
|
+
* The individual configuration values can be found in the table.
|
235
|
+
*
|
236
|
+
* @property {Object} templates Template definitions
|
237
|
+
* @property {string} templates.main Main template
|
238
|
+
* @property {Object} labels Label definitions
|
239
|
+
* @property {string} labels.search Search button label
|
240
|
+
* @property {string} labels.reset Reset button label
|
241
|
+
* @property {string} labels.save Save button label
|
242
|
+
* @property {string} labels.filter-name Filter name label
|
243
|
+
* @property {string} labels.empty-query-and-no-default Empty query and no default query label
|
244
|
+
* @property {string} labels.query-not-changed Query not changed label
|
245
|
+
* @property {Object} formatter Formatter definitions
|
246
|
+
* @property {Object} formatter.marker Marker definitions
|
247
|
+
* @property {Object} formatter.marker.open Marker open
|
248
|
+
* @property {Object} formatter.marker.close Marker close
|
249
|
+
* @property {Object} features Feature definitions
|
250
|
+
* @property {boolean} features.storedConfig Stored configuration, this replaces the setting `storedConfig.enabled` @since 3.97.0
|
251
|
+
* @property {boolean} features.autoFilter Auto filter @since 3.100.0
|
252
|
+
* @property {boolean} features.preventSameQuery Prevent same query @since 3.103.0
|
253
|
+
* @property {Object} storedConfig Stored configuration
|
254
|
+
* @property {boolean} storedConfig.enabled The store has been enabled, this option will no longer have any effect. @deprecated 20250101
|
255
|
+
* @property {string} storedConfig.selector Selector
|
256
|
+
* @property {Object} timeouts Timeout definitions
|
257
|
+
* @property {number} timeouts.message Message timeout
|
258
|
+
* @property {Object} queries Query definitions
|
259
|
+
* @property {Function} queries.wrap Wrap callback
|
260
|
+
* @property {Function} queries.join Join callback
|
261
|
+
* @property {string} query Query
|
262
|
+
* @property {string} defaultQuery Default query
|
263
|
+
* @property {boolean} eventProcessing Event processing
|
264
|
+
*/
|
265
|
+
get defaults() {
|
266
|
+
return Object.assign({}, super.defaults, {
|
267
|
+
templates: {
|
268
|
+
main: getTemplate(),
|
269
|
+
},
|
270
|
+
|
271
|
+
formatter: {
|
272
|
+
marker: {
|
273
|
+
open: null,
|
274
|
+
close: null,
|
275
|
+
},
|
276
|
+
},
|
277
|
+
|
278
|
+
labels: getTranslations(),
|
279
|
+
|
280
|
+
templateMapping: {
|
281
|
+
"filter-save-label": null,
|
282
|
+
"filter-name-label": name,
|
283
|
+
},
|
284
|
+
|
285
|
+
features: {
|
286
|
+
storedConfig: false,
|
287
|
+
autoFilter: true,
|
288
|
+
preventSameQuery: false,
|
289
|
+
},
|
290
|
+
|
291
|
+
storedConfig: {
|
292
|
+
enabled: true,
|
293
|
+
selector: "",
|
294
|
+
},
|
295
|
+
|
296
|
+
timeouts: {
|
297
|
+
message: 4000,
|
298
|
+
},
|
299
|
+
|
300
|
+
queries: {
|
301
|
+
wrap: (value, definition) => {
|
302
|
+
return value;
|
303
|
+
},
|
304
|
+
join: (queries) => {
|
305
|
+
if (queries.length === 0) {
|
306
|
+
return "";
|
307
|
+
}
|
308
|
+
return queries.join(" AND ");
|
309
|
+
},
|
310
|
+
},
|
311
|
+
|
312
|
+
query: null,
|
313
|
+
defaultQuery: null,
|
314
|
+
eventProcessing: true,
|
315
|
+
|
316
|
+
templateFormatter: {
|
317
|
+
marker: {
|
318
|
+
open: null,
|
319
|
+
close: null,
|
320
|
+
},
|
321
|
+
i18n: true,
|
322
|
+
},
|
323
|
+
});
|
324
|
+
}
|
325
|
+
|
326
|
+
/**
|
327
|
+
*
|
328
|
+
* @return {string}
|
329
|
+
*/
|
330
|
+
static getTag() {
|
331
|
+
return "monster-datatable-filter";
|
332
|
+
}
|
333
|
+
|
334
|
+
/**
|
335
|
+
* @return {FilterButton}
|
336
|
+
* @fires monster-filter-initialized
|
337
|
+
*/
|
338
|
+
[assembleMethodSymbol]() {
|
339
|
+
const self = this;
|
340
|
+
|
341
|
+
this.setOption(
|
342
|
+
"templateMapping.filter-save-label",
|
343
|
+
this.getOption("labels.save"),
|
344
|
+
);
|
345
|
+
|
346
|
+
this.setOption(
|
347
|
+
"templateMapping.filter-name-label",
|
348
|
+
this.getOption("labels.filter-name"),
|
349
|
+
);
|
350
|
+
|
351
|
+
super[assembleMethodSymbol]();
|
352
|
+
|
353
|
+
initControlReferences.call(self);
|
354
|
+
getWindow().requestAnimationFrame(() => {
|
355
|
+
initEventHandler.call(self);
|
356
|
+
});
|
357
|
+
|
358
|
+
initFromConfig
|
359
|
+
.call(self)
|
360
|
+
.then(() => {})
|
361
|
+
.catch((error) => {
|
362
|
+
addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, error?.message);
|
363
|
+
})
|
364
|
+
.finally(() => {
|
365
|
+
initFilter.call(self);
|
366
|
+
updateFilterTabs.call(self);
|
367
|
+
|
368
|
+
if (self.getOption("features.autoFilter") === true) {
|
369
|
+
doSearch
|
370
|
+
.call(self, { showEffect: false })
|
371
|
+
.then(() => {
|
372
|
+
fireCustomEvent(self, "monster-filter-initialized");
|
373
|
+
})
|
374
|
+
.catch(() => {});
|
375
|
+
}
|
376
|
+
});
|
377
|
+
}
|
378
|
+
|
379
|
+
/**
|
380
|
+
*
|
381
|
+
*/
|
382
|
+
connectedCallback() {
|
383
|
+
super.connectedCallback();
|
384
|
+
getWindow().addEventListener(
|
385
|
+
"hashchange",
|
386
|
+
this[locationChangeHandlerSymbol],
|
387
|
+
);
|
388
|
+
}
|
389
|
+
|
390
|
+
/**
|
391
|
+
*
|
392
|
+
*/
|
393
|
+
disconnectedCallback() {
|
394
|
+
super.disconnectedCallback();
|
395
|
+
|
396
|
+
getWindow().removeEventListener(
|
397
|
+
"hashchange",
|
398
|
+
this[locationChangeHandlerSymbol],
|
399
|
+
);
|
400
|
+
}
|
401
|
+
|
402
|
+
/**
|
403
|
+
* @return {CSSStyleSheet[]}
|
404
|
+
*/
|
405
|
+
static getCSSStyleSheet() {
|
406
|
+
return [FilterStyleSheet, FormStyleSheet, ThemeStyleSheet, SpaceStyleSheet];
|
407
|
+
}
|
408
408
|
}
|
409
409
|
|
410
410
|
/**
|
@@ -412,215 +412,212 @@ class Filter extends CustomElement {
|
|
412
412
|
* @returns {object}
|
413
413
|
*/
|
414
414
|
function getTranslations() {
|
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
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
"The search request has not changed, so no search is required.",
|
622
|
-
};
|
623
|
-
}
|
415
|
+
const locale = getLocaleOfDocument();
|
416
|
+
switch (locale.language) {
|
417
|
+
case "de":
|
418
|
+
return {
|
419
|
+
search: "Suchen",
|
420
|
+
reset: "Zurücksetzen",
|
421
|
+
save: "Speichern",
|
422
|
+
"filter-name": "Filtername",
|
423
|
+
"empty-query-and-no-default":
|
424
|
+
"Die Abfrage ist leer und es gibt keine Standardabfrage.",
|
425
|
+
"query-not-changed":
|
426
|
+
"Die Suchanfrage hat sich nicht verändert, daher ist keine Suche erforderlich.",
|
427
|
+
};
|
428
|
+
case "fr":
|
429
|
+
return {
|
430
|
+
search: "Chercher",
|
431
|
+
reset: "Réinitialiser",
|
432
|
+
save: "Sauvegarder",
|
433
|
+
"filter-name": "Nom du filtre",
|
434
|
+
"empty-query-and-no-default":
|
435
|
+
"La requête est vide et il n'y a pas de requête par défaut.",
|
436
|
+
"query-not-changed":
|
437
|
+
"La requête de recherche n'a pas changé, donc aucune recherche n'est nécessaire.",
|
438
|
+
};
|
439
|
+
case "es":
|
440
|
+
return {
|
441
|
+
search: "Buscar",
|
442
|
+
reset: "Restablecer",
|
443
|
+
save: "Guardar",
|
444
|
+
"filter-name": "Nombre del filtro",
|
445
|
+
"empty-query-and-no-default":
|
446
|
+
"La consulta está vacía y no hay una consulta predeterminada.",
|
447
|
+
"query-not-changed":
|
448
|
+
"La solicitud de búsqueda no ha cambiado, por lo que no se requiere búsqueda.",
|
449
|
+
};
|
450
|
+
case "it":
|
451
|
+
return {
|
452
|
+
search: "Cerca",
|
453
|
+
reset: "Reimposta",
|
454
|
+
save: "Salva",
|
455
|
+
"filter-name": "Nome del filtro",
|
456
|
+
"empty-query-and-no-default":
|
457
|
+
"La query è vuota e non c'è una query predefinita.",
|
458
|
+
"query-not-changed":
|
459
|
+
"La richiesta di ricerca non è cambiata, quindi non è necessaria una ricerca.",
|
460
|
+
};
|
461
|
+
case "pl":
|
462
|
+
return {
|
463
|
+
search: "Szukaj",
|
464
|
+
reset: "Resetuj",
|
465
|
+
save: "Zapisz",
|
466
|
+
"filter-name": "Nazwa filtra",
|
467
|
+
"empty-query-and-no-default":
|
468
|
+
"Zapytanie jest puste i nie ma domyślnego zapytania.",
|
469
|
+
"query-not-changed":
|
470
|
+
"Żądanie wyszukiwania nie zmieniło się, więc wyszukiwanie nie jest wymagane.",
|
471
|
+
};
|
472
|
+
case "no":
|
473
|
+
return {
|
474
|
+
search: "Søk",
|
475
|
+
reset: "Tilbakestill",
|
476
|
+
save: "Lagre",
|
477
|
+
"filter-name": "Filternavn",
|
478
|
+
"empty-query-and-no-default":
|
479
|
+
"Spørringen er tom og det er ingen standardspørring.",
|
480
|
+
"query-not-changed":
|
481
|
+
"Søkeforespørselen har ikke endret seg, så ingen søk er nødvendig.",
|
482
|
+
};
|
483
|
+
case "da":
|
484
|
+
return {
|
485
|
+
search: "Søg",
|
486
|
+
reset: "Nulstil",
|
487
|
+
save: "Gem",
|
488
|
+
"filter-name": "Filternavn",
|
489
|
+
"empty-query-and-no-default":
|
490
|
+
"Forespørgslen er tom og der er ingen standardforespørgsel.",
|
491
|
+
"query-not-changed":
|
492
|
+
"Søgeanmodningen er ikke ændret, så ingen søgning er nødvendig.",
|
493
|
+
};
|
494
|
+
case "sv":
|
495
|
+
return {
|
496
|
+
search: "Sök",
|
497
|
+
reset: "Återställ",
|
498
|
+
save: "Spara",
|
499
|
+
"filter-name": "Filternamn",
|
500
|
+
"empty-query-and-no-default":
|
501
|
+
"Förfrågan är tom och det finns ingen standardförfrågan.",
|
502
|
+
"query-not-changed":
|
503
|
+
"Sökförfrågan har inte ändrats, så ingen sökning krävs.",
|
504
|
+
};
|
505
|
+
case "nl":
|
506
|
+
return {
|
507
|
+
search: "Zoeken",
|
508
|
+
reset: "Resetten",
|
509
|
+
save: "Opslaan",
|
510
|
+
"filter-name": "Filternaam",
|
511
|
+
"empty-query-and-no-default":
|
512
|
+
"De zoekopdracht is leeg en er is geen standaardzoekopdracht.",
|
513
|
+
"query-not-changed":
|
514
|
+
"De zoekopdracht is niet gewijzigd, dus zoeken is niet nodig.",
|
515
|
+
};
|
516
|
+
case "fi":
|
517
|
+
return {
|
518
|
+
search: "Haku",
|
519
|
+
reset: "Palauta",
|
520
|
+
save: "Tallenna",
|
521
|
+
"filter-name": "Suodattimen nimi",
|
522
|
+
"empty-query-and-no-default":
|
523
|
+
"Hakukysely on tyhjä eikä oletushakua ole määritetty.",
|
524
|
+
"query-not-changed":
|
525
|
+
"Hakupyyntö ei ole muuttunut, joten hakua ei tarvita.",
|
526
|
+
};
|
527
|
+
case "cs":
|
528
|
+
return {
|
529
|
+
search: "Hledat",
|
530
|
+
reset: "Resetovat",
|
531
|
+
save: "Uložit",
|
532
|
+
"filter-name": "Název filtru",
|
533
|
+
"empty-query-and-no-default":
|
534
|
+
"Dotaz je prázdný a není nastavena žádná výchozí hodnota.",
|
535
|
+
"query-not-changed":
|
536
|
+
"Dotaz na hledání se nezměnil, takže hledání není nutné.",
|
537
|
+
};
|
538
|
+
case "pt":
|
539
|
+
return {
|
540
|
+
search: "Buscar",
|
541
|
+
reset: "Redefinir",
|
542
|
+
save: "Salvar",
|
543
|
+
"filter-name": "Nome do filtro",
|
544
|
+
"empty-query-and-no-default":
|
545
|
+
"A consulta está vazia e não há uma consulta padrão.",
|
546
|
+
"query-not-changed":
|
547
|
+
"A solicitação de pesquisa não foi alterada, portanto, nenhuma pesquisa é necessária.",
|
548
|
+
};
|
549
|
+
case "ru":
|
550
|
+
return {
|
551
|
+
search: "Поиск",
|
552
|
+
reset: "Сброс",
|
553
|
+
save: "Сохранить",
|
554
|
+
"filter-name": "Имя фильтра",
|
555
|
+
"empty-query-and-no-default": "Запрос пуст и нет запроса по умолчанию.",
|
556
|
+
"query-not-changed":
|
557
|
+
"Поисковый запрос не изменился, поэтому поиск не требуется.",
|
558
|
+
};
|
559
|
+
case "zh":
|
560
|
+
return {
|
561
|
+
search: "搜索",
|
562
|
+
reset: "重置",
|
563
|
+
save: "保存",
|
564
|
+
"filter-name": "过滤器名称",
|
565
|
+
"empty-query-and-no-default": "查询为空,且没有默认查询。",
|
566
|
+
"query-not-changed": "搜索请求没有更改,因此不需要进行搜索。",
|
567
|
+
};
|
568
|
+
case "hi":
|
569
|
+
return {
|
570
|
+
search: "खोजें",
|
571
|
+
reset: "रीसेट करें",
|
572
|
+
save: "सहेजें",
|
573
|
+
"filter-name": "फ़िल्टर नाम",
|
574
|
+
"empty-query-and-no-default": "क्वेरी खाली है और कोई डिफ़ॉल्ट क्वेरी नहीं है।",
|
575
|
+
"query-not-changed":
|
576
|
+
"खोज अनुरोध में कोई बदलाव नहीं हुआ है, इसलिए खोज आवश्यक नहीं है।",
|
577
|
+
};
|
578
|
+
case "bn":
|
579
|
+
return {
|
580
|
+
search: "অনুসন্ধান",
|
581
|
+
reset: "রিসেট",
|
582
|
+
save: "সংরক্ষণ করুন",
|
583
|
+
"filter-name": "ফিল্টারের নাম",
|
584
|
+
"empty-query-and-no-default": "কোয়েরি খালি এবং কোনো ডিফল্ট কোয়েরি নেই।",
|
585
|
+
"query-not-changed":
|
586
|
+
"অনুসন্ধানের অনুরোধ পরিবর্তন হয়নি, তাই অনুসন্ধান প্রয়োজন নয়।",
|
587
|
+
};
|
588
|
+
case "ja":
|
589
|
+
return {
|
590
|
+
search: "検索",
|
591
|
+
reset: "リセット",
|
592
|
+
save: "保存",
|
593
|
+
"filter-name": "フィルター名",
|
594
|
+
"empty-query-and-no-default":
|
595
|
+
"クエリが空で、デフォルトクエリがありません。",
|
596
|
+
"query-not-changed": "検索リクエストに変更がないため、検索は不要です。",
|
597
|
+
};
|
598
|
+
case "pa":
|
599
|
+
return {
|
600
|
+
search: "ਖੋਜੋ",
|
601
|
+
reset: "ਰੀਸੈੱਟ ਕਰੋ",
|
602
|
+
save: "ਸੇਵ ਕਰੋ",
|
603
|
+
"filter-name": "ਫਿਲਟਰ ਦਾ ਨਾਂ",
|
604
|
+
"empty-query-and-no-default": "ਕੁਐਰੀ ਖਾਲੀ ਹੈ ਅਤੇ ਕੋਈ ਡਿਫੌਲਟ ਕੁਐਰੀ ਨਹੀਂ ਹੈ।",
|
605
|
+
"query-not-changed":
|
606
|
+
"ਖੋਜ ਦੀ ਬੇਨਤੀ ਵਿੱਚ ਕੋਈ ਤਬਦੀਲੀ ਨਹੀਂ ਆਈ ਹੈ, ਇਸ ਲਈ ਖੋਜ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ।",
|
607
|
+
};
|
608
|
+
default:
|
609
|
+
case "en":
|
610
|
+
return {
|
611
|
+
search: "Search",
|
612
|
+
reset: "Reset",
|
613
|
+
save: "Save",
|
614
|
+
"filter-name": "Filter name",
|
615
|
+
"empty-query-and-no-default":
|
616
|
+
"The query is empty and there is no default query.",
|
617
|
+
"query-not-changed":
|
618
|
+
"The search request has not changed, so no search is required.",
|
619
|
+
};
|
620
|
+
}
|
624
621
|
}
|
625
622
|
|
626
623
|
/**
|
@@ -628,52 +625,52 @@ function getTranslations() {
|
|
628
625
|
* @return {FilterButton}
|
629
626
|
*/
|
630
627
|
function initControlReferences() {
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
628
|
+
if (!this.shadowRoot) {
|
629
|
+
throw new Error("no shadow-root is defined");
|
630
|
+
}
|
631
|
+
|
632
|
+
this[filterControlElementSymbol] = this.shadowRoot.querySelector(
|
633
|
+
"[data-monster-role=control]",
|
634
|
+
);
|
635
|
+
this[filterSelectElementSymbol] = this.shadowRoot.querySelector(
|
636
|
+
"[data-monster-role=filter-select]",
|
637
|
+
);
|
638
|
+
this[searchButtonElementSymbol] = this.shadowRoot.querySelector(
|
639
|
+
"[data-monster-role=search-button]",
|
640
|
+
);
|
641
|
+
this[resetButtonElementSymbol] = this.shadowRoot.querySelector(
|
642
|
+
"[data-monster-role=reset-button]",
|
643
|
+
);
|
644
|
+
|
645
|
+
this[saveButtonElementSymbol] = this.shadowRoot.querySelector(
|
646
|
+
"[data-monster-role=save-button]",
|
647
|
+
);
|
648
|
+
|
649
|
+
this[filterSaveActionButtonElementSymbol] = this.shadowRoot.querySelector(
|
650
|
+
"[data-monster-role=save-action-button]",
|
651
|
+
);
|
652
|
+
|
653
|
+
this[filterTabElementSymbol] = findElementWithSelectorUpwards(
|
654
|
+
this,
|
655
|
+
this.getOption("storedConfig.selector", ""),
|
656
|
+
);
|
657
|
+
|
658
|
+
return this;
|
662
659
|
}
|
663
660
|
|
664
661
|
/**
|
665
662
|
* @private
|
666
663
|
*/
|
667
664
|
function updateFilterSelections() {
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
665
|
+
queueMicrotask(() => {
|
666
|
+
const options = this[settingsSymbol].getOptions();
|
667
|
+
this[filterSelectElementSymbol].setOption("options", options);
|
668
|
+
|
669
|
+
setTimeout(() => {
|
670
|
+
this[filterSelectElementSymbol].value =
|
671
|
+
this[settingsSymbol].getSelected();
|
672
|
+
}, 10);
|
673
|
+
});
|
677
674
|
}
|
678
675
|
|
679
676
|
/**
|
@@ -681,64 +678,64 @@ function updateFilterSelections() {
|
|
681
678
|
* @throws {Error} no filter label is defined
|
682
679
|
*/
|
683
680
|
function initFilter() {
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
681
|
+
const storedSetting = this[settingsSymbol];
|
682
|
+
this[settingsSymbol] = new Settings();
|
683
|
+
|
684
|
+
const result = parseBracketedKeyValueHash(getGlobal().location.hash);
|
685
|
+
let valuesFromHash = {};
|
686
|
+
if (isObject(result) && result?.[this.id]) {
|
687
|
+
valuesFromHash = result[this.id];
|
688
|
+
}
|
689
|
+
|
690
|
+
getSlottedElements
|
691
|
+
.call(this, "label[data-monster-label]")
|
692
|
+
.forEach((element) => {
|
693
|
+
const label = element.getAttribute("data-monster-label");
|
694
|
+
if (!label) {
|
695
|
+
addAttributeToken(
|
696
|
+
this,
|
697
|
+
ATTRIBUTE_ERRORMESSAGE,
|
698
|
+
"no filter label is defined",
|
699
|
+
);
|
700
|
+
return;
|
701
|
+
}
|
702
|
+
|
703
|
+
let value = element.id;
|
704
|
+
if (!value) {
|
705
|
+
const prefix = label.replace(/\W/g, "-");
|
706
|
+
prefix.charAt(0).match(/[\d_]/g)?.length ? `f${prefix}` : prefix;
|
707
|
+
|
708
|
+
value = new ID(prefix + "-").toString();
|
709
|
+
element.id = value;
|
710
|
+
}
|
711
|
+
|
712
|
+
let setting = storedSetting.get(value);
|
713
|
+
|
714
|
+
if (setting) {
|
715
|
+
this[settingsSymbol].set(setting);
|
716
|
+
}
|
717
|
+
|
718
|
+
if (valuesFromHash?.[element.id]) {
|
719
|
+
const v = escapeAttributeValue(valuesFromHash[element.id]);
|
720
|
+
const searchInput = element.firstElementChild;
|
721
|
+
try {
|
722
|
+
searchInput.value = v;
|
723
|
+
} catch (error) {}
|
724
|
+
}
|
725
|
+
|
726
|
+
setting = this[settingsSymbol].get(value);
|
727
|
+
let visible = false;
|
728
|
+
if (setting) {
|
729
|
+
setSlotAttribute(element, setting.visible);
|
730
|
+
visible = setting.visible;
|
731
|
+
} else {
|
732
|
+
visible = getVisibilityFromSlotAttribute(element);
|
733
|
+
}
|
734
|
+
|
735
|
+
this[settingsSymbol].set({ value, label, visible });
|
736
|
+
});
|
737
|
+
|
738
|
+
updateFilterSelections.call(this);
|
742
739
|
}
|
743
740
|
|
744
741
|
/**
|
@@ -747,16 +744,16 @@ function initFilter() {
|
|
747
744
|
* @return {*}
|
748
745
|
*/
|
749
746
|
function escapeAttributeValue(input) {
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
747
|
+
if (input === undefined || input === null) {
|
748
|
+
return input;
|
749
|
+
}
|
750
|
+
|
751
|
+
return input
|
752
|
+
.replace(/&/g, "&")
|
753
|
+
.replace(/"/g, """)
|
754
|
+
.replace(/'/g, "'")
|
755
|
+
.replace(/</g, "<")
|
756
|
+
.replace(/>/g, ">");
|
760
757
|
}
|
761
758
|
|
762
759
|
/**
|
@@ -765,9 +762,9 @@ function escapeAttributeValue(input) {
|
|
765
762
|
* @return {boolean}
|
766
763
|
*/
|
767
764
|
function getVisibilityFromSlotAttribute(element) {
|
768
|
-
|
769
|
-
|
770
|
-
|
765
|
+
return !(
|
766
|
+
element.hasAttribute("slot") && element.getAttribute("slot") === "hidden"
|
767
|
+
);
|
771
768
|
}
|
772
769
|
|
773
770
|
/**
|
@@ -776,369 +773,369 @@ function getVisibilityFromSlotAttribute(element) {
|
|
776
773
|
* @param {boolean} visible
|
777
774
|
*/
|
778
775
|
function setSlotAttribute(element, visible) {
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
776
|
+
if (visible) {
|
777
|
+
element.removeAttribute("slot");
|
778
|
+
return;
|
779
|
+
}
|
783
780
|
|
784
|
-
|
781
|
+
element.setAttribute("slot", "hidden");
|
785
782
|
}
|
786
783
|
|
787
784
|
/**
|
788
785
|
* @private
|
789
786
|
*/
|
790
787
|
function initEventHandler() {
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
788
|
+
const self = this;
|
789
|
+
|
790
|
+
let lastHash = getGlobal().location.hash;
|
791
|
+
self[locationChangeHandlerSymbol] = () => {
|
792
|
+
if (lastHash === getGlobal().location.hash) {
|
793
|
+
return;
|
794
|
+
}
|
795
|
+
|
796
|
+
/**
|
797
|
+
* debounce the hash change event if doSearch
|
798
|
+
* is called by click the search button
|
799
|
+
*/
|
800
|
+
if (self[hashChangeSymbol] > 0) {
|
801
|
+
self[hashChangeSymbol]--;
|
802
|
+
return;
|
803
|
+
}
|
804
|
+
|
805
|
+
initFilter.call(this);
|
806
|
+
|
807
|
+
doSearch
|
808
|
+
.call(self)
|
809
|
+
.then(() => {})
|
810
|
+
.catch((error) => {})
|
811
|
+
.finally(() => {
|
812
|
+
lastHash = getGlobal().location.hash;
|
813
|
+
});
|
814
|
+
};
|
815
|
+
|
816
|
+
/**
|
817
|
+
* Monster.Components.Form.event:monster-selection-cleared
|
818
|
+
*/
|
819
|
+
if (self[filterSelectElementSymbol]) {
|
820
|
+
self[filterSelectElementSymbol].addEventListener(
|
821
|
+
"monster-selection-cleared",
|
822
|
+
function () {
|
823
|
+
const settings = self[settingsSymbol].getOptions();
|
824
|
+
|
825
|
+
for (const setting of settings) {
|
826
|
+
const filterElement = findElementWithIdUpwards(self, setting.value);
|
827
|
+
if (filterElement) {
|
828
|
+
setSlotAttribute(filterElement, false);
|
829
|
+
|
830
|
+
self[settingsSymbol].set({ value: setting.value, visible: false });
|
831
|
+
}
|
832
|
+
}
|
833
|
+
|
834
|
+
updateConfig.call(self);
|
835
|
+
},
|
836
|
+
);
|
837
|
+
|
838
|
+
self[filterSelectElementSymbol].addEventListener(
|
839
|
+
"monster-changed",
|
840
|
+
function (event) {
|
841
|
+
const filterElement = findElementWithIdUpwards(
|
842
|
+
self,
|
843
|
+
event.detail.value,
|
844
|
+
);
|
845
|
+
if (filterElement) {
|
846
|
+
setSlotAttribute(filterElement, event.detail.checked);
|
847
|
+
}
|
848
|
+
|
849
|
+
self[settingsSymbol].set({
|
850
|
+
value: event.detail.value,
|
851
|
+
visible: event.detail.checked,
|
852
|
+
});
|
853
|
+
|
854
|
+
updateConfig.call(self);
|
855
|
+
},
|
856
|
+
);
|
857
|
+
}
|
858
|
+
|
859
|
+
/** save the current filter */
|
860
|
+
if (self[filterSaveActionButtonElementSymbol]) {
|
861
|
+
self[filterSaveActionButtonElementSymbol].setOption(
|
862
|
+
"actions.click",
|
863
|
+
function (event) {
|
864
|
+
const button = findTargetElementFromEvent(
|
865
|
+
event,
|
866
|
+
"data-monster-role",
|
867
|
+
"save-action-button",
|
868
|
+
);
|
869
|
+
const form = button.closest("[data-monster-role=form]");
|
870
|
+
|
871
|
+
if (!form) {
|
872
|
+
button.setState("failed", self.getOption("timeouts.message", 4000));
|
873
|
+
return;
|
874
|
+
}
|
875
|
+
|
876
|
+
const input = form.querySelector("input[name=filter-name]");
|
877
|
+
if (!input) {
|
878
|
+
button.setState("failed", self.getOption("timeouts.message", 4000));
|
879
|
+
return;
|
880
|
+
}
|
881
|
+
|
882
|
+
const name = input.value;
|
883
|
+
if (!name) {
|
884
|
+
button.setState("failed", self.getOption("timeouts.message", 4000));
|
885
|
+
button.setMessage("Please enter a name").showMessage();
|
886
|
+
return;
|
887
|
+
}
|
888
|
+
|
889
|
+
doSearch
|
890
|
+
.call(self, { showEffect: false })
|
891
|
+
.then(() => {
|
892
|
+
const configKey = getStoredFilterConfigKey.call(self);
|
893
|
+
const host = getDocument().querySelector("monster-host");
|
894
|
+
if (!host) {
|
895
|
+
return;
|
896
|
+
}
|
897
|
+
|
898
|
+
const query = self.getOption("query");
|
899
|
+
if (!query) {
|
900
|
+
button.setState(
|
901
|
+
"failed",
|
902
|
+
self.getOption(
|
903
|
+
"timeouts.message",
|
904
|
+
self.getOption("timeouts.message", 4000),
|
905
|
+
),
|
906
|
+
);
|
907
|
+
button
|
908
|
+
.setMessage("No query found")
|
909
|
+
.showMessage(self.getOption("timeouts.message", 4000));
|
910
|
+
return;
|
911
|
+
}
|
912
|
+
|
913
|
+
host
|
914
|
+
.hasConfig(configKey)
|
915
|
+
.then((hasConfig) => {
|
916
|
+
return new Promise((resolve, reject) => {
|
917
|
+
if (hasConfig) {
|
918
|
+
host.getConfig(configKey).then(resolve).catch(reject);
|
919
|
+
return;
|
920
|
+
}
|
921
|
+
return resolve({});
|
922
|
+
});
|
923
|
+
})
|
924
|
+
.then((config) => {
|
925
|
+
config[name] = query;
|
926
|
+
return host.setConfig(configKey, {
|
927
|
+
...config,
|
928
|
+
});
|
929
|
+
})
|
930
|
+
.then(() => {
|
931
|
+
button.setState(
|
932
|
+
"successful",
|
933
|
+
self.getOption("timeouts.message", 4000),
|
934
|
+
);
|
935
|
+
updateFilterTabs.call(self);
|
936
|
+
})
|
937
|
+
.catch((error) => {
|
938
|
+
button.setState(
|
939
|
+
"failed",
|
940
|
+
self.getOption("timeouts.message", 4000),
|
941
|
+
);
|
942
|
+
button
|
943
|
+
.setMessage(error.message)
|
944
|
+
.showMessage(self.getOption("timeouts.message", 4000));
|
945
|
+
});
|
946
|
+
})
|
947
|
+
.catch((error) => {
|
948
|
+
button.setState("failed", self.getOption("timeouts.message", 4000));
|
949
|
+
const msg = error.message || error;
|
950
|
+
button
|
951
|
+
.setMessage(msg)
|
952
|
+
.showMessage(self.getOption("timeouts.message", 4000));
|
953
|
+
});
|
954
|
+
},
|
955
|
+
);
|
956
|
+
}
|
957
|
+
|
958
|
+
self[searchButtonElementSymbol].setOption("actions.click", () => {
|
959
|
+
self[hashChangeSymbol] = 1;
|
960
|
+
|
961
|
+
doSearch
|
962
|
+
.call(self)
|
963
|
+
.then(() => {})
|
964
|
+
.catch((error) => {});
|
965
|
+
});
|
966
|
+
|
967
|
+
// the reset button should reset the filter and the search query
|
968
|
+
// all input elements should be reset to their default values
|
969
|
+
// which is the empty string. we search for all input elements
|
970
|
+
// in the filter and reset them to their default value
|
971
|
+
self[resetButtonElementSymbol].setOption("actions.click", () => {
|
972
|
+
getSlottedElements
|
973
|
+
.call(self, "label[data-monster-label]")
|
974
|
+
.forEach((element) => {
|
975
|
+
const label = element.getAttribute("data-monster-label");
|
976
|
+
if (!label) {
|
977
|
+
return;
|
978
|
+
}
|
979
|
+
|
980
|
+
const input = element.firstElementChild;
|
981
|
+
|
982
|
+
if (input) {
|
983
|
+
input.value = "";
|
984
|
+
}
|
985
|
+
});
|
986
|
+
|
987
|
+
doSearch
|
988
|
+
.call(self, { showEffect: false })
|
989
|
+
.then(() => {})
|
990
|
+
.catch((e) => addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.message));
|
991
|
+
});
|
992
|
+
|
993
|
+
self.addEventListener("keyup", (event) => {
|
994
|
+
const path = event.composedPath();
|
995
|
+
if (path.length === 0) {
|
996
|
+
return;
|
997
|
+
}
|
998
|
+
|
999
|
+
if (!(path[0] instanceof HTMLInputElement)) {
|
1000
|
+
return;
|
1001
|
+
}
|
1002
|
+
|
1003
|
+
if (event.keyCode === 13) {
|
1004
|
+
doSearch
|
1005
|
+
.call(self, { showEffect: false })
|
1006
|
+
.then(() => {})
|
1007
|
+
.catch((error) => {});
|
1008
|
+
}
|
1009
|
+
});
|
1010
|
+
|
1011
|
+
// tabs
|
1012
|
+
const element = this[filterTabElementSymbol];
|
1013
|
+
if (element) {
|
1014
|
+
initTabEvents.call(this);
|
1015
|
+
}
|
1019
1016
|
}
|
1020
1017
|
|
1021
1018
|
function initTabEvents() {
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1019
|
+
const self = this;
|
1020
|
+
this[filterTabElementSymbol].addEventListener(
|
1021
|
+
"monster-tab-changed",
|
1022
|
+
(event) => {
|
1023
|
+
const query = event?.detail?.data?.["data-monster-query"];
|
1024
|
+
const q = this.getOption("query");
|
1025
|
+
if (query !== q) {
|
1026
|
+
this.setOption("query", query);
|
1027
|
+
}
|
1028
|
+
},
|
1029
|
+
);
|
1030
|
+
|
1031
|
+
this[filterTabElementSymbol].addEventListener(
|
1032
|
+
"monster-tab-remove",
|
1033
|
+
(event) => {
|
1034
|
+
const labels = [];
|
1035
|
+
const buttons = this[filterTabElementSymbol].getOption("buttons");
|
1036
|
+
|
1037
|
+
const keys = ["popper", "standard"];
|
1038
|
+
for (let i = 0; i < keys.length; i++) {
|
1039
|
+
const key = keys[i];
|
1040
|
+
|
1041
|
+
for (const button of buttons[key]) {
|
1042
|
+
if (button.label !== event.detail.label) {
|
1043
|
+
labels.push(button.label);
|
1044
|
+
}
|
1045
|
+
}
|
1046
|
+
}
|
1047
|
+
|
1048
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
1049
|
+
if (!(host && this.id)) {
|
1050
|
+
return;
|
1051
|
+
}
|
1052
|
+
|
1053
|
+
const configKey = getStoredFilterConfigKey.call(this);
|
1054
|
+
host
|
1055
|
+
.hasConfig(configKey)
|
1056
|
+
.then((hasConfig) => {
|
1057
|
+
if (!hasConfig) {
|
1058
|
+
return;
|
1059
|
+
}
|
1060
|
+
|
1061
|
+
return host.getConfig(configKey);
|
1062
|
+
})
|
1063
|
+
.then((config) => {
|
1064
|
+
for (const [name, query] of Object.entries(config)) {
|
1065
|
+
if (labels.includes(name)) {
|
1066
|
+
continue;
|
1067
|
+
}
|
1068
|
+
|
1069
|
+
delete config[name];
|
1070
|
+
}
|
1071
|
+
|
1072
|
+
return host.setConfig(configKey, {
|
1073
|
+
...config,
|
1074
|
+
});
|
1075
|
+
});
|
1076
|
+
},
|
1077
|
+
);
|
1081
1078
|
}
|
1082
1079
|
|
1083
1080
|
/**
|
1084
1081
|
* @private
|
1085
1082
|
*/
|
1086
1083
|
function updateFilterTabs() {
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1084
|
+
const element = this[filterTabElementSymbol];
|
1085
|
+
if (!element) {
|
1086
|
+
return;
|
1087
|
+
}
|
1088
|
+
|
1089
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
1090
|
+
if (!(host && this.id)) {
|
1091
|
+
return;
|
1092
|
+
}
|
1093
|
+
|
1094
|
+
const configKey = getStoredFilterConfigKey.call(this);
|
1095
|
+
host
|
1096
|
+
.hasConfig(configKey)
|
1097
|
+
.then((hasConfig) => {
|
1098
|
+
if (!hasConfig) {
|
1099
|
+
return;
|
1100
|
+
}
|
1101
|
+
|
1102
|
+
return host.getConfig(configKey);
|
1103
|
+
})
|
1104
|
+
.then((config) => {
|
1105
|
+
for (const [name, query] of Object.entries(config)) {
|
1106
|
+
const found = element.querySelector(
|
1107
|
+
`[data-monster-button-label="${name}"]`,
|
1108
|
+
);
|
1109
|
+
if (found) {
|
1110
|
+
continue;
|
1111
|
+
}
|
1112
|
+
|
1113
|
+
if (query === undefined || query === null) {
|
1114
|
+
continue;
|
1115
|
+
}
|
1116
|
+
|
1117
|
+
const escapedQuery = escapeAttributeValue(query);
|
1118
|
+
|
1119
|
+
element.insertAdjacentHTML(
|
1120
|
+
"beforeend",
|
1121
|
+
`<div data-monster-button-label="${name}"
|
1125
1122
|
data-monster-removable="true"
|
1126
1123
|
data-monster-query="${escapedQuery}" data-monster-role="filter-tab" >
|
1127
1124
|
</div>`,
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1125
|
+
);
|
1126
|
+
}
|
1127
|
+
})
|
1128
|
+
.catch((error) => {
|
1129
|
+
if (error instanceof Error) {
|
1130
|
+
addAttributeToken(
|
1131
|
+
this,
|
1132
|
+
ATTRIBUTE_ERRORMESSAGE,
|
1133
|
+
error.message + " " + error.stack,
|
1134
|
+
);
|
1135
|
+
} else {
|
1136
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error + "");
|
1137
|
+
}
|
1138
|
+
});
|
1142
1139
|
}
|
1143
1140
|
|
1144
1141
|
/**
|
@@ -1147,92 +1144,92 @@ function updateFilterTabs() {
|
|
1147
1144
|
* @return {Promise}
|
1148
1145
|
*/
|
1149
1146
|
function doSearch({ showEffect } = { showEffect: true }) {
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
1147
|
+
this.resetFailureMessage();
|
1148
|
+
|
1149
|
+
if (showEffect) {
|
1150
|
+
this[searchButtonElementSymbol].setState(
|
1151
|
+
"activity",
|
1152
|
+
this.getOption("timeouts.message", 4000),
|
1153
|
+
);
|
1154
|
+
}
|
1155
|
+
|
1156
|
+
return collectSearchQueries
|
1157
|
+
.call(this)
|
1158
|
+
.then((query) => {
|
1159
|
+
const buildQuery = buildSearchQuery.call(this, query);
|
1160
|
+
if (buildQuery === null) {
|
1161
|
+
const msg = this.getOption("labels.empty-query-and-no-default");
|
1162
|
+
if (showEffect) {
|
1163
|
+
this[searchButtonElementSymbol].removeState();
|
1164
|
+
this[searchButtonElementSymbol]
|
1165
|
+
.setMessage(msg)
|
1166
|
+
.showMessage(this.getOption("timeouts.message", 4000));
|
1167
|
+
}
|
1168
|
+
return Promise.reject(new Error(msg));
|
1169
|
+
}
|
1170
|
+
|
1171
|
+
if (buildQuery === "" && this.getOption("defaultQuery") === null) {
|
1172
|
+
const msg = this.getOption("labels.empty-query-and-no-default");
|
1173
|
+
|
1174
|
+
if (showEffect) {
|
1175
|
+
this[searchButtonElementSymbol].removeState();
|
1176
|
+
this[searchButtonElementSymbol]
|
1177
|
+
.setMessage(msg)
|
1178
|
+
.showMessage(this.getOption("timeouts.message", 4000));
|
1179
|
+
}
|
1180
|
+
|
1181
|
+
return Promise.reject(new Error(msg));
|
1182
|
+
}
|
1183
|
+
|
1184
|
+
if (
|
1185
|
+
this.getOption("features.preventSameQuery") &&
|
1186
|
+
buildQuery === this.getOption("query")
|
1187
|
+
) {
|
1188
|
+
const msg = this.getOption("labels.query-not-changed");
|
1189
|
+
|
1190
|
+
if (showEffect) {
|
1191
|
+
this[searchButtonElementSymbol].removeState();
|
1192
|
+
this[searchButtonElementSymbol]
|
1193
|
+
.setMessage(msg)
|
1194
|
+
.showMessage(this.getOption("timeouts.message", 4000));
|
1195
|
+
}
|
1196
|
+
|
1197
|
+
return Promise.reject(new Error(msg));
|
1198
|
+
}
|
1199
|
+
|
1200
|
+
if (showEffect) {
|
1201
|
+
this[searchButtonElementSymbol].removeState();
|
1202
|
+
this[searchButtonElementSymbol].setState(
|
1203
|
+
"activity",
|
1204
|
+
this.getOption("timeouts.message", 4000),
|
1205
|
+
);
|
1206
|
+
}
|
1207
|
+
|
1208
|
+
this.setOption("query", buildSearchQuery.call(this, query));
|
1209
|
+
|
1210
|
+
return Promise.resolve();
|
1211
|
+
})
|
1212
|
+
.catch((error) => {
|
1213
|
+
if (error instanceof Error) {
|
1214
|
+
addAttributeToken(
|
1215
|
+
this,
|
1216
|
+
ATTRIBUTE_ERRORMESSAGE,
|
1217
|
+
error.message + " " + error.stack,
|
1218
|
+
);
|
1219
|
+
} else {
|
1220
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, String(error));
|
1221
|
+
}
|
1222
|
+
|
1223
|
+
if (showEffect) {
|
1224
|
+
this[searchButtonElementSymbol].setState(
|
1225
|
+
"failed",
|
1226
|
+
this.getOption("timeouts.message", 4000),
|
1227
|
+
);
|
1228
|
+
this[searchButtonElementSymbol].setMessage(error.message).showMessage();
|
1229
|
+
}
|
1230
|
+
|
1231
|
+
return Promise.reject(error);
|
1232
|
+
});
|
1236
1233
|
}
|
1237
1234
|
|
1238
1235
|
/**
|
@@ -1241,21 +1238,21 @@ function doSearch({ showEffect } = { showEffect: true }) {
|
|
1241
1238
|
* @return {*|string}
|
1242
1239
|
*/
|
1243
1240
|
function buildSearchQuery(queries) {
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1241
|
+
if (!isArray(queries) || queries.length === 0) {
|
1242
|
+
return this.getOption("defaultQuery");
|
1243
|
+
}
|
1247
1244
|
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1245
|
+
const joinCallback = this.getOption("queries.join");
|
1246
|
+
if (isFunction(joinCallback)) {
|
1247
|
+
return joinCallback(queries);
|
1248
|
+
}
|
1252
1249
|
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1250
|
+
const q = queries.join(" ").trim();
|
1251
|
+
if (q.length === 0) {
|
1252
|
+
return this.getOption("defaultQuery");
|
1253
|
+
}
|
1257
1254
|
|
1258
|
-
|
1255
|
+
return q;
|
1259
1256
|
}
|
1260
1257
|
|
1261
1258
|
/**
|
@@ -1263,247 +1260,247 @@ function buildSearchQuery(queries) {
|
|
1263
1260
|
* @return {Promise<unknown>}
|
1264
1261
|
*/
|
1265
1262
|
function collectSearchQueries() {
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1263
|
+
const currentHash = parseBracketedKeyValueHash(getGlobal().location.hash);
|
1264
|
+
const self = this;
|
1265
|
+
|
1266
|
+
return new Promise((resolve, reject) => {
|
1267
|
+
const query = [];
|
1268
|
+
const wrapCallback = this.getOption("queries.wrap");
|
1269
|
+
|
1270
|
+
let hasNoIdError = false;
|
1271
|
+
|
1272
|
+
getSlottedElements
|
1273
|
+
.call(this, "label[data-monster-label]")
|
1274
|
+
.forEach((element) => {
|
1275
|
+
const label = element.getAttribute("data-monster-label");
|
1276
|
+
if (!label) {
|
1277
|
+
throw new Error("no filter label is defined");
|
1278
|
+
}
|
1279
|
+
|
1280
|
+
const id = element.id;
|
1281
|
+
if (!id) {
|
1282
|
+
hasNoIdError = true;
|
1283
|
+
return;
|
1284
|
+
}
|
1285
|
+
|
1286
|
+
const visible = getVisibilityFromSlotAttribute(element);
|
1287
|
+
if (!visible) {
|
1288
|
+
return;
|
1289
|
+
}
|
1290
|
+
|
1291
|
+
let template = element.getAttribute("data-monster-template");
|
1292
|
+
if (!template) {
|
1293
|
+
template = "${id}=${value}";
|
1294
|
+
}
|
1295
|
+
|
1296
|
+
const controlValue = getControlValuesFromLabel(element);
|
1297
|
+
if (!controlValue) {
|
1298
|
+
if (controlValue === "" && currentHash?.[this.id]?.[id]) {
|
1299
|
+
delete currentHash[this.id][id];
|
1300
|
+
}
|
1301
|
+
|
1302
|
+
return;
|
1303
|
+
}
|
1304
|
+
|
1305
|
+
if (!isObject(currentHash[this.id])) {
|
1306
|
+
currentHash[this.id] = {};
|
1307
|
+
}
|
1308
|
+
currentHash[this.id][id] = controlValue;
|
1309
|
+
|
1310
|
+
const mapping = {
|
1311
|
+
id,
|
1312
|
+
value: controlValue,
|
1313
|
+
label,
|
1314
|
+
};
|
1315
|
+
|
1316
|
+
const formatter = new Formatter(mapping, {
|
1317
|
+
callbacks: {
|
1318
|
+
range: (value, key) => {
|
1319
|
+
return generateRangeComparisonExpression(value, key, {
|
1320
|
+
urlEncode: true,
|
1321
|
+
andOp: "AND",
|
1322
|
+
orOp: "OR",
|
1323
|
+
eqOp: "=",
|
1324
|
+
gtOp: ">",
|
1325
|
+
ltOp: "<",
|
1326
|
+
});
|
1327
|
+
},
|
1328
|
+
"tag-list": (value, key) => {
|
1329
|
+
if (isString(value)) {
|
1330
|
+
value = value.split(",");
|
1331
|
+
}
|
1332
|
+
|
1333
|
+
if (!isArray(value)) {
|
1334
|
+
return "";
|
1335
|
+
}
|
1336
|
+
|
1337
|
+
return (
|
1338
|
+
key +
|
1339
|
+
" IN " +
|
1340
|
+
value
|
1341
|
+
.map((v) => {
|
1342
|
+
return `"${encodeURIComponent(v)}"`;
|
1343
|
+
})
|
1344
|
+
.join(",")
|
1345
|
+
);
|
1346
|
+
},
|
1347
|
+
"list-tag": (value, key) => {
|
1348
|
+
if (isString(value)) {
|
1349
|
+
value = value.split(",");
|
1350
|
+
}
|
1351
|
+
|
1352
|
+
if (!isArray(value)) {
|
1353
|
+
return "";
|
1354
|
+
}
|
1355
|
+
|
1356
|
+
return (
|
1357
|
+
value
|
1358
|
+
.map((v) => {
|
1359
|
+
return `"${encodeURIComponent(v)}"`;
|
1360
|
+
})
|
1361
|
+
.join(",") +
|
1362
|
+
" IN " +
|
1363
|
+
encodeURIComponent(key)
|
1364
|
+
);
|
1365
|
+
},
|
1366
|
+
"tags-in-list": (value, key, op) => {
|
1367
|
+
if (isString(value)) {
|
1368
|
+
value = value.split(",");
|
1369
|
+
}
|
1370
|
+
|
1371
|
+
if (!isArray(value)) {
|
1372
|
+
return "";
|
1373
|
+
}
|
1374
|
+
|
1375
|
+
if (!op || !isString(op)) op = "OR";
|
1376
|
+
op = " " + op.toUpperCase().trim() + " ";
|
1377
|
+
|
1378
|
+
let query = "";
|
1379
|
+
value.forEach((v) => {
|
1380
|
+
if (query.length > 0) {
|
1381
|
+
query += op;
|
1382
|
+
}
|
1383
|
+
query += `${encodeURIComponent(key)} IN "${encodeURIComponent(v)}"`;
|
1384
|
+
});
|
1385
|
+
|
1386
|
+
return query;
|
1387
|
+
},
|
1388
|
+
"list-not-in-tags": (value, key, op) => {
|
1389
|
+
if (isString(value)) {
|
1390
|
+
value = value.split(",");
|
1391
|
+
}
|
1392
|
+
if (!isArray(value)) {
|
1393
|
+
return "";
|
1394
|
+
}
|
1395
|
+
if (!op || !isString(op)) op = "OR";
|
1396
|
+
op = " " + op.toUpperCase().trim() + " ";
|
1397
|
+
let query = "";
|
1398
|
+
value.forEach((v) => {
|
1399
|
+
if (query.length > 0) {
|
1400
|
+
query += op;
|
1401
|
+
}
|
1402
|
+
query += `"${encodeURIComponent(v)}" NOT IN ${encodeURIComponent(key)}`;
|
1403
|
+
});
|
1404
|
+
return query;
|
1405
|
+
},
|
1406
|
+
"list-in-tags": (value, key, op) => {
|
1407
|
+
if (isString(value)) {
|
1408
|
+
value = value.split(",");
|
1409
|
+
}
|
1410
|
+
|
1411
|
+
if (!isArray(value)) {
|
1412
|
+
return "";
|
1413
|
+
}
|
1414
|
+
|
1415
|
+
if (!op || !isString(op)) op = "OR";
|
1416
|
+
op = " " + op.toUpperCase().trim() + " ";
|
1417
|
+
|
1418
|
+
let query = "";
|
1419
|
+
value.forEach((v) => {
|
1420
|
+
if (query.length > 0) {
|
1421
|
+
query += op;
|
1422
|
+
}
|
1423
|
+
query += `"${encodeURIComponent(v)}" IN ${encodeURIComponent(key)}`;
|
1424
|
+
});
|
1425
|
+
|
1426
|
+
return query;
|
1427
|
+
},
|
1428
|
+
"array-list": (value, key) => {
|
1429
|
+
if (isString(value)) {
|
1430
|
+
value = value.split(",");
|
1431
|
+
}
|
1432
|
+
|
1433
|
+
if (!isArray(value)) {
|
1434
|
+
return "";
|
1435
|
+
}
|
1436
|
+
|
1437
|
+
return (
|
1438
|
+
key +
|
1439
|
+
"=" +
|
1440
|
+
value
|
1441
|
+
.map((v) => {
|
1442
|
+
return `"${encodeURIComponent(v)}"`;
|
1443
|
+
})
|
1444
|
+
.join(",")
|
1445
|
+
);
|
1446
|
+
},
|
1447
|
+
"date-range": (value, key) => {
|
1448
|
+
const query = parseDateInput(value, key);
|
1449
|
+
if (!query || query === "false") {
|
1450
|
+
return "";
|
1451
|
+
}
|
1452
|
+
|
1453
|
+
// return query as url encoded
|
1454
|
+
return encodeURIComponent(query);
|
1455
|
+
},
|
1456
|
+
"to-int-2": (value, key) => {
|
1457
|
+
const query = normalizeNumber(value);
|
1458
|
+
if (Number.isNaN(query)) {
|
1459
|
+
return key + " IS NULL";
|
1460
|
+
}
|
1461
|
+
return key + "=" + encodeURIComponent(Math.round(query * 100));
|
1462
|
+
},
|
1463
|
+
"to-int-3": (value, key) => {
|
1464
|
+
const query = normalizeNumber(value);
|
1465
|
+
if (Number.isNaN(query)) {
|
1466
|
+
return "";
|
1467
|
+
}
|
1468
|
+
return key + "=" + encodeURIComponent(Math.round(query * 1000));
|
1469
|
+
},
|
1470
|
+
"to-int-4": (value, key) => {
|
1471
|
+
const query = normalizeNumber(value);
|
1472
|
+
if (Number.isNaN(query)) {
|
1473
|
+
return "";
|
1474
|
+
}
|
1475
|
+
return key + "=" + encodeURIComponent(Math.round(query * 10000));
|
1476
|
+
},
|
1477
|
+
},
|
1478
|
+
});
|
1479
|
+
|
1480
|
+
if (self.getOption("formatter.marker.open")) {
|
1481
|
+
formatter.setMarker(
|
1482
|
+
self.getOption("formatter.marker.open"),
|
1483
|
+
self.getOption("formatter.marker.close"),
|
1484
|
+
);
|
1485
|
+
}
|
1486
|
+
|
1487
|
+
let queryPart = formatter.format(template);
|
1488
|
+
if (queryPart) {
|
1489
|
+
if (isFunction(wrapCallback)) {
|
1490
|
+
queryPart = wrapCallback(queryPart, mapping);
|
1491
|
+
}
|
1492
|
+
query.push(queryPart);
|
1493
|
+
}
|
1494
|
+
});
|
1495
|
+
|
1496
|
+
if (hasNoIdError) {
|
1497
|
+
reject(new Error("some or all filter elements have no id"));
|
1498
|
+
return;
|
1499
|
+
}
|
1500
|
+
|
1501
|
+
getGlobal().location.hash = createBracketedKeyValueHash(currentHash);
|
1502
|
+
resolve(query);
|
1503
|
+
});
|
1507
1504
|
}
|
1508
1505
|
|
1509
1506
|
/**
|
@@ -1512,41 +1509,41 @@ function collectSearchQueries() {
|
|
1512
1509
|
* @return {null|Array|undefined|string}
|
1513
1510
|
*/
|
1514
1511
|
function getControlValuesFromLabel(label) {
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1512
|
+
// finde das erste Kind-Element vom type input
|
1513
|
+
// wenn es ein input-Element ist, dann @todo
|
1514
|
+
|
1515
|
+
const foundControl = label.firstElementChild;
|
1516
|
+
|
1517
|
+
if (foundControl) {
|
1518
|
+
if (foundControl.tagName === "INPUT") {
|
1519
|
+
if (foundControl.type === "checkbox") {
|
1520
|
+
const checkedControls = label.querySelectorAll(
|
1521
|
+
`${foundControl}:checked`,
|
1522
|
+
);
|
1523
|
+
const values = [];
|
1524
|
+
|
1525
|
+
checkedControls.forEach((checkedControl) => {
|
1526
|
+
values.push(checkedControl.value);
|
1527
|
+
});
|
1528
|
+
|
1529
|
+
return values;
|
1530
|
+
} else if (foundControl.type === "radio") {
|
1531
|
+
const checkedControl = label.querySelector(`${foundControl}:checked`);
|
1532
|
+
|
1533
|
+
if (checkedControl) {
|
1534
|
+
return checkedControl.value;
|
1535
|
+
} else {
|
1536
|
+
return null;
|
1537
|
+
}
|
1538
|
+
} else {
|
1539
|
+
return foundControl.value;
|
1540
|
+
}
|
1541
|
+
} else {
|
1542
|
+
return foundControl.value;
|
1543
|
+
}
|
1544
|
+
}
|
1545
|
+
|
1546
|
+
return null;
|
1550
1547
|
}
|
1551
1548
|
|
1552
1549
|
/**
|
@@ -1554,60 +1551,60 @@ function getControlValuesFromLabel(label) {
|
|
1554
1551
|
* @return {Promise<unknown>}
|
1555
1552
|
*/
|
1556
1553
|
function initFromConfig() {
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1590
|
-
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1554
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
1555
|
+
|
1556
|
+
if (!(isInstance(host, Host) && this.id)) {
|
1557
|
+
return Promise.resolve();
|
1558
|
+
}
|
1559
|
+
|
1560
|
+
const configKey = getFilterConfigKey.call(this);
|
1561
|
+
|
1562
|
+
return new Promise((resolve, reject) => {
|
1563
|
+
host
|
1564
|
+
.getConfig(configKey)
|
1565
|
+
.then((config) => {
|
1566
|
+
if ((config && isObject(config)) || isArray(config)) {
|
1567
|
+
this[settingsSymbol].setOptions(config);
|
1568
|
+
}
|
1569
|
+
resolve();
|
1570
|
+
})
|
1571
|
+
.catch((error) => {
|
1572
|
+
if (error === undefined) {
|
1573
|
+
resolve();
|
1574
|
+
return;
|
1575
|
+
}
|
1576
|
+
|
1577
|
+
// config not written
|
1578
|
+
if (error?.message?.match(/is not defined/)) {
|
1579
|
+
resolve();
|
1580
|
+
return;
|
1581
|
+
}
|
1582
|
+
|
1583
|
+
addAttributeToken(
|
1584
|
+
this,
|
1585
|
+
ATTRIBUTE_ERRORMESSAGE,
|
1586
|
+
error?.message || error,
|
1587
|
+
);
|
1588
|
+
reject(error);
|
1589
|
+
});
|
1590
|
+
});
|
1594
1591
|
}
|
1595
1592
|
|
1596
1593
|
/**
|
1597
1594
|
* @private
|
1598
1595
|
*/
|
1599
1596
|
function updateConfig() {
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1597
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
1598
|
+
if (!(host && this.id)) {
|
1599
|
+
return;
|
1600
|
+
}
|
1601
|
+
const configKey = getFilterConfigKey.call(this);
|
1602
|
+
|
1603
|
+
try {
|
1604
|
+
host.setConfig(configKey, this[settingsSymbol].getOptions());
|
1605
|
+
} catch (error) {
|
1606
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error?.message || error);
|
1607
|
+
}
|
1611
1608
|
}
|
1612
1609
|
|
1613
1610
|
/**
|
@@ -1615,8 +1612,8 @@ function updateConfig() {
|
|
1615
1612
|
* @return {string}
|
1616
1613
|
*/
|
1617
1614
|
function getTemplate() {
|
1618
|
-
|
1619
|
-
|
1615
|
+
// language=HTML
|
1616
|
+
return `
|
1620
1617
|
<div data-monster-role="control" part="control">
|
1621
1618
|
<div data-monster-role="container">
|
1622
1619
|
<div data-monster-role="layout">
|