diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval.ts | 118 | ||||
| -rw-r--r-- | src/index.ts | 37 | ||||
| -rw-r--r-- | src/parser.ts | 6 | ||||
| -rw-r--r-- | src/utils/adt.ts | 2 |
4 files changed, 86 insertions, 77 deletions
diff --git a/src/eval.ts b/src/eval.ts index 03391c2..466cafd 100644 --- a/src/eval.ts +++ b/src/eval.ts @@ -1,5 +1,5 @@ -import { Expr } from "./parser"; -import { match, matchString } from "./utils/adt"; +import { CSSUnit, Expr } from './parser' +import { match, matchString } from './utils/adt' export type EvalActions = { addClass(id: string, classes: string): Promise<void> @@ -14,59 +14,67 @@ export type EvalActions = { type EvalValue = string | undefined | void -export const evalExpr = async (expr: Expr, actions: EvalActions): Promise<EvalValue> => +export const evalExpr = async ( + expr: Expr, + actions: EvalActions +): Promise<EvalValue> => match<Promise<EvalValue>, Expr>(expr, { - Call: async ({ name, args }) => { - return matchString<Promise<EvalValue>, string>(name, { - 'add-class': async () => { - const id = await evalExpr(args[0], actions) - const classes = await evalExpr(args[1], actions) - if (id && classes) { - await actions.addClass(id, classes) - } - }, - 'remove-class': async () => { - const id = await evalExpr(args[0], actions) - const classes = await evalExpr(args[1], actions) - if (id && classes) { - await actions.removeClass(id, classes) - } - }, - 'delay': async () => { - const num = await evalExpr(args[0], actions) - num && await actions.delay(parseInt(num, 10)) - }, - 'js-eval': async () => { - 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) - if (id && url) { - await actions.loadCssx(id, url) - } - }, - 'var': async () => { - const varName = await evalExpr(args[0], actions) - const defaultValue = await evalExpr(args[1], actions) - return varName && (actions.getVariable(varName) ?? defaultValue) - }, - 'update': async () => { - const id = await evalExpr(args[0], actions) - const varName = await evalExpr(args[1], actions) - const value = await evalExpr(args[2], actions) - if (id && varName && value) { - actions.updateVariable(id, varName, value) - } - }, - _: () => Promise.reject(new Error('not supposed to be here')), - }) - }, - LiteralString: async s => s, - Identifier: async s => s, - VarIdentifier: async s => s, - _: async _ => undefined, + Call: async ({ name, args }) => getFunctions(name, args, actions), + LiteralString: async (s) => s, + LiteralNumber: async ({ value, unit }) => + matchString<number, CSSUnit>(unit, { + s: () => value * 1000, + _: () => value, + }).toString(), + Identifier: async (s) => s, + VarIdentifier: async (s) => s, + _: async (_) => undefined, }) - +const getFunctions = (name: string, args: Expr[], actions: EvalActions) => + matchString<Promise<EvalValue>>(name, { + 'add-class': async () => { + const id = await evalExpr(args[0], actions) + const classes = await evalExpr(args[1], actions) + if (id && classes) { + await actions.addClass(id, classes) + } + }, + 'remove-class': async () => { + const id = await evalExpr(args[0], actions) + const classes = await evalExpr(args[1], actions) + if (id && classes) { + await actions.removeClass(id, classes) + } + }, + delay: async () => { + const num = await evalExpr(args[0], actions) + console.log(num) + num && (await actions.delay(parseInt(num, 10))) + }, + 'js-eval': async () => { + 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) + if (id && url) { + await actions.loadCssx(id, url) + } + }, + var: async () => { + const varName = await evalExpr(args[0], actions) + const defaultValue = await evalExpr(args[1], actions) + return varName && (actions.getVariable(varName) ?? defaultValue) + }, + update: async () => { + const id = await evalExpr(args[0], actions) + const varName = await evalExpr(args[1], actions) + const value = await evalExpr(args[2], actions) + if (id && varName && value) { + actions.updateVariable(id, varName, value) + } + }, + _: () => Promise.reject(new Error('not supposed to be here')), + }) diff --git a/src/index.ts b/src/index.ts index 9e9443c..2d6e9b8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -39,25 +39,26 @@ const getEvalActions = ($element: Element): EvalActions => ({ document.getElementById(id)?.classList.remove(cls), delay: (delay) => new Promise((res) => setTimeout(res, delay)), jsEval: async (js) => (0, eval)(js), - loadCssx: async (id, url) => new Promise((resolve, reject) => { - const $link = Object.assign(document.createElement('link'), { - href: url, - rel: 'stylesheet', - }) - $link.onload = () => { - const $el = document.getElementById(id); - // NOTE: Maybe create and append to body if no root? - if ($el) { - manageElement($el) - resolve(id) - } else { - console.error(`[CSSX] Unable to find root for ${id}`) - reject(`[CSSX] Unable to find root for ${id}`) + loadCssx: async (id, url) => + new Promise((resolve, reject) => { + const $link = Object.assign(document.createElement('link'), { + href: url, + rel: 'stylesheet', + }) + $link.onload = () => { + const $el = document.getElementById(id) + // NOTE: Maybe create and append to body if no root? + if ($el) { + manageElement($el) + resolve(id) + } else { + console.error(`[CSSX] Unable to find root for ${id}`) + reject(`[CSSX] Unable to find root for ${id}`) + } } - } - document.body.appendChild($link); - }), - getVariable: async varName => getPropertyValue($element, varName), + document.body.appendChild($link) + }), + getVariable: async (varName) => getPropertyValue($element, varName), updateVariable: async (targetId, varName, value) => { const $el = document.getElementById(targetId) if ($el) { diff --git a/src/parser.ts b/src/parser.ts index 8230825..9cb0405 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -1,14 +1,14 @@ import { Enum, constructors, match } from './utils/adt' import * as P from './utils/parser-comb' -type Unit = '' | 's' | 'ms' +export type CSSUnit = '' | 's' | 'ms' export type Expr = Enum<{ Call: { name: string; args: Expr[] } Identifier: string VarIdentifier: string LiteralString: string - LiteralNumber: { value: number, unit: Unit } + LiteralNumber: { value: number, unit: CSSUnit } }> export const Expr = constructors<Expr>() @@ -48,7 +48,7 @@ const numberParser = P.regex(/^[-+]?((\d*\.\d+)|\d+)/) const numberExprParser: P.Parser<Expr> = P.map( P.zip2(numberParser, P.optional(P.regex(/^(s|ms)/i))), - ([value, unit]) => Expr.LiteralNumber({ value: Number(value), unit: (unit ?? '') as Unit }), + ([value, unit]) => Expr.LiteralNumber({ value: Number(value), unit: (unit ?? '') as CSSUnit }), ) const exprParser: P.Parser<Expr> = P.or([ diff --git a/src/utils/adt.ts b/src/utils/adt.ts index 7234f67..78ab667 100644 --- a/src/utils/adt.ts +++ b/src/utils/adt.ts @@ -6,7 +6,7 @@ export const match = }): R => ((pattern as any)[tag.tag] || (pattern._ as any))(tag.value) export const matchString = - <R, T extends string>(key: T, pattern: { + <R, T extends string = string>(key: T, pattern: { [key in T | '_']?: (key: key) => R }): R => ((pattern as any)[key] || (pattern._ as any))(key) |
