Skip to content

Commit ead4e6d

Browse files
committed
fix(editor): stop saving blank blocks as br tags
1 parent d1e5404 commit ead4e6d

2 files changed

Lines changed: 49 additions & 2 deletions

File tree

apps/desktop/src/components/MarkdownPaper.test.tsx

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2126,11 +2126,54 @@ describe("MarkdownPaper editing", () => {
21262126
expect(screen.getByRole("option", { name: "Heading 1" })).toBeInTheDocument();
21272127

21282128
const serializeMarkdown = editor.action((ctx) => ctx.get(serializerCtx));
2129-
expect(serializeMarkdown(view.state.doc)).toBe("First\n\nSecond\n\n<br />\n\nThird\n");
2129+
expect(serializeMarkdown(view.state.doc)).toBe("First\n\nSecond\n\n\n\nThird\n");
21302130
expect(container.querySelector(".ProseMirror")?.textContent).not.toContain("/");
21312131
restoreLayout();
21322132
});
21332133

2134+
it("saves side-toolbar blank paragraphs as markdown blank lines instead of br tags", async () => {
2135+
const onMarkdownChange = vi.fn();
2136+
const { container, view } = await renderEditor("First\n\nSecond\n\nThird", { onMarkdownChange });
2137+
const restoreLayout = mockTopLevelBlockDragLayout(view, container);
2138+
const surface = container.querySelector<HTMLElement>(".ProseMirror");
2139+
expect(surface).toBeInTheDocument();
2140+
2141+
fireEvent.pointerMove(surface!, {
2142+
clientX: 240,
2143+
clientY: 152
2144+
});
2145+
2146+
fireEvent.click(await screen.findByRole("button", { name: "Add block below" }));
2147+
2148+
await settleMarkdownListener();
2149+
const latestMarkdown = String(onMarkdownChange.mock.calls.at(-1)?.[0] ?? "");
2150+
expect(latestMarkdown).toContain("Second\n\n\n\nThird");
2151+
expect(latestMarkdown).not.toContain("<br");
2152+
restoreLayout();
2153+
});
2154+
2155+
it("saves blank list items without br tags", async () => {
2156+
const onMarkdownChange = vi.fn();
2157+
const { container, view } = await renderEditor("- First\n- Second", { onMarkdownChange });
2158+
const restoreLayout = mockListItemBlockDragLayout(view, container);
2159+
const surface = container.querySelector<HTMLElement>(".ProseMirror");
2160+
expect(surface).toBeInTheDocument();
2161+
2162+
fireEvent.pointerMove(surface!, {
2163+
clientX: 240,
2164+
clientY: 112
2165+
});
2166+
2167+
fireEvent.click(await screen.findByRole("button", { name: "Add block below" }));
2168+
2169+
await settleMarkdownListener();
2170+
const latestMarkdown = String(onMarkdownChange.mock.calls.at(-1)?.[0] ?? "");
2171+
expect(latestMarkdown).not.toContain("<br");
2172+
expect(latestMarkdown).toContain("* First");
2173+
expect(latestMarkdown).toContain("* Second");
2174+
restoreLayout();
2175+
});
2176+
21342177
it("runs slash commands by mouse after adding a paragraph from the side toolbar", async () => {
21352178
const { container, view } = await renderEditor("First\n\nSecond\n\nThird");
21362179
const restoreLayout = mockTopLevelBlockDragLayout(view, container);

apps/desktop/src/components/markdown-paper-plugins.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
inputRules as commonmarkInputRules,
44
keymap as commonmarkKeymap,
55
plugins as commonmarkPlugins,
6+
remarkPreserveEmptyLinePlugin,
67
schema as commonmarkSchema
78
} from "@milkdown/kit/preset/commonmark";
89
import {
@@ -26,7 +27,10 @@ export const markraCommonmark = [
2627
commonmarkInputRules,
2728
commonmarkCommands,
2829
commonmarkKeymap,
29-
commonmarkPlugins
30+
commonmarkPlugins.filter((plugin) =>
31+
plugin !== remarkPreserveEmptyLinePlugin.plugin &&
32+
plugin !== remarkPreserveEmptyLinePlugin.options
33+
)
3034
].flat();
3135

3236
export const markraGfm = [

0 commit comments

Comments
 (0)