1/** 2 * @example Add mixin to a class 3 * 4 * Object.assign(ComponentClass, CustomElementStaticMixin) 5 * 6 * @see https://javascript.info/mixins 7 */ 8const CustomElementStaticMixin = { 9 /** 10 * Create custom element with provided attributes 11 * 12 * Example: 13 * 14 * MyComponent.create({message: "hello, world"}) 15 * => <my-component message="hello, world" /> 16 * 17 * @return {object} 18 */ 19 create(attrs = {}) { 20 const elem = document.createElement(this.TAG) 21 22 for (let attrName in attrs) { 23 elem.setAttribute(attrName, attrs[attrName]) 24 } 25 26 return elem 27 }, 28} 29 30/** 31 * @example Add mixin to a class 32 * 33 * Object.assign(ComponentClass.prototype, CustomElementMixin) 34 */ 35const CustomElementMixin = { 36 connectedCallback() { 37 this.events = this.events || [] 38 39 if (this.attach) this.attach() 40 if (this.setup) this.setup() 41 }, 42 43 disconnectedCallback() { 44 if (this.events?.length > 0) { 45 for (let evt of this.events) { 46 evt.target.removeEventListener(evt.name, evt.handler) 47 } 48 } 49 //Array.from(this.children).forEach(el => this.removeChild(el)) 50 }, 51 52 attach() { 53 if (this.template) { 54 // TODO: think of a better check for this check, maybe adding a custom object-DOM ID 55 if (this.children.length < this.template.content.children.length) { 56 this.appendChild(this.template.content.cloneNode(true)) 57 } 58 this.classList.add(this.constructor.TAG) 59 } else { 60 console.error(`Could not attach ${this.constructor.name}: template with id '${this.constructor.TEMPLATE_ID}' not found or null`) 61 } 62 }, 63 64 /** 65 * Add event listener to HTML element, intended to be a child of CustomElement 66 * 67 * @param {HTMLElement} target 68 * @param {string} eventName E.g., 'click' 69 * @param {Function} handler Event callback 70 */ 71 on(target, eventName, handler) { 72 target.addEventListener(eventName, handler) 73 74 this.events.push({ 75 target: target, 76 name: eventName, 77 handler: handler, 78 }) 79 }, 80 81 remove() { 82 this.parentElement.removeChild(this) 83 }, 84} 85 86/** 87 * @example Add getters and setters to class prototype 88 * 89 * for (let k in CustomElementGetSetMixin) { 90 * Object.defineProperty(ComponentClass.prototype, k, CustomElementGetSetMixin[k]) 91 * } 92 */ 93const CustomElementGetSetMixin = { 94 template: { 95 get: function() { 96 return document.getElementById(this.constructor.TEMPLATE_ID) 97 }, 98 enumerable: true, 99 configurable: true, 100 }, 101}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.