@taybart/corvid 0.1.31 → 0.2.2

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/dist/index.js CHANGED
@@ -29,9 +29,12 @@ __webpack_require__.d(strings_namespaceObject, {
29
29
  var style_namespaceObject = {};
30
30
  __webpack_require__.r(style_namespaceObject);
31
31
  __webpack_require__.d(style_namespaceObject, {
32
+ css: ()=>css,
32
33
  cssVar: ()=>cssVar,
34
+ eject: ()=>eject,
33
35
  gradient: ()=>gradient,
34
36
  handleThemeSwitch: ()=>handleThemeSwitch,
37
+ inject: ()=>inject,
35
38
  isDarkMode: ()=>isDarkMode,
36
39
  onDarkMode: ()=>onDarkMode,
37
40
  render: ()=>render,
@@ -40,13 +43,18 @@ __webpack_require__.d(style_namespaceObject, {
40
43
  var dom_namespaceObject = {};
41
44
  __webpack_require__.r(dom_namespaceObject);
42
45
  __webpack_require__.d(dom_namespaceObject, {
46
+ component: ()=>component,
47
+ create: ()=>create,
43
48
  default: ()=>dom,
44
49
  el: ()=>dom_el,
45
50
  els: ()=>els,
46
51
  interpolate: ()=>interpolate,
47
52
  on: ()=>on,
53
+ onBlur: ()=>onBlur,
54
+ onFocus: ()=>onFocus,
48
55
  onKey: ()=>onKey,
49
- ready: ()=>ready
56
+ ready: ()=>ready,
57
+ registerElement: ()=>registerElement
50
58
  });
51
59
  var network_namespaceObject = {};
52
60
  __webpack_require__.r(network_namespaceObject);
@@ -123,6 +131,105 @@ function render(style) {
123
131
  Object.entries(style).forEach(([k, v])=>s += `${toKebab(k)}:${v};`);
124
132
  return s;
125
133
  }
134
+ function splitSelectors(selector) {
135
+ const out = [];
136
+ let depth = 0;
137
+ let quote = '';
138
+ let current = '';
139
+ for (const ch of selector){
140
+ if (quote) {
141
+ if (ch === quote) quote = '';
142
+ } else if ('"' === ch || "'" === ch) quote = ch;
143
+ else if ('(' === ch || '[' === ch) depth++;
144
+ else if (')' === ch || ']' === ch) depth--;
145
+ else if (',' === ch && 0 === depth) {
146
+ if (current.trim()) out.push(current.trim());
147
+ current = '';
148
+ continue;
149
+ }
150
+ current += ch;
151
+ }
152
+ if (current.trim()) out.push(current.trim());
153
+ return out;
154
+ }
155
+ function resolve(parents, selector) {
156
+ const out = [];
157
+ for (const parent of parents)for (const part of splitSelectors(selector))out.push(part.includes('&') ? part.replaceAll('&', parent) : `${parent} ${part}`);
158
+ return out;
159
+ }
160
+ function compile(parents, decls, indent = '') {
161
+ const blocks = [];
162
+ const props = [];
163
+ const nested = [];
164
+ for (const [k, v] of Object.entries(decls))if (null !== v && 'object' == typeof v) nested.push([
165
+ k,
166
+ v
167
+ ]);
168
+ else props.push(`${indent} ${toKebab(k)}: ${v};`);
169
+ if (props.length) blocks.push(`${indent}${parents.join(', ')} {\n${props.join('\n')}\n${indent}}`);
170
+ for (const [selector, block] of nested){
171
+ if (selector.startsWith('@')) {
172
+ const inner = selector.startsWith('@keyframes') ? Object.entries(block).flatMap(([step, d])=>null !== d && 'object' == typeof d ? compile([
173
+ step
174
+ ], d, `${indent} `) : []) : compile(parents, block, `${indent} `);
175
+ if (inner.length) blocks.push(`${indent}${selector} {\n${inner.join('\n')}\n${indent}}`);
176
+ continue;
177
+ }
178
+ blocks.push(...compile(resolve(parents, selector), block, indent));
179
+ }
180
+ return blocks;
181
+ }
182
+ function css(selector, style) {
183
+ return compile(splitSelectors(selector), style).join('\n');
184
+ }
185
+ function registry() {
186
+ const doc = document;
187
+ if (!doc.__corvidSheets) doc.__corvidSheets = new Map();
188
+ return doc.__corvidSheets;
189
+ }
190
+ function adoptable() {
191
+ return 'undefined' != typeof CSSStyleSheet && 'replaceSync' in CSSStyleSheet.prototype && 'undefined' != typeof Document && 'adoptedStyleSheets' in Document.prototype;
192
+ }
193
+ function styleTag(key) {
194
+ const tagged = Array.from(document.head.querySelectorAll('style[data-corvid]'));
195
+ for (const node of tagged)if (node.dataset.corvid === key) return node;
196
+ const node = document.createElement('style');
197
+ node.dataset.corvid = key;
198
+ document.head.appendChild(node);
199
+ return node;
200
+ }
201
+ function inject(selector, style, { key = selector } = {}) {
202
+ const rules = css(selector, style);
203
+ const sheets = registry();
204
+ const existing = sheets.get(key);
205
+ if (existing) {
206
+ if ('replaceSync' in existing) existing.replaceSync(rules);
207
+ else existing.textContent = rules;
208
+ return rules;
209
+ }
210
+ if (adoptable()) {
211
+ const sheet = new CSSStyleSheet();
212
+ sheet.replaceSync(rules);
213
+ document.adoptedStyleSheets = [
214
+ ...document.adoptedStyleSheets,
215
+ sheet
216
+ ];
217
+ sheets.set(key, sheet);
218
+ return rules;
219
+ }
220
+ const node = styleTag(key);
221
+ node.textContent = rules;
222
+ sheets.set(key, node);
223
+ return rules;
224
+ }
225
+ function eject(key) {
226
+ const sheets = registry();
227
+ const sheet = sheets.get(key);
228
+ if (!sheet) return;
229
+ if ('replaceSync' in sheet) document.adoptedStyleSheets = document.adoptedStyleSheets.filter((s)=>s !== sheet);
230
+ else sheet.remove();
231
+ sheets.delete(key);
232
+ }
126
233
  function isDarkMode() {
127
234
  return window.matchMedia('(prefers-color-scheme: dark)').matches;
128
235
  }
@@ -257,6 +364,37 @@ class logger {
257
364
  });
258
365
  }
259
366
  }
367
+ function _check_private_redeclaration(obj, privateCollection) {
368
+ if (privateCollection.has(obj)) throw new TypeError("Cannot initialize the same private elements twice on an object");
369
+ }
370
+ function _class_apply_descriptor_get(receiver, descriptor) {
371
+ if (descriptor.get) return descriptor.get.call(receiver);
372
+ return descriptor.value;
373
+ }
374
+ function _class_apply_descriptor_set(receiver, descriptor, value) {
375
+ if (descriptor.set) descriptor.set.call(receiver, value);
376
+ else {
377
+ if (!descriptor.writable) throw new TypeError("attempted to set read only private field");
378
+ descriptor.value = value;
379
+ }
380
+ }
381
+ function _class_extract_field_descriptor(receiver, privateMap, action) {
382
+ if (!privateMap.has(receiver)) throw new TypeError("attempted to " + action + " private field on non-instance");
383
+ return privateMap.get(receiver);
384
+ }
385
+ function _class_private_field_get(receiver, privateMap) {
386
+ var descriptor = _class_extract_field_descriptor(receiver, privateMap, "get");
387
+ return _class_apply_descriptor_get(receiver, descriptor);
388
+ }
389
+ function _class_private_field_init(obj, privateMap, value) {
390
+ _check_private_redeclaration(obj, privateMap);
391
+ privateMap.set(obj, value);
392
+ }
393
+ function _class_private_field_set(receiver, privateMap, value) {
394
+ var descriptor = _class_extract_field_descriptor(receiver, privateMap, "set");
395
+ _class_apply_descriptor_set(receiver, descriptor, value);
396
+ return value;
397
+ }
260
398
  function dom_define_property(obj, key, value) {
261
399
  if (key in obj) Object.defineProperty(obj, key, {
262
400
  value: value,
@@ -270,6 +408,16 @@ function dom_define_property(obj, key, value) {
270
408
  function ready(cb) {
271
409
  window.addEventListener('DOMContentLoaded', cb);
272
410
  }
411
+ function onFocus(cb) {
412
+ window.addEventListener('focus', ()=>{
413
+ cb();
414
+ });
415
+ }
416
+ function onBlur(cb) {
417
+ window.addEventListener('blur', ()=>{
418
+ cb();
419
+ });
420
+ }
273
421
  function on(event, cb) {
274
422
  document.addEventListener(event, cb);
275
423
  return ()=>{
@@ -296,6 +444,14 @@ function onKey(key, cb, verbose = false) {
296
444
  function els(query, verbose = false) {
297
445
  return Array.from(document.querySelectorAll(query)).map((n)=>new dom_el(n, verbose));
298
446
  }
447
+ function registerElement(name, ctor) {
448
+ const existing = customElements.get(name);
449
+ if (existing) {
450
+ if (existing !== ctor) throw new Error(`custom element ${name} is already registered by ${existing.name}`);
451
+ return;
452
+ }
453
+ customElements.define(name, ctor);
454
+ }
299
455
  class dom_el {
300
456
  static query(query, verbose = false) {
301
457
  return new dom_el(query, verbose);
@@ -318,21 +474,29 @@ class dom_el {
318
474
  parent.appendChild(this.el);
319
475
  return this;
320
476
  }
477
+ append(ch) {
478
+ return this.child(ch);
479
+ }
321
480
  appendChild(ch) {
322
481
  return this.child(ch);
323
482
  }
324
483
  child(ch) {
325
484
  if (!this.el) throw new Error(`no element from query: ${this.query}`);
326
- if (ch instanceof dom_el) this.el.appendChild(ch.el);
485
+ if ('string' == typeof ch) this.el.append(ch);
486
+ else if (ch instanceof dom_el) this.el.appendChild(ch.el);
327
487
  else this.el.appendChild(ch);
328
488
  return this;
329
489
  }
330
- prependChild(ch) {
490
+ prepend(ch) {
331
491
  if (!this.el) throw new Error(`no element from query: ${this.query}`);
332
- if (ch instanceof dom_el) this.el.prepend(ch.el);
492
+ if ('string' == typeof ch) this.el.prepend(ch);
493
+ else if (ch instanceof dom_el) this.el.prepend(ch.el);
333
494
  else this.el.prepend(ch);
334
495
  return this;
335
496
  }
497
+ prependChild(ch) {
498
+ return this.prepend(ch);
499
+ }
336
500
  empty() {
337
501
  if (this.el) this.el.innerHTML = '';
338
502
  return this;
@@ -343,17 +507,37 @@ class dom_el {
343
507
  else this.el.innerHTML = content;
344
508
  return this;
345
509
  }
510
+ html(content) {
511
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
512
+ this.el.innerHTML = content;
513
+ return this;
514
+ }
346
515
  src(url) {
347
516
  if (this.el && 'src' in this.el) this.el.src = url;
348
517
  return this;
349
518
  }
519
+ attrs(attrs) {
520
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
521
+ for (const [k, v] of Object.entries(attrs))this.el.setAttribute(k, v);
522
+ return this;
523
+ }
524
+ attr(key, val) {
525
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
526
+ this.el.setAttribute(key, val);
527
+ return this;
528
+ }
529
+ removeAttr(key) {
530
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
531
+ this.el.removeAttribute(key);
532
+ return this;
533
+ }
350
534
  style(update, stringify = false) {
351
535
  if (this.el) {
352
536
  if ('string' == typeof update) this.el.style = update;
353
537
  else if ('object' == typeof update) {
354
538
  if (!stringify) {
355
539
  for (const [k, v] of Object.entries(update))this.el.style[k] = v;
356
- return;
540
+ return this;
357
541
  }
358
542
  const s = render(update);
359
543
  this.log.debug(`set style: ${this.el.style} -> ${s}`);
@@ -378,38 +562,23 @@ class dom_el {
378
562
  else for (const sc of className)this.el.classList.remove(sc);
379
563
  return this;
380
564
  }
381
- html(content) {
382
- if (!this.el) throw new Error(`no element from query: ${this.query}`);
383
- this.el.innerHTML = content;
384
- }
385
- render(vars = {}) {
386
- if (!this.el) throw new Error(`no element from query: ${this.query}`);
387
- try {
388
- return interpolate(this.el.innerHTML, vars);
389
- } catch (e) {
390
- throw new Error(`could not render template ${this.query}: ${e}`);
391
- }
392
- }
393
- appendTemplate(template, vars) {
394
- if (!this.el) throw new Error(`no element from query: ${this.query}`);
395
- if (!template.el) throw new Error("template does not contain element");
396
- const tmpl = template.render(vars);
397
- this.el.insertAdjacentHTML('beforeend', tmpl);
398
- }
399
- on(event, cb) {
565
+ on(event, cb, options) {
400
566
  if (!this.el) throw new Error(`no element from query: ${this.query}`);
401
567
  if (!this.listeners[event]) this.listeners[event] = [];
402
- this.listeners[event].push(cb);
403
- this.el.addEventListener(event, cb);
568
+ this.listeners[event].push({
569
+ cb,
570
+ options
571
+ });
572
+ this.el.addEventListener(event, cb, options);
404
573
  return this;
405
574
  }
406
- listen(event, cb) {
407
- return this.on(event, cb);
575
+ listen(event, cb, options) {
576
+ return this.on(event, cb, options);
408
577
  }
409
578
  removeListeners(event) {
410
579
  if (!this.el) throw new Error(`no element from query: ${this.query}`);
411
580
  if (!this.listeners[event]) return this;
412
- for (const cb of this.listeners[event])this.el.removeEventListener(event, cb);
581
+ for (const { cb, options } of this.listeners[event])this.el.removeEventListener(event, cb, options);
413
582
  this.listeners[event] = [];
414
583
  return this;
415
584
  }
@@ -429,7 +598,7 @@ class dom_el {
429
598
  this.el = opts;
430
599
  return;
431
600
  }
432
- const { query, element, type, class: styleClass, style, id, content, parent, attrs } = opts;
601
+ const { query, element, tag, class: styleClass, style, id, content, parent, attrs } = opts;
433
602
  if (query) {
434
603
  this.log.debug(`using query: ${query}`);
435
604
  this.query = query;
@@ -438,11 +607,11 @@ class dom_el {
438
607
  } else if (element) {
439
608
  this.log.debug(`using existing element: ${element}`);
440
609
  this.el = element;
441
- } else if (type) {
442
- this.query = type;
443
- this.log.debug(`creating element: ${type}`);
444
- this.el = document.createElement(type);
445
- } else throw new Error('no query or type provided');
610
+ } else if (tag) {
611
+ this.query = tag;
612
+ this.log.debug(`creating element: ${tag}`);
613
+ this.el = document.createElement(tag);
614
+ } else throw new Error('no query or tag provided');
446
615
  if (this.el) {
447
616
  if (id) {
448
617
  this.log.debug(`setting id: ${id}`);
@@ -457,7 +626,12 @@ class dom_el {
457
626
  }
458
627
  if (parent) {
459
628
  this.log.debug("adding to parent");
460
- parent.appendChild(this.el);
629
+ let p = parent;
630
+ if ('string' == typeof parent) {
631
+ this.log.debug(`parent query: ${parent}`);
632
+ p = document.querySelector(parent);
633
+ }
634
+ p.appendChild(this.el);
461
635
  }
462
636
  }
463
637
  if (attrs) for (const [key, val] of Object.entries(attrs)){
@@ -466,6 +640,56 @@ class dom_el {
466
640
  }
467
641
  }
468
642
  }
643
+ function create(opts, verbose = false) {
644
+ const node = new dom_el(opts, verbose).el;
645
+ if (!node) throw new Error(`could not create element: ${opts.tag ?? opts.query ?? '?'}`);
646
+ return node;
647
+ }
648
+ var _mounted = /*#__PURE__*/ new WeakMap(), _pendingAttrs = /*#__PURE__*/ new WeakMap();
649
+ class component extends HTMLElement {
650
+ static register(tag) {
651
+ const name = tag ?? this.tag;
652
+ if (!name) throw new Error(`${this.name}: nothing to register as, set \`static tag = 'x-...'\``);
653
+ if (!name.includes('-')) throw new Error(`${this.name}: '${name}' is not a valid custom element name, it needs a hyphen`);
654
+ if (this.styles) inject(name, this.styles);
655
+ registerElement(name, this);
656
+ }
657
+ mount() {}
658
+ unmount() {}
659
+ onAttr(_name, _value, _prev) {}
660
+ connectedCallback() {
661
+ if (!_class_private_field_get(this, _mounted)) {
662
+ _class_private_field_set(this, _mounted, true);
663
+ this.mount();
664
+ const queued = _class_private_field_get(this, _pendingAttrs);
665
+ _class_private_field_set(this, _pendingAttrs, []);
666
+ for (const [name, value, prev] of queued)this.onAttr(name, value, prev);
667
+ }
668
+ }
669
+ disconnectedCallback() {
670
+ this.unmount();
671
+ }
672
+ attributeChangedCallback(name, prev, value) {
673
+ if (prev === value) return;
674
+ if (!_class_private_field_get(this, _mounted)) return void _class_private_field_get(this, _pendingAttrs).push([
675
+ name,
676
+ value,
677
+ prev
678
+ ]);
679
+ this.onAttr(name, value, prev);
680
+ }
681
+ constructor(...args){
682
+ super(...args), _class_private_field_init(this, _mounted, {
683
+ writable: true,
684
+ value: false
685
+ }), _class_private_field_init(this, _pendingAttrs, {
686
+ writable: true,
687
+ value: []
688
+ });
689
+ }
690
+ }
691
+ dom_define_property(component, "tag", '');
692
+ dom_define_property(component, "styles", null);
469
693
  function interpolate(str, params) {
470
694
  let names = Object.keys(params).map((k)=>`_${k}`);
471
695
  let vals = Object.values(params);
@@ -474,6 +698,9 @@ function interpolate(str, params) {
474
698
  const dom = {
475
699
  el: dom_el,
476
700
  els,
701
+ create,
702
+ component,
703
+ registerElement,
477
704
  ready,
478
705
  on,
479
706
  onKey