1 | import { html, render as litRender } from '../lit-html/lit-html.js'
|
2 |
|
3 | export const LitElement = (superclass) => class extends superclass {
|
4 |
|
5 | static get observedAttributes() {
|
6 | let attrs = [];
|
7 | for(const prop in this.properties)
|
8 | if(this.properties[prop].reflectToAttribute)
|
9 | attrs.push(prop)
|
10 | return attrs;
|
11 | }
|
12 |
|
13 | constructor() {
|
14 | super();
|
15 | this.__data = {};
|
16 | this.attachShadow({mode: "open"});
|
17 | }
|
18 |
|
19 | connectedCallback() {
|
20 | const props = this.constructor.properties;
|
21 | this._wait = true;
|
22 | for(let prop in props) {
|
23 | if(typeof props[prop] === 'object') {
|
24 | this._makeComplexGetterSetter(prop, props[prop])
|
25 | } else {
|
26 | this._makeGetterSetter(prop, props[prop])
|
27 | }
|
28 | }
|
29 | delete this._wait;
|
30 | litRender(this.render(), this.shadowRoot);
|
31 | if(this.afterFirstRender)
|
32 | this.afterFirstRender();
|
33 | }
|
34 |
|
35 | _makeGetterSetter(prop, val) {
|
36 | Object.defineProperty(this, prop, {
|
37 | get() {
|
38 | return this.__data[prop]
|
39 | },
|
40 | set(val) {
|
41 | this.__data[prop] = val;
|
42 | this._propertiesChanged()
|
43 | }
|
44 | })
|
45 | this[prop] = this.getAttribute(prop);
|
46 | }
|
47 |
|
48 | _makeComplexGetterSetter(prop, info) {
|
49 | Object.defineProperty(this, prop, {
|
50 | get() {
|
51 | if(info.reflectToAttribute) {
|
52 | if(info.type === Object || info.type === Array)
|
53 | console.warn('Rich Data shouldn\'t be set as attribte!')
|
54 | }
|
55 | return this.__data[prop];
|
56 | },
|
57 |
|
58 | set(val) {
|
59 | if(info.reflectToAttribute) {
|
60 | if(info.type === Object || info.type === Array)
|
61 | console.warn('Rich Data shouldn\'t be set as attribte!')
|
62 | this.setAttribute(prop, val);
|
63 | } else this.__data[prop] = val;
|
64 | this._propertiesChanged();
|
65 | }
|
66 | });
|
67 | if(info.value) {
|
68 | typeof info.value === 'function'
|
69 | ? this[prop] = info.value()
|
70 | : this[prop] = info.value;
|
71 | }
|
72 | }
|
73 |
|
74 | _propertiesChanged() {
|
75 | if(!this._wait)
|
76 | litRender(this.render(), this.shadowRoot)
|
77 | }
|
78 |
|
79 | attributeChangedCallback(prop, old, val) {
|
80 | if(this[prop] !== val) {
|
81 | const {type} = this.constructor.properties[prop];
|
82 | if(type.name === 'Boolean') {
|
83 | if(val !== 'false') {
|
84 | this.__data[prop] = this.hasAttribute(prop);
|
85 | } else {
|
86 | this.__data[prop] = false
|
87 | }
|
88 | } else this.__data[prop] = type(val);
|
89 | this._propertiesChanged();
|
90 | }
|
91 | }
|
92 |
|
93 | render() {
|
94 | return html`Render Function not defined`
|
95 | }
|
96 |
|
97 | get $() {
|
98 | const arr = this.shadowRoot.querySelectorAll('[id]');
|
99 | const obj = {};
|
100 | for(const el of arr)
|
101 | obj[el.id] = el;
|
102 |
|
103 | return obj;
|
104 | }
|
105 | } |
\ | No newline at end of file |