diff --git a/src/core.js b/src/core.js index 860e52a..fbb26a2 100644 --- a/src/core.js +++ b/src/core.js @@ -3,9 +3,23 @@ * @author yutent * @date 2023/03/03 11:21:44 */ +const finalize = Symbol('finalize') +const RESET_CSS_STYLE = css` + * { + box-sizing: border-box; + margin: 0; + padding: 0; + } + ::before, + ::after { + box-sizing: border-box; + } +` export function css(strs, ...args) { - let output = '' + let output = ` + + ` let tmp = Array.from(strs) while (tmp.length) { output += tmp.shift() + (args.shift() || '') @@ -50,14 +64,61 @@ function getTemplate(html) { return template.content.cloneNode(true) } -export class Compoent extends HTMLElement { +function adoptStyles(root, styles = '') { + let sheet = new CSSStyleSheet() + if (typeof styles === 'string') { + styles = [styles] + } else { + styles = styles.flat(Infinity) + } + styles = (RESET_CSS_STYLE + styles.join(' ')).trim() + sheet.replaceSync(styles) + root.adoptedStyleSheets.push(sheet) +} + +function render(root, html) { + root.appendChild(getTemplate(html)) +} + +export class Component extends HTMLElement { static get observedAttributes() { - console.log(this.properties) - return [] + this[finalize]() + + let list = [] + this.elemProps.forEach((it, prop) => { + list.push(prop) + }) + return list } constructor() { super() + this.created && this.created() + } + + static [finalize]() { + if (this.finalized) { + return + } + + this.finalized = true + + this.elemProps = new Map() + + for (let k in this.props) { + let prop = Symbol(k) + let options = this.props[k] + this.elemProps.set(k, prop) + Object.defineProperty(this.prototype, k, { + get() { + return this[prop] || options.default + }, + set(val) { + this[prop] = val + }, + enumerable: false + }) + } } render() { @@ -66,10 +127,28 @@ export class Compoent extends HTMLElement { connectedCallback() { Object.defineProperty(this, 'root', { - value: this.attachShadow({ mode: 'open' }), + value: this.shadowRoot || this.attachShadow({ mode: 'open' }), enumerable: false }) - this.root.appendChild(getTemplate(this.render())) + adoptStyles(this.root, this.constructor.styles) + + render(this.root, this.render()) + + this.mounted && this.mounted() + } + + disconnectedCallback() { + console.log('>>>>') + } + + attributeChangedCallback(name, old, val) { + if (old === val) { + return + } + } + + adoptedCallback() { + // } }