@symbiotejs/symbiote 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,697 @@
1
+ /** @returns {Object<string, any>} */
2
+ function cloneObj(obj) {
3
+ let clone = (o) => {
4
+ for (let prop in o) {
5
+ if (o[prop]?.constructor === Object) {
6
+ o[prop] = clone(o[prop]);
7
+ }
8
+ }
9
+ return { ...o };
10
+ };
11
+ return clone(obj);
12
+ }
13
+
14
+ class Data {
15
+ /**
16
+ * @param {Object} src
17
+ * @param {String} [src.name]
18
+ * @param {Object<string, any>} src.schema
19
+ */
20
+ constructor(src) {
21
+ this.uid = Symbol();
22
+ this.name = src.name || null;
23
+ if (src.schema.constructor === Object) {
24
+ this.store = cloneObj(src.schema);
25
+ } else {
26
+ // For Proxy support:
27
+ this._storeIsProxy = true;
28
+ this.store = src.schema;
29
+ }
30
+ /** @type {Object<String, Set<Function>>} */
31
+ this.callbackMap = Object.create(null);
32
+ }
33
+
34
+ /**
35
+ * @param {String} actionName
36
+ * @param {String} prop
37
+ */
38
+ static warn(actionName, prop) {
39
+ console.warn(`Symbiote Data: cannot ${actionName}. Prop name: ` + prop);
40
+ }
41
+
42
+ /** @param {String} prop */
43
+ read(prop) {
44
+ if (!this._storeIsProxy && !this.store.hasOwnProperty(prop)) {
45
+ Data.warn('read', prop);
46
+ return null;
47
+ }
48
+ return this.store[prop];
49
+ }
50
+
51
+ /** @param {String} prop */
52
+ has(prop) {
53
+ return this._storeIsProxy ? this.store[prop] !== undefined : this.store.hasOwnProperty(prop);
54
+ }
55
+
56
+ /**
57
+ * @param {String} prop
58
+ * @param {any} val
59
+ * @param {Boolean} [rewrite]
60
+ */
61
+ add(prop, val, rewrite = true) {
62
+ if (!rewrite && Object.keys(this.store).includes(prop)) {
63
+ return;
64
+ }
65
+ this.store[prop] = val;
66
+ if (this.callbackMap[prop]) {
67
+ this.callbackMap[prop].forEach((callback) => {
68
+ callback(this.store[prop]);
69
+ });
70
+ }
71
+ }
72
+
73
+ /**
74
+ * @param {String} prop
75
+ * @param {any} val
76
+ */
77
+ pub(prop, val) {
78
+ if (!this._storeIsProxy && !this.store.hasOwnProperty(prop)) {
79
+ Data.warn('publish', prop);
80
+ return;
81
+ }
82
+ this.add(prop, val);
83
+ }
84
+
85
+ /** @param {Object<string, any>} updObj */
86
+ multiPub(updObj) {
87
+ for (let prop in updObj) {
88
+ this.pub(prop, updObj[prop]);
89
+ }
90
+ }
91
+
92
+ /** @param {String} prop */
93
+ notify(prop) {
94
+ if (this.callbackMap[prop]) {
95
+ this.callbackMap[prop].forEach((callback) => {
96
+ callback(this.store[prop]);
97
+ });
98
+ }
99
+ }
100
+
101
+ /**
102
+ * @param {String} prop
103
+ * @param {Function} callback
104
+ * @param {Boolean} [init]
105
+ */
106
+ sub(prop, callback, init = true) {
107
+ if (!this._storeIsProxy && !this.store.hasOwnProperty(prop)) {
108
+ Data.warn('subscribe', prop);
109
+ return null;
110
+ }
111
+ if (!this.callbackMap[prop]) {
112
+ this.callbackMap[prop] = new Set();
113
+ }
114
+ this.callbackMap[prop].add(callback);
115
+ if (init) {
116
+ callback(this.store[prop]);
117
+ }
118
+ return {
119
+ remove: () => {
120
+ this.callbackMap[prop].delete(callback);
121
+ if (!this.callbackMap[prop].size) {
122
+ delete this.callbackMap[prop];
123
+ }
124
+ },
125
+ callback,
126
+ };
127
+ }
128
+
129
+ remove() {
130
+ delete Data.globalStore[this.uid];
131
+ }
132
+
133
+ /** @param {Object<string, any>} schema */
134
+ static registerLocalCtx(schema) {
135
+ let state = new Data({
136
+ schema,
137
+ });
138
+ Data.globalStore[state.uid] = state;
139
+ return state;
140
+ }
141
+
142
+ /**
143
+ * @param {String} ctxName
144
+ * @param {Object<string, any>} schema
145
+ * @returns {Data}
146
+ */
147
+ static registerNamedCtx(ctxName, schema) {
148
+ /** @type {Data} */
149
+ let state = Data.globalStore[ctxName];
150
+ if (state) {
151
+ console.warn('State: context name "' + ctxName + '" already in use');
152
+ } else {
153
+ state = new Data({
154
+ name: ctxName,
155
+ schema,
156
+ });
157
+ Data.globalStore[ctxName] = state;
158
+ }
159
+ return state;
160
+ }
161
+
162
+ /** @param {String} ctxName */
163
+ static clearNamedCtx(ctxName) {
164
+ delete Data.globalStore[ctxName];
165
+ }
166
+
167
+ /**
168
+ * @param {String} ctxName
169
+ * @param {Boolean} [notify]
170
+ * @returns {Data}
171
+ */
172
+ static getNamedCtx(ctxName, notify = true) {
173
+ return Data.globalStore[ctxName] || (notify && console.warn('State: wrong context name - "' + ctxName + '"'), null);
174
+ }
175
+ }
176
+
177
+ Data.globalStore = Object.create(null);
178
+
179
+ const DICT = Object.freeze({
180
+ // Template data binding attribute:
181
+ BIND_ATTR: 'set',
182
+ // Local state binding attribute name:
183
+ ATTR_BIND_PRFX: '@',
184
+ // External prop prefix:
185
+ EXT_DATA_CTX_PRFX: '*',
186
+ // Named data context property splitter:
187
+ NAMED_DATA_CTX_SPLTR: '/',
188
+ // Data context name attribute:
189
+ CTX_NAME_ATTR: 'ctx-name',
190
+ // Data context name in CSS custom property:
191
+ CSS_CTX_PROP: '--ctx-name',
192
+ // Element reference attribute:
193
+ EL_REF_ATTR: 'ref',
194
+ // Prefix for auto generated tag names:
195
+ AUTO_TAG_PRFX: 'sym',
196
+ });
197
+
198
+ const CHARS = '1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm';
199
+ const CHLENGTH = CHARS.length - 1;
200
+
201
+ class UID {
202
+
203
+ /**
204
+ *
205
+ * @param {String} [pattern] any symbols sequence with dashes. Default dash is used for human readability
206
+ * @returns {String} output example: v6xYaSk7C-kzZ
207
+ */
208
+ static generate(pattern = 'XXXXXXXXX-XXX') {
209
+ let uid = '';
210
+ for (let i = 0; i < pattern.length; i++) {
211
+ uid += pattern[i] === '-' ? pattern[i] : CHARS.charAt(Math.random() * CHLENGTH);
212
+ }
213
+ return uid;
214
+ }
215
+ }
216
+
217
+ function slotProcessor(fr, fnCtx) {
218
+ if (fnCtx.renderShadow) {
219
+ return;
220
+ }
221
+ let slots = [...fr.querySelectorAll('slot')];
222
+ if (fnCtx.__initChildren.length && slots.length) {
223
+ let slotMap = {};
224
+ slots.forEach((slot) => {
225
+ let slotName = slot.getAttribute('name');
226
+ if (slotName) {
227
+ slotMap[slotName] = {
228
+ slot,
229
+ fr: document.createDocumentFragment(),
230
+ };
231
+ } else {
232
+ slotMap.__default__ = {
233
+ slot,
234
+ fr: document.createDocumentFragment(),
235
+ };
236
+ }
237
+ });
238
+ fnCtx.__initChildren.forEach((/** @type {Element} */ child) => {
239
+ let slotName = child.getAttribute?.('slot');
240
+ if (slotName) {
241
+ child.removeAttribute('slot');
242
+ slotMap[slotName].fr.appendChild(child);
243
+ } else if (slotMap.__default__) {
244
+ slotMap.__default__.fr.appendChild(child);
245
+ }
246
+ });
247
+ Object.values(slotMap).forEach((mapObj) => {
248
+ mapObj.slot.parentNode.insertBefore(mapObj.fr, mapObj.slot);
249
+ mapObj.slot.remove();
250
+ });
251
+ } else {
252
+ fnCtx.innerHTML = '';
253
+ }
254
+ }
255
+
256
+ function refProcessor(fr, fnCtx) {
257
+ [...fr.querySelectorAll(`[${DICT.EL_REF_ATTR}]`)].forEach((/** @type {HTMLElement} */ el) => {
258
+ let refName = el.getAttribute(DICT.EL_REF_ATTR);
259
+ fnCtx.ref[refName] = el;
260
+ el.removeAttribute(DICT.EL_REF_ATTR);
261
+ });
262
+ }
263
+
264
+ /**
265
+ * @param {DocumentFragment} fr
266
+ * @param {any} fnCtx
267
+ */
268
+ function domSetProcessor(fr, fnCtx) {
269
+ [...fr.querySelectorAll(`[${DICT.BIND_ATTR}]`)].forEach((el) => {
270
+ let subStr = el.getAttribute(DICT.BIND_ATTR);
271
+ let keyValsArr = subStr.split(';');
272
+ keyValsArr.forEach((keyValStr) => {
273
+ if (!keyValStr) {
274
+ return;
275
+ }
276
+ let kv = keyValStr.split(':').map((str) => str.trim());
277
+ let prop = kv[0];
278
+ let isAttr;
279
+
280
+ if (prop.indexOf(DICT.ATTR_BIND_PRFX) === 0) {
281
+ isAttr = true;
282
+ prop = prop.replace(DICT.ATTR_BIND_PRFX, '');
283
+ }
284
+ /** @type {String[]} */
285
+ let valKeysArr = kv[1].split(',').map((valKey) => {
286
+ return valKey.trim();
287
+ });
288
+ // Deep property:
289
+ let isDeep, parent, lastStep, dive;
290
+ if (prop.includes('.')) {
291
+ isDeep = true;
292
+ let propPath = prop.split('.');
293
+ dive = () => {
294
+ parent = el;
295
+ propPath.forEach((step, idx) => {
296
+ if (idx < propPath.length - 1) {
297
+ parent = parent[step];
298
+ } else {
299
+ lastStep = step;
300
+ }
301
+ });
302
+ };
303
+ dive();
304
+ }
305
+ for (let valKey of valKeysArr) {
306
+ fnCtx.sub(valKey, (val) => {
307
+ if (isAttr) {
308
+ if (val?.constructor === Boolean) {
309
+ val ? el.setAttribute(prop, '') : el.removeAttribute(prop);
310
+ } else {
311
+ el.setAttribute(prop, val);
312
+ }
313
+ } else if (isDeep) {
314
+ if (parent) {
315
+ parent[lastStep] = val;
316
+ } else {
317
+ // Custom element instances are not constructed properly at this time, so:
318
+ window.setTimeout(() => {
319
+ dive();
320
+ parent[lastStep] = val;
321
+ });
322
+ // TODO: investigate how to do it better ^^^
323
+ }
324
+ } else {
325
+ el[prop] = val;
326
+ }
327
+ });
328
+ }
329
+ });
330
+ el.removeAttribute(DICT.BIND_ATTR);
331
+ });
332
+ }
333
+
334
+ var PROCESSORS = [slotProcessor, refProcessor, domSetProcessor];
335
+
336
+ let autoTagsCount = 0;
337
+
338
+ class BaseComponent extends HTMLElement {
339
+ /**
340
+ * @param {String | DocumentFragment} [template]
341
+ * @param {Boolean} [shadow]
342
+ */
343
+ render(template, shadow = this.renderShadow) {
344
+ /** @type {DocumentFragment} */
345
+ let fr;
346
+ if (template || this.constructor['template']) {
347
+ if (this.constructor['template'] && !this.constructor['__tpl']) {
348
+ this.constructor['__tpl'] = document.createElement('template');
349
+ this.constructor['__tpl'].innerHTML = this.constructor['template'];
350
+ }
351
+ while (this.firstChild) {
352
+ this.firstChild.remove();
353
+ }
354
+ if (template?.constructor === DocumentFragment) {
355
+ fr = template;
356
+ } else if (template?.constructor === String) {
357
+ let tpl = document.createElement('template');
358
+ tpl.innerHTML = template;
359
+ // @ts-ignore
360
+ fr = tpl.content.cloneNode(true);
361
+ } else if (this.constructor['__tpl']) {
362
+ fr = this.constructor['__tpl'].content.cloneNode(true);
363
+ }
364
+ for (let fn of this.tplProcessors) {
365
+ fn(fr, this);
366
+ }
367
+ }
368
+ if (shadow) {
369
+ if (!this.shadowRoot) {
370
+ this.attachShadow({
371
+ mode: 'open',
372
+ });
373
+ }
374
+ fr && this.shadowRoot.appendChild(fr);
375
+ } else {
376
+ fr && this.appendChild(fr);
377
+ }
378
+ }
379
+
380
+ /** @param {(fr: DocumentFragment, fnCtx: any) => any} processorFn */
381
+ addTemplateProcessor(processorFn) {
382
+ this.tplProcessors.add(processorFn);
383
+ }
384
+
385
+ constructor() {
386
+ super();
387
+ /** @type {Object<string, any>} */
388
+ this.init$ = Object.create(null);
389
+ /** @type {Set<(fr: DocumentFragment, fnCtx: any) => any>} */
390
+ this.tplProcessors = new Set();
391
+ /** @type {Object<string, HTMLElement>} */
392
+ this.ref = Object.create(null);
393
+ this.allSubs = new Set();
394
+ this.pauseRender = false;
395
+ this.renderShadow = false;
396
+ this.readyToDestroy = true;
397
+ }
398
+
399
+ get autoCtxName() {
400
+ if (!this.__autoCtxName) {
401
+ this.__autoCtxName = UID.generate();
402
+ this.style.setProperty(DICT.CSS_CTX_PROP, `'${this.__autoCtxName}'`);
403
+ }
404
+ return this.__autoCtxName;
405
+ }
406
+
407
+ get cssCtxName() {
408
+ return this.getCssData(DICT.CSS_CTX_PROP, true);
409
+ }
410
+
411
+ get ctxName() {
412
+ return this.getAttribute(DICT.CTX_NAME_ATTR)?.trim() || this.cssCtxName || this.autoCtxName;
413
+ }
414
+
415
+ get localCtx() {
416
+ if (!this.__localCtx) {
417
+ this.__localCtx = Data.registerLocalCtx({});
418
+ }
419
+ return this.__localCtx;
420
+ }
421
+
422
+ get nodeCtx() {
423
+ return Data.getNamedCtx(this.ctxName, false) || Data.registerNamedCtx(this.ctxName, {});
424
+ }
425
+
426
+ /**
427
+ * @param {String} prop
428
+ * @param {any} fnCtx
429
+ */
430
+ static __parseProp(prop, fnCtx) {
431
+ /** @type {Data} */
432
+ let ctx;
433
+ /** @type {String} */
434
+ let name;
435
+ if (prop.startsWith(DICT.EXT_DATA_CTX_PRFX)) {
436
+ ctx = fnCtx.nodeCtx;
437
+ name = prop.replace(DICT.EXT_DATA_CTX_PRFX, '');
438
+ } else if (prop.includes(DICT.NAMED_DATA_CTX_SPLTR)) {
439
+ let pArr = prop.split(DICT.NAMED_DATA_CTX_SPLTR);
440
+ ctx = Data.getNamedCtx(pArr[0]);
441
+ name = pArr[1];
442
+ } else {
443
+ ctx = fnCtx.localCtx;
444
+ name = prop;
445
+ }
446
+ return {
447
+ ctx,
448
+ name,
449
+ };
450
+ }
451
+
452
+ /**
453
+ * @param {String} prop
454
+ * @param {(value: any) => void} handler
455
+ */
456
+ sub(prop, handler) {
457
+ let parsed = BaseComponent.__parseProp(prop, this);
458
+ this.allSubs.add(parsed.ctx.sub(parsed.name, handler));
459
+ }
460
+
461
+ /** @param {String} prop */
462
+ notify(prop) {
463
+ let parsed = BaseComponent.__parseProp(prop, this);
464
+ parsed.ctx.notify(parsed.name);
465
+ }
466
+
467
+ /** @param {String} prop */
468
+ has(prop) {
469
+ let parsed = BaseComponent.__parseProp(prop, this);
470
+ return parsed.ctx.has(parsed.name);
471
+ }
472
+
473
+ /**
474
+ * @param {String} prop
475
+ * @param {any} val
476
+ */
477
+ add(prop, val) {
478
+ let parsed = BaseComponent.__parseProp(prop, this);
479
+ parsed.ctx.add(parsed.name, val, false);
480
+ }
481
+
482
+ /** @param {Object<string, any>} obj */
483
+ add$(obj) {
484
+ for (let prop in obj) {
485
+ this.add(prop, obj[prop]);
486
+ }
487
+ }
488
+
489
+ get $() {
490
+ if (!this.__stateProxy) {
491
+ /** @type {Object<string, any>} */
492
+ let o = Object.create(null);
493
+ this.__stateProxy = new Proxy(o, {
494
+ set: (obj, /** @type {String} */ prop, val) => {
495
+ let parsed = BaseComponent.__parseProp(prop, this);
496
+ parsed.ctx.pub(parsed.name, val);
497
+ return true;
498
+ },
499
+ get: (obj, /** @type {String} */ prop) => {
500
+ let parsed = BaseComponent.__parseProp(prop, this);
501
+ return parsed.ctx.read(parsed.name);
502
+ },
503
+ });
504
+ }
505
+ return this.__stateProxy;
506
+ }
507
+
508
+ /** @param {Object<string, any>} kvObj */
509
+ set$(kvObj) {
510
+ for (let key in kvObj) {
511
+ this.$[key] = kvObj[key];
512
+ }
513
+ }
514
+
515
+ initCallback() {}
516
+
517
+ __initDataCtx() {
518
+ let attrDesc = this.constructor['__attrDesc'];
519
+ if (attrDesc) {
520
+ for (let prop of Object.values(attrDesc)) {
521
+ if (!Object.keys(this.init$).includes(prop)) {
522
+ this.init$[prop] = '';
523
+ }
524
+ }
525
+ }
526
+ for (let prop in this.init$) {
527
+ if (prop.startsWith(DICT.EXT_DATA_CTX_PRFX)) {
528
+ this.nodeCtx.add(prop.replace(DICT.EXT_DATA_CTX_PRFX, ''), this.init$[prop]);
529
+ } else if (prop.includes(DICT.NAMED_DATA_CTX_SPLTR)) {
530
+ let propArr = prop.split(DICT.NAMED_DATA_CTX_SPLTR);
531
+ let ctxName = propArr[0].trim();
532
+ let propName = propArr[1].trim();
533
+ if (ctxName && propName) {
534
+ let namedCtx = Data.getNamedCtx(ctxName, false);
535
+ if (!namedCtx) {
536
+ namedCtx = Data.registerNamedCtx(ctxName, {});
537
+ }
538
+ namedCtx.add(propName, this.init$[prop]);
539
+ }
540
+ } else {
541
+ this.localCtx.add(prop, this.init$[prop]);
542
+ }
543
+ }
544
+ this.__dataCtxInitialized = true;
545
+ }
546
+
547
+ connectedCallback() {
548
+ if (this.__disconnectTimeout) {
549
+ window.clearTimeout(this.__disconnectTimeout);
550
+ }
551
+ if (!this.connectedOnce) {
552
+ let ctxNameAttrVal = this.getAttribute(DICT.CTX_NAME_ATTR)?.trim();
553
+ if (ctxNameAttrVal) {
554
+ this.style.setProperty(DICT.CSS_CTX_PROP, `'${ctxNameAttrVal}'`);
555
+ }
556
+ this.__initDataCtx();
557
+ this.__initChildren = [...this.childNodes];
558
+ for (let proc of PROCESSORS) {
559
+ this.addTemplateProcessor(proc);
560
+ }
561
+ if (!this.pauseRender) {
562
+ this.render();
563
+ }
564
+ this.initCallback?.();
565
+ }
566
+ this.connectedOnce = true;
567
+ }
568
+
569
+ destroyCallback() {}
570
+
571
+ disconnectedCallback() {
572
+ this.dropCssDataCache();
573
+ if (!this.readyToDestroy) {
574
+ return;
575
+ }
576
+ if (this.__disconnectTimeout) {
577
+ window.clearTimeout(this.__disconnectTimeout);
578
+ }
579
+ this.__disconnectTimeout = window.setTimeout(() => {
580
+ this.destroyCallback();
581
+ for (let sub of this.allSubs) {
582
+ sub.remove();
583
+ this.allSubs.delete(sub);
584
+ }
585
+ for (let proc of this.tplProcessors) {
586
+ this.tplProcessors.delete(proc);
587
+ }
588
+ }, 100);
589
+ }
590
+
591
+ /**
592
+ * @param {String} [tagName]
593
+ * @param {Boolean} [isAlias]
594
+ */
595
+ static reg(tagName, isAlias = false) {
596
+ if (!tagName) {
597
+ autoTagsCount++;
598
+ tagName = `${DICT.AUTO_TAG_PRFX}-${autoTagsCount}`;
599
+ }
600
+ this.__tag = tagName;
601
+ if (window.customElements.get(tagName)) {
602
+ console.warn(`${tagName} - is already in "customElements" registry`);
603
+ return;
604
+ }
605
+ window.customElements.define(tagName, isAlias ? class extends this {} : this);
606
+ }
607
+
608
+ static get is() {
609
+ if (!this.__tag) {
610
+ this.reg();
611
+ }
612
+ return this.__tag;
613
+ }
614
+
615
+ /** @param {Object<string, string>} desc */
616
+ static bindAttributes(desc) {
617
+ this.observedAttributes = Object.keys(desc);
618
+ this.__attrDesc = desc;
619
+ }
620
+
621
+ attributeChangedCallback(name, oldVal, newVal) {
622
+ if (oldVal === newVal) {
623
+ return;
624
+ }
625
+ /** @type {String} */
626
+ let $prop = this.constructor['__attrDesc'][name];
627
+ if ($prop) {
628
+ if (this.__dataCtxInitialized) {
629
+ this.$[$prop] = newVal;
630
+ } else {
631
+ this.init$[$prop] = newVal;
632
+ }
633
+ } else {
634
+ this[name] = newVal;
635
+ }
636
+ }
637
+
638
+ /**
639
+ * @param {String} propName
640
+ * @param {Boolean} [silentCheck]
641
+ */
642
+ getCssData(propName, silentCheck = false) {
643
+ if (!this.__cssDataCache) {
644
+ this.__cssDataCache = Object.create(null);
645
+ }
646
+ if (!Object.keys(this.__cssDataCache).includes(propName)) {
647
+ if (!this.__computedStyle) {
648
+ this.__computedStyle = window.getComputedStyle(this);
649
+ }
650
+ let val = this.__computedStyle.getPropertyValue(propName).trim();
651
+ // Firefox doesn't transform string values into JSON format:
652
+ if (val.startsWith(`'`) && val.endsWith(`'`)) {
653
+ val = val.replace(/\'/g, '"');
654
+ }
655
+ try {
656
+ this.__cssDataCache[propName] = JSON.parse(val);
657
+ } catch (e) {
658
+ !silentCheck && console.warn(`CSS Data error: ${propName}`);
659
+ this.__cssDataCache[propName] = null;
660
+ }
661
+ }
662
+ return this.__cssDataCache[propName];
663
+ }
664
+
665
+ dropCssDataCache() {
666
+ this.__cssDataCache = null;
667
+ this.__computedStyle = null;
668
+ }
669
+
670
+ /**
671
+ * @param {String} propName
672
+ * @param {Function} [handler]
673
+ * @param {Boolean} [isAsync]
674
+ */
675
+ defineAccessor(propName, handler, isAsync) {
676
+ let localPropName = '__' + propName;
677
+ this[localPropName] = this[propName];
678
+ Object.defineProperty(this, propName, {
679
+ set: (val) => {
680
+ this[localPropName] = val;
681
+ if (isAsync) {
682
+ window.setTimeout(() => {
683
+ handler?.(val);
684
+ });
685
+ } else {
686
+ handler?.(val);
687
+ }
688
+ },
689
+ get: () => {
690
+ return this[localPropName];
691
+ },
692
+ });
693
+ this[propName] = this[localPropName];
694
+ }
695
+ }
696
+
697
+ export { BaseComponent };
@@ -0,0 +1 @@
1
+ function y(h){let t=e=>{var s;for(let i in e)((s=e[i])==null?void 0:s.constructor)===Object&&(e[i]=t(e[i]));return{...e}};return t(h)}var l=class{constructor(t){this.uid=Symbol(),this.name=t.name||null,t.schema.constructor===Object?this.store=y(t.schema):(this._storeIsProxy=!0,this.store=t.schema),this.callbackMap=Object.create(null)}static warn(t,e){console.warn(`Symbiote Data: cannot ${t}. Prop name: `+e)}read(t){return!this._storeIsProxy&&!this.store.hasOwnProperty(t)?(l.warn("read",t),null):this.store[t]}has(t){return this._storeIsProxy?this.store[t]!==void 0:this.store.hasOwnProperty(t)}add(t,e,s=!0){!s&&Object.keys(this.store).includes(t)||(this.store[t]=e,this.callbackMap[t]&&this.callbackMap[t].forEach(i=>{i(this.store[t])}))}pub(t,e){if(!this._storeIsProxy&&!this.store.hasOwnProperty(t)){l.warn("publish",t);return}this.add(t,e)}multiPub(t){for(let e in t)this.pub(e,t[e])}notify(t){this.callbackMap[t]&&this.callbackMap[t].forEach(e=>{e(this.store[t])})}sub(t,e,s=!0){return!this._storeIsProxy&&!this.store.hasOwnProperty(t)?(l.warn("subscribe",t),null):(this.callbackMap[t]||(this.callbackMap[t]=new Set),this.callbackMap[t].add(e),s&&e(this.store[t]),{remove:()=>{this.callbackMap[t].delete(e),this.callbackMap[t].size||delete this.callbackMap[t]},callback:e})}remove(){delete l.globalStore[this.uid]}static registerLocalCtx(t){let e=new l({schema:t});return l.globalStore[e.uid]=e,e}static registerNamedCtx(t,e){let s=l.globalStore[t];return s?console.warn('State: context name "'+t+'" already in use'):(s=new l({name:t,schema:e}),l.globalStore[t]=s),s}static clearNamedCtx(t){delete l.globalStore[t]}static getNamedCtx(t,e=!0){return l.globalStore[t]||(e&&console.warn('State: wrong context name - "'+t+'"'),null)}};l.globalStore=Object.create(null);var r=Object.freeze({BIND_ATTR:"set",ATTR_BIND_PRFX:"@",EXT_DATA_CTX_PRFX:"*",NAMED_DATA_CTX_SPLTR:"/",CTX_NAME_ATTR:"ctx-name",CSS_CTX_PROP:"--ctx-name",EL_REF_ATTR:"ref",AUTO_TAG_PRFX:"sym"});var b="1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm",p=b.length-1,m=class{static generate(t="XXXXXXXXX-XXX"){let e="";for(let s=0;s<t.length;s++)e+=t[s]==="-"?t[s]:b.charAt(Math.random()*p);return e}};function R(h,t){if(t.renderShadow)return;let e=[...h.querySelectorAll("slot")];if(t.__initChildren.length&&e.length){let s={};e.forEach(i=>{let o=i.getAttribute("name");o?s[o]={slot:i,fr:document.createDocumentFragment()}:s.__default__={slot:i,fr:document.createDocumentFragment()}}),t.__initChildren.forEach(i=>{var c;let o=(c=i.getAttribute)==null?void 0:c.call(i,"slot");o?(i.removeAttribute("slot"),s[o].fr.appendChild(i)):s.__default__&&s.__default__.fr.appendChild(i)}),Object.values(s).forEach(i=>{i.slot.parentNode.insertBefore(i.fr,i.slot),i.slot.remove()})}else t.innerHTML=""}function X(h,t){[...h.querySelectorAll(`[${r.EL_REF_ATTR}]`)].forEach(e=>{let s=e.getAttribute(r.EL_REF_ATTR);t.ref[s]=e,e.removeAttribute(r.EL_REF_ATTR)})}function D(h,t){[...h.querySelectorAll(`[${r.BIND_ATTR}]`)].forEach(e=>{e.getAttribute(r.BIND_ATTR).split(";").forEach(o=>{if(!o)return;let c=o.split(":").map(u=>u.trim()),n=c[0],C;n.indexOf(r.ATTR_BIND_PRFX)===0&&(C=!0,n=n.replace(r.ATTR_BIND_PRFX,""));let S=c[1].split(",").map(u=>u.trim()),A,d,f,T;if(n.includes(".")){A=!0;let u=n.split(".");T=()=>{d=e,u.forEach((a,g)=>{g<u.length-1?d=d[a]:f=a})},T()}for(let u of S)t.sub(u,a=>{C?(a==null?void 0:a.constructor)===Boolean?a?e.setAttribute(n,""):e.removeAttribute(n):e.setAttribute(n,a):A?d?d[f]=a:window.setTimeout(()=>{T(),d[f]=a}):e[n]=a})}),e.removeAttribute(r.BIND_ATTR)})}var P=[R,X,D];var x=0,_=class extends HTMLElement{render(t,e=this.renderShadow){let s;if(t||this.constructor.template){for(this.constructor.template&&!this.constructor.__tpl&&(this.constructor.__tpl=document.createElement("template"),this.constructor.__tpl.innerHTML=this.constructor.template);this.firstChild;)this.firstChild.remove();if((t==null?void 0:t.constructor)===DocumentFragment)s=t;else if((t==null?void 0:t.constructor)===String){let i=document.createElement("template");i.innerHTML=t,s=i.content.cloneNode(!0)}else this.constructor.__tpl&&(s=this.constructor.__tpl.content.cloneNode(!0));for(let i of this.tplProcessors)i(s,this)}e?(this.shadowRoot||this.attachShadow({mode:"open"}),s&&this.shadowRoot.appendChild(s)):s&&this.appendChild(s)}addTemplateProcessor(t){this.tplProcessors.add(t)}constructor(){super();this.init$=Object.create(null),this.tplProcessors=new Set,this.ref=Object.create(null),this.allSubs=new Set,this.pauseRender=!1,this.renderShadow=!1,this.readyToDestroy=!0}get autoCtxName(){return this.__autoCtxName||(this.__autoCtxName=m.generate(),this.style.setProperty(r.CSS_CTX_PROP,`'${this.__autoCtxName}'`)),this.__autoCtxName}get cssCtxName(){return this.getCssData(r.CSS_CTX_PROP,!0)}get ctxName(){var t;return((t=this.getAttribute(r.CTX_NAME_ATTR))==null?void 0:t.trim())||this.cssCtxName||this.autoCtxName}get localCtx(){return this.__localCtx||(this.__localCtx=l.registerLocalCtx({})),this.__localCtx}get nodeCtx(){return l.getNamedCtx(this.ctxName,!1)||l.registerNamedCtx(this.ctxName,{})}static __parseProp(t,e){let s,i;if(t.startsWith(r.EXT_DATA_CTX_PRFX))s=e.nodeCtx,i=t.replace(r.EXT_DATA_CTX_PRFX,"");else if(t.includes(r.NAMED_DATA_CTX_SPLTR)){let o=t.split(r.NAMED_DATA_CTX_SPLTR);s=l.getNamedCtx(o[0]),i=o[1]}else s=e.localCtx,i=t;return{ctx:s,name:i}}sub(t,e){let s=_.__parseProp(t,this);this.allSubs.add(s.ctx.sub(s.name,e))}notify(t){let e=_.__parseProp(t,this);e.ctx.notify(e.name)}has(t){let e=_.__parseProp(t,this);return e.ctx.has(e.name)}add(t,e){let s=_.__parseProp(t,this);s.ctx.add(s.name,e,!1)}add$(t){for(let e in t)this.add(e,t[e])}get $(){if(!this.__stateProxy){let t=Object.create(null);this.__stateProxy=new Proxy(t,{set:(e,s,i)=>{let o=_.__parseProp(s,this);return o.ctx.pub(o.name,i),!0},get:(e,s)=>{let i=_.__parseProp(s,this);return i.ctx.read(i.name)}})}return this.__stateProxy}set$(t){for(let e in t)this.$[e]=t[e]}initCallback(){}__initDataCtx(){let t=this.constructor.__attrDesc;if(t)for(let e of Object.values(t))Object.keys(this.init$).includes(e)||(this.init$[e]="");for(let e in this.init$)if(e.startsWith(r.EXT_DATA_CTX_PRFX))this.nodeCtx.add(e.replace(r.EXT_DATA_CTX_PRFX,""),this.init$[e]);else if(e.includes(r.NAMED_DATA_CTX_SPLTR)){let s=e.split(r.NAMED_DATA_CTX_SPLTR),i=s[0].trim(),o=s[1].trim();if(i&&o){let c=l.getNamedCtx(i,!1);c||(c=l.registerNamedCtx(i,{})),c.add(o,this.init$[e])}}else this.localCtx.add(e,this.init$[e]);this.__dataCtxInitialized=!0}connectedCallback(){var t,e;if(this.__disconnectTimeout&&window.clearTimeout(this.__disconnectTimeout),!this.connectedOnce){let s=(t=this.getAttribute(r.CTX_NAME_ATTR))==null?void 0:t.trim();s&&this.style.setProperty(r.CSS_CTX_PROP,`'${s}'`),this.__initDataCtx(),this.__initChildren=[...this.childNodes];for(let i of P)this.addTemplateProcessor(i);this.pauseRender||this.render(),(e=this.initCallback)==null||e.call(this)}this.connectedOnce=!0}destroyCallback(){}disconnectedCallback(){this.dropCssDataCache(),!!this.readyToDestroy&&(this.__disconnectTimeout&&window.clearTimeout(this.__disconnectTimeout),this.__disconnectTimeout=window.setTimeout(()=>{this.destroyCallback();for(let t of this.allSubs)t.remove(),this.allSubs.delete(t);for(let t of this.tplProcessors)this.tplProcessors.delete(t)},100))}static reg(t,e=!1){if(t||(x++,t=`${r.AUTO_TAG_PRFX}-${x}`),this.__tag=t,window.customElements.get(t)){console.warn(`${t} - is already in "customElements" registry`);return}window.customElements.define(t,e?class extends this{}:this)}static get is(){return this.__tag||this.reg(),this.__tag}static bindAttributes(t){this.observedAttributes=Object.keys(t),this.__attrDesc=t}attributeChangedCallback(t,e,s){if(e===s)return;let i=this.constructor.__attrDesc[t];i?this.__dataCtxInitialized?this.$[i]=s:this.init$[i]=s:this[t]=s}getCssData(t,e=!1){if(this.__cssDataCache||(this.__cssDataCache=Object.create(null)),!Object.keys(this.__cssDataCache).includes(t)){this.__computedStyle||(this.__computedStyle=window.getComputedStyle(this));let s=this.__computedStyle.getPropertyValue(t).trim();s.startsWith("'")&&s.endsWith("'")&&(s=s.replace(/\'/g,'"'));try{this.__cssDataCache[t]=JSON.parse(s)}catch{!e&&console.warn(`CSS Data error: ${t}`),this.__cssDataCache[t]=null}}return this.__cssDataCache[t]}dropCssDataCache(){this.__cssDataCache=null,this.__computedStyle=null}defineAccessor(t,e,s){let i="__"+t;this[i]=this[t],Object.defineProperty(this,t,{set:o=>{this[i]=o,s?window.setTimeout(()=>{e==null||e(o)}):e==null||e(o)},get:()=>this[i]}),this[t]=this[i]}};export{_ as BaseComponent};