Skip to content

refactor: remove simplifyblocks and make copy sync #1160

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 44 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
51f4216
extract updateBlockCommand
YousefED Oct 8, 2024
18ff213
Extracted remaining commands
matthewlipski Oct 8, 2024
de6f1ec
extract keyboard shortcuts
YousefED Oct 8, 2024
c3cea79
move directory
YousefED Oct 8, 2024
717301e
remove createblockcommand
YousefED Oct 8, 2024
9c32c92
Added merge/split tests
matthewlipski Oct 8, 2024
3fe50d5
Updated snapshots
matthewlipski Oct 9, 2024
6a0fda3
Added update block tests and unified test setup
matthewlipski Oct 9, 2024
df6dccc
Added test cases for reverting props
matthewlipski Oct 9, 2024
d4f206d
Added additional test cases for changing content type
matthewlipski Oct 9, 2024
5ac23d9
remove "nested" insert option
YousefED Oct 9, 2024
fc0010b
Split remaining commands & cleaned up
matthewlipski Oct 9, 2024
e392637
Added `getNearestBlockContainerPos`
matthewlipski Oct 10, 2024
5dd4afd
Refactored `getBlockInfoFromPos`
matthewlipski Oct 10, 2024
58016a9
Rewrote `splitBlockCommand`
matthewlipski Oct 12, 2024
6bcd81d
Added text cursor position tests
matthewlipski Oct 12, 2024
ab18dd4
Fixed lint issue
matthewlipski Oct 12, 2024
968b6fc
fix lint
YousefED Oct 13, 2024
89a86fb
Fixed `splitBlock` selection
matthewlipski Oct 14, 2024
adb0907
Merge remote-tracking branch 'origin/refactor/clean-blockcontainer' i…
matthewlipski Oct 14, 2024
ba11dd2
Small fix
matthewlipski Oct 14, 2024
dd572c3
Added unit tests to check selection setting
matthewlipski Oct 14, 2024
74a0cda
simplify splitblocks
YousefED Oct 14, 2024
690ec6a
Merge branch 'refactor/clean-blockcontainer' of github.com:TypeCellOS…
YousefED Oct 14, 2024
f57b0eb
Fixed selection in `splitBlock` tests
matthewlipski Oct 14, 2024
1236476
wip: deprecate getBlockInfoFromPos
YousefED Oct 14, 2024
7b17ded
finish cleanup
YousefED Oct 14, 2024
bf4635e
Fixed `mergeBlocks` edge cases
matthewlipski Oct 14, 2024
3f73033
fix build
YousefED Oct 15, 2024
0a50308
Merge branch 'refactor/clean-blockcontainer' of github.com:TypeCellOS…
YousefED Oct 15, 2024
9ae58f6
clean nodeconversions
YousefED Oct 15, 2024
80c8b46
Implemented PR feedback
matthewlipski Oct 15, 2024
1414e14
Finished review and remaining changes
matthewlipski Oct 15, 2024
f627732
Fixed bug in `insertOrUpdateBlock`
matthewlipski Oct 15, 2024
3d09350
Removed log
matthewlipski Oct 15, 2024
3d0e80e
Tiny changes
matthewlipski Oct 16, 2024
cb1e705
Merge pull request #1151 from TypeCellOS/refactor/clean-blockcontaine…
matthewlipski Oct 16, 2024
74e7d53
remove simplifyblocks, make copy sync
YousefED Oct 17, 2024
0ef0a4c
Merge remote-tracking branch 'origin/refactor/clean-blockcontainer' i…
YousefED Oct 17, 2024
b984d35
fix bug
YousefED Oct 17, 2024
b31e9e0
fix all tests
YousefED Oct 17, 2024
ab902c9
Fixed merge/delete behaviour on Backspace
matthewlipski Oct 17, 2024
ffa039b
Merge branch 'refactor/clean-blockcontainer' into fix/remove-simplify…
matthewlipski Oct 17, 2024
fe61cd1
Merge branch 'main' into fix/remove-simplify-blocks
matthewlipski Oct 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 24 additions & 31 deletions packages/core/src/api/clipboard/toClipboard/copyExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
InlineContentSchema,
StyleSchema,
} from "../../../schema/index.js";
import { initializeESMDependencies } from "../../../util/esmDependencies.js";
import { createExternalHTMLExporter } from "../../exporters/html/externalHTMLExporter.js";
import { cleanHTMLToMarkdown } from "../../exporters/markdown/markdownExporter.js";
import { fragmentToBlocks } from "../../nodeConversions/fragmentToBlocks.js";
Expand All @@ -20,7 +19,7 @@ import {
contentNodeToTableContent,
} from "../../nodeConversions/nodeToBlock.js";

async function fragmentToExternalHTML<
function fragmentToExternalHTML<
BSchema extends BlockSchema,
I extends InlineContentSchema,
S extends StyleSchema
Expand Down Expand Up @@ -61,7 +60,6 @@ async function fragmentToExternalHTML<

let externalHTML: string;

await initializeESMDependencies();
const externalHTMLExporter = createExternalHTMLExporter(
view.state.schema,
editor
Expand All @@ -82,9 +80,7 @@ async function fragmentToExternalHTML<
editor.schema.styleSchema
);

externalHTML = externalHTMLExporter.exportInlineContent(ic as any, {
simplifyBlocks: false,
});
externalHTML = externalHTMLExporter.exportInlineContent(ic as any, {});
} else if (isWithinBlockContent) {
// first convert selection to blocknote-style inline content, and then
// pass this to the exporter
Expand All @@ -93,28 +89,26 @@ async function fragmentToExternalHTML<
editor.schema.inlineContentSchema,
editor.schema.styleSchema
);
externalHTML = externalHTMLExporter.exportInlineContent(ic, {
simplifyBlocks: false,
});
externalHTML = externalHTMLExporter.exportInlineContent(ic, {});
} else {
const blocks = fragmentToBlocks(selectedFragment, editor.schema);
externalHTML = externalHTMLExporter.exportBlocks(blocks, {});
}
return externalHTML;
}

export async function selectedFragmentToHTML<
export function selectedFragmentToHTML<
BSchema extends BlockSchema,
I extends InlineContentSchema,
S extends StyleSchema
>(
view: EditorView,
editor: BlockNoteEditor<BSchema, I, S>
): Promise<{
): {
clipboardHTML: string;
externalHTML: string;
markdown: string;
}> {
} {
// Checks if a `blockContent` node is being copied and expands
// the selection to the parent `blockContainer` node. This is
// for the use-case in which only a block without content is
Expand All @@ -138,7 +132,7 @@ export async function selectedFragmentToHTML<

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

const externalHTML = await fragmentToExternalHTML<BSchema, I, S>(
const externalHTML = fragmentToExternalHTML<BSchema, I, S>(
view,
selectedFragment,
editor
Expand All @@ -162,16 +156,16 @@ const copyToClipboard = <
event.preventDefault();
event.clipboardData!.clearData();

(async () => {
const { clipboardHTML, externalHTML, markdown } =
await selectedFragmentToHTML(view, editor);
const { clipboardHTML, externalHTML, markdown } = selectedFragmentToHTML(
view,
editor
);

// TODO: Writing to other MIME types not working in Safari for
// some reason.
event.clipboardData!.setData("blocknote/html", clipboardHTML);
event.clipboardData!.setData("text/html", externalHTML);
event.clipboardData!.setData("text/plain", markdown);
})();
// TODO: Writing to other MIME types not working in Safari for
// some reason.
event.clipboardData!.setData("blocknote/html", clipboardHTML);
event.clipboardData!.setData("text/html", externalHTML);
event.clipboardData!.setData("text/plain", markdown);
};

export const createCopyToClipboardExtension = <
Expand Down Expand Up @@ -229,16 +223,15 @@ export const createCopyToClipboardExtension = <
event.preventDefault();
event.dataTransfer!.clearData();

(async () => {
const { clipboardHTML, externalHTML, markdown } =
await selectedFragmentToHTML(view, editor);
const { clipboardHTML, externalHTML, markdown } =
selectedFragmentToHTML(view, editor);

// TODO: Writing to other MIME types not working in Safari for
// some reason.
event.dataTransfer!.setData("blocknote/html", clipboardHTML);
event.dataTransfer!.setData("text/html", externalHTML);
event.dataTransfer!.setData("text/plain", markdown);

// TODO: Writing to other MIME types not working in Safari for
// some reason.
event.dataTransfer!.setData("blocknote/html", clipboardHTML);
event.dataTransfer!.setData("text/html", externalHTML);
event.dataTransfer!.setData("text/plain", markdown);
})();
// Prevent default PM handler to be called
return true;
},
Expand Down
Original file line number Diff line number Diff line change
@@ -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>
<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 number Diff line number Diff line change
@@ -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>
<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 number Diff line number Diff line change
@@ -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>
<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>
56 changes: 12 additions & 44 deletions packages/core/src/api/exporters/html/externalHTMLExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@ import {
InlineContentSchema,
StyleSchema,
} from "../../../schema/index.js";
import { esmDependencies } from "../../../util/esmDependencies.js";
import {
serializeBlocks,
serializeInlineContent,
} from "./util/sharedHTMLConversion.js";
import { simplifyBlocks } from "./util/simplifyBlocksRehypePlugin.js";
serializeBlocksExternalHTML,
serializeInlineContentExternalHTML,
} from "./util/serializeBlocksExternalHTML.js";

// Used to export BlockNote blocks and ProseMirror nodes to HTML for use outside
// the editor. Blocks are exported using the `toExternalHTML` method in their
Expand All @@ -39,64 +37,34 @@ export const createExternalHTMLExporter = <
schema: Schema,
editor: BlockNoteEditor<BSchema, I, S>
) => {
const deps = esmDependencies;

if (!deps) {
throw new Error(
"External HTML exporter requires ESM dependencies to be initialized"
);
}

const serializer = DOMSerializer.fromSchema(schema);

return {
exportBlocks: (
blocks: PartialBlock<BSchema, I, S>[],
options: { document?: Document }
) => {
const html = serializeBlocks(
const html = serializeBlocksExternalHTML(
editor,
blocks,
serializer,
true,
new Set<string>(["numberedListItem"]),
new Set<string>(["bulletListItem", "checkListItem"]),
options
).outerHTML;

// Possible improvement: now, we first use the serializeBlocks function
// which adds blockcontainer and blockgroup wrappers. We then pass the
// result to simplifyBlocks, which then cleans the wrappers.
//
// It might be easier if we create a version of serializeBlocks that
// doesn't add the wrappers in the first place, then we can get rid of
// the more complex simplifyBlocks plugin.
let externalHTML: any = deps.unified
.unified()
.use(deps.rehypeParse.default, { fragment: true });
if ((options as any).simplifyBlocks !== false) {
externalHTML = externalHTML.use(simplifyBlocks, {
orderedListItemBlockTypes: new Set<string>(["numberedListItem"]),
unorderedListItemBlockTypes: new Set<string>([
"bulletListItem",
"checkListItem",
]),
});
}
externalHTML = externalHTML
.use(deps.rehypeStringify.default)
.processSync(html);

return externalHTML.value as string;
);
const div = document.createElement("div");
div.append(html);
return div.innerHTML;
},

exportInlineContent: (
inlineContent: InlineContent<I, S>[],
options: { simplifyBlocks: boolean; document?: Document }
options: { document?: Document }
) => {
const domFragment = serializeInlineContent(
const domFragment = serializeInlineContentExternalHTML(
editor,
inlineContent as any,
serializer,
true,
options
);

Expand Down
11 changes: 8 additions & 3 deletions packages/core/src/api/exporters/html/internalHTMLSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
InlineContentSchema,
StyleSchema,
} from "../../../schema/index.js";
import { serializeBlocks } from "./util/sharedHTMLConversion.js";
import { serializeBlocksInternalHTML } from "./util/serializeBlocksInternalHTML.js";
// Used to serialize BlockNote blocks and ProseMirror nodes to HTML without
// losing data. Blocks are exported using the `toInternalHTML` method in their
// `blockSpec`.
Expand All @@ -31,8 +31,13 @@ export const createInternalHTMLSerializer = <
blocks: PartialBlock<BSchema, I, S>[],
options: { document?: Document }
) => {
return serializeBlocks(editor, blocks, serializer, false, options)
.outerHTML;
return serializeBlocksInternalHTML(
editor,
blocks,
serializer,
false,
options
).outerHTML;
},
};
};
Loading
Loading