Skip to content

Commit 5a48db4

Browse files
committed
extract transformPasted
1 parent fc61e25 commit 5a48db4

File tree

2 files changed

+61
-45
lines changed

2 files changed

+61
-45
lines changed

packages/core/src/BlockNoteEditor.ts

Lines changed: 3 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Editor, EditorOptions, Extension } from "@tiptap/core";
2-
import { Fragment, Node, Slice } from "prosemirror-model";
2+
import { Node } from "prosemirror-model";
33
// import "./blocknote.css";
44
import { Editor as TiptapEditor } from "@tiptap/core/dist/packages/core/src/Editor";
55
import * as Y from "yjs";
@@ -69,6 +69,7 @@ import { getDefaultSlashMenuItems } from "./extensions/SlashMenu/defaultSlashMen
6969
import { TableHandlesProsemirrorPlugin } from "./extensions/TableHandles/TableHandlesPlugin";
7070
import { UniqueID } from "./extensions/UniqueID/UniqueID";
7171
import { UnreachableCaseError, mergeCSSClasses } from "./shared/utils";
72+
import { transformPasted } from "./transformPasted";
7273

7374
export type BlockNoteEditorOptions<
7475
BSpecs extends BlockSpecs,
@@ -445,50 +446,7 @@ export class BlockNoteEditor<
445446
newOptions.domAttributes?.editor?.class || ""
446447
),
447448
},
448-
transformPasted(slice, view) {
449-
// helper function
450-
function removeChild(node: Fragment, n: number) {
451-
const children: any[] = [];
452-
node.forEach((child, _, i) => {
453-
if (i !== n) {
454-
children.push(child);
455-
}
456-
});
457-
return Fragment.from(children);
458-
}
459-
460-
// fix for https://github.com/ProseMirror/prosemirror/issues/1430#issuecomment-1822570821
461-
let f = Fragment.from(slice.content);
462-
for (let i = 0; i < f.childCount; i++) {
463-
if (f.child(i).type.spec.group === "blockContent") {
464-
const content = [f.child(i)];
465-
if (i + 1 < f.childCount) {
466-
// when there is a blockGroup, it should be nested in the new blockcontainer
467-
if (f.child(i + 1).type.spec.group === "blockGroup") {
468-
const nestedChild = f
469-
.child(i + 1)
470-
.child(0)
471-
.child(0);
472-
473-
if (
474-
nestedChild.type.name === "bulletListItem" ||
475-
nestedChild.type.name === "numberedListItem"
476-
) {
477-
content.push(f.child(i + 1));
478-
f = removeChild(f, i + 1);
479-
}
480-
}
481-
}
482-
const container = view.state.schema.nodes.blockContainer.create(
483-
undefined,
484-
content
485-
);
486-
f = f.replaceChild(i, container);
487-
}
488-
}
489-
490-
return new Slice(f, slice.openStart, slice.openEnd);
491-
},
449+
transformPasted,
492450
},
493451
};
494452

packages/core/src/transformPasted.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { Fragment, Slice } from "@tiptap/pm/model";
2+
import { EditorView } from "@tiptap/pm/view";
3+
4+
// helper function to remove a child from a fragment
5+
function removeChild(node: Fragment, n: number) {
6+
const children: any[] = [];
7+
node.forEach((child, _, i) => {
8+
if (i !== n) {
9+
children.push(child);
10+
}
11+
});
12+
return Fragment.from(children);
13+
}
14+
15+
/**
16+
* fix for https://github.com/ProseMirror/prosemirror/issues/1430#issuecomment-1822570821
17+
*
18+
* Without this fix, pasting two paragraphs would cause the second one to be indented in the other
19+
* this fix wraps every element in the slice in it's own blockContainer, to prevent Prosemirror from nesting the
20+
* elements on paste.
21+
*
22+
* The exception is when we encounter blockGroups with listitems, because those actually should be nested
23+
*/
24+
export function transformPasted(slice: Slice, view: EditorView) {
25+
let f = Fragment.from(slice.content);
26+
for (let i = 0; i < f.childCount; i++) {
27+
if (f.child(i).type.spec.group === "blockContent") {
28+
const content = [f.child(i)];
29+
30+
// when there is a blockGroup with lists, it should be nested in the new blockcontainer
31+
// (if we remove this if-block, the nesting bug will be fixed, but lists won't be nested correctly)
32+
if (
33+
i + 1 < f.childCount &&
34+
f.child(i + 1).type.spec.group === "blockGroup"
35+
) {
36+
const nestedChild = f
37+
.child(i + 1)
38+
.child(0)
39+
.child(0);
40+
41+
if (
42+
nestedChild.type.name === "bulletListItem" ||
43+
nestedChild.type.name === "numberedListItem"
44+
) {
45+
content.push(f.child(i + 1));
46+
f = removeChild(f, i + 1);
47+
}
48+
}
49+
const container = view.state.schema.nodes.blockContainer.create(
50+
undefined,
51+
content
52+
);
53+
f = f.replaceChild(i, container);
54+
}
55+
}
56+
57+
return new Slice(f, slice.openStart, slice.openEnd);
58+
}

0 commit comments

Comments
 (0)