|
|
@ -12,18 +12,22 @@ interface buildOpts<T> {
|
|
|
|
id?: string
|
|
|
|
id?: string
|
|
|
|
typ?: string
|
|
|
|
typ?: string
|
|
|
|
class?: string
|
|
|
|
class?: string
|
|
|
|
|
|
|
|
attrs?: attrs
|
|
|
|
style?: string
|
|
|
|
style?: string
|
|
|
|
innerHtml?: string
|
|
|
|
innerHtml?: string
|
|
|
|
onclick?: any
|
|
|
|
onclick?: any
|
|
|
|
children?: childTyp<T>[]
|
|
|
|
children?: childTyp<T>[]
|
|
|
|
updator?: (p: HTMLElement) => void
|
|
|
|
updator?: (p: HTMLElement) => void
|
|
|
|
|
|
|
|
vbind?: [Object, string]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const typs = ['div', 'img', 'span', 'p', 'a']
|
|
|
|
const typs = ['div', 'img', 'span', 'p', 'a', 'input']
|
|
|
|
|
|
|
|
|
|
|
|
type iterChild<T> = [T[], (d: T) => HTMLElement]
|
|
|
|
type iterChild<T> = [T[], (d: T) => HTMLElement]
|
|
|
|
type childTyp<T> = HTMLElement | iterChild<T>
|
|
|
|
type childTyp<T> = HTMLElement | iterChild<T>
|
|
|
|
export default <T>(opts: buildOpts<T> | string, inner?: string | childTyp<T>[], updator?: (p: HTMLElement) => void) => {
|
|
|
|
type computedFn = () => any
|
|
|
|
|
|
|
|
type attrs = { [key: string]: string | number | computedFn }
|
|
|
|
|
|
|
|
export default <T>(opts: buildOpts<T> | string, inner?: string | computedFn | childTyp<T>[], attrs?: attrs) => {
|
|
|
|
if (typeof opts === 'string') {
|
|
|
|
if (typeof opts === 'string') {
|
|
|
|
if (typs.indexOf(opts) >= 0) {
|
|
|
|
if (typs.indexOf(opts) >= 0) {
|
|
|
|
opts = { typ: opts }
|
|
|
|
opts = { typ: opts }
|
|
|
@ -31,17 +35,27 @@ export default <T>(opts: buildOpts<T> | string, inner?: string | childTyp<T>[],
|
|
|
|
opts = { class: opts }
|
|
|
|
opts = { class: opts }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let dom = document.createElement(opts.typ || 'div')
|
|
|
|
if (inner) {
|
|
|
|
if (inner) {
|
|
|
|
if (typeof inner == 'string') {
|
|
|
|
if (typeof inner == 'string') {
|
|
|
|
opts.innerHtml = inner
|
|
|
|
opts.innerHtml = inner
|
|
|
|
|
|
|
|
} else if (typeof inner == 'function') {
|
|
|
|
|
|
|
|
addListener(dom, () => {
|
|
|
|
|
|
|
|
let res = inner()
|
|
|
|
|
|
|
|
if (typeof res === 'string') {
|
|
|
|
|
|
|
|
dom.innerHTML = res
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
dom.innerHTML = ''
|
|
|
|
|
|
|
|
dom.appendChild(inner())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
opts.children = inner
|
|
|
|
opts.children = inner
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (opts.updator) {
|
|
|
|
if (attrs) {
|
|
|
|
updator = opts.updator
|
|
|
|
opts.attrs = attrs
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let dom = document.createElement(opts.typ || 'div')
|
|
|
|
|
|
|
|
if (opts.id) {
|
|
|
|
if (opts.id) {
|
|
|
|
dom.id = opts.id
|
|
|
|
dom.id = opts.id
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -51,6 +65,18 @@ export default <T>(opts: buildOpts<T> | string, inner?: string | childTyp<T>[],
|
|
|
|
if (opts.innerHtml) {
|
|
|
|
if (opts.innerHtml) {
|
|
|
|
dom.innerHTML = opts.innerHtml
|
|
|
|
dom.innerHTML = opts.innerHtml
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (opts.attrs) {
|
|
|
|
|
|
|
|
for (let a in opts.attrs) {
|
|
|
|
|
|
|
|
let attr = opts.attrs[a]
|
|
|
|
|
|
|
|
if (typeof attr === 'function') {
|
|
|
|
|
|
|
|
addListener(dom, () => {
|
|
|
|
|
|
|
|
dom.setAttribute(a, attr())
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
dom.setAttribute(a, String(attr))
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
if (opts.onclick) {
|
|
|
|
if (opts.onclick) {
|
|
|
|
dom.onclick = opts.onclick
|
|
|
|
dom.onclick = opts.onclick
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -60,7 +86,7 @@ export default <T>(opts: buildOpts<T> | string, inner?: string | childTyp<T>[],
|
|
|
|
if (Object.prototype.toString.call(c) === '[object Array]') {
|
|
|
|
if (Object.prototype.toString.call(c) === '[object Array]') {
|
|
|
|
const iterID = proxy.generateUniqueId()
|
|
|
|
const iterID = proxy.generateUniqueId()
|
|
|
|
const iterLast = tmpID
|
|
|
|
const iterLast = tmpID
|
|
|
|
proxy.Listen(() => {
|
|
|
|
addListener(dom, () => {
|
|
|
|
c = c as iterChild<T>
|
|
|
|
c = c as iterChild<T>
|
|
|
|
let itemIDs: string[] = []
|
|
|
|
let itemIDs: string[] = []
|
|
|
|
for (let i = 0; i < c[0].length; i++) {
|
|
|
|
for (let i = 0; i < c[0].length; i++) {
|
|
|
@ -144,11 +170,29 @@ export default <T>(opts: buildOpts<T> | string, inner?: string | childTyp<T>[],
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dom.setAttribute('voa', '1')
|
|
|
|
dom.setAttribute('voa', '1')
|
|
|
|
if (updator) {
|
|
|
|
if (opts.updator) {
|
|
|
|
proxy.Listen(() => {
|
|
|
|
addListener(dom, () => {
|
|
|
|
updator(dom)
|
|
|
|
opts.updator!(dom)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (opts.vbind && opts.typ === 'input') {
|
|
|
|
|
|
|
|
dom.setAttribute('value', Reflect.get(opts.vbind[0], opts.vbind[1]))
|
|
|
|
|
|
|
|
dom.addEventListener('input', (e) => {
|
|
|
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
|
|
|
Reflect.set(opts.vbind[0], opts.vbind[1], e.target.value)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return dom
|
|
|
|
return dom
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function addListener(dom: HTMLElement, fn: () => void) {
|
|
|
|
|
|
|
|
let fns = dom.getAttribute('vbind-fns')
|
|
|
|
|
|
|
|
let fnid = proxy.Listen(fn)
|
|
|
|
|
|
|
|
if (fns) {
|
|
|
|
|
|
|
|
fns += ',' + fnid
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
fns = String(fnid)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
dom.setAttribute('vbind-fns', fns)
|
|
|
|
|
|
|
|
}
|
|
|
|