refactor: improve formatting and readability in triggerDomUpdates and processTemplateMacros
All checks were successful
Publish to npm / quality (push) Successful in 20s
Publish to npm / publish (push) Successful in 25s

This commit is contained in:
Astrian Zheng 2025-05-21 14:28:11 +10:00
parent 4aed034100
commit 9ea14fc2b9
Signed by: Astrian
SSH Key Fingerprint: SHA256:rVnhx3DAKjujCwWE13aDl7uV6+9U1MvydLkNRXJrBiA
3 changed files with 58 additions and 61 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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))