@winged/core
Version:
Morden webapp framekwork made only for ts developers. (UNDER DEVELOPMENT, PLEASE DO NOT USE)
99 lines (89 loc) • 2.91 kB
text/typescript
import { StateDependencies, ViewState } from '../types'
import { DataPoint } from './dataPoint/DataPoint'
import { Renderable } from './Renderable'
import { PrevSibling } from './vdom'
import { vdomUtils } from './vdomUtils'
export enum VTextType { text, data }
export class VText extends Renderable {
public type: VTextType
public dataPoint?: DataPoint
public content?: string
public textNode?: Text
public stateDependencies: StateDependencies
private lastValue?: string
constructor(content: string | DataPoint) {
super()
if (typeof content === 'string') {
this.type = VTextType.text
this.content = content
} else {
this.type = VTextType.data
this.dataPoint = content
}
this.stateDependencies = this.initStateDependencies()
}
public render(state: ViewState, modifiedState: ViewState, container: HTMLElement, prevSibling: PrevSibling) {
if (!this.textNode) {
this.createDomNode(state, modifiedState, container, prevSibling)
} else {
if (this.type === VTextType.data) {
if (vdomUtils.checkStateDependencies(modifiedState, this.stateDependencies)) {
const value = (this.dataPoint as DataPoint).getStringValue(state, modifiedState)
if (value !== this.lastValue) {
this.textNode.nodeValue = value
this.lastValue = value
}
}
}
}
prevSibling.node = this.textNode
}
public skipRender(prevSibling: PrevSibling) {
if (!this.textNode) {
return
}
super.skipRender(prevSibling)
prevSibling.node = this.textNode
}
public destroyDomElement() {
if (!this.textNode) {
return
}
if (this.textNode.parentElement) {
this.textNode.parentElement.removeChild(this.textNode)
}
this.textNode = undefined
}
public destroy() {
if (this.dataPoint) {
this.dataPoint.destory()
delete this.dataPoint
}
if (this.textNode && this.textNode.parentElement) {
this.textNode.parentElement.removeChild(this.textNode)
}
delete this.textNode
delete this.content
super.destroy()
}
public forEachChildren(fn: Renderable.ChildrenIter) {
// do nothing
}
protected initStateDependencies(): StateDependencies {
if (this.type === VTextType.text) {
return {}
} else {
return (this.dataPoint as DataPoint).stateDependencies
}
}
private createDomNode(state: ViewState, modifiedState: ViewState, container: HTMLElement, prevSibling: PrevSibling) {
const value = this.type === VTextType.text ?
this.content as string : (this.dataPoint as DataPoint).getStringValue(state, modifiedState)
this.textNode = document.createTextNode(value)
if (prevSibling.node) {
container.insertBefore(this.textNode, prevSibling.node.nextSibling)
} else {
container.insertBefore(this.textNode, container.firstChild)
}
}
}