refactor: move arrow function handler logic to a dedicated utility function
This commit is contained in:
parent
8f6b4a6cd9
commit
fe046f4500
67
src/main.ts
67
src/main.ts
|
@ -137,7 +137,6 @@ export default (options: ComponentOptions) => {
|
||||||
utils.processTemplateMacros(rootElement, this, {
|
utils.processTemplateMacros(rootElement, this, {
|
||||||
updateTextNode: this._updateTextNode.bind(this),
|
updateTextNode: this._updateTextNode.bind(this),
|
||||||
setupAttributeBinding: this._setupAttributeBinding.bind(this),
|
setupAttributeBinding: this._setupAttributeBinding.bind(this),
|
||||||
setupArrowFunctionHandler: this._setupArrowFunctionHandler.bind(this),
|
|
||||||
setupExpressionHandler: this._setupExpressionHandler.bind(this),
|
setupExpressionHandler: this._setupExpressionHandler.bind(this),
|
||||||
setupFunctionCallHandler: this._setupFunctionCallHandler.bind(this),
|
setupFunctionCallHandler: this._setupFunctionCallHandler.bind(this),
|
||||||
stateToElementsMap: this._stateToElementsMap,
|
stateToElementsMap: this._stateToElementsMap,
|
||||||
|
@ -156,6 +155,7 @@ export default (options: ComponentOptions) => {
|
||||||
this._extractStatePathsFromExpression.bind(this),
|
this._extractStatePathsFromExpression.bind(this),
|
||||||
states: this._states,
|
states: this._states,
|
||||||
triggerFunc: this.triggerFunc.bind(this),
|
triggerFunc: this.triggerFunc.bind(this),
|
||||||
|
setupArrowFunctionHandler: utils.setupArrowFunctionHandler.bind(this),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,71 +243,6 @@ export default (options: ComponentOptions) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle arrow function
|
|
||||||
private _setupArrowFunctionHandler(
|
|
||||||
element: Element,
|
|
||||||
eventName: string,
|
|
||||||
handlerValue: string,
|
|
||||||
) {
|
|
||||||
element.addEventListener(eventName, (event: Event) => {
|
|
||||||
try {
|
|
||||||
// Arrow function parsing
|
|
||||||
const splitted = handlerValue.split('=>')
|
|
||||||
if (splitted.length !== 2) {
|
|
||||||
throw new Error(`Invalid arrow function syntax: ${handlerValue}`)
|
|
||||||
}
|
|
||||||
const paramsStr = (() => {
|
|
||||||
if (splitted[0].includes('(')) return splitted[0].trim()
|
|
||||||
return `(${splitted[0].trim()})`
|
|
||||||
})()
|
|
||||||
const bodyStr = splitted[1].trim()
|
|
||||||
|
|
||||||
// Check if the function body is wrapped in {}
|
|
||||||
const isMultiline = bodyStr.startsWith('{') && bodyStr.endsWith('}')
|
|
||||||
|
|
||||||
// If it is a multiline function body, remove the outer braces
|
|
||||||
if (isMultiline) {
|
|
||||||
// Remove the outer braces
|
|
||||||
let bodyStr = handlerValue.split('=>')[1].trim()
|
|
||||||
bodyStr = bodyStr.substring(1, bodyStr.length - 1)
|
|
||||||
|
|
||||||
// Build code for multiline arrow function
|
|
||||||
const functionCode = `
|
|
||||||
return function${paramsStr} {
|
|
||||||
${bodyStr}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
// Create context object
|
|
||||||
const context = this._createHandlerContext(event, element)
|
|
||||||
|
|
||||||
// Create and call function
|
|
||||||
const handlerFn = new Function(functionCode).call(null)
|
|
||||||
handlerFn.apply(context, [event])
|
|
||||||
} else {
|
|
||||||
// Single line arrow function, directly return expression result
|
|
||||||
const functionCode = `
|
|
||||||
return function${paramsStr} {
|
|
||||||
return ${bodyStr}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
// Create context object
|
|
||||||
const context = this._createHandlerContext(event, element)
|
|
||||||
|
|
||||||
// Create and call function
|
|
||||||
const handlerFn = new Function(functionCode).call(null)
|
|
||||||
handlerFn.apply(context, [event])
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error(
|
|
||||||
`Error executing arrow function handler: ${handlerValue}`,
|
|
||||||
err,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create handler context
|
// Create handler context
|
||||||
private _createHandlerContext(event: Event, element: Element) {
|
private _createHandlerContext(event: Event, element: Element) {
|
||||||
// Basic context, including state
|
// Basic context, including state
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import parseTemplate from './parseTemplate'
|
import parseTemplate from './parseTemplate'
|
||||||
import processTemplateMacros from './processTemplateMarco'
|
import processTemplateMacros from './processTemplateMarco'
|
||||||
import triggerDomUpdates from './triggerDomUpdates'
|
import triggerDomUpdates from './triggerDomUpdates'
|
||||||
|
import setupArrowFunctionHandler from './setupArrowFunctionHandler'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
parseTemplate,
|
parseTemplate,
|
||||||
processTemplateMacros,
|
processTemplateMacros,
|
||||||
triggerDomUpdates,
|
triggerDomUpdates,
|
||||||
|
setupArrowFunctionHandler,
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,19 @@ export default function processTemplateMacros(
|
||||||
element: Element,
|
element: Element,
|
||||||
eventName: string,
|
eventName: string,
|
||||||
handlerValue: string,
|
handlerValue: string,
|
||||||
|
ops: {
|
||||||
|
createHandlerContext: (
|
||||||
|
event: Event,
|
||||||
|
element: Element,
|
||||||
|
) => {
|
||||||
|
states: Record<string, unknown>
|
||||||
|
stateToElementsMap: Record<string, Set<HTMLElement>>
|
||||||
|
statesListeners: Record<string, (value: unknown) => void>
|
||||||
|
setState: (keyPath: string, value: unknown) => void
|
||||||
|
getState: (keyPath: string) => unknown
|
||||||
|
triggerFunc: (eventName: string, ...args: unknown[]) => void
|
||||||
|
}
|
||||||
|
},
|
||||||
) => void
|
) => void
|
||||||
setupFunctionCallHandler: (
|
setupFunctionCallHandler: (
|
||||||
element: Element,
|
element: Element,
|
||||||
|
@ -153,6 +166,16 @@ export default function processTemplateMacros(
|
||||||
currentElementNode,
|
currentElementNode,
|
||||||
eventName,
|
eventName,
|
||||||
handlerValue,
|
handlerValue,
|
||||||
|
{
|
||||||
|
createHandlerContext: (_event: Event, _element: Element) => ({
|
||||||
|
states: options.states,
|
||||||
|
stateToElementsMap: options.stateToElementsMap,
|
||||||
|
statesListeners: options.stateListeners,
|
||||||
|
setState: context.setState.bind(context),
|
||||||
|
getState: context.getState.bind(context),
|
||||||
|
triggerFunc: options.triggerFunc.bind(context),
|
||||||
|
}),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
} else if (handlerValue.includes('(') && handlerValue.includes(')')) {
|
} else if (handlerValue.includes('(') && handlerValue.includes(')')) {
|
||||||
// Handle function call: @click="increment(5)"
|
// Handle function call: @click="increment(5)"
|
||||||
|
|
76
src/utils/setupArrowFunctionHandler.ts
Normal file
76
src/utils/setupArrowFunctionHandler.ts
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
export default function setupArrowFunctionHandler(
|
||||||
|
element: Element,
|
||||||
|
eventName: string,
|
||||||
|
handlerValue: string,
|
||||||
|
ops: {
|
||||||
|
createHandlerContext: (
|
||||||
|
event: Event,
|
||||||
|
element: Element,
|
||||||
|
) => {
|
||||||
|
states: Record<string, unknown>
|
||||||
|
stateToElementsMap: Record<string, Set<HTMLElement>>
|
||||||
|
statesListeners: Record<string, (value: unknown) => void>
|
||||||
|
setState: (keyPath: string, value: unknown) => void
|
||||||
|
getState: (keyPath: string) => unknown
|
||||||
|
triggerFunc: (eventName: string, ...args: unknown[]) => void
|
||||||
|
}
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
element.addEventListener(eventName, (event: Event) => {
|
||||||
|
try {
|
||||||
|
// Arrow function parsing
|
||||||
|
const splitted = handlerValue.split('=>')
|
||||||
|
if (splitted.length !== 2) {
|
||||||
|
throw new Error(`Invalid arrow function syntax: ${handlerValue}`)
|
||||||
|
}
|
||||||
|
const paramsStr = (() => {
|
||||||
|
if (splitted[0].includes('(')) return splitted[0].trim()
|
||||||
|
return `(${splitted[0].trim()})`
|
||||||
|
})()
|
||||||
|
const bodyStr = splitted[1].trim()
|
||||||
|
|
||||||
|
// Check if the function body is wrapped in {}
|
||||||
|
const isMultiline = bodyStr.startsWith('{') && bodyStr.endsWith('}')
|
||||||
|
|
||||||
|
// If it is a multiline function body, remove the outer braces
|
||||||
|
if (isMultiline) {
|
||||||
|
// Remove the outer braces
|
||||||
|
let bodyStr = handlerValue.split('=>')[1].trim()
|
||||||
|
bodyStr = bodyStr.substring(1, bodyStr.length - 1)
|
||||||
|
|
||||||
|
// Build code for multiline arrow function
|
||||||
|
const functionCode = `
|
||||||
|
return function${paramsStr} {
|
||||||
|
${bodyStr}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// Create context object
|
||||||
|
const context = ops.createHandlerContext(event, element)
|
||||||
|
|
||||||
|
// Create and call function
|
||||||
|
const handlerFn = new Function(functionCode).call(null)
|
||||||
|
handlerFn.apply(context, [event])
|
||||||
|
} else {
|
||||||
|
// Single line arrow function, directly return expression result
|
||||||
|
const functionCode = `
|
||||||
|
return function${paramsStr} {
|
||||||
|
return ${bodyStr}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// Create context object
|
||||||
|
const context = ops.createHandlerContext(event, element)
|
||||||
|
|
||||||
|
// Create and call function
|
||||||
|
const handlerFn = new Function(functionCode).call(null)
|
||||||
|
handlerFn.apply(context, [event])
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(
|
||||||
|
`Error executing arrow function handler: ${handlerValue}`,
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user