Notes app :)
at main 67 lines 1.9 kB view raw
1// To be paired with a server-side rendering step. 2class DeclarativeElement extends HTMLElement { 3 static element_name = "never"; 4 5 static attrs = []; 6 dryAttributes = []; 7 8 constructor() { 9 super(); 10 } 11 12 connectedCallback() { 13 const supportsDeclarative = HTMLElement.prototype.hasOwnProperty("attachInternals"); 14 const internals = supportsDeclarative ? this.attachInternals() : undefined; 15 16 // check for a Declarative Shadow Root. 17 let shadow = internals?.shadowRoot; 18 19 if (!shadow) { 20 // there wasn't one. create a new Shadow Root: 21 shadow = this.attachShadow({ 22 mode: "closed", 23 }); 24 const templateEl = document.querySelector(`template[element="${this.constructor.element_name}"]`); 25 shadow.append(templateEl.content.cloneNode(true)); 26 } 27 28 this.shadow = shadow; 29 30 this.dryAttributes.forEach(element => { 31 this.attributeSet(element.property, element.oldValue, element.newValue); 32 }); 33 this.start(shadow); 34 } 35 36 static get observedAttributes() { 37 return this.attrs; 38 } 39 attributeChangedCallback(property, oldValue, newValue) { 40 if (oldValue === newValue) return; 41 this[property] = newValue; 42 43 if (this.shadow == null) { 44 this.dryAttributes.push({ property: property, oldValue: oldValue, newValue: newValue }); 45 } else { 46 this.attributeSet(property, oldValue, newValue); 47 } 48 } 49 50 static define() { 51 if (this.element_name === undefined) { 52 console.warn("No template!"); 53 } 54 customElements.define(this.element_name, this); 55 } 56 57 start(shadow) { 58 // ... 59 } 60 61 attributeSet(property, oldValue, newValue) { 62 // ... 63 } 64} 65 66 67export { DeclarativeElement };