Skip to content

Commit 2daa264

Browse files
refactor: remove simplifyblocks and make copy sync (#1160)
* extract updateBlockCommand * Extracted remaining commands * extract keyboard shortcuts * move directory * remove createblockcommand * Added merge/split tests * Updated snapshots * Added update block tests and unified test setup * Added test cases for reverting props * Added additional test cases for changing content type * remove "nested" insert option * Split remaining commands & cleaned up * Added `getNearestBlockContainerPos` * Refactored `getBlockInfoFromPos` * Rewrote `splitBlockCommand` * Added text cursor position tests * Fixed lint issue * fix lint * Fixed `splitBlock` selection * Small fix * Added unit tests to check selection setting * simplify splitblocks * Fixed selection in `splitBlock` tests * wip: deprecate getBlockInfoFromPos * finish cleanup * Fixed `mergeBlocks` edge cases * fix build * clean nodeconversions * Implemented PR feedback * Finished review and remaining changes * Fixed bug in `insertOrUpdateBlock` * Removed log * Tiny changes * remove simplifyblocks, make copy sync * fix bug * fix all tests * Fixed merge/delete behaviour on Backspace --------- Co-authored-by: matthewlipski <[email protected]> Co-authored-by: Matthew Lipski <[email protected]>
1 parent bb32c03 commit 2daa264

File tree

15 files changed

+318
-312
lines changed

15 files changed

+318
-312
lines changed

Diff for: packages/core/src/api/clipboard/toClipboard/copyExtension.ts

+24-31
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
InlineContentSchema,
1212
StyleSchema,
1313
} from "../../../schema/index.js";
14-
import { initializeESMDependencies } from "../../../util/esmDependencies.js";
1514
import { createExternalHTMLExporter } from "../../exporters/html/externalHTMLExporter.js";
1615
import { cleanHTMLToMarkdown } from "../../exporters/markdown/markdownExporter.js";
1716
import { fragmentToBlocks } from "../../nodeConversions/fragmentToBlocks.js";
@@ -20,7 +19,7 @@ import {
2019
contentNodeToTableContent,
2120
} from "../../nodeConversions/nodeToBlock.js";
2221

23-
async function fragmentToExternalHTML<
22+
function fragmentToExternalHTML<
2423
BSchema extends BlockSchema,
2524
I extends InlineContentSchema,
2625
S extends StyleSchema
@@ -61,7 +60,6 @@ async function fragmentToExternalHTML<
6160

6261
let externalHTML: string;
6362

64-
await initializeESMDependencies();
6563
const externalHTMLExporter = createExternalHTMLExporter(
6664
view.state.schema,
6765
editor
@@ -82,9 +80,7 @@ async function fragmentToExternalHTML<
8280
editor.schema.styleSchema
8381
);
8482

85-
externalHTML = externalHTMLExporter.exportInlineContent(ic as any, {
86-
simplifyBlocks: false,
87-
});
83+
externalHTML = externalHTMLExporter.exportInlineContent(ic as any, {});
8884
} else if (isWithinBlockContent) {
8985
// first convert selection to blocknote-style inline content, and then
9086
// pass this to the exporter
@@ -93,28 +89,26 @@ async function fragmentToExternalHTML<
9389
editor.schema.inlineContentSchema,
9490
editor.schema.styleSchema
9591
);
96-
externalHTML = externalHTMLExporter.exportInlineContent(ic, {
97-
simplifyBlocks: false,
98-
});
92+
externalHTML = externalHTMLExporter.exportInlineContent(ic, {});
9993
} else {
10094
const blocks = fragmentToBlocks(selectedFragment, editor.schema);
10195
externalHTML = externalHTMLExporter.exportBlocks(blocks, {});
10296
}
10397
return externalHTML;
10498
}
10599

106-
export async function selectedFragmentToHTML<
100+
export function selectedFragmentToHTML<
107101
BSchema extends BlockSchema,
108102
I extends InlineContentSchema,
109103
S extends StyleSchema
110104
>(
111105
view: EditorView,
112106
editor: BlockNoteEditor<BSchema, I, S>
113-
): Promise<{
107+
): {
114108
clipboardHTML: string;
115109
externalHTML: string;
116110
markdown: string;
117-
}> {
111+
} {
118112
// Checks if a `blockContent` node is being copied and expands
119113
// the selection to the parent `blockContainer` node. This is
120114
// for the use-case in which only a block without content is
@@ -138,7 +132,7 @@ export async function selectedFragmentToHTML<
138132

139133
const selectedFragment = view.state.selection.content().content;
140134

141-
const externalHTML = await fragmentToExternalHTML<BSchema, I, S>(
135+
const externalHTML = fragmentToExternalHTML<BSchema, I, S>(
142136
view,
143137
selectedFragment,
144138
editor
@@ -162,16 +156,16 @@ const copyToClipboard = <
162156
event.preventDefault();
163157
event.clipboardData!.clearData();
164158

165-
(async () => {
166-
const { clipboardHTML, externalHTML, markdown } =
167-
await selectedFragmentToHTML(view, editor);
159+
const { clipboardHTML, externalHTML, markdown } = selectedFragmentToHTML(
160+
view,
161+
editor
162+
);
168163

169-
// TODO: Writing to other MIME types not working in Safari for
170-
// some reason.
171-
event.clipboardData!.setData("blocknote/html", clipboardHTML);
172-
event.clipboardData!.setData("text/html", externalHTML);
173-
event.clipboardData!.setData("text/plain", markdown);
174-
})();
164+
// TODO: Writing to other MIME types not working in Safari for
165+
// some reason.
166+
event.clipboardData!.setData("blocknote/html", clipboardHTML);
167+
event.clipboardData!.setData("text/html", externalHTML);
168+
event.clipboardData!.setData("text/plain", markdown);
175169
};
176170

177171
export const createCopyToClipboardExtension = <
@@ -229,16 +223,15 @@ export const createCopyToClipboardExtension = <
229223
event.preventDefault();
230224
event.dataTransfer!.clearData();
231225

232-
(async () => {
233-
const { clipboardHTML, externalHTML, markdown } =
234-
await selectedFragmentToHTML(view, editor);
226+
const { clipboardHTML, externalHTML, markdown } =
227+
selectedFragmentToHTML(view, editor);
228+
229+
// TODO: Writing to other MIME types not working in Safari for
230+
// some reason.
231+
event.dataTransfer!.setData("blocknote/html", clipboardHTML);
232+
event.dataTransfer!.setData("text/html", externalHTML);
233+
event.dataTransfer!.setData("text/plain", markdown);
235234

236-
// TODO: Writing to other MIME types not working in Safari for
237-
// some reason.
238-
event.dataTransfer!.setData("blocknote/html", clipboardHTML);
239-
event.dataTransfer!.setData("text/html", externalHTML);
240-
event.dataTransfer!.setData("text/plain", markdown);
241-
})();
242235
// Prevent default PM handler to be called
243236
return true;
244237
},
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<h2 data-text-color="yellow" data-background-color="blue" data-text-alignment="right" data-level="2"><strong><u>Heading </u></strong><em><s>2</s></em></h2><p data-background-color="red">Paragraph</p><ul><li><p class="bn-inline-content"></p></li></ul>
1+
<h2 data-text-color="yellow" data-background-color="blue" data-text-alignment="right" data-level="2"><strong><u>Heading </u></strong><em><s>2</s></em></h2><p data-background-color="red">Paragraph</p><ul><li><p></p></li></ul>
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<ul><li><p class="bn-inline-content">Bullet List Item 1</p></li><li><p class="bn-inline-content">Bullet List Item 2</p></li></ul><ol><li><p class="bn-inline-content">Numbered List Item 1</p></li><li><p class="bn-inline-content">Numbered List Item 2</p></li></ol><ul><li><input type="checkbox"><p class="bn-inline-content">Check List Item 1</p></li><li><input type="checkbox" checked><p class="bn-inline-content">Check List Item 2</p></li></ul>
1+
<ul><li><p>Bullet List Item 1</p></li><li><p>Bullet List Item 2</p></li></ul><ol><li><p>Numbered List Item 1</p></li><li><p>Numbered List Item 2</p></li></ol><ul><li><input type="checkbox"><p class="bn-inline-content">Check List Item 1</p></li><li><input type="checkbox" checked="" data-checked="true"><p class="bn-inline-content">Check List Item 2</p></li></ul>
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<ul><li><p class="bn-inline-content">Bullet List Item 1</p></li><li><p class="bn-inline-content">Bullet List Item 2</p><ol><li><p class="bn-inline-content">Numbered List Item 1</p></li><li><p class="bn-inline-content">Numbered List Item 2</p><ul><li><input type="checkbox"><p class="bn-inline-content">Check List Item 1</p></li><li><input type="checkbox" checked><p class="bn-inline-content">Check List Item 2</p></li></ul></li></ol></li></ul>
1+
<ul><li><p>Bullet List Item 1</p></li><li><p>Bullet List Item 2</p><ol><li><p>Numbered List Item 1</p></li><li><p>Numbered List Item 2</p><ul><li><input type="checkbox"><p class="bn-inline-content">Check List Item 1</p></li><li><input type="checkbox" checked="" data-checked="true"><p class="bn-inline-content">Check List Item 2</p></li></ul></li></ol></li></ul>

Diff for: packages/core/src/api/exporters/html/externalHTMLExporter.ts

+12-44
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@ import {
88
InlineContentSchema,
99
StyleSchema,
1010
} from "../../../schema/index.js";
11-
import { esmDependencies } from "../../../util/esmDependencies.js";
1211
import {
13-
serializeBlocks,
14-
serializeInlineContent,
15-
} from "./util/sharedHTMLConversion.js";
16-
import { simplifyBlocks } from "./util/simplifyBlocksRehypePlugin.js";
12+
serializeBlocksExternalHTML,
13+
serializeInlineContentExternalHTML,
14+
} from "./util/serializeBlocksExternalHTML.js";
1715

1816
// Used to export BlockNote blocks and ProseMirror nodes to HTML for use outside
1917
// the editor. Blocks are exported using the `toExternalHTML` method in their
@@ -39,64 +37,34 @@ export const createExternalHTMLExporter = <
3937
schema: Schema,
4038
editor: BlockNoteEditor<BSchema, I, S>
4139
) => {
42-
const deps = esmDependencies;
43-
44-
if (!deps) {
45-
throw new Error(
46-
"External HTML exporter requires ESM dependencies to be initialized"
47-
);
48-
}
49-
5040
const serializer = DOMSerializer.fromSchema(schema);
5141

5242
return {
5343
exportBlocks: (
5444
blocks: PartialBlock<BSchema, I, S>[],
5545
options: { document?: Document }
5646
) => {
57-
const html = serializeBlocks(
47+
const html = serializeBlocksExternalHTML(
5848
editor,
5949
blocks,
6050
serializer,
61-
true,
51+
new Set<string>(["numberedListItem"]),
52+
new Set<string>(["bulletListItem", "checkListItem"]),
6253
options
63-
).outerHTML;
64-
65-
// Possible improvement: now, we first use the serializeBlocks function
66-
// which adds blockcontainer and blockgroup wrappers. We then pass the
67-
// result to simplifyBlocks, which then cleans the wrappers.
68-
//
69-
// It might be easier if we create a version of serializeBlocks that
70-
// doesn't add the wrappers in the first place, then we can get rid of
71-
// the more complex simplifyBlocks plugin.
72-
let externalHTML: any = deps.unified
73-
.unified()
74-
.use(deps.rehypeParse.default, { fragment: true });
75-
if ((options as any).simplifyBlocks !== false) {
76-
externalHTML = externalHTML.use(simplifyBlocks, {
77-
orderedListItemBlockTypes: new Set<string>(["numberedListItem"]),
78-
unorderedListItemBlockTypes: new Set<string>([
79-
"bulletListItem",
80-
"checkListItem",
81-
]),
82-
});
83-
}
84-
externalHTML = externalHTML
85-
.use(deps.rehypeStringify.default)
86-
.processSync(html);
87-
88-
return externalHTML.value as string;
54+
);
55+
const div = document.createElement("div");
56+
div.append(html);
57+
return div.innerHTML;
8958
},
9059

9160
exportInlineContent: (
9261
inlineContent: InlineContent<I, S>[],
93-
options: { simplifyBlocks: boolean; document?: Document }
62+
options: { document?: Document }
9463
) => {
95-
const domFragment = serializeInlineContent(
64+
const domFragment = serializeInlineContentExternalHTML(
9665
editor,
9766
inlineContent as any,
9867
serializer,
99-
true,
10068
options
10169
);
10270

Diff for: packages/core/src/api/exporters/html/internalHTMLSerializer.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
InlineContentSchema,
77
StyleSchema,
88
} from "../../../schema/index.js";
9-
import { serializeBlocks } from "./util/sharedHTMLConversion.js";
9+
import { serializeBlocksInternalHTML } from "./util/serializeBlocksInternalHTML.js";
1010
// Used to serialize BlockNote blocks and ProseMirror nodes to HTML without
1111
// losing data. Blocks are exported using the `toInternalHTML` method in their
1212
// `blockSpec`.
@@ -31,8 +31,13 @@ export const createInternalHTMLSerializer = <
3131
blocks: PartialBlock<BSchema, I, S>[],
3232
options: { document?: Document }
3333
) => {
34-
return serializeBlocks(editor, blocks, serializer, false, options)
35-
.outerHTML;
34+
return serializeBlocksInternalHTML(
35+
editor,
36+
blocks,
37+
serializer,
38+
false,
39+
options
40+
).outerHTML;
3641
},
3742
};
3843
};

0 commit comments

Comments
 (0)