aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/eval.ts118
-rw-r--r--src/index.ts37
-rw-r--r--src/parser.ts6
-rw-r--r--src/utils/adt.ts2
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)