mirror of https://github.com/veypi/OneAuth.git
feat: rename to v2dom
parent
62711e1ff2
commit
9f789b78e7
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* build.ts
|
||||
* Copyright (C) 2024 veypi <i@veypi.com>
|
||||
* 2024-10-23 15:54
|
||||
* Distributed under terms of the GPL license.
|
||||
*/
|
||||
|
||||
import proxy from "./proxy"
|
||||
|
||||
|
||||
interface buildOpts {
|
||||
id?: string
|
||||
typ?: string
|
||||
class?: string
|
||||
style?: string
|
||||
innerHtml?: string
|
||||
onclick?: any
|
||||
children?: HTMLElement[]
|
||||
updator?: (p: HTMLElement) => void
|
||||
}
|
||||
|
||||
const typs = ['div', 'img', 'span', 'p', 'a']
|
||||
|
||||
export default (opts: buildOpts | string, inner?: string | HTMLElement[], updator?: (p: HTMLElement) => void) => {
|
||||
if (typeof opts === 'string') {
|
||||
if (typs.indexOf(opts) >= 0) {
|
||||
opts = { typ: opts }
|
||||
} else {
|
||||
opts = { class: opts }
|
||||
}
|
||||
}
|
||||
if (inner) {
|
||||
if (typeof inner == 'string') {
|
||||
opts.innerHtml = inner
|
||||
} else {
|
||||
opts.children = inner
|
||||
}
|
||||
}
|
||||
if (opts.updator) {
|
||||
updator = opts.updator
|
||||
}
|
||||
let dom = document.createElement(opts.typ || 'div')
|
||||
if (opts.id) {
|
||||
dom.id = opts.id
|
||||
}
|
||||
if (opts.class) {
|
||||
dom.classList.add(...opts.class.split(' '))
|
||||
}
|
||||
if (opts.innerHtml) {
|
||||
dom.innerHTML = opts.innerHtml
|
||||
}
|
||||
if (opts.onclick) {
|
||||
dom.onclick = opts.onclick
|
||||
}
|
||||
if (opts.children) {
|
||||
for (let c in opts.children) {
|
||||
dom.appendChild(opts.children[c])
|
||||
}
|
||||
}
|
||||
if (opts.style) {
|
||||
const regex = /([a-zA-Z-]+)\s*:\s*([^;]+);?/g;
|
||||
let match: any
|
||||
while ((match = regex.exec(opts.style)) !== null) {
|
||||
const key = match[1].trim();
|
||||
const value = match[2].trim();
|
||||
dom.style.setProperty(key, value)
|
||||
}
|
||||
}
|
||||
dom.setAttribute('voa', '1')
|
||||
if (updator) {
|
||||
proxy.Listen(() => {
|
||||
updator(dom)
|
||||
})
|
||||
}
|
||||
return dom
|
||||
}
|
||||
|
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* v2dom.ts
|
||||
* Copyright (C) 2024 veypi <i@veypi.com>
|
||||
* 2024-10-23 15:54
|
||||
* Distributed under terms of the GPL license.
|
||||
*/
|
||||
|
||||
import proxy from "./proxy"
|
||||
|
||||
|
||||
interface buildOpts<T> {
|
||||
id?: string
|
||||
typ?: string
|
||||
class?: string
|
||||
style?: string
|
||||
innerHtml?: string
|
||||
onclick?: any
|
||||
children?: childTyp<T>[]
|
||||
updator?: (p: HTMLElement) => void
|
||||
}
|
||||
|
||||
const typs = ['div', 'img', 'span', 'p', 'a']
|
||||
|
||||
type iterChild<T> = [T[], (d: T) => HTMLElement]
|
||||
type childTyp<T> = HTMLElement | iterChild<T>
|
||||
export default <T>(opts: buildOpts<T> | string, inner?: string | childTyp<T>[], updator?: (p: HTMLElement) => void) => {
|
||||
if (typeof opts === 'string') {
|
||||
if (typs.indexOf(opts) >= 0) {
|
||||
opts = { typ: opts }
|
||||
} else {
|
||||
opts = { class: opts }
|
||||
}
|
||||
}
|
||||
if (inner) {
|
||||
if (typeof inner == 'string') {
|
||||
opts.innerHtml = inner
|
||||
} else {
|
||||
opts.children = inner
|
||||
}
|
||||
}
|
||||
if (opts.updator) {
|
||||
updator = opts.updator
|
||||
}
|
||||
let dom = document.createElement(opts.typ || 'div')
|
||||
if (opts.id) {
|
||||
dom.id = opts.id
|
||||
}
|
||||
if (opts.class) {
|
||||
dom.classList.add(...opts.class.split(' '))
|
||||
}
|
||||
if (opts.innerHtml) {
|
||||
dom.innerHTML = opts.innerHtml
|
||||
}
|
||||
if (opts.onclick) {
|
||||
dom.onclick = opts.onclick
|
||||
}
|
||||
if (opts.children) {
|
||||
let tmpID = ''
|
||||
for (let c of opts.children) {
|
||||
if (Object.prototype.toString.call(c) === '[object Array]') {
|
||||
const iterID = proxy.generateUniqueId()
|
||||
const iterLast = tmpID
|
||||
proxy.Listen(() => {
|
||||
c = c as iterChild<T>
|
||||
let itemIDs: string[] = []
|
||||
for (let i = 0; i < c[0].length; i++) {
|
||||
let line = c[0][i]
|
||||
//@ts-ignore
|
||||
let itemID = line[proxy.DataID] || ''
|
||||
let nextID = ''
|
||||
if (i < c[0].length - 1) {
|
||||
//@ts-ignore
|
||||
nextID = c[0][i + 1][proxy.DataID] || ''
|
||||
}
|
||||
itemIDs.push(itemID)
|
||||
let inserted = -2
|
||||
let subdom: HTMLElement | null = null
|
||||
let beforeChild: HTMLElement | null = null
|
||||
for (let childID = 0; childID < dom.children.length; childID++) {
|
||||
let child = dom.children[childID]
|
||||
// console.log(`${inserted} ${childID} ${itemID} ${nextID}`)
|
||||
if (child.getAttribute('vbind-iter') === iterID) {
|
||||
if (child.getAttribute('vbind-proxy') === itemID) {
|
||||
inserted = childID
|
||||
subdom = child as HTMLElement
|
||||
} else if (child.getAttribute('vbind-proxy') === nextID && nextID != '') {
|
||||
// 用于交换位置
|
||||
if (inserted != childID - 1) {
|
||||
beforeChild = child as HTMLElement
|
||||
}
|
||||
}
|
||||
} else if (child.getAttribute('vbind-iterlast') === iterID) {
|
||||
if (inserted == -2) {
|
||||
beforeChild = child as HTMLElement
|
||||
}
|
||||
// 找到第一个不是这个循环块的dom元素时退出
|
||||
break
|
||||
}
|
||||
}
|
||||
if (inserted == -2) {
|
||||
subdom = c[1](line)
|
||||
subdom.setAttribute('vbind-proxy', itemID)
|
||||
subdom.setAttribute('vbind-iter', iterID)
|
||||
if (iterLast != '') {
|
||||
subdom.setAttribute('vbind-iterlast', iterLast)
|
||||
}
|
||||
if (beforeChild) {
|
||||
dom.insertBefore(subdom, beforeChild)
|
||||
// console.log(`${iterID} insert new`, subdom)
|
||||
} else {
|
||||
// console.log(`${iterID} append new`, subdom)
|
||||
dom.appendChild(subdom)
|
||||
}
|
||||
} else if (beforeChild) {
|
||||
// console.log(`${iterID} insert old`, subdom)
|
||||
dom.insertBefore(subdom!, beforeChild)
|
||||
} else {
|
||||
// console.log(`${iterID} none`, subdom)
|
||||
}
|
||||
}
|
||||
for (let child of dom.children) {
|
||||
if (child.getAttribute('vbind-iter') === iterID && itemIDs.indexOf(child.getAttribute('vbind-proxy') || '') == -1) {
|
||||
dom.removeChild(child)
|
||||
}
|
||||
}
|
||||
})
|
||||
tmpID = iterID
|
||||
} else {
|
||||
c = c as HTMLElement
|
||||
if (tmpID != '') {
|
||||
c.setAttribute('vbind-iterlast', tmpID)
|
||||
}
|
||||
dom.appendChild(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (opts.style) {
|
||||
const regex = /([a-zA-Z-]+)\s*:\s*([^;]+);?/g;
|
||||
let match: any
|
||||
while ((match = regex.exec(opts.style)) !== null) {
|
||||
const key = match[1].trim();
|
||||
const value = match[2].trim();
|
||||
dom.style.setProperty(key, value)
|
||||
}
|
||||
}
|
||||
dom.setAttribute('voa', '1')
|
||||
if (updator) {
|
||||
proxy.Listen(() => {
|
||||
updator(dom)
|
||||
})
|
||||
}
|
||||
return dom
|
||||
}
|
||||
|
Loading…
Reference in New Issue