a post-component library for building user-interfaces on the web.
at main 45 lines 1.3 kB view raw
1import { html } from 'dhtml' 2import { assert_eq, test } from '../../../scripts/test/test.ts' 3 4type JsonML = string | readonly [tag: string, attrs?: Record<string, any>, ...children: JsonML[]] 5interface Formatter { 6 header(value: unknown): JsonML | null 7 hasBody(value: unknown): boolean 8 body?(value: unknown): JsonML | null 9} 10 11const { devtoolsFormatters = [] } = globalThis as { devtoolsFormatters?: Formatter[] } 12 13function stringify(markup: JsonML): string { 14 if (typeof markup === 'string') return markup 15 const [tag, attrs, ...children] = markup 16 17 if (tag === 'object') return format(attrs!.object) 18 19 let str = `<${tag}` 20 if (attrs) for (const [k, v] of Object.entries(attrs)) str += ` ${k}="${v}"` 21 str += '>' 22 for (const child of children) str += stringify(child) 23 str += `</${tag}>` 24 return str 25} 26 27function format(value: unknown): string { 28 for (const formatter of devtoolsFormatters) { 29 const header = formatter.header(value) 30 if (header === null) continue 31 32 let str = stringify(header) 33 if (formatter.hasBody(value)) { 34 str += '\n\n' + stringify(formatter.body!(value)!) 35 } 36 return str 37 } 38 return JSON.stringify(value) 39} 40 41if (__DEV__) { 42 test('devtools formatter', () => { 43 assert_eq(format(html`<p>Count is ${1}</p>`), '<span>html`<p>Count is 1</p>`</span>') 44 }) 45}