Spec
Spec.js
import * as descriptor from './descriptor'
import * as exporter from './exporter'
import {immutable, lift, chainLift} from '../helper/index'
export default (state = {}) => {
const immutableState = immutable(state)
return {
...chainLift(immutableState, descriptor),
...lift(immutableState, exporter)
}
}
lift
- 모든 오퍼레이터에 Wrapper를 씌운다.
- Wrapper를 통해 호출되면 사용자가 전달한 인자앞에
Immutable State
를 공유한다.
helper/index.js
export const chainLift = (state, operators) => {
const newOperators = {}
for (const [name, cb] of Object.entries(operators)) {
newOperators[name] = (...args) => Spec(cb(state, ...args))
}
return newOperators
}
export const lift = (state, operators) => {
const newOperators = {}
for (const [name, cb] of Object.entries(operators)) {
newOperators[name] = (...args) => cb(state, ...args)
}
return newOperators
}
Descriptor
- Hypertext의 속성을 정의할 수 있는 오퍼레이터를 제공한다.
- Descriptor의 각 오퍼레이터는 Spec의 펙토리 메서드이며, 항상 새로운 Spec을 반환한다.
operator(state: ImmutableState, [...arguments]) : ImmutableState
형태로 추가한다.
- 사용자에게는
operator(...arguments) : Spec
형태로 사용된다.
Descriptor.js
export { on } from './on'
export { className } from './className'
export { children } from './children'
export { spec } from './spec'
on.js
import {merge} from '../../helper/index'
export const on = (state, eventName, listener) => {
return merge(state, {[eventName]: listener})
}
Exporter
- Hypertext를 데이터 타입으로 변환해주는 오퍼레이터를 제공한다.
operator(state: ImmutableState, [...arguments]) : DataType
형태로 추가한다.
- 사용자에게는
operator(...arguments) : DataType
형태로 사용된다.
- 예)
toString() : String
, toJSON() : Object
, toDOM() : HTMLElement
Exporter.js
export { toJSON } from './toJSON'
export { toDOM } from './toDOM'
export { toString } from './toString'
toJSON.js
export const toJSON = state => JSON.parse(JSON.stringify(state))
Hypertext
- HTMLElement 객체 생성 오퍼레이터를 제공한다.
- Hypertext의 각 오퍼레이터는
Spec
의 펙토리 메서드이며, 항상 새로운 Spec
을 반환한다.
div() : Spec
Hypertext.js
export { div } from './div'
export { p } from './p'
export { text } from './text'
div.js
import Spec from '../Spec/index'
export const div = () => Spec({nodeName: 'div'})
사용예제
import Spec from './Spec'
import { div, p, text } from './Hypertext'
const spec = Spec()
.on('click', () => {})
.className('table table-border')
const child = [
div(),
p(),
text('Hello world')
]
const tag = div().spec(spec).children(...child)
const data = tag.toJSON()
spec
{
spec: {
className: 'table table-border',
click () {}
}
}
children
{
children: [
{nodeName: 'div'},
{nodeName: 'p'},
{nodeName: 'text', value: 'Hello World'}
]
}
data
{
nodeName: 'div',
children: [
{nodeName: 'div'},
{nodeName: 'p'},
{nodeName: 'text', value: 'Hello World'}
],
spec: {
className: 'table table-border'
}
}