aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2023-08-11 20:42:02 +0530
committerAkshay Nair <phenax5@gmail.com>2023-08-11 20:42:02 +0530
commit695365fa359fb98f14d06c205159739077f67fed (patch)
tree6b99fa9a2f18c30ab784f6f9890a409337c9dbf0 /src
parente7d02fc16d4b814c44752a49bca5e7854fed719f (diff)
downloadcss-everything-695365fa359fb98f14d06c205159739077f67fed.tar.gz
css-everything-695365fa359fb98f14d06c205159739077f67fed.zip
feat: complets form submit example
Diffstat (limited to 'src')
-rw-r--r--src/eval.ts27
-rw-r--r--src/index.ts41
2 files changed, 57 insertions, 11 deletions
diff --git a/src/eval.ts b/src/eval.ts
index 466cafd..191a76b 100644
--- a/src/eval.ts
+++ b/src/eval.ts
@@ -9,6 +9,10 @@ export type EvalActions = {
loadCssx(id: string, url: string): Promise<string>
getVariable(name: string): Promise<string | undefined>
updateVariable(id: string, varName: string, value: string): Promise<void>
+ setAttribute(name: string, value: string): Promise<void>
+ withEvent(fn: (e: any) => void): Promise<void>
+ getFormData(): Promise<FormData | undefined>
+ sendRequest(_: { method: string, url: string, data: FormData | undefined }): Promise<void>
// calculate ??
}
@@ -47,6 +51,7 @@ const getFunctions = (name: string, args: Expr[], actions: EvalActions) =>
await actions.removeClass(id, classes)
}
},
+
delay: async () => {
const num = await evalExpr(args[0], actions)
console.log(num)
@@ -56,6 +61,7 @@ const getFunctions = (name: string, args: Expr[], actions: EvalActions) =>
const js = await evalExpr(args[0], actions)
js && (await actions.jsEval(js))
},
+
'load-cssx': async () => {
const id = await evalExpr(args[0], actions)
const url = await evalExpr(args[1], actions)
@@ -63,6 +69,7 @@ const getFunctions = (name: string, args: Expr[], actions: EvalActions) =>
await actions.loadCssx(id, url)
}
},
+
var: async () => {
const varName = await evalExpr(args[0], actions)
const defaultValue = await evalExpr(args[1], actions)
@@ -76,5 +83,25 @@ const getFunctions = (name: string, args: Expr[], actions: EvalActions) =>
actions.updateVariable(id, varName, value)
}
},
+
+ 'set-attr': async () => {
+ const name = await evalExpr(args[0], actions)
+ const value = await evalExpr(args[1], actions)
+ if (name && value) {
+ actions.setAttribute(name, value)
+ }
+ },
+ 'prevent-default': async () => actions.withEvent(e => e.preventDefault()),
+
+ 'request': async () => {
+ const url = await evalExpr(args[0], actions)
+ const method = args[1] ? (await evalExpr(args[1], actions) ?? 'post') : 'post'
+
+ if (url) {
+ const data = await actions.getFormData()
+ await actions.sendRequest({ method, url, data })
+ }
+ },
+
_: () => Promise.reject(new Error('not supposed to be here')),
})
diff --git a/src/index.ts b/src/index.ts
index 7e73cf5..88347df 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -5,6 +5,8 @@ const UNSET_PROPERTY_VALUE = '<unset>'
const EVENT_HANDLERS = {
click: '--cssx-on-click',
load: '--cssx-on-load',
+ mount: '--cssx-on-mount',
+ submit: '--cssx-on-submit',
}
const injectStyles = () => {
@@ -33,7 +35,7 @@ const getChildrenIds = ($element: Element) => {
return value.split(/(\s*,\s*)|\s+/g).filter(Boolean)
}
-const getEvalActions = ($element: Element): EvalActions => ({
+const getEvalActions = ($element: Element, event: any): EvalActions => ({
addClass: async (id, cls) => document.getElementById(id)?.classList.add(cls),
removeClass: async (id, cls) =>
document.getElementById(id)?.classList.remove(cls),
@@ -65,29 +67,44 @@ const getEvalActions = ($element: Element): EvalActions => ({
$el.style.setProperty(varName, JSON.stringify(value))
}
},
+ setAttribute: async (name, value) => {
+ $element.setAttribute(name, value)
+ },
+ withEvent: async (fn) => fn(event),
+ getFormData: async () => $element.nodeName === 'FORM' ? new FormData($element as HTMLFormElement) : undefined,
+ sendRequest: async ({ url, method, data }) => {
+ await fetch(url, { method, body: data })
+ // TODO: Handle response?
+ },
})
-const handleEvents = async ($element: Element) => {
- for (const [event, property] of Object.entries(EVENT_HANDLERS)) {
+const handleEvents = async ($element: Element, isNewElement: boolean = false) => {
+ for (const [eventType, property] of Object.entries(EVENT_HANDLERS)) {
const handlerExpr = getPropertyValue($element, property)
if (handlerExpr) {
- ;($element as any)[`on${event}`] = async () => {
- console.log(`Triggered event: ${event}`)
+ const eventHandler = async (event: any) => {
+ console.log(`Triggered event: ${eventType}`)
const exprs = parse(handlerExpr)
for (const expr of exprs) {
- await evalExpr(expr, getEvalActions($element))
+ await evalExpr(expr, getEvalActions($element, event))
}
}
+
+ if (eventType === 'mount') {
+ if (isNewElement) setTimeout(eventHandler)
+ } else {
+ ;($element as any)[`on${eventType}`] = eventHandler
+ }
}
}
}
let nodeCount = 0
-const manageElement = async ($element: Element) => {
+const manageElement = async ($element: Element, isNewElement: boolean = false) => {
if (nodeCount++ > 100) return // NOTE: Temporary. To prevent infinite rec
- await handleEvents($element)
+ await handleEvents($element, isNewElement)
const childrenIds = getChildrenIds($element)
if (childrenIds.length > 0) {
@@ -98,12 +115,14 @@ const manageElement = async ($element: Element) => {
$element.appendChild($childrenRoot)
for (const childId of childrenIds) {
- const [tag, id] = childId.split('#')
+ let isNewElement = false;
+ const selector = childId.split('#')
+ const [tag, id] = selector.length >= 2 ? selector : ['div', ...selector]
const $child =
$childrenRoot.querySelector(`:scope > #${id}`) ??
- Object.assign(document.createElement(tag || 'div'), { id })
+ (isNewElement = true, Object.assign(document.createElement(tag || 'div'), { id }))
$childrenRoot.appendChild($child)
- await manageElement($child)
+ await manageElement($child, isNewElement)
}
}
}