diff options
| author | Akshay Nair <phenax5@gmail.com> | 2023-08-10 23:26:49 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2023-08-10 23:26:49 +0530 |
| commit | 629993f2d7de1270d3aaa4ab2a6f9571cdffd621 (patch) | |
| tree | 9b3c352f95e719ed5193293c1aaa4deb1e198e38 | |
| parent | e01cb693bc5737792e2b37abfd98d2d8f81bac4d (diff) | |
| download | css-everything-629993f2d7de1270d3aaa4ab2a6f9571cdffd621.tar.gz css-everything-629993f2d7de1270d3aaa4ab2a6f9571cdffd621.zip | |
feat: integrates parser and evaluator and creates a complete working example
| -rw-r--r-- | examples/api/style.css | 24 | ||||
| -rw-r--r-- | src/eval.ts | 10 | ||||
| -rw-r--r-- | src/index.ts | 39 |
3 files changed, 56 insertions, 17 deletions
diff --git a/examples/api/style.css b/examples/api/style.css index d1be912..213d9e2 100644 --- a/examples/api/style.css +++ b/examples/api/style.css @@ -3,20 +3,34 @@ body { } #load-btn { + display: inline-block; + border: 1px solid gray; + padding: 0.5rem 1rem; + cursor: pointer; + --cssx-on-click: + add-class(output-container, 'loading') add-class(load-btn, 'loading') - get('./more-style.css') - add-class(load-btn, 'hidden'); + delay('2000') + remove-class(output-container, 'loading') + add-class(output-container, 'loaded') + remove-class(load-btn, 'loading') + js-eval('alert("Loaded page")') + ; } +#load-btn::after { content: "Click me for magic"; } #load-btn.loading { pointer-events: none; opacity: 0.4; } -#load-btn.hidden { - display: none; -} #output-container { --cssx-children: output-container-content; } +#output-container.loading::after { + content: "Loading..."; +} +#output-container.loaded::after { + content: "This content is loaded my guy"; +} diff --git a/src/eval.ts b/src/eval.ts index 1e18457..0ab52c8 100644 --- a/src/eval.ts +++ b/src/eval.ts @@ -4,6 +4,8 @@ import { match, matchString } from "./utils/adt"; export type Dependencies = { addClass(id: string, classes: string): Promise<void> removeClass(id: string, classes: string): Promise<void> + delay(num: number): Promise<void> + jsEval(js: string): Promise<any> // requestGetCss(url: string): Promise<string> // getVarable(name: string, def?: string): Promise<string> // updateVariable(id: string, varName: string, value: string): Promise<void> @@ -28,6 +30,14 @@ export const evalExpr = async (expr: Expr, deps: Dependencies): Promise<string | await deps.removeClass(id, classes) } }, + 'delay': async () => { + const num = await evalExpr(args[0], deps) + num && await deps.delay(parseInt(num, 10)) + }, + 'js-eval': async () => { + const js = await evalExpr(args[0], deps) + js && await deps.jsEval(js) + }, _: () => Promise.reject(new Error('not supposed to be here')), }) return undefined diff --git a/src/index.ts b/src/index.ts index 02da27a..f09d940 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,6 @@ +import { Dependencies, evalExpr } from "./eval"; +import { parse } from "./parser"; + const UNSET_PROPERTY_VALUE = '<unset>'; const EVENT_HANDLERS = { click: '--cssx-on-click', @@ -30,25 +33,37 @@ const getPropertyValue = ($element: HTMLElement, prop: string) => { const getChildrenIds = ($element: HTMLElement) => { const value = getPropertyValue($element, '--cssx-children') - return value.split(/(\s*,\s*)|\s*/g).filter(Boolean) + return value.split(/(\s*,\s*)|\s+/g).filter(Boolean) } -const handleEvents = ($element: HTMLElement) => { - Object.entries(EVENT_HANDLERS).forEach(([event, property]) => { +const evalDeps = (_el: HTMLElement): Dependencies => ({ + addClass: async (id, cls) => document.getElementById(id)?.classList.add(cls), + removeClass: async (id, cls) => document.getElementById(id)?.classList.remove(cls), + delay: delay => new Promise((res) => setTimeout(res, delay)), + jsEval: async js => (0, eval)(js), +}) + +const handleEvents = async ($element: HTMLElement) => { + for (const [event, property] of Object.entries(EVENT_HANDLERS)) { const handlerExpr = getPropertyValue($element, property); + if (handlerExpr) { - // TODO: Parse onclick - // TODO: attach handler for eval - console.log(event, handlerExpr); + ($element as any)[`on${event}`] = async () => { + console.log(`Triggered event: ${event}`) + const exprs = parse(handlerExpr) + for (const expr of exprs) { + await evalExpr(expr, evalDeps($element)) + } + }; } - }); + } }; let iters = 0; -const manageElement = ($element: HTMLElement) => { +const manageElement = async ($element: HTMLElement) => { if (iters++ > 100) return; // NOTE: Temporary. To prevent infinite rec - handleEvents($element); + await handleEvents($element); const $childrenRoot = Object.assign(document.createElement('div'), { className: 'cssx-layer', @@ -59,16 +74,16 @@ const manageElement = ($element: HTMLElement) => { for (const id of childrenIds) { const $child = Object.assign(document.createElement('div'), { id }); $childrenRoot.appendChild($child); - manageElement($child); + await manageElement($child); } } interface Options { root?: HTMLElement; } -const render = ({ root = document.body }: Options = {}) => { +const render = async ({ root = document.body }: Options = {}) => { injectStyles(); - manageElement(root); + await manageElement(root); } render(); |
