@schukai/monster 3.99.1 → 3.99.3
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 +16 -0
- package/package.json +1 -1
- package/source/components/datatable/dataset.mjs +7 -2
- package/source/components/datatable/datasource/rest.mjs +7 -7
- package/source/components/datatable/datatable/header.mjs +13 -4
- package/source/components/datatable/datatable.mjs +1141 -1152
- package/source/components/datatable/filter.mjs +1101 -1088
- package/source/components/form/action-button.mjs +1 -1
- package/source/components/form/api-button.mjs +1 -1
- package/source/components/form/button-bar.mjs +1 -1
- package/source/components/form/button.mjs +1 -1
- package/source/components/form/context-error.mjs +1 -1
- package/source/components/form/field-set.mjs +1 -1
- package/source/components/form/popper-button.mjs +274 -274
- package/source/components/form/reload.mjs +1 -1
- package/source/components/form/toggle-switch.mjs +1 -1
- package/source/components/style/form.css +8 -0
- package/source/dom/customelement.mjs +936 -946
- package/source/dom/error.mjs +59 -66
- package/source/monster.mjs +1 -0
@@ -12,59 +12,56 @@
|
|
12
12
|
* SPDX-License-Identifier: AGPL-3.0
|
13
13
|
*/
|
14
14
|
|
15
|
-
import {findElementWithIdUpwards, getDocument, getWindow} from "./util.mjs";
|
16
|
-
import {internalSymbol} from "../constants.mjs";
|
17
|
-
import {extend} from "../data/extend.mjs";
|
18
|
-
import {Pathfinder} from "../data/pathfinder.mjs";
|
19
|
-
import {Formatter} from "../text/formatter.mjs";
|
20
|
-
|
21
|
-
import {parseDataURL} from "../types/dataurl.mjs";
|
22
|
-
import {getGlobalObject} from "../types/global.mjs";
|
15
|
+
import { findElementWithIdUpwards, getDocument, getWindow } from "./util.mjs";
|
16
|
+
import { internalSymbol } from "../constants.mjs";
|
17
|
+
import { extend } from "../data/extend.mjs";
|
18
|
+
import { Pathfinder } from "../data/pathfinder.mjs";
|
19
|
+
import { Formatter } from "../text/formatter.mjs";
|
20
|
+
|
21
|
+
import { parseDataURL } from "../types/dataurl.mjs";
|
22
|
+
import { getGlobalObject } from "../types/global.mjs";
|
23
23
|
import {
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
isArray,
|
25
|
+
isFunction,
|
26
|
+
isIterable,
|
27
|
+
isObject,
|
28
|
+
isString,
|
29
29
|
} from "../types/is.mjs";
|
30
|
-
import {Observer} from "../types/observer.mjs";
|
31
|
-
import {ProxyObserver} from "../types/proxyobserver.mjs";
|
30
|
+
import { Observer } from "../types/observer.mjs";
|
31
|
+
import { ProxyObserver } from "../types/proxyobserver.mjs";
|
32
32
|
import {
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
validateFunction,
|
34
|
+
validateInstance,
|
35
|
+
validateObject,
|
36
36
|
} from "../types/validate.mjs";
|
37
|
-
import {clone} from "../util/clone.mjs";
|
37
|
+
import { clone } from "../util/clone.mjs";
|
38
|
+
import { getLinkedObjects, hasObjectLink } from "./attributes.mjs";
|
38
39
|
import {
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
ATTRIBUTE_OPTIONS_SELECTOR,
|
47
|
-
ATTRIBUTE_SCRIPT_HOST,
|
48
|
-
customElementUpdaterLinkSymbol,
|
49
|
-
initControlCallbackName,
|
40
|
+
ATTRIBUTE_DISABLED,
|
41
|
+
ATTRIBUTE_OPTIONS,
|
42
|
+
ATTRIBUTE_INIT_CALLBACK,
|
43
|
+
ATTRIBUTE_OPTIONS_SELECTOR,
|
44
|
+
ATTRIBUTE_SCRIPT_HOST,
|
45
|
+
customElementUpdaterLinkSymbol,
|
46
|
+
initControlCallbackName,
|
50
47
|
} from "./constants.mjs";
|
51
|
-
import {findDocumentTemplate, Template} from "./template.mjs";
|
52
|
-
import {addObjectWithUpdaterToElement} from "./updater.mjs";
|
53
|
-
import {instanceSymbol} from "../constants.mjs";
|
54
|
-
import {getDocumentTranslations} from "../i18n/translations.mjs";
|
55
|
-
import {getSlottedElements} from "./slotted.mjs";
|
56
|
-
import {initOptionsFromAttributes} from "./util/init-options-from-attributes.mjs";
|
57
|
-
import {setOptionFromAttribute} from "./util/set-option-from-attribute.mjs";
|
58
|
-
import {addErrorAttribute} from "./error.mjs";
|
48
|
+
import { findDocumentTemplate, Template } from "./template.mjs";
|
49
|
+
import { addObjectWithUpdaterToElement } from "./updater.mjs";
|
50
|
+
import { instanceSymbol } from "../constants.mjs";
|
51
|
+
import { getDocumentTranslations } from "../i18n/translations.mjs";
|
52
|
+
import { getSlottedElements } from "./slotted.mjs";
|
53
|
+
import { initOptionsFromAttributes } from "./util/init-options-from-attributes.mjs";
|
54
|
+
import { setOptionFromAttribute } from "./util/set-option-from-attribute.mjs";
|
55
|
+
import { addErrorAttribute } from "./error.mjs";
|
59
56
|
|
60
57
|
export {
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
58
|
+
CustomElement,
|
59
|
+
initMethodSymbol,
|
60
|
+
assembleMethodSymbol,
|
61
|
+
attributeObserverSymbol,
|
62
|
+
registerCustomElement,
|
63
|
+
getSlottedElements,
|
64
|
+
updaterTransformerMethodsSymbol,
|
68
65
|
};
|
69
66
|
|
70
67
|
/**
|
@@ -76,14 +73,14 @@ const initMethodSymbol = Symbol.for("@schukai/monster/dom/@@initMethodSymbol");
|
|
76
73
|
* @type {symbol}
|
77
74
|
*/
|
78
75
|
const assembleMethodSymbol = Symbol.for(
|
79
|
-
|
76
|
+
"@schukai/monster/dom/@@assembleMethodSymbol",
|
80
77
|
);
|
81
78
|
|
82
79
|
/**
|
83
80
|
* @type {symbol}
|
84
81
|
*/
|
85
82
|
const updaterTransformerMethodsSymbol = Symbol.for(
|
86
|
-
|
83
|
+
"@schukai/monster/dom/@@updaterTransformerMethodsSymbol",
|
87
84
|
);
|
88
85
|
|
89
86
|
/**
|
@@ -91,7 +88,7 @@ const updaterTransformerMethodsSymbol = Symbol.for(
|
|
91
88
|
* @type {symbol}
|
92
89
|
*/
|
93
90
|
const attributeObserverSymbol = Symbol.for(
|
94
|
-
|
91
|
+
"@schukai/monster/dom/@@attributeObserver",
|
95
92
|
);
|
96
93
|
|
97
94
|
/**
|
@@ -99,7 +96,7 @@ const attributeObserverSymbol = Symbol.for(
|
|
99
96
|
* @type {symbol}
|
100
97
|
*/
|
101
98
|
const attributeMutationObserverSymbol = Symbol(
|
102
|
-
|
99
|
+
"@schukai/monster/dom/@@mutationObserver",
|
103
100
|
);
|
104
101
|
|
105
102
|
/**
|
@@ -188,558 +185,555 @@ const scriptHostElementSymbol = Symbol("scriptHostElement");
|
|
188
185
|
* @summary A base class for HTML5 custom controls.
|
189
186
|
*/
|
190
187
|
class CustomElement extends HTMLElement {
|
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
|
-
|
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
|
-
|
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
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
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
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
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
|
-
callCallback(name, args) {
|
741
|
-
return callControlCallback.call(this, name, ...args);
|
742
|
-
}
|
188
|
+
/**
|
189
|
+
* A new object is created. First, the `initOptions` method is called. Here the
|
190
|
+
* options can be defined in derived classes. Subsequently, the shadowRoot is initialized.
|
191
|
+
*
|
192
|
+
* IMPORTANT: CustomControls instances are not created via the constructor, but either via a tag in the HTML or via <code>document.createElement()</code>.
|
193
|
+
*
|
194
|
+
* @throws {Error} the option attribute does not contain a valid JSON definition.
|
195
|
+
*/
|
196
|
+
constructor() {
|
197
|
+
super();
|
198
|
+
|
199
|
+
this[attributeObserverSymbol] = {};
|
200
|
+
this[internalSymbol] = new ProxyObserver({
|
201
|
+
options: initOptionsFromAttributes(this, extend({}, this.defaults)),
|
202
|
+
});
|
203
|
+
this[initMethodSymbol]();
|
204
|
+
initOptionObserver.call(this);
|
205
|
+
this[scriptHostElementSymbol] = [];
|
206
|
+
}
|
207
|
+
|
208
|
+
/**
|
209
|
+
* This method is called by the `instanceof` operator.
|
210
|
+
*
|
211
|
+
* @return {symbol}
|
212
|
+
* @since 2.1.0
|
213
|
+
*/
|
214
|
+
static get [instanceSymbol]() {
|
215
|
+
return Symbol.for("@schukai/monster/dom/custom-element@@instance");
|
216
|
+
}
|
217
|
+
|
218
|
+
/**
|
219
|
+
* This method determines which attributes are to be
|
220
|
+
* monitored by `attributeChangedCallback()`. Unfortunately, this method is static.
|
221
|
+
* Therefore, the `observedAttributes` property cannot be changed during runtime.
|
222
|
+
*
|
223
|
+
* @return {string[]}
|
224
|
+
* @since 1.15.0
|
225
|
+
*/
|
226
|
+
static get observedAttributes() {
|
227
|
+
return [];
|
228
|
+
}
|
229
|
+
|
230
|
+
/**
|
231
|
+
*
|
232
|
+
* @param attribute
|
233
|
+
* @param callback
|
234
|
+
* @return {CustomElement}
|
235
|
+
*/
|
236
|
+
addAttributeObserver(attribute, callback) {
|
237
|
+
validateFunction(callback);
|
238
|
+
this[attributeObserverSymbol][attribute] = callback;
|
239
|
+
return this;
|
240
|
+
}
|
241
|
+
|
242
|
+
/**
|
243
|
+
*
|
244
|
+
* @param attribute
|
245
|
+
* @return {CustomElement}
|
246
|
+
*/
|
247
|
+
removeAttributeObserver(attribute) {
|
248
|
+
delete this[attributeObserverSymbol][attribute];
|
249
|
+
return this;
|
250
|
+
}
|
251
|
+
|
252
|
+
/**
|
253
|
+
* The `defaults` property defines the default values for a control. If you want to override these,
|
254
|
+
* you can use various methods, which are described in the documentation available at
|
255
|
+
* {@link https://monsterjs.orgendocconfigurate-a-monster-control}.
|
256
|
+
*
|
257
|
+
* The individual configuration values are listed below:
|
258
|
+
*
|
259
|
+
* More information about the shadowRoot can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow),
|
260
|
+
* in the [HTML Standard](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements) or in the [WHATWG Wiki](https://wiki.whatwg.org/wiki/Custom_Elements).
|
261
|
+
*
|
262
|
+
* More information about the template element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template).
|
263
|
+
*
|
264
|
+
* More information about the slot element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot).
|
265
|
+
*
|
266
|
+
* @property {boolean} disabled=false Specifies whether the control is disabled. When present, it makes the element non-mutable, non-focusable, and non-submittable with the form.
|
267
|
+
* @property {string} shadowMode=open Specifies the mode of the shadow root. When set to `open`, elements in the shadow root are accessible from JavaScript outside the root, while setting it to `closed` denies access to the root's nodes from JavaScript outside it.
|
268
|
+
* @property {Boolean} delegatesFocus=true Specifies the behavior of the control with respect to focusability. When set to `true`, it mitigates custom element issues around focusability. When a non-focusable part of the shadow DOM is clicked, the first focusable part is given focus, and the shadow host is given any available :focus styling.
|
269
|
+
* @property {Object} templates Specifies the templates used by the control.
|
270
|
+
* @property {string} templates.main=undefined Specifies the main template used by the control.
|
271
|
+
* @property {Object} templateMapping Specifies the mapping of templates.
|
272
|
+
* @property {Object} templateFormatter Specifies the formatter for the templates.
|
273
|
+
* @property {Object} templateFormatter.marker Specifies the marker for the templates.
|
274
|
+
* @property {Function} templateFormatter.marker.open=null Specifies the opening marker for the templates.
|
275
|
+
* @property {Function} templateFormatter.marker.close=null Specifies the closing marker for the templates.
|
276
|
+
* @property {Boolean} eventProcessing=false Specifies whether the control processes events.
|
277
|
+
* @since 1.8.0
|
278
|
+
*/
|
279
|
+
get defaults() {
|
280
|
+
return {
|
281
|
+
disabled: false,
|
282
|
+
shadowMode: "open",
|
283
|
+
delegatesFocus: true,
|
284
|
+
templates: {
|
285
|
+
main: undefined,
|
286
|
+
},
|
287
|
+
templateMapping: {},
|
288
|
+
templateFormatter: {
|
289
|
+
marker: {
|
290
|
+
open: null,
|
291
|
+
close: null,
|
292
|
+
},
|
293
|
+
},
|
294
|
+
|
295
|
+
eventProcessing: false,
|
296
|
+
};
|
297
|
+
}
|
298
|
+
|
299
|
+
/**
|
300
|
+
* This method updates the labels of the element.
|
301
|
+
* The labels are defined in the option object.
|
302
|
+
* The key of the label is used to retrieve the translation from the document.
|
303
|
+
* If the translation is different from the label, the label is updated.
|
304
|
+
*
|
305
|
+
* Before you can use this method, you must have loaded the translations.
|
306
|
+
*
|
307
|
+
* @return {CustomElement}
|
308
|
+
* @throws {Error} Cannot find an element with translations. Add a translation object to the document.
|
309
|
+
*/
|
310
|
+
updateI18n() {
|
311
|
+
let translations;
|
312
|
+
|
313
|
+
try {
|
314
|
+
translations = getDocumentTranslations();
|
315
|
+
} catch (e) {
|
316
|
+
addErrorAttribute(this, e);
|
317
|
+
return this;
|
318
|
+
}
|
319
|
+
|
320
|
+
if (!translations) {
|
321
|
+
return this;
|
322
|
+
}
|
323
|
+
|
324
|
+
const labels = this.getOption("labels");
|
325
|
+
if (!(isObject(labels) || isIterable(labels))) {
|
326
|
+
return this;
|
327
|
+
}
|
328
|
+
|
329
|
+
for (const key in labels) {
|
330
|
+
const def = labels[key];
|
331
|
+
|
332
|
+
if (isString(def)) {
|
333
|
+
const text = translations.getText(key, def);
|
334
|
+
if (text !== def) {
|
335
|
+
this.setOption(`labels.${key}`, text);
|
336
|
+
}
|
337
|
+
continue;
|
338
|
+
} else if (isObject(def)) {
|
339
|
+
for (const k in def) {
|
340
|
+
const d = def[k];
|
341
|
+
|
342
|
+
const text = translations.getPluralRuleText(key, k, d);
|
343
|
+
if (!isString(text)) {
|
344
|
+
throw new Error("Invalid labels definition");
|
345
|
+
}
|
346
|
+
if (text !== d) {
|
347
|
+
this.setOption(`labels.${key}.${k}`, text);
|
348
|
+
}
|
349
|
+
}
|
350
|
+
continue;
|
351
|
+
}
|
352
|
+
|
353
|
+
throw new Error("Invalid labels definition");
|
354
|
+
}
|
355
|
+
return this;
|
356
|
+
}
|
357
|
+
|
358
|
+
/**
|
359
|
+
* The `getTag()` method returns the tag name associated with the custom element. This method should be overwritten
|
360
|
+
* by the derived class.
|
361
|
+
*
|
362
|
+
* Note that there is no check on the name of the tag in this class. It is the responsibility of
|
363
|
+
* the developer to assign an appropriate tag name. If the name is not valid, the
|
364
|
+
* `registerCustomElement()` method will issue an error.
|
365
|
+
*
|
366
|
+
* @see https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
|
367
|
+
* @throws {Error} This method must be overridden by the derived class.
|
368
|
+
* @return {string} The tag name associated with the custom element.
|
369
|
+
* @since 1.7.0
|
370
|
+
*/
|
371
|
+
static getTag() {
|
372
|
+
throw new Error(
|
373
|
+
"The method `getTag()` must be overridden by the derived class.",
|
374
|
+
);
|
375
|
+
}
|
376
|
+
|
377
|
+
/**
|
378
|
+
* The `getCSSStyleSheet()` method returns a `CSSStyleSheet` object that defines the styles for the custom element.
|
379
|
+
* If the environment does not support the `CSSStyleSheet` constructor, then an object can be built using the provided detour.
|
380
|
+
*
|
381
|
+
* If `undefined` is returned, then the shadow root does not receive a stylesheet.
|
382
|
+
*
|
383
|
+
* Example usage:
|
384
|
+
*
|
385
|
+
* ```js
|
386
|
+
* class MyElement extends CustomElement {
|
387
|
+
* static getCSSStyleSheet() {
|
388
|
+
* const sheet = new CSSStyleSheet();
|
389
|
+
* sheet.replaceSync("p { color: red; }");
|
390
|
+
* return sheet;
|
391
|
+
* }
|
392
|
+
* }
|
393
|
+
* ```
|
394
|
+
*
|
395
|
+
* If the environment does not support the `CSSStyleSheet` constructor,
|
396
|
+
* you can use the following workaround to create the stylesheet:
|
397
|
+
*
|
398
|
+
* ```js
|
399
|
+
* const doc = document.implementation.createHTMLDocument('title');
|
400
|
+
* let style = doc.createElement("style");
|
401
|
+
* style.innerHTML = "p { color: red; }";
|
402
|
+
* style.appendChild(document.createTextNode(""));
|
403
|
+
* doc.head.appendChild(style);
|
404
|
+
* return doc.styleSheets[0];
|
405
|
+
* ```
|
406
|
+
*
|
407
|
+
* @return {CSSStyleSheet|CSSStyleSheet[]|string|undefined} A `CSSStyleSheet` object or an array of such objects that define the styles for the custom element, or `undefined` if no stylesheet should be applied.
|
408
|
+
*/
|
409
|
+
static getCSSStyleSheet() {
|
410
|
+
return undefined;
|
411
|
+
}
|
412
|
+
|
413
|
+
/**
|
414
|
+
* attach a new observer
|
415
|
+
*
|
416
|
+
* @param {Observer} observer
|
417
|
+
* @return {CustomElement}
|
418
|
+
*/
|
419
|
+
attachObserver(observer) {
|
420
|
+
this[internalSymbol].attachObserver(observer);
|
421
|
+
return this;
|
422
|
+
}
|
423
|
+
|
424
|
+
/**
|
425
|
+
* detach a observer
|
426
|
+
*
|
427
|
+
* @param {Observer} observer
|
428
|
+
* @return {CustomElement}
|
429
|
+
*/
|
430
|
+
detachObserver(observer) {
|
431
|
+
this[internalSymbol].detachObserver(observer);
|
432
|
+
return this;
|
433
|
+
}
|
434
|
+
|
435
|
+
/**
|
436
|
+
* @param {Observer} observer
|
437
|
+
* @return {ProxyObserver}
|
438
|
+
*/
|
439
|
+
containsObserver(observer) {
|
440
|
+
return this[internalSymbol].containsObserver(observer);
|
441
|
+
}
|
442
|
+
|
443
|
+
/**
|
444
|
+
* nested options can be specified by path `a.b.c`
|
445
|
+
*
|
446
|
+
* @param {string} path
|
447
|
+
* @param {*} defaultValue
|
448
|
+
* @return {*}
|
449
|
+
* @since 1.10.0
|
450
|
+
*/
|
451
|
+
getOption(path, defaultValue = undefined) {
|
452
|
+
let value;
|
453
|
+
|
454
|
+
try {
|
455
|
+
value = new Pathfinder(
|
456
|
+
this[internalSymbol].getRealSubject()["options"],
|
457
|
+
).getVia(path);
|
458
|
+
} catch (e) {}
|
459
|
+
|
460
|
+
if (value === undefined) return defaultValue;
|
461
|
+
return value;
|
462
|
+
}
|
463
|
+
|
464
|
+
/**
|
465
|
+
* Set option and inform elements
|
466
|
+
*
|
467
|
+
* @param {string} path
|
468
|
+
* @param {*} value
|
469
|
+
* @return {CustomElement}
|
470
|
+
* @since 1.14.0
|
471
|
+
*/
|
472
|
+
setOption(path, value) {
|
473
|
+
new Pathfinder(this[internalSymbol].getSubject()["options"]).setVia(
|
474
|
+
path,
|
475
|
+
value,
|
476
|
+
);
|
477
|
+
return this;
|
478
|
+
}
|
479
|
+
|
480
|
+
/**
|
481
|
+
* @since 1.15.0
|
482
|
+
* @param {string|object} options
|
483
|
+
* @return {CustomElement}
|
484
|
+
*/
|
485
|
+
setOptions(options) {
|
486
|
+
if (isString(options)) {
|
487
|
+
options = parseOptionsJSON.call(this, options);
|
488
|
+
}
|
489
|
+
// 2024-01-21: remove this.defaults, otherwise it will overwrite
|
490
|
+
// the current settings that have already been made.
|
491
|
+
// https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/136
|
492
|
+
extend(this[internalSymbol].getSubject()["options"], options);
|
493
|
+
|
494
|
+
return this;
|
495
|
+
}
|
496
|
+
|
497
|
+
/**
|
498
|
+
* Is called once via the constructor
|
499
|
+
*
|
500
|
+
* @return {CustomElement}
|
501
|
+
* @since 1.8.0
|
502
|
+
*/
|
503
|
+
[initMethodSymbol]() {
|
504
|
+
return this;
|
505
|
+
}
|
506
|
+
|
507
|
+
/**
|
508
|
+
* This method is called once when the object is equipped with update for the dynamic change of the dom.
|
509
|
+
* The functions returned here can be used as pipe functions in the template.
|
510
|
+
*
|
511
|
+
* In the example, the function `my-transformer` is defined. In the template, you can use it as follows:
|
512
|
+
*
|
513
|
+
* ```html
|
514
|
+
* <my-element
|
515
|
+
* data-monster-option-transformer="path:my-value | call:my-transformer">
|
516
|
+
* </my-element>
|
517
|
+
* ```
|
518
|
+
*
|
519
|
+
* The function `my-transformer` is called with the value of `my-value` as a parameter.
|
520
|
+
*
|
521
|
+
* ```js
|
522
|
+
* class MyElement extends CustomElement {
|
523
|
+
* [updaterTransformerMethodsSymbol]() {
|
524
|
+
* return {
|
525
|
+
* "my-transformer": (value) => {
|
526
|
+
* switch (typeof Wert) {
|
527
|
+
* case "string":
|
528
|
+
* return value + "!";
|
529
|
+
* case "Zahl":
|
530
|
+
* return value + 1;
|
531
|
+
* default:
|
532
|
+
* return value;
|
533
|
+
* }
|
534
|
+
* }
|
535
|
+
* };
|
536
|
+
* };
|
537
|
+
* }
|
538
|
+
* ```
|
539
|
+
*
|
540
|
+
* @return {object}
|
541
|
+
* @since 2.43.0
|
542
|
+
*/
|
543
|
+
[updaterTransformerMethodsSymbol]() {
|
544
|
+
return {};
|
545
|
+
}
|
546
|
+
|
547
|
+
/**
|
548
|
+
* This method is called once when the object is included in the DOM for the first time. It performs the following actions:
|
549
|
+
*
|
550
|
+
* <ol>
|
551
|
+
* <li>Extracts the options from the attributes and the script tag of the element and sets them.</li>
|
552
|
+
* <li>Initializes the shadow root and its CSS stylesheet (if specified).</li>
|
553
|
+
* <li>Initializes the HTML content of the element.</li>
|
554
|
+
* <li>Initializes the custom elements inside the shadow root and the slotted elements.</li>
|
555
|
+
* <li>Attaches a mutation observer to observe changes to the attributes of the element.</li>
|
556
|
+
*
|
557
|
+
* @return {CustomElement} - The updated custom element.
|
558
|
+
* @since 1.8.0
|
559
|
+
*/
|
560
|
+
[assembleMethodSymbol]() {
|
561
|
+
let elements;
|
562
|
+
let nodeList;
|
563
|
+
|
564
|
+
// Extract options from attributes and set them
|
565
|
+
const AttributeOptions = getOptionsFromAttributes.call(this);
|
566
|
+
if (
|
567
|
+
isObject(AttributeOptions) &&
|
568
|
+
Object.keys(AttributeOptions).length > 0
|
569
|
+
) {
|
570
|
+
this.setOptions(AttributeOptions);
|
571
|
+
}
|
572
|
+
|
573
|
+
// Extract options from script tag and set them
|
574
|
+
const ScriptOptions = getOptionsFromScriptTag.call(this);
|
575
|
+
if (isObject(ScriptOptions) && Object.keys(ScriptOptions).length > 0) {
|
576
|
+
this.setOptions(ScriptOptions);
|
577
|
+
}
|
578
|
+
|
579
|
+
// Initialize the shadow root and its CSS stylesheet
|
580
|
+
if (this.getOption("shadowMode", false) !== false) {
|
581
|
+
try {
|
582
|
+
initShadowRoot.call(this);
|
583
|
+
elements = this.shadowRoot.childNodes;
|
584
|
+
} catch (e) {
|
585
|
+
addErrorAttribute(this, e);
|
586
|
+
}
|
587
|
+
|
588
|
+
try {
|
589
|
+
initCSSStylesheet.call(this);
|
590
|
+
} catch (e) {
|
591
|
+
addErrorAttribute(this, e);
|
592
|
+
}
|
593
|
+
}
|
594
|
+
|
595
|
+
// If the elements are not found inside the shadow root, initialize the HTML content of the element
|
596
|
+
if (!(elements instanceof NodeList)) {
|
597
|
+
initHtmlContent.call(this);
|
598
|
+
elements = this.childNodes;
|
599
|
+
}
|
600
|
+
|
601
|
+
// Initialize the custom elements inside the shadow root and the slotted elements
|
602
|
+
initFromCallbackHost.call(this);
|
603
|
+
try {
|
604
|
+
nodeList = new Set([...elements, ...getSlottedElements.call(this)]);
|
605
|
+
} catch (e) {
|
606
|
+
nodeList = elements;
|
607
|
+
}
|
608
|
+
|
609
|
+
try {
|
610
|
+
this[updateCloneDataSymbol] = clone(
|
611
|
+
this[internalSymbol].getRealSubject()["options"],
|
612
|
+
);
|
613
|
+
} catch (e) {
|
614
|
+
addErrorAttribute(this, e);
|
615
|
+
}
|
616
|
+
|
617
|
+
const cfg = {};
|
618
|
+
if (this.getOption("eventProcessing") === true) {
|
619
|
+
cfg.eventProcessing = true;
|
620
|
+
}
|
621
|
+
|
622
|
+
addObjectWithUpdaterToElement.call(
|
623
|
+
this,
|
624
|
+
nodeList,
|
625
|
+
customElementUpdaterLinkSymbol,
|
626
|
+
this[updateCloneDataSymbol],
|
627
|
+
cfg,
|
628
|
+
);
|
629
|
+
|
630
|
+
// Attach a mutation observer to observe changes to the attributes of the element
|
631
|
+
attachAttributeChangeMutationObserver.call(this);
|
632
|
+
|
633
|
+
return this;
|
634
|
+
}
|
635
|
+
|
636
|
+
/**
|
637
|
+
* You know what you are doing? This function is only for advanced users.
|
638
|
+
* The result is a clone of the internal data.
|
639
|
+
*
|
640
|
+
* @return {*}
|
641
|
+
*/
|
642
|
+
getInternalUpdateCloneData() {
|
643
|
+
return clone(this[updateCloneDataSymbol]);
|
644
|
+
}
|
645
|
+
|
646
|
+
/**
|
647
|
+
* This method is called every time the element is inserted into the DOM. It checks if the custom element
|
648
|
+
* has already been initialized and if not, calls the assembleMethod to initialize it.
|
649
|
+
*
|
650
|
+
* @return {void}
|
651
|
+
* @since 1.7.0
|
652
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element/connectedCallback
|
653
|
+
*/
|
654
|
+
connectedCallback() {
|
655
|
+
// Check if the object has already been initialized
|
656
|
+
if (!hasObjectLink(this, customElementUpdaterLinkSymbol)) {
|
657
|
+
// If not, call the assembleMethod to initialize the object
|
658
|
+
this[assembleMethodSymbol]();
|
659
|
+
}
|
660
|
+
}
|
661
|
+
|
662
|
+
/**
|
663
|
+
* Called every time the element is removed from the DOM. Useful for running clean up code.
|
664
|
+
*
|
665
|
+
* @return {void}
|
666
|
+
* @since 1.7.0
|
667
|
+
*/
|
668
|
+
disconnectedCallback() {}
|
669
|
+
|
670
|
+
/**
|
671
|
+
* The custom element has been moved into a new document (e.g. someone called document.adoptNode(el)).
|
672
|
+
*
|
673
|
+
* @return {void}
|
674
|
+
* @since 1.7.0
|
675
|
+
*/
|
676
|
+
adoptedCallback() {}
|
677
|
+
|
678
|
+
/**
|
679
|
+
* Called when an observed attribute has been added, removed, updated, or replaced. Also called for initial
|
680
|
+
* values when an element is created by the parser, or upgraded. Note: only attributes listed in the observedAttributes
|
681
|
+
* property will receive this callback.
|
682
|
+
*
|
683
|
+
* @param {string} attrName
|
684
|
+
* @param {string} oldVal
|
685
|
+
* @param {string} newVal
|
686
|
+
* @return {void}
|
687
|
+
* @since 1.15.0
|
688
|
+
*/
|
689
|
+
attributeChangedCallback(attrName, oldVal, newVal) {
|
690
|
+
if (attrName.startsWith("data-monster-option-")) {
|
691
|
+
setOptionFromAttribute(
|
692
|
+
this,
|
693
|
+
attrName,
|
694
|
+
this[internalSymbol].getSubject()["options"],
|
695
|
+
);
|
696
|
+
}
|
697
|
+
|
698
|
+
const callback = this[attributeObserverSymbol]?.[attrName];
|
699
|
+
if (isFunction(callback)) {
|
700
|
+
try {
|
701
|
+
callback.call(this, newVal, oldVal);
|
702
|
+
} catch (e) {
|
703
|
+
addErrorAttribute(this, e);
|
704
|
+
}
|
705
|
+
}
|
706
|
+
}
|
707
|
+
|
708
|
+
/**
|
709
|
+
*
|
710
|
+
* @param {Node} node
|
711
|
+
* @return {boolean}
|
712
|
+
* @throws {TypeError} value is not an instance of
|
713
|
+
* @since 1.19.0
|
714
|
+
*/
|
715
|
+
hasNode(node) {
|
716
|
+
if (containChildNode.call(this, validateInstance(node, Node))) {
|
717
|
+
return true;
|
718
|
+
}
|
719
|
+
|
720
|
+
if (!(this.shadowRoot instanceof ShadowRoot)) {
|
721
|
+
return false;
|
722
|
+
}
|
723
|
+
|
724
|
+
return containChildNode.call(this.shadowRoot, node);
|
725
|
+
}
|
726
|
+
|
727
|
+
/**
|
728
|
+
* Calls a callback function if it exists.
|
729
|
+
*
|
730
|
+
* @param {string} name
|
731
|
+
* @param {*} args
|
732
|
+
* @return {*}
|
733
|
+
*/
|
734
|
+
callCallback(name, args) {
|
735
|
+
return callControlCallback.call(this, name, ...args);
|
736
|
+
}
|
743
737
|
}
|
744
738
|
|
745
739
|
/**
|
@@ -748,49 +742,46 @@ class CustomElement extends HTMLElement {
|
|
748
742
|
* @return {any}
|
749
743
|
*/
|
750
744
|
function callControlCallback(callBackFunctionName, ...args) {
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
this,
|
792
|
-
`callback ${callBackFunctionName} not found`,
|
793
|
-
);
|
745
|
+
if (!isString(callBackFunctionName) || callBackFunctionName === "") {
|
746
|
+
return;
|
747
|
+
}
|
748
|
+
|
749
|
+
if (callBackFunctionName in this) {
|
750
|
+
return this[callBackFunctionName](this, ...args);
|
751
|
+
}
|
752
|
+
|
753
|
+
if (!this.hasAttribute(ATTRIBUTE_SCRIPT_HOST)) {
|
754
|
+
return;
|
755
|
+
}
|
756
|
+
|
757
|
+
if (this[scriptHostElementSymbol].length === 0) {
|
758
|
+
const targetId = this.getAttribute(ATTRIBUTE_SCRIPT_HOST);
|
759
|
+
if (!targetId) {
|
760
|
+
return;
|
761
|
+
}
|
762
|
+
|
763
|
+
const list = targetId.split(",");
|
764
|
+
for (const id of list) {
|
765
|
+
const host = findElementWithIdUpwards(this, targetId);
|
766
|
+
if (!(host instanceof HTMLElement)) {
|
767
|
+
continue;
|
768
|
+
}
|
769
|
+
|
770
|
+
this[scriptHostElementSymbol].push(host);
|
771
|
+
}
|
772
|
+
}
|
773
|
+
|
774
|
+
for (const host of this[scriptHostElementSymbol]) {
|
775
|
+
if (callBackFunctionName in host) {
|
776
|
+
try {
|
777
|
+
return host[callBackFunctionName](this, ...args);
|
778
|
+
} catch (e) {
|
779
|
+
addErrorAttribute(this, e);
|
780
|
+
}
|
781
|
+
}
|
782
|
+
}
|
783
|
+
|
784
|
+
addErrorAttribute(this, `callback ${callBackFunctionName} not found`);
|
794
785
|
}
|
795
786
|
|
796
787
|
/**
|
@@ -807,16 +798,16 @@ function callControlCallback(callBackFunctionName, ...args) {
|
|
807
798
|
* @since 1.8.0
|
808
799
|
*/
|
809
800
|
function initFromCallbackHost() {
|
810
|
-
|
811
|
-
|
801
|
+
// Set the default callback function name
|
802
|
+
let callBackFunctionName = initControlCallbackName;
|
812
803
|
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
804
|
+
// If the `data-monster-option-callback` attribute is set, use its value as the callback function name
|
805
|
+
if (this.hasAttribute(ATTRIBUTE_INIT_CALLBACK)) {
|
806
|
+
callBackFunctionName = this.getAttribute(ATTRIBUTE_INIT_CALLBACK);
|
807
|
+
}
|
817
808
|
|
818
|
-
|
819
|
-
|
809
|
+
// Call the callback function with the element as a parameter if it exists
|
810
|
+
callControlCallback.call(this, callBackFunctionName);
|
820
811
|
}
|
821
812
|
|
822
813
|
/**
|
@@ -826,34 +817,34 @@ function initFromCallbackHost() {
|
|
826
817
|
* @this CustomElement
|
827
818
|
*/
|
828
819
|
function attachAttributeChangeMutationObserver() {
|
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
|
-
|
820
|
+
const self = this;
|
821
|
+
|
822
|
+
if (typeof self[attributeMutationObserverSymbol] !== "undefined") {
|
823
|
+
return;
|
824
|
+
}
|
825
|
+
|
826
|
+
self[attributeMutationObserverSymbol] = new MutationObserver(
|
827
|
+
function (mutations, observer) {
|
828
|
+
for (const mutation of mutations) {
|
829
|
+
if (mutation.type === "attributes") {
|
830
|
+
self.attributeChangedCallback(
|
831
|
+
mutation.attributeName,
|
832
|
+
mutation.oldValue,
|
833
|
+
mutation.target.getAttribute(mutation.attributeName),
|
834
|
+
);
|
835
|
+
}
|
836
|
+
}
|
837
|
+
},
|
838
|
+
);
|
839
|
+
|
840
|
+
try {
|
841
|
+
self[attributeMutationObserverSymbol].observe(self, {
|
842
|
+
attributes: true,
|
843
|
+
attributeOldValue: true,
|
844
|
+
});
|
845
|
+
} catch (e) {
|
846
|
+
addErrorAttribute(self, e);
|
847
|
+
}
|
857
848
|
}
|
858
849
|
|
859
850
|
/**
|
@@ -863,19 +854,19 @@ function attachAttributeChangeMutationObserver() {
|
|
863
854
|
* @return {boolean}
|
864
855
|
*/
|
865
856
|
function containChildNode(node) {
|
866
|
-
|
867
|
-
|
868
|
-
|
857
|
+
if (this.contains(node)) {
|
858
|
+
return true;
|
859
|
+
}
|
869
860
|
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
861
|
+
for (const [, e] of Object.entries(this.childNodes)) {
|
862
|
+
if (e.contains(node)) {
|
863
|
+
return true;
|
864
|
+
}
|
874
865
|
|
875
|
-
|
876
|
-
|
866
|
+
containChildNode.call(e, node);
|
867
|
+
}
|
877
868
|
|
878
|
-
|
869
|
+
return false;
|
879
870
|
}
|
880
871
|
|
881
872
|
/**
|
@@ -885,89 +876,89 @@ function containChildNode(node) {
|
|
885
876
|
* @this CustomElement
|
886
877
|
*/
|
887
878
|
function initOptionObserver() {
|
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
|
-
|
879
|
+
const self = this;
|
880
|
+
|
881
|
+
let lastDisabledValue = undefined;
|
882
|
+
self.attachObserver(
|
883
|
+
new Observer(function () {
|
884
|
+
const flag = self.getOption("disabled");
|
885
|
+
|
886
|
+
if (flag === lastDisabledValue) {
|
887
|
+
return;
|
888
|
+
}
|
889
|
+
|
890
|
+
lastDisabledValue = flag;
|
891
|
+
|
892
|
+
if (!(self.shadowRoot instanceof ShadowRoot)) {
|
893
|
+
return;
|
894
|
+
}
|
895
|
+
|
896
|
+
const query =
|
897
|
+
"button, command, fieldset, keygen, optgroup, option, select, textarea, input, [data-monster-objectlink]";
|
898
|
+
const elements = self.shadowRoot.querySelectorAll(query);
|
899
|
+
|
900
|
+
let nodeList;
|
901
|
+
try {
|
902
|
+
nodeList = new Set([
|
903
|
+
...elements,
|
904
|
+
...getSlottedElements.call(self, query),
|
905
|
+
]);
|
906
|
+
} catch (e) {
|
907
|
+
nodeList = elements;
|
908
|
+
}
|
909
|
+
|
910
|
+
for (const element of [...nodeList]) {
|
911
|
+
if (flag === true) {
|
912
|
+
element.setAttribute(ATTRIBUTE_DISABLED, "");
|
913
|
+
} else {
|
914
|
+
element.removeAttribute(ATTRIBUTE_DISABLED);
|
915
|
+
}
|
916
|
+
}
|
917
|
+
}),
|
918
|
+
);
|
919
|
+
|
920
|
+
self.attachObserver(
|
921
|
+
new Observer(function () {
|
922
|
+
// not initialised
|
923
|
+
if (!hasObjectLink(self, customElementUpdaterLinkSymbol)) {
|
924
|
+
return;
|
925
|
+
}
|
926
|
+
// inform every element
|
927
|
+
const updaters = getLinkedObjects(self, customElementUpdaterLinkSymbol);
|
928
|
+
|
929
|
+
for (const list of updaters) {
|
930
|
+
for (const updater of list) {
|
931
|
+
const d = clone(self[internalSymbol].getRealSubject()["options"]);
|
932
|
+
Object.assign(updater.getSubject(), d);
|
933
|
+
}
|
934
|
+
}
|
935
|
+
}),
|
936
|
+
);
|
937
|
+
|
938
|
+
// disabled
|
939
|
+
self[attributeObserverSymbol][ATTRIBUTE_DISABLED] = () => {
|
940
|
+
if (self.hasAttribute(ATTRIBUTE_DISABLED)) {
|
941
|
+
self.setOption(ATTRIBUTE_DISABLED, true);
|
942
|
+
} else {
|
943
|
+
self.setOption(ATTRIBUTE_DISABLED, undefined);
|
944
|
+
}
|
945
|
+
};
|
946
|
+
|
947
|
+
// data-monster-options
|
948
|
+
self[attributeObserverSymbol][ATTRIBUTE_OPTIONS] = () => {
|
949
|
+
const options = getOptionsFromAttributes.call(self);
|
950
|
+
if (isObject(options) && Object.keys(options).length > 0) {
|
951
|
+
self.setOptions(options);
|
952
|
+
}
|
953
|
+
};
|
954
|
+
|
955
|
+
// data-monster-options-selector
|
956
|
+
self[attributeObserverSymbol][ATTRIBUTE_OPTIONS_SELECTOR] = () => {
|
957
|
+
const options = getOptionsFromScriptTag.call(self);
|
958
|
+
if (isObject(options) && Object.keys(options).length > 0) {
|
959
|
+
self.setOptions(options);
|
960
|
+
}
|
961
|
+
};
|
971
962
|
}
|
972
963
|
|
973
964
|
/**
|
@@ -976,35 +967,35 @@ function initOptionObserver() {
|
|
976
967
|
* @throws {TypeError} value is not a object
|
977
968
|
*/
|
978
969
|
function getOptionsFromScriptTag() {
|
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
|
-
|
970
|
+
if (!this.hasAttribute(ATTRIBUTE_OPTIONS_SELECTOR)) {
|
971
|
+
return {};
|
972
|
+
}
|
973
|
+
|
974
|
+
const node = document.querySelector(
|
975
|
+
this.getAttribute(ATTRIBUTE_OPTIONS_SELECTOR),
|
976
|
+
);
|
977
|
+
if (!(node instanceof HTMLScriptElement)) {
|
978
|
+
addErrorAttribute(
|
979
|
+
this,
|
980
|
+
`the selector ${ATTRIBUTE_OPTIONS_SELECTOR} for options was specified (${this.getAttribute(
|
981
|
+
ATTRIBUTE_OPTIONS_SELECTOR,
|
982
|
+
)}) but not found.`,
|
983
|
+
);
|
984
|
+
return {};
|
985
|
+
}
|
986
|
+
|
987
|
+
let obj = {};
|
988
|
+
|
989
|
+
try {
|
990
|
+
obj = parseOptionsJSON.call(this, node.textContent.trim());
|
991
|
+
} catch (e) {
|
992
|
+
addErrorAttribute(
|
993
|
+
this,
|
994
|
+
`when analyzing the configuration from the script tag there was an error. ${e}`,
|
995
|
+
);
|
996
|
+
}
|
997
|
+
|
998
|
+
return obj;
|
1008
999
|
}
|
1009
1000
|
|
1010
1001
|
/**
|
@@ -1012,20 +1003,20 @@ function getOptionsFromScriptTag() {
|
|
1012
1003
|
* @return {object}
|
1013
1004
|
*/
|
1014
1005
|
function getOptionsFromAttributes() {
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1006
|
+
if (this.hasAttribute(ATTRIBUTE_OPTIONS)) {
|
1007
|
+
try {
|
1008
|
+
return parseOptionsJSON.call(this, this.getAttribute(ATTRIBUTE_OPTIONS));
|
1009
|
+
} catch (e) {
|
1010
|
+
addErrorAttribute(
|
1011
|
+
this,
|
1012
|
+
`the options attribute ${ATTRIBUTE_OPTIONS} does not contain a valid json definition (actual: ${this.getAttribute(
|
1013
|
+
ATTRIBUTE_OPTIONS,
|
1014
|
+
)}).${e}`,
|
1015
|
+
);
|
1016
|
+
}
|
1017
|
+
}
|
1018
|
+
|
1019
|
+
return {};
|
1029
1020
|
}
|
1030
1021
|
|
1031
1022
|
/**
|
@@ -1037,26 +1028,25 @@ function getOptionsFromAttributes() {
|
|
1037
1028
|
* @throws {error} Throws an error if the JSON data is not valid.
|
1038
1029
|
*/
|
1039
1030
|
function parseOptionsJSON(data) {
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
return validateObject(obj);
|
1031
|
+
let obj = {};
|
1032
|
+
|
1033
|
+
if (!isString(data)) {
|
1034
|
+
return obj;
|
1035
|
+
}
|
1036
|
+
|
1037
|
+
// the configuration can be specified as a data url.
|
1038
|
+
try {
|
1039
|
+
const dataUrl = parseDataURL(data);
|
1040
|
+
data = dataUrl.content;
|
1041
|
+
} catch (e) {}
|
1042
|
+
|
1043
|
+
try {
|
1044
|
+
obj = JSON.parse(data);
|
1045
|
+
} catch (e) {
|
1046
|
+
throw e;
|
1047
|
+
}
|
1048
|
+
|
1049
|
+
return validateObject(obj);
|
1060
1050
|
}
|
1061
1051
|
|
1062
1052
|
/**
|
@@ -1064,21 +1054,21 @@ function parseOptionsJSON(data) {
|
|
1064
1054
|
* @return {initHtmlContent}
|
1065
1055
|
*/
|
1066
1056
|
function initHtmlContent() {
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1057
|
+
try {
|
1058
|
+
const template = findDocumentTemplate(this.constructor.getTag());
|
1059
|
+
this.appendChild(template.createDocumentFragment());
|
1060
|
+
} catch (e) {
|
1061
|
+
let html = this.getOption("templates.main", "");
|
1062
|
+
if (isString(html) && html.length > 0) {
|
1063
|
+
const mapping = this.getOption("templateMapping", {});
|
1064
|
+
if (isObject(mapping)) {
|
1065
|
+
html = new Formatter(mapping, {}).format(html);
|
1066
|
+
}
|
1067
|
+
this.innerHTML = html;
|
1068
|
+
}
|
1069
|
+
}
|
1070
|
+
|
1071
|
+
return this;
|
1082
1072
|
}
|
1083
1073
|
|
1084
1074
|
/**
|
@@ -1090,49 +1080,49 @@ function initHtmlContent() {
|
|
1090
1080
|
* @throws {TypeError} value is not an instance of
|
1091
1081
|
*/
|
1092
1082
|
function initCSSStylesheet() {
|
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
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1083
|
+
if (!(this.shadowRoot instanceof ShadowRoot)) {
|
1084
|
+
return this;
|
1085
|
+
}
|
1086
|
+
|
1087
|
+
const styleSheet = this.constructor.getCSSStyleSheet();
|
1088
|
+
|
1089
|
+
if (styleSheet instanceof CSSStyleSheet) {
|
1090
|
+
if (styleSheet.cssRules.length > 0) {
|
1091
|
+
this.shadowRoot.adoptedStyleSheets = [styleSheet];
|
1092
|
+
}
|
1093
|
+
} else if (isArray(styleSheet)) {
|
1094
|
+
const assign = [];
|
1095
|
+
for (const s of styleSheet) {
|
1096
|
+
if (isString(s)) {
|
1097
|
+
const trimedStyleSheet = s.trim();
|
1098
|
+
if (trimedStyleSheet !== "") {
|
1099
|
+
const style = document.createElement("style");
|
1100
|
+
style.innerHTML = trimedStyleSheet;
|
1101
|
+
this.shadowRoot.prepend(style);
|
1102
|
+
}
|
1103
|
+
continue;
|
1104
|
+
}
|
1105
|
+
|
1106
|
+
validateInstance(s, CSSStyleSheet);
|
1107
|
+
|
1108
|
+
if (s.cssRules.length > 0) {
|
1109
|
+
assign.push(s);
|
1110
|
+
}
|
1111
|
+
}
|
1112
|
+
|
1113
|
+
if (assign.length > 0) {
|
1114
|
+
this.shadowRoot.adoptedStyleSheets = assign;
|
1115
|
+
}
|
1116
|
+
} else if (isString(styleSheet)) {
|
1117
|
+
const trimedStyleSheet = styleSheet.trim();
|
1118
|
+
if (trimedStyleSheet !== "") {
|
1119
|
+
const style = document.createElement("style");
|
1120
|
+
style.innerHTML = styleSheet;
|
1121
|
+
this.shadowRoot.prepend(style);
|
1122
|
+
}
|
1123
|
+
}
|
1124
|
+
|
1125
|
+
return this;
|
1136
1126
|
}
|
1137
1127
|
|
1138
1128
|
/**
|
@@ -1144,42 +1134,42 @@ function initCSSStylesheet() {
|
|
1144
1134
|
* @since 1.8.0
|
1145
1135
|
*/
|
1146
1136
|
function initShadowRoot() {
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
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
|
-
|
1137
|
+
let template;
|
1138
|
+
let html;
|
1139
|
+
|
1140
|
+
try {
|
1141
|
+
template = findDocumentTemplate(this.constructor.getTag());
|
1142
|
+
} catch (e) {
|
1143
|
+
html = this.getOption("templates.main", "");
|
1144
|
+
if (!isString(html) || html === undefined || html === "") {
|
1145
|
+
throw new Error("html is not set.");
|
1146
|
+
}
|
1147
|
+
}
|
1148
|
+
|
1149
|
+
this.attachShadow({
|
1150
|
+
mode: this.getOption("shadowMode", "open"),
|
1151
|
+
delegatesFocus: this.getOption("delegatesFocus", true),
|
1152
|
+
});
|
1153
|
+
|
1154
|
+
if (template instanceof Template) {
|
1155
|
+
this.shadowRoot.appendChild(template.createDocumentFragment());
|
1156
|
+
return this;
|
1157
|
+
}
|
1158
|
+
|
1159
|
+
const mapping = this.getOption("templateMapping", {});
|
1160
|
+
if (isObject(mapping)) {
|
1161
|
+
const formatter = new Formatter(mapping);
|
1162
|
+
if (this.getOption("templateFormatter.marker.open") !== null) {
|
1163
|
+
formatter.setMarker(
|
1164
|
+
this.getOption("templateFormatter.marker.open"),
|
1165
|
+
this.getOption("templateFormatter.marker.close"),
|
1166
|
+
);
|
1167
|
+
}
|
1168
|
+
html = formatter.format(html);
|
1169
|
+
}
|
1170
|
+
|
1171
|
+
this.shadowRoot.innerHTML = html;
|
1172
|
+
return this;
|
1183
1173
|
}
|
1184
1174
|
|
1185
1175
|
/**
|
@@ -1193,20 +1183,20 @@ function initShadowRoot() {
|
|
1193
1183
|
* @throws {DOMException} Failed to execute 'define' on 'CustomElementRegistry': is not a valid custom element name
|
1194
1184
|
*/
|
1195
1185
|
function registerCustomElement(element) {
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1186
|
+
validateFunction(element);
|
1187
|
+
const customElements = getGlobalObject("customElements");
|
1188
|
+
if (customElements === undefined) {
|
1189
|
+
throw new Error("customElements is not supported.");
|
1190
|
+
}
|
1191
|
+
|
1192
|
+
const tag = element?.getTag();
|
1193
|
+
if (!isString(tag) || tag === "") {
|
1194
|
+
throw new Error("tag is not set.");
|
1195
|
+
}
|
1196
|
+
|
1197
|
+
if (customElements.get(tag) !== undefined) {
|
1198
|
+
return;
|
1199
|
+
}
|
1200
|
+
|
1201
|
+
customElements.define(tag, element);
|
1212
1202
|
}
|