aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2023-08-10 23:26:49 +0530
committerAkshay Nair <phenax5@gmail.com>2023-08-10 23:26:49 +0530
commit629993f2d7de1270d3aaa4ab2a6f9571cdffd621 (patch)
tree9b3c352f95e719ed5193293c1aaa4deb1e198e38
parente01cb693bc5737792e2b37abfd98d2d8f81bac4d (diff)
downloadcss-everything-629993f2d7de1270d3aaa4ab2a6f9571cdffd621.tar.gz
css-everything-629993f2d7de1270d3aaa4ab2a6f9571cdffd621.zip
feat: integrates parser and evaluator and creates a complete working example
Diffstat (limited to '')
-rw-r--r--examples/api/style.css24
-rw-r--r--src/eval.ts10
-rw-r--r--src/index.ts39
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();