Skip to content
This repository was archived by the owner on Jul 6, 2025. It is now read-only.

Commit c4a92e8

Browse files
committed
refactor: improve markdown loader
1 parent 84bcbb5 commit c4a92e8

File tree

3 files changed

+64
-35
lines changed

3 files changed

+64
-35
lines changed

framework/react/htmlpage.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/// <reference lib="dom" />
2+
3+
import React, { useEffect, useRef, RefObject, PropsWithRef, HTMLAttributes } from 'https://esm.sh/react'
4+
import { redirect } from '../core/redirect.ts'
5+
6+
type HTMLPageProps = PropsWithRef<HTMLAttributes<{}> & {
7+
ref?: RefObject<HTMLDivElement>
8+
html: string
9+
}>
10+
11+
export default function HTMLPage({
12+
ref: pRef,
13+
html,
14+
children,
15+
dangerouslySetInnerHTML,
16+
...rest
17+
}: HTMLPageProps) {
18+
const ref = useRef<HTMLDivElement>(null)
19+
20+
useEffect(() => {
21+
const REF = pRef || ref
22+
const anchors: HTMLAnchorElement[] = []
23+
const onClick = (e: MouseEvent) => {
24+
e.preventDefault()
25+
if (e.currentTarget) {
26+
redirect((e.currentTarget as HTMLAnchorElement).getAttribute('href')!)
27+
}
28+
}
29+
30+
if (REF.current) {
31+
REF.current.querySelectorAll('a').forEach((a: HTMLAnchorElement) => {
32+
const href = a.getAttribute('href')
33+
if (href && !/^[a-z0-9]+:/i.test(href)) {
34+
a.addEventListener('click', onClick, false)
35+
anchors.push(a)
36+
}
37+
})
38+
}
39+
40+
return () => anchors.forEach(a => a.removeEventListener('click', onClick))
41+
}, [])
42+
43+
return React.createElement('div', {
44+
...rest,
45+
ref: pRef || ref,
46+
dangerouslySetInnerHTML: { __html: html }
47+
})
48+
}

plugins/markdown.ts

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ export default (): LoaderPlugin => {
1010
name: 'markdown-loader',
1111
type: 'loader',
1212
test: /\.(md|markdown)$/i,
13-
acceptHMR: true,
1413
asPage: true,
1514
pagePathResolve: (url) => {
1615
let path = util.trimPrefix(url.replace(/\.(md|markdown)$/i, ''), '/pages')
@@ -25,40 +24,21 @@ export default (): LoaderPlugin => {
2524
},
2625
transform: ({ content }) => {
2726
const { __content, ...meta } = safeLoadFront(decoder.decode(content))
28-
const html = marked.parse(__content)
27+
const props = {
28+
id: util.isString(meta.id) ? meta.id : undefined,
29+
className: util.isString(meta.id) ? meta.className : undefined,
30+
style: util.isPlainObject(meta.style) ? meta.style : undefined,
31+
html: marked.parse(__content)
32+
}
2933

3034
return {
3135
code: [
32-
`import React, { useEffect, useRef } from "https://esm.sh/react";`,
33-
`import { redirect } from "https://deno.land/x/aleph/mod.ts";`,
36+
`import { createElement } from 'https://esm.sh/react'`,
37+
`import HTMLPage from "https://deno.land/x/aleph/framework/react/htmlpage.ts";`,
3438
`export default function MarkdownPage() {`,
35-
` const ref = useRef(null);`,
36-
``,
37-
` useEffect(() => {`,
38-
` const anchors = [];`,
39-
` const onClick = e => {`,
40-
` e.preventDefault();`,
41-
` redirect(e.currentTarget.getAttribute("href"));`,
42-
` };`,
43-
` if (ref.current) {`,
44-
` ref.current.querySelectorAll("a").forEach(a => {`,
45-
` const href = a.getAttribute("href");`,
46-
` if (href && !/^[a-z0-9]+:/i.test(href)) {`,
47-
` a.addEventListener("click", onClick, false);`,
48-
` anchors.push(a);`,
49-
` }`,
50-
` });`,
51-
` }`,
52-
` return () => anchors.forEach(a => a.removeEventListener("click", onClick));`,
53-
` }, []);`,
54-
``,
55-
` return React.createElement("div", {`,
56-
` className: "markdown-page",`,
57-
` ref,`,
58-
` dangerouslySetInnerHTML: { __html: ${JSON.stringify(html)} }`,
59-
` });`,
39+
` return createElement(HTMLPage, ${JSON.stringify(props)})`,
6040
`}`,
61-
`MarkdownPage.meta = ${JSON.stringify(meta, undefined, 2)};`,
41+
`MarkdownPage.meta = ${JSON.stringify(meta)}`,
6242
].join('\n')
6343
}
6444
}

plugins/markdown_test.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ Deno.test('markdown loader', async () => {
77
url: '/test.md',
88
content: (new TextEncoder).encode([
99
'---',
10+
'id: mark-page-1',
11+
'className: mark-page',
12+
'style:',
13+
' color: "#333"',
1014
'url: https://alephjs.org',
1115
'---',
1216
'',
@@ -16,12 +20,9 @@ Deno.test('markdown loader', async () => {
1620
})
1721
assertEquals(loader.test.test('/test.md'), true)
1822
assertEquals(loader.test.test('/test.markdown'), true)
19-
assertEquals(loader.acceptHMR, true)
2023
assertEquals(loader.asPage, true)
2124
assertEquals(loader.pagePathResolve!('/pages/docs/get-started.md'), { path: '/docs/get-started', isIndex: false })
2225
assertEquals(loader.pagePathResolve!('/pages/docs/index.md'), { path: '/docs', isIndex: true })
23-
assertEquals(code.includes('{ __html: "<h1 id=\\"alephjs\\">Aleph.js</h1>\\n<p>The Full-stack Framework in Deno.</p>\\n" }'), true)
24-
assertEquals(code.includes('MarkdownPage.meta = {\n "url": "https://alephjs.org"\n}'), true)
26+
assertEquals(code.includes('html: "<h1 id=\\"alephjs\\">Aleph.js</h1>\\n<p>The Full-stack Framework in Deno.</p>\\n"'), true)
27+
assertEquals(code.includes('MarkdownPage.meta = {"id":"mark-page-1","className":"mark-page","style":{"color":"#333"},"url":"https://alephjs.org"}'), true)
2528
})
26-
27-

0 commit comments

Comments
 (0)