Skip to content

Commit 99a4b3d

Browse files
Links as inline nodes (#111)
* links as inline nodes instead of marks * move unittests * add comments * Made partial block type optional * Added function to traverse all blocks * fix test names * fix ids + snaps * add comment * fix type * refactor links a bit (#109) --------- Co-authored-by: Matthew Lipski <[email protected]>
1 parent 79b6261 commit 99a4b3d

File tree

15 files changed

+641
-799
lines changed

15 files changed

+641
-799
lines changed

packages/core/src/api/Editor.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export class Editor {
2626
/**
2727
* Gets a list of all top-level blocks that are in the editor.
2828
*/
29-
public get allBlocks(): Block[] {
29+
public get topLevelBlocks(): Block[] {
3030
const blocks: Block[] = [];
3131

3232
this.tiptapEditor.state.doc.firstChild!.descendants((node) => {
@@ -38,6 +38,33 @@ export class Editor {
3838
return blocks;
3939
}
4040

41+
/**
42+
* Traverses all blocks in the editor, including all nested blocks, and executes a callback for each. The traversal is
43+
* depth-first, which is the same order as blocks appear in the editor by y-coordinate.
44+
* @param callback The callback to execute for each block.
45+
* @param reverse Whether the blocks should be traversed in reverse order.
46+
*/
47+
public allBlocks(
48+
callback: (block: Block) => void,
49+
reverse: boolean = false
50+
): void {
51+
function helper(blocks: Block[]) {
52+
if (reverse) {
53+
for (const block of blocks.reverse()) {
54+
helper(block.children);
55+
callback(block);
56+
}
57+
} else {
58+
for (const block of blocks) {
59+
callback(block);
60+
helper(block.children);
61+
}
62+
}
63+
}
64+
65+
helper(this.topLevelBlocks);
66+
}
67+
4168
/**
4269
* Gets information regarding the position of the text cursor in the editor.
4370
*/

packages/core/src/api/blockManipulation/__snapshots__/blockManipulation.test.ts.snap

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ exports[`Insert, Update, & Delete Blocks > Insert, update, & delete multiple blo
1010
{
1111
"styles": [],
1212
"text": "Nested Heading 1",
13+
"type": "text",
1314
},
1415
],
1516
"id": 2,
@@ -26,6 +27,7 @@ exports[`Insert, Update, & Delete Blocks > Insert, update, & delete multiple blo
2627
{
2728
"styles": [],
2829
"text": "Heading 1",
30+
"type": "text",
2931
},
3032
],
3133
"id": 1,
@@ -45,6 +47,7 @@ exports[`Insert, Update, & Delete Blocks > Insert, update, & delete multiple blo
4547
{
4648
"styles": [],
4749
"text": "Nested Heading 2",
50+
"type": "text",
4851
},
4952
],
5053
"id": 4,
@@ -61,6 +64,7 @@ exports[`Insert, Update, & Delete Blocks > Insert, update, & delete multiple blo
6164
{
6265
"styles": [],
6366
"text": "Heading 2",
67+
"type": "text",
6468
},
6569
],
6670
"id": 3,
@@ -96,6 +100,7 @@ exports[`Insert, Update, & Delete Blocks > Insert, update, & delete multiple blo
96100
{
97101
"styles": [],
98102
"text": "Nested Heading 1",
103+
"type": "text",
99104
},
100105
],
101106
"id": 2,
@@ -112,6 +117,7 @@ exports[`Insert, Update, & Delete Blocks > Insert, update, & delete multiple blo
112117
{
113118
"styles": [],
114119
"text": "Heading 1",
120+
"type": "text",
115121
},
116122
],
117123
"id": 1,
@@ -130,6 +136,7 @@ exports[`Insert, Update, & Delete Blocks > Insert, update, & delete multiple blo
130136
{
131137
"styles": [],
132138
"text": "Nested Heading 2",
139+
"type": "text",
133140
},
134141
],
135142
"id": 4,
@@ -146,6 +153,7 @@ exports[`Insert, Update, & Delete Blocks > Insert, update, & delete multiple blo
146153
{
147154
"styles": [],
148155
"text": "Heading 2",
156+
"type": "text",
149157
},
150158
],
151159
"id": 3,
@@ -179,6 +187,7 @@ exports[`Insert, Update, & Delete Blocks > Insert, update, & delete multiple blo
179187
{
180188
"styles": [],
181189
"text": "Heading 1",
190+
"type": "text",
182191
},
183192
],
184193
"id": 1,
@@ -211,6 +220,7 @@ exports[`Insert, Update, & Delete Blocks > Insert, update, & delete single block
211220
{
212221
"styles": [],
213222
"text": "Paragraph",
223+
"type": "text",
214224
},
215225
],
216226
"id": 1,
@@ -245,6 +255,7 @@ exports[`Insert, Update, & Delete Blocks > Insert, update, & delete single block
245255
{
246256
"styles": [],
247257
"text": "Paragraph",
258+
"type": "text",
248259
},
249260
],
250261
"id": 2,
@@ -267,6 +278,7 @@ exports[`Insert, Update, & Delete Blocks > Insert, update, & delete single block
267278
},
268279
],
269280
"text": "Heading ",
281+
"type": "text",
270282
},
271283
{
272284
"styles": [
@@ -278,6 +290,7 @@ exports[`Insert, Update, & Delete Blocks > Insert, update, & delete single block
278290
},
279291
],
280292
"text": "3",
293+
"type": "text",
281294
},
282295
],
283296
"id": 1,
@@ -340,6 +353,7 @@ exports[`Inserting Blocks with Different Placements > Insert after existing bloc
340353
{
341354
"styles": [],
342355
"text": "Nested Heading 1",
356+
"type": "text",
343357
},
344358
],
345359
"id": 2,
@@ -356,6 +370,7 @@ exports[`Inserting Blocks with Different Placements > Insert after existing bloc
356370
{
357371
"styles": [],
358372
"text": "Heading 1",
373+
"type": "text",
359374
},
360375
],
361376
"id": 1,
@@ -375,6 +390,7 @@ exports[`Inserting Blocks with Different Placements > Insert after existing bloc
375390
{
376391
"styles": [],
377392
"text": "Nested Heading 2",
393+
"type": "text",
378394
},
379395
],
380396
"id": 4,
@@ -391,6 +407,7 @@ exports[`Inserting Blocks with Different Placements > Insert after existing bloc
391407
{
392408
"styles": [],
393409
"text": "Heading 2",
410+
"type": "text",
394411
},
395412
],
396413
"id": 3,
@@ -426,6 +443,7 @@ exports[`Inserting Blocks with Different Placements > Insert before existing blo
426443
{
427444
"styles": [],
428445
"text": "Nested Heading 1",
446+
"type": "text",
429447
},
430448
],
431449
"id": 2,
@@ -442,6 +460,7 @@ exports[`Inserting Blocks with Different Placements > Insert before existing blo
442460
{
443461
"styles": [],
444462
"text": "Heading 1",
463+
"type": "text",
445464
},
446465
],
447466
"id": 1,
@@ -461,6 +480,7 @@ exports[`Inserting Blocks with Different Placements > Insert before existing blo
461480
{
462481
"styles": [],
463482
"text": "Nested Heading 2",
483+
"type": "text",
464484
},
465485
],
466486
"id": 4,
@@ -477,6 +497,7 @@ exports[`Inserting Blocks with Different Placements > Insert before existing blo
477497
{
478498
"styles": [],
479499
"text": "Heading 2",
500+
"type": "text",
480501
},
481502
],
482503
"id": 3,
@@ -514,6 +535,7 @@ exports[`Inserting Blocks with Different Placements > Insert nested inside exist
514535
{
515536
"styles": [],
516537
"text": "Nested Heading 1",
538+
"type": "text",
517539
},
518540
],
519541
"id": 2,
@@ -530,6 +552,7 @@ exports[`Inserting Blocks with Different Placements > Insert nested inside exist
530552
{
531553
"styles": [],
532554
"text": "Heading 1",
555+
"type": "text",
533556
},
534557
],
535558
"id": 1,
@@ -549,6 +572,7 @@ exports[`Inserting Blocks with Different Placements > Insert nested inside exist
549572
{
550573
"styles": [],
551574
"text": "Nested Heading 2",
575+
"type": "text",
552576
},
553577
],
554578
"id": 4,
@@ -565,6 +589,7 @@ exports[`Inserting Blocks with Different Placements > Insert nested inside exist
565589
{
566590
"styles": [],
567591
"text": "Heading 2",
592+
"type": "text",
568593
},
569594
],
570595
"id": 3,

packages/core/src/api/blockManipulation/blockManipulation.test.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ beforeEach(() => {
6666
];
6767

6868
insert = (placement) => {
69-
const existingBlock = editor.allBlocks[0];
69+
const existingBlock = editor.topLevelBlocks[0];
7070
editor.insertBlocks(multipleBlocks, existingBlock, placement);
7171

72-
return editor.allBlocks;
72+
return editor.topLevelBlocks;
7373
};
7474
});
7575

@@ -110,12 +110,12 @@ describe("Insert, Update, & Delete Blocks", () => {
110110
it("Insert, update, & delete single block", async () => {
111111
await waitForEditor();
112112

113-
const existingBlock = editor.allBlocks[0];
113+
const existingBlock = editor.topLevelBlocks[0];
114114
editor.insertBlocks([singleBlock], existingBlock);
115115

116-
expect(editor.allBlocks).toMatchSnapshot();
116+
expect(editor.topLevelBlocks).toMatchSnapshot();
117117

118-
const newBlock = editor.allBlocks[0];
118+
const newBlock = editor.topLevelBlocks[0];
119119
editor.updateBlock(newBlock, {
120120
type: "heading",
121121
props: {
@@ -124,6 +124,7 @@ describe("Insert, Update, & Delete Blocks", () => {
124124
},
125125
content: [
126126
{
127+
type: "text",
127128
text: "Heading ",
128129
styles: [
129130
{
@@ -135,6 +136,7 @@ describe("Insert, Update, & Delete Blocks", () => {
135136
],
136137
},
137138
{
139+
type: "text",
138140
text: "3",
139141
styles: [
140142
{
@@ -149,32 +151,32 @@ describe("Insert, Update, & Delete Blocks", () => {
149151
children: [singleBlock],
150152
});
151153

152-
expect(editor.allBlocks).toMatchSnapshot();
154+
expect(editor.topLevelBlocks).toMatchSnapshot();
153155

154-
const updatedBlock = editor.allBlocks[0];
156+
const updatedBlock = editor.topLevelBlocks[0];
155157
editor.removeBlocks([updatedBlock]);
156158

157-
expect(editor.allBlocks).toMatchSnapshot();
159+
expect(editor.topLevelBlocks).toMatchSnapshot();
158160
});
159161

160162
it("Insert, update, & delete multiple blocks", async () => {
161163
await waitForEditor();
162164

163-
const existingBlock = editor.allBlocks[0];
165+
const existingBlock = editor.topLevelBlocks[0];
164166
editor.insertBlocks(multipleBlocks, existingBlock);
165167

166-
expect(editor.allBlocks).toMatchSnapshot();
168+
expect(editor.topLevelBlocks).toMatchSnapshot();
167169

168-
const newBlock = editor.allBlocks[0];
170+
const newBlock = editor.topLevelBlocks[0];
169171
editor.updateBlock(newBlock, {
170172
type: "paragraph",
171173
});
172174

173-
expect(editor.allBlocks).toMatchSnapshot();
175+
expect(editor.topLevelBlocks).toMatchSnapshot();
174176

175-
const updatedBlocks = editor.allBlocks.slice(0, 2);
177+
const updatedBlocks = editor.topLevelBlocks.slice(0, 2);
176178
editor.removeBlocks([updatedBlocks[0].children[0], updatedBlocks[1]]);
177179

178-
expect(editor.allBlocks).toMatchSnapshot();
180+
expect(editor.topLevelBlocks).toMatchSnapshot();
179181
});
180182
});

packages/core/src/api/blockManipulation/blockManipulation.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { Editor } from "@tiptap/core";
22
import { Node } from "prosemirror-model";
33
import { Block, PartialBlock } from "../../extensions/Blocks/api/blockTypes";
4-
import { blockToNode, getNodeById } from "../nodeConversions/nodeConversions";
4+
import { blockToNode } from "../nodeConversions/nodeConversions";
5+
import { getNodeById } from "../util/nodeUtil";
56

67
export function insertBlocks(
78
blocksToInsert: PartialBlock[],

0 commit comments

Comments
 (0)