Skip to content

Commit 4bcedd0

Browse files
feat: 🎸 add on api for crepe (#1622)
* feat: 🎸 add `on` api for crepe ✅ Closes: #1620 * test: add e2e * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent d1c630e commit 4bcedd0

File tree

5 files changed

+83
-16
lines changed

5 files changed

+83
-16
lines changed

Diff for: e2e/shim.d.ts

+3-7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import type { Editor } from '@milkdown/core'
55
import type { EditorView } from '@milkdown/prose/view'
66
import type { Telemetry } from '@milkdown/ctx'
7+
import type { Crepe } from '@milkdown/crepe'
78

89
declare global {
910
var __milkdown__: Editor
@@ -14,13 +15,8 @@ declare global {
1415

1516
var __inspect__: () => Telemetry[]
1617

17-
namespace Cypress {
18-
interface Chainable {
19-
paste: (payload: Record<string, unknown>) => Chainable<void>
20-
isMarkdown: (markdown: string) => Chainable<void>
21-
markdownFixture: (path: string) => Chainable<void>
22-
}
23-
}
18+
var __beforeCrepeCreate__: (crepe: Crepe) => void
19+
var __afterCrepeCreated__: (crepe: Crepe) => void
2420

2521
var commands: {
2622
toggleStrong?: () => void

Diff for: e2e/src/crepe/main.ts

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ setup(async () => {
88
const crepe = new Crepe({
99
root: '#app',
1010
})
11+
if (globalThis.__beforeCrepeCreate__) {
12+
globalThis.__beforeCrepeCreate__(crepe)
13+
}
1114
await crepe.create()
15+
if (globalThis.__afterCrepeCreated__) {
16+
globalThis.__afterCrepeCreated__(crepe)
17+
}
1218
return crepe.editor
1319
})

Diff for: e2e/tests/crepe/listener.spec.ts

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { expect, test } from '@playwright/test'
2+
import { focusEditor } from 'tests/misc'
3+
4+
test('listen change before editor is created', async ({ page }) => {
5+
await page.addInitScript(() => {
6+
window.__beforeCrepeCreate__ = (crepe) => {
7+
crepe.on((listener) => {
8+
listener.markdownUpdated((_, markdown) => {
9+
// oxlint-disable-next-line no-console
10+
console.log('markdown', markdown)
11+
})
12+
})
13+
}
14+
})
15+
await page.goto('/crepe/')
16+
17+
const messagePromise = page.waitForEvent('console', (msg) => {
18+
return msg.text().includes('Hello')
19+
})
20+
21+
await focusEditor(page)
22+
await page.keyboard.type('Hello')
23+
24+
const message = await messagePromise
25+
const log: string = await message.args()[1]?.jsonValue()
26+
expect(log.trim()).toBe('Hello')
27+
})
28+
29+
test('listen change after editor is created', async ({ page }) => {
30+
await page.addInitScript(() => {
31+
window.__afterCrepeCreated__ = (crepe) => {
32+
crepe.on((listener) => {
33+
listener.markdownUpdated((_, markdown) => {
34+
// oxlint-disable-next-line no-console
35+
console.log('markdown', markdown)
36+
})
37+
})
38+
}
39+
})
40+
await page.goto('/crepe/')
41+
42+
const messagePromise = page.waitForEvent('console', (msg) => {
43+
return msg.text().includes('World')
44+
})
45+
46+
await focusEditor(page)
47+
await page.keyboard.type('World')
48+
49+
const message = await messagePromise
50+
const log: string = await message.args()[1]?.jsonValue()
51+
expect(log.trim()).toBe('World')
52+
})

Diff for: packages/crepe/src/core/crepe.ts

+19
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { DefaultValue } from '@milkdown/kit/core'
22
import {
33
Editor,
4+
EditorStatus,
45
defaultValueCtx,
56
editorViewOptionsCtx,
67
rootCtx,
@@ -17,6 +18,8 @@ import { trailing } from '@milkdown/kit/plugin/trailing'
1718
import type { CrepeFeatureConfig } from '../feature'
1819
import { CrepeFeature, defaultFeatures, loadFeature } from '../feature'
1920
import { configureFeatures } from './slice'
21+
import type { ListenerManager } from '@milkdown/kit/plugin/listener'
22+
import { listener, listenerCtx } from '@milkdown/kit/plugin/listener'
2023

2124
export interface CrepeConfig {
2225
features?: Partial<Record<CrepeFeature, boolean>>
@@ -62,6 +65,7 @@ export class Crepe {
6265
}))
6366
})
6467
.use(commonmark)
68+
.use(listener)
6569
.use(history)
6670
.use(indent)
6771
.use(trailing)
@@ -102,4 +106,19 @@ export class Crepe {
102106
getMarkdown() {
103107
return this.#editor.action(getMarkdown())
104108
}
109+
110+
on(fn: (api: ListenerManager) => void) {
111+
if (this.#editor.status !== EditorStatus.Created) {
112+
this.#editor.config((ctx) => {
113+
const listener = ctx.get(listenerCtx)
114+
fn(listener)
115+
})
116+
return this
117+
}
118+
this.#editor.action((ctx) => {
119+
const listener = ctx.get(listenerCtx)
120+
fn(listener)
121+
})
122+
return this
123+
}
105124
}

Diff for: storybook/stories/crepe/setup.ts

+3-9
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ import { Crepe } from '@milkdown/crepe'
22
import all from '@milkdown/crepe/theme/common/style.css?inline'
33
import localStyle from './style.css?inline'
44
import type { Extension } from '@codemirror/state'
5-
import { listener, listenerCtx } from '@milkdown/kit/plugin/listener'
6-
import { codeToHtml } from 'shiki'
75
import { injectMarkdown, wrapInShadow } from '../utils/shadow'
86

97
export interface Args {
@@ -109,16 +107,12 @@ export function setup({ args, style, theme }: setupConfig) {
109107
injectMarkdown(args.defaultValue, markdownContainer)
110108
}
111109

112-
crepe.editor
113-
.config((ctx) => {
114-
const listenerAPI = ctx.get(listenerCtx)
115-
listenerAPI.markdownUpdated((_, markdown) => {
110+
crepe
111+
.on((listener) => {
112+
listener.markdownUpdated((_, markdown) => {
116113
injectMarkdown(markdown, markdownContainer)
117114
})
118115
})
119-
.use(listener)
120-
121-
crepe
122116
.setReadonly(args.readonly)
123117
.create()
124118
.then(() => {

0 commit comments

Comments
 (0)