refactor: improve formatting and readability in triggerDomUpdates and processTemplateMacros
This commit is contained in:
parent
4aed034100
commit
9ea14fc2b9
23
src/main.ts
23
src/main.ts
|
@ -161,13 +161,16 @@ export default (options: ComponentOptions) => {
|
||||||
setupListRendering: this._setupListRendering.bind(this),
|
setupListRendering: this._setupListRendering.bind(this),
|
||||||
stateToElementsMap: this._stateToElementsMap,
|
stateToElementsMap: this._stateToElementsMap,
|
||||||
textBindings: this._textBindings,
|
textBindings: this._textBindings,
|
||||||
availableFuncs: Object.getOwnPropertyNames(Object.getPrototypeOf(this)).filter(
|
availableFuncs: Object.getOwnPropertyNames(
|
||||||
name => typeof (this as Record<string, unknown>)[name] === 'function' && name !== 'constructor'
|
Object.getPrototypeOf(this),
|
||||||
|
).filter(
|
||||||
|
(name) =>
|
||||||
|
typeof (this as Record<string, unknown>)[name] === 'function' &&
|
||||||
|
name !== 'constructor',
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private _scheduleUpdate(elements: Set<HTMLElement>) {
|
private _scheduleUpdate(elements: Set<HTMLElement>) {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
for (const element of elements) this._updateElement(element)
|
for (const element of elements) this._updateElement(element)
|
||||||
|
@ -325,12 +328,12 @@ export default (options: ComponentOptions) => {
|
||||||
// Determine the key for this item
|
// Determine the key for this item
|
||||||
const key = keyAttr
|
const key = keyAttr
|
||||||
? this._evaluateExpressionWithItemContext(
|
? this._evaluateExpressionWithItemContext(
|
||||||
keyAttr ?? '',
|
keyAttr ?? '',
|
||||||
item,
|
item,
|
||||||
index,
|
index,
|
||||||
itemVar,
|
itemVar,
|
||||||
indexVar ? indexVar : undefined,
|
indexVar ? indexVar : undefined,
|
||||||
)
|
)
|
||||||
: index
|
: index
|
||||||
|
|
||||||
// Check if we can reuse an existing element
|
// Check if we can reuse an existing element
|
||||||
|
@ -415,7 +418,7 @@ export default (options: ComponentOptions) => {
|
||||||
itemContext: Record<string, unknown>,
|
itemContext: Record<string, unknown>,
|
||||||
) {
|
) {
|
||||||
// 1. Store the item context of the element so that subsequent updates can find it
|
// 1. Store the item context of the element so that subsequent updates can find it
|
||||||
; (element as { _itemContext?: Record<string, unknown> })._itemContext =
|
;(element as { _itemContext?: Record<string, unknown> })._itemContext =
|
||||||
itemContext
|
itemContext
|
||||||
|
|
||||||
// 2. Process bindings in text nodes
|
// 2. Process bindings in text nodes
|
||||||
|
|
|
@ -32,7 +32,7 @@ export default function processTemplateMacros(
|
||||||
node: Text
|
node: Text
|
||||||
expr: string
|
expr: string
|
||||||
originalContent: string
|
originalContent: string
|
||||||
}[],
|
}[]
|
||||||
availableFuncs: string[]
|
availableFuncs: string[]
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
|
@ -129,9 +129,9 @@ export default function processTemplateMacros(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process @event bindings, such as @click="handleClick"
|
// Process @event bindings, such as @click="handleClick"
|
||||||
const eventBindings = Array.from(
|
const eventBindings = Array.from(currentElementNode.attributes).filter(
|
||||||
currentElementNode.attributes,
|
(attr) => attr.name.startsWith('@'),
|
||||||
).filter((attr) => attr.name.startsWith('@'))
|
)
|
||||||
// eventBindings.forEach((attr) => {
|
// eventBindings.forEach((attr) => {
|
||||||
for (const attr of eventBindings) {
|
for (const attr of eventBindings) {
|
||||||
const eventName = attr.name.substring(1) // Remove '@'
|
const eventName = attr.name.substring(1) // Remove '@'
|
||||||
|
@ -141,16 +141,15 @@ export default function processTemplateMacros(
|
||||||
currentElementNode.removeAttribute(attr.name)
|
currentElementNode.removeAttribute(attr.name)
|
||||||
|
|
||||||
// Handle different types of event handlers
|
// Handle different types of event handlers
|
||||||
if (handlerValue.includes('=>')) { // Handle arrow function: @click="e => setState('count', count + 1)"
|
if (handlerValue.includes('=>')) {
|
||||||
|
// Handle arrow function: @click="e => setState('count', count + 1)"
|
||||||
options.setupArrowFunctionHandler(
|
options.setupArrowFunctionHandler(
|
||||||
currentElementNode,
|
currentElementNode,
|
||||||
eventName,
|
eventName,
|
||||||
handlerValue,
|
handlerValue,
|
||||||
)
|
)
|
||||||
} else if (
|
} else if (handlerValue.includes('(') && handlerValue.includes(')')) {
|
||||||
handlerValue.includes('(') &&
|
// Handle function call: @click="increment(5)"
|
||||||
handlerValue.includes(')')
|
|
||||||
) { // Handle function call: @click="increment(5)"
|
|
||||||
options.setupFunctionCallHandler(
|
options.setupFunctionCallHandler(
|
||||||
currentElementNode,
|
currentElementNode,
|
||||||
eventName,
|
eventName,
|
||||||
|
@ -159,16 +158,14 @@ export default function processTemplateMacros(
|
||||||
} else if (
|
} else if (
|
||||||
options.availableFuncs.includes(handlerValue) &&
|
options.availableFuncs.includes(handlerValue) &&
|
||||||
typeof (context as unknown as Record<string, unknown>)[
|
typeof (context as unknown as Record<string, unknown>)[
|
||||||
handlerValue
|
handlerValue
|
||||||
] === 'function'
|
] === 'function'
|
||||||
) { // Handle method reference: @click="handleClick"
|
) {
|
||||||
|
// Handle method reference: @click="handleClick"
|
||||||
currentElementNode.addEventListener(
|
currentElementNode.addEventListener(
|
||||||
eventName,
|
eventName,
|
||||||
(
|
(
|
||||||
context as unknown as Record<
|
context as unknown as Record<string, (...args: unknown[]) => void>
|
||||||
string,
|
|
||||||
(...args: unknown[]) => void
|
|
||||||
>
|
|
||||||
)[handlerValue].bind(context),
|
)[handlerValue].bind(context),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -182,9 +179,9 @@ export default function processTemplateMacros(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process %-started macros, such as %connect="stateName", %if="condition", %for="item in items"
|
// Process %-started macros, such as %connect="stateName", %if="condition", %for="item in items"
|
||||||
const macroBindings = Array.from(
|
const macroBindings = Array.from(currentElementNode.attributes).filter(
|
||||||
currentElementNode.attributes,
|
(attr) => attr.name.startsWith('%'),
|
||||||
).filter((attr) => attr.name.startsWith('%'))
|
)
|
||||||
|
|
||||||
// macroBindings.forEach((attr) => {
|
// macroBindings.forEach((attr) => {
|
||||||
for (const attr of macroBindings) {
|
for (const attr of macroBindings) {
|
||||||
|
|
|
@ -1,20 +1,27 @@
|
||||||
export default function triggerDomUpdates(keyPath: string, ops: {
|
export default function triggerDomUpdates(
|
||||||
stateToElementsMap: Record<string, Set<HTMLElement>>,
|
keyPath: string,
|
||||||
scheduleUpdate: (elements: Set<HTMLElement>) => void,
|
ops: {
|
||||||
textBindings: Array<{
|
stateToElementsMap: Record<string, Set<HTMLElement>>
|
||||||
node: Text
|
scheduleUpdate: (elements: Set<HTMLElement>) => void
|
||||||
expr: string
|
textBindings:
|
||||||
originalContent: string
|
| Array<{
|
||||||
}> | undefined,
|
node: Text
|
||||||
attributeBindings: Array<{
|
expr: string
|
||||||
element: Element
|
originalContent: string
|
||||||
attrName: string
|
}>
|
||||||
expr: string
|
| undefined
|
||||||
template: string
|
attributeBindings:
|
||||||
}> | undefined,
|
| Array<{
|
||||||
updateTextNode: (node: Text, expr: string, template: string) => void,
|
element: Element
|
||||||
getNestedState: (path: string) => unknown,
|
attrName: string
|
||||||
}) {
|
expr: string
|
||||||
|
template: string
|
||||||
|
}>
|
||||||
|
| undefined
|
||||||
|
updateTextNode: (node: Text, expr: string, template: string) => void
|
||||||
|
getNestedState: (path: string) => unknown
|
||||||
|
},
|
||||||
|
) {
|
||||||
if (ops.stateToElementsMap[keyPath]) {
|
if (ops.stateToElementsMap[keyPath]) {
|
||||||
const updateQueue = new Set<HTMLElement>()
|
const updateQueue = new Set<HTMLElement>()
|
||||||
|
|
||||||
|
@ -28,24 +35,14 @@ export default function triggerDomUpdates(keyPath: string, ops: {
|
||||||
if (ops.textBindings) {
|
if (ops.textBindings) {
|
||||||
// this._textBindings.forEach((binding) => {
|
// this._textBindings.forEach((binding) => {
|
||||||
for (const binding of ops.textBindings)
|
for (const binding of ops.textBindings)
|
||||||
if (
|
if (binding.expr === keyPath || binding.expr.startsWith(`${keyPath}.`))
|
||||||
binding.expr === keyPath ||
|
ops.updateTextNode(binding.node, binding.expr, binding.originalContent)
|
||||||
binding.expr.startsWith(`${keyPath}.`)
|
|
||||||
)
|
|
||||||
ops.updateTextNode(
|
|
||||||
binding.node,
|
|
||||||
binding.expr,
|
|
||||||
binding.originalContent,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update attribute bindings that depend on this state
|
// Update attribute bindings that depend on this state
|
||||||
if (ops.attributeBindings) {
|
if (ops.attributeBindings) {
|
||||||
for (const binding of ops.attributeBindings)
|
for (const binding of ops.attributeBindings)
|
||||||
if (
|
if (binding.expr === keyPath || binding.expr.startsWith(`${keyPath}.`)) {
|
||||||
binding.expr === keyPath ||
|
|
||||||
binding.expr.startsWith(`${keyPath}.`)
|
|
||||||
) {
|
|
||||||
const value = ops.getNestedState(binding.expr)
|
const value = ops.getNestedState(binding.expr)
|
||||||
if (value !== undefined)
|
if (value !== undefined)
|
||||||
binding.element.setAttribute(binding.attrName, String(value))
|
binding.element.setAttribute(binding.attrName, String(value))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user