refactor: split initState function into indipendent file
Some checks failed
Some checks failed
This commit is contained in:
parent
2c04be8607
commit
0a971f16d9
86
src/main.ts
86
src/main.ts
|
@ -47,80 +47,22 @@ export default (options: ComponentOptions) => {
|
|||
this._initialize()
|
||||
}
|
||||
|
||||
private _initState() {
|
||||
// copy state from options
|
||||
this._states = new Proxy(
|
||||
{ ...(states || {}) },
|
||||
{
|
||||
set: (
|
||||
target: Record<string, unknown>,
|
||||
keyPath: string,
|
||||
value: unknown,
|
||||
) => {
|
||||
const valueRoute = keyPath.split('.')
|
||||
let currentTarget = target
|
||||
for (const i in valueRoute) {
|
||||
const key = valueRoute[i]
|
||||
if (Number.parseInt(i) === valueRoute.length - 1) {
|
||||
currentTarget[key] = value
|
||||
} else {
|
||||
if (!currentTarget[key]) currentTarget[key] = {}
|
||||
currentTarget = currentTarget[key] as Record<string, unknown>
|
||||
}
|
||||
}
|
||||
// trigger dom updates
|
||||
utils.triggerDomUpdates(keyPath, {
|
||||
stateToElementsMap: this._stateToElementsMap,
|
||||
textBindings: this._textBindings,
|
||||
attributeBindings: this._attributeBindings,
|
||||
updateTextNode: this._updateTextNode.bind(this),
|
||||
getNestedState: this._getNestedState.bind(this),
|
||||
scheduleUpdate: this._scheduleUpdate.bind(this),
|
||||
})
|
||||
if (this._statesListeners[keyPath])
|
||||
this._statesListeners[keyPath](value)
|
||||
|
||||
// trigger %if macros
|
||||
if (this._conditionalElements.size > 0)
|
||||
this._conditionalElements.forEach((info, element) => {
|
||||
if (info.expr.includes(keyPath))
|
||||
this._evaluateIfCondition(element, info.expr)
|
||||
})
|
||||
|
||||
// trigger state update events
|
||||
statesListeners?.[keyPath]?.(value)
|
||||
|
||||
return true
|
||||
},
|
||||
get: (target: Record<string, unknown>, keyPath: string) => {
|
||||
// collect state dependencies
|
||||
if (this._currentRenderingElement) {
|
||||
if (!this._stateToElementsMap[keyPath])
|
||||
this._stateToElementsMap[keyPath] = new Set()
|
||||
this._stateToElementsMap[keyPath].add(
|
||||
this._currentRenderingElement,
|
||||
)
|
||||
}
|
||||
|
||||
const valueRoute = keyPath.split('.')
|
||||
let currentTarget = target
|
||||
for (const i in valueRoute) {
|
||||
const key = valueRoute[i]
|
||||
if (Number.parseInt(i) === valueRoute.length - 1)
|
||||
return currentTarget[key]
|
||||
|
||||
if (!currentTarget[key]) currentTarget[key] = {}
|
||||
currentTarget = currentTarget[key] as Record<string, unknown>
|
||||
}
|
||||
return undefined
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private _initialize() {
|
||||
// initialize state
|
||||
this._initState()
|
||||
this._states = utils.initState(
|
||||
{
|
||||
stateToElementsMap: this._stateToElementsMap,
|
||||
textBindings: this._textBindings,
|
||||
attributeBindings: this._attributeBindings,
|
||||
updateTextNode: (node: Text, value: string) => this._updateTextNode(node, value, value),
|
||||
getNestedState: (keyPath: string) => this._getNestedState(keyPath),
|
||||
scheduleUpdate: this._scheduleUpdate.bind(this),
|
||||
statesListeners: this._statesListeners,
|
||||
conditionalElements: this._conditionalElements,
|
||||
evaluateIfCondition: this._evaluateIfCondition.bind(this),
|
||||
},
|
||||
options.states,
|
||||
)
|
||||
|
||||
// initialize shadow dom
|
||||
const shadow = this.attachShadow({ mode: 'open' })
|
||||
|
|
|
@ -2,10 +2,12 @@ import parseTemplate from './parseTemplate'
|
|||
import processTemplateMacros from './processTemplateMarcos'
|
||||
import setupArrowFunctionHandler from './setupArrowFunctionHandler'
|
||||
import triggerDomUpdates from './triggerDomUpdates'
|
||||
import initState from './initState'
|
||||
|
||||
export default {
|
||||
parseTemplate,
|
||||
processTemplateMacros,
|
||||
setupArrowFunctionHandler,
|
||||
triggerDomUpdates,
|
||||
initState,
|
||||
}
|
||||
|
|
103
src/utils/initState.ts
Normal file
103
src/utils/initState.ts
Normal file
|
@ -0,0 +1,103 @@
|
|||
import triggerDomUpdates from "./triggerDomUpdates"
|
||||
|
||||
export default function initState(
|
||||
ops: {
|
||||
stateToElementsMap: Record<string, Set<HTMLElement>>
|
||||
textBindings: Array<{
|
||||
node: Text
|
||||
expr: string
|
||||
originalContent: string
|
||||
}>
|
||||
attributeBindings: Array<{
|
||||
element: Element
|
||||
attrName: string
|
||||
expr: string
|
||||
template: string
|
||||
}>
|
||||
updateTextNode: (node: Text, value: string) => void
|
||||
getNestedState: (keyPath: string) => unknown
|
||||
scheduleUpdate: (elements: Set<HTMLElement>) => void
|
||||
statesListeners: Record<string, (value: unknown) => void>
|
||||
conditionalElements: Map<
|
||||
Element,
|
||||
{
|
||||
expr: string
|
||||
placeholder: Comment
|
||||
isPresent: boolean
|
||||
}
|
||||
>
|
||||
evaluateIfCondition: (element: Element, expr: string) => void
|
||||
currentRenderingElement?: HTMLElement
|
||||
},
|
||||
states?: Record<string, unknown>,
|
||||
) {
|
||||
console.log(states)
|
||||
// copy state from options
|
||||
return new Proxy(
|
||||
{ ...(states || {}) },
|
||||
{
|
||||
set: (
|
||||
target: Record<string, unknown>,
|
||||
keyPath: string,
|
||||
value: unknown,
|
||||
) => {
|
||||
const valueRoute = keyPath.split('.')
|
||||
let currentTarget = target
|
||||
for (const i in valueRoute) {
|
||||
const key = valueRoute[i]
|
||||
if (Number.parseInt(i) === valueRoute.length - 1) {
|
||||
currentTarget[key] = value
|
||||
} else {
|
||||
if (!currentTarget[key]) currentTarget[key] = {}
|
||||
currentTarget = currentTarget[key] as Record<string, unknown>
|
||||
}
|
||||
}
|
||||
// trigger dom updates
|
||||
triggerDomUpdates(keyPath, {
|
||||
stateToElementsMap: ops.stateToElementsMap,
|
||||
textBindings: ops.textBindings,
|
||||
attributeBindings: ops.attributeBindings,
|
||||
updateTextNode: ops.updateTextNode,
|
||||
getNestedState: ops.getNestedState,
|
||||
scheduleUpdate: ops.scheduleUpdate,
|
||||
})
|
||||
if (ops.statesListeners[keyPath])
|
||||
ops.statesListeners[keyPath](value)
|
||||
|
||||
// trigger %if macros
|
||||
if (ops.conditionalElements.size > 0)
|
||||
ops.conditionalElements.forEach((info, element) => {
|
||||
if (info.expr.includes(keyPath))
|
||||
ops.evaluateIfCondition(element, info.expr)
|
||||
})
|
||||
|
||||
// trigger state update events
|
||||
ops.statesListeners?.[keyPath]?.(value)
|
||||
|
||||
return true
|
||||
},
|
||||
get: (target: Record<string, unknown>, keyPath: string) => {
|
||||
// collect state dependencies
|
||||
if (ops.currentRenderingElement) {
|
||||
if (!ops.stateToElementsMap[keyPath])
|
||||
ops.stateToElementsMap[keyPath] = new Set()
|
||||
ops.stateToElementsMap[keyPath].add(
|
||||
ops.currentRenderingElement,
|
||||
)
|
||||
}
|
||||
|
||||
const valueRoute = keyPath.split('.')
|
||||
let currentTarget = target
|
||||
for (const i in valueRoute) {
|
||||
const key = valueRoute[i]
|
||||
if (Number.parseInt(i) === valueRoute.length - 1)
|
||||
return currentTarget[key]
|
||||
|
||||
if (!currentTarget[key]) currentTarget[key] = {}
|
||||
currentTarget = currentTarget[key] as Record<string, unknown>
|
||||
}
|
||||
return undefined
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue
Block a user