diff options
| author | Akshay Nair <phenax5@gmail.com> | 2023-08-11 23:06:57 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2023-08-11 23:08:16 +0530 |
| commit | ca80dee29014298bd8a1a82bd0418cc073a76316 (patch) | |
| tree | 70607817c0b27738eeb91b954aa5656adc2a311e /src/index.ts | |
| parent | b4548ce257c301154a39f5296387c2a72c552e70 (diff) | |
| download | css-everything-ca80dee29014298bd8a1a82bd0418cc073a76316.tar.gz css-everything-ca80dee29014298bd8a1a82bd0418cc073a76316.zip | |
test: adds test for simple signup page example
Diffstat (limited to 'src/index.ts')
| -rw-r--r-- | src/index.ts | 158 |
1 files changed, 2 insertions, 156 deletions
diff --git a/src/index.ts b/src/index.ts index 2d70c3f..9ca6c4e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,157 +1,3 @@ -import { EvalActions, evalExpr } from './eval' -import { parse } from './parser' +import { render } from './renderer' -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 PROPERTIES = [ - '--cssx-children', - '--cssx-text', - '--cssx-disgustingly-set-innerhtml', -] - -const injectStyles = () => { - const STYLE_TAG_CLASS = 'cssx-style-root' - if (document.querySelector(`.${STYLE_TAG_CLASS}`)) return - - const $style = document.createElement('style') - $style.className = STYLE_TAG_CLASS - - const properties = [...PROPERTIES, ...Object.values(EVENT_HANDLERS)] - - $style.textContent = `.cssx-layer { - ${properties.map(p => `${p}: ${UNSET_PROPERTY_VALUE};`).join(' ')} - }` - - document.body.appendChild($style) -} - -const getPropertyValue = ($element: Element, prop: string) => { - const value = `${getComputedStyle($element).getPropertyValue(prop)}`.trim() - return !value || value === UNSET_PROPERTY_VALUE ? '' : value -} - -const getChildrenIds = ($element: Element) => { - const value = getPropertyValue($element, '--cssx-children') - return value.split(/(\s*,\s*)|\s+/g).filter(Boolean) -} - -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), - 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}`) - } - } - document.body.appendChild($link) - }), - getVariable: async varName => getPropertyValue($element, varName), - updateVariable: async (targetId, varName, value) => { - const $el = document.getElementById(targetId) - if ($el) { - $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, - isNewElement: boolean = false, -) => { - for (const [eventType, property] of Object.entries(EVENT_HANDLERS)) { - const handlerExpr = getPropertyValue($element, property) - - if (handlerExpr) { - const eventHandler = async (event: any) => { - console.log(`Triggered event: ${eventType}`) - const exprs = parse(handlerExpr) - for (const expr of exprs) { - await evalExpr(expr, getEvalActions($element, event)) - } - } - - if (eventType === 'mount') { - if (isNewElement) setTimeout(eventHandler) - } else { - ;($element as any)[`on${eventType}`] = eventHandler - } - } - } -} - -const manageElement = async ( - $element: Element, - isNewElement: boolean = false, -) => { - await handleEvents($element, isNewElement) - - const text = getPropertyValue($element, '--cssx-text') - if (text) $element.textContent = text - - const html = getPropertyValue($element, '--cssx-disgustingly-set-innerhtml') - if (html) $element.innerHTML = html.replace(/(^'|")|('|"$)/g, '') - - const childrenIds = getChildrenIds($element) - if (childrenIds.length > 0) { - const LAYER_CLASS = 'cssx-layer' - const $childrenRoot = - $element.querySelector(`:scope > .${LAYER_CLASS}`) ?? - Object.assign(document.createElement('div'), { className: LAYER_CLASS }) - $element.appendChild($childrenRoot) - - for (const childId of childrenIds) { - const selector = childId.split('#') - const [tag, id] = selector.length >= 2 ? selector : ['div', ...selector] - let $child = $childrenRoot.querySelector(`:scope > #${id}`) - const isNewElement = !$child - if (!$child) { - $child = Object.assign(document.createElement(tag || 'div'), { id }) - } - $childrenRoot.appendChild($child) - await manageElement($child, isNewElement) - } - } -} - -interface Options { - root?: HTMLElement -} -const render = async ({ root = document.body }: Options = {}) => { - injectStyles() - await manageElement(root) -} - -render()
\ No newline at end of file +render({ root: document.body }) |
