Skip to content

Commit e2a095d

Browse files
Made BNDeleteBlock not set focus and selection, removed BNCreateOrUpdateBlock (#121)
1 parent 19faaae commit e2a095d

File tree

1 file changed

+77
-111
lines changed

1 file changed

+77
-111
lines changed

packages/core/src/extensions/Blocks/nodes/BlockContainer.ts

Lines changed: 77 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ export const BlockContainer = Node.create<IBlock>({
110110

111111
return true;
112112
},
113-
// Deletes a block at a given position and sets the selection to where the block was.
113+
// Deletes a block at a given position.
114114
BNDeleteBlock:
115115
(posInBlock) =>
116-
({ state, view, dispatch }) => {
116+
({ state, dispatch }) => {
117117
const blockInfo = getBlockInfoFromPos(state.doc, posInBlock);
118118
if (blockInfo === undefined) {
119119
return false;
@@ -123,10 +123,82 @@ export const BlockContainer = Node.create<IBlock>({
123123

124124
if (dispatch) {
125125
state.tr.deleteRange(startPos, endPos);
126-
state.tr.setSelection(
127-
new TextSelection(state.doc.resolve(startPos + 1))
126+
}
127+
128+
return true;
129+
},
130+
// Updates a block at a given position.
131+
BNUpdateBlock:
132+
(posInBlock, block) =>
133+
({ state, dispatch }) => {
134+
const blockInfo = getBlockInfoFromPos(state.doc, posInBlock);
135+
if (blockInfo === undefined) {
136+
return false;
137+
}
138+
139+
const { startPos, endPos, node, contentNode } = blockInfo;
140+
141+
if (dispatch) {
142+
// Adds blockGroup node with child blocks if necessary.
143+
if (block.children !== undefined) {
144+
const childNodes = [];
145+
146+
// Creates ProseMirror nodes for each child block, including their descendants.
147+
for (const child of block.children) {
148+
childNodes.push(blockToNode(child, state.schema));
149+
}
150+
151+
// Checks if a blockGroup node already exists.
152+
if (node.childCount === 2) {
153+
// Replaces all child nodes in the existing blockGroup with the ones created earlier.
154+
state.tr.replace(
155+
startPos + contentNode.nodeSize + 1,
156+
endPos - 1,
157+
new Slice(Fragment.from(childNodes), 0, 0)
158+
);
159+
} else {
160+
// Inserts a new blockGroup containing the child nodes created earlier.
161+
state.tr.insert(
162+
startPos + contentNode.nodeSize,
163+
state.schema.nodes["blockGroup"].create({}, childNodes)
164+
);
165+
}
166+
}
167+
168+
// Replaces the blockContent node's content if necessary.
169+
if (block.content !== undefined) {
170+
let content: PMNode[] = [];
171+
172+
// Checks if the provided content is a string or InlineContent[] type.
173+
if (typeof block.content === "string") {
174+
// Adds a single text node with no marks to the content.
175+
content.push(state.schema.text(block.content));
176+
} else {
177+
// Adds a text node with the provided styles converted into marks to the content, for each InlineContent
178+
// object.
179+
content = inlineContentToNodes(block.content, state.schema);
180+
}
181+
182+
// Replaces the contents of the blockContent node with the previously created text node(s).
183+
state.tr.replace(
184+
startPos + 1,
185+
startPos + contentNode.nodeSize - 1,
186+
new Slice(Fragment.from(content), 0, 0)
187+
);
188+
}
189+
190+
// Changes the block type and adds the provided props as node attributes. Also preserves all existing node
191+
// attributes that are compatible with the new type.
192+
state.tr.setNodeMarkup(
193+
startPos,
194+
block.type === undefined
195+
? undefined
196+
: state.schema.nodes[block.type],
197+
{
198+
...contentNode.attrs,
199+
...block.props,
200+
}
128201
);
129-
view.focus();
130202
}
131203

132204
return true;
@@ -283,112 +355,6 @@ export const BlockContainer = Node.create<IBlock>({
283355

284356
return true;
285357
},
286-
// Updates a block to the given specification.
287-
BNUpdateBlock:
288-
(posInBlock, block) =>
289-
({ state, dispatch }) => {
290-
const blockInfo = getBlockInfoFromPos(state.doc, posInBlock);
291-
if (blockInfo === undefined) {
292-
return false;
293-
}
294-
295-
const { startPos, endPos, node, contentNode } = blockInfo;
296-
297-
if (dispatch) {
298-
// Adds blockGroup node with child blocks if necessary.
299-
if (block.children !== undefined) {
300-
const childNodes = [];
301-
302-
// Creates ProseMirror nodes for each child block, including their descendants.
303-
for (const child of block.children) {
304-
childNodes.push(blockToNode(child, state.schema));
305-
}
306-
307-
// Checks if a blockGroup node already exists.
308-
if (node.childCount === 2) {
309-
// Replaces all child nodes in the existing blockGroup with the ones created earlier.
310-
state.tr.replace(
311-
startPos + contentNode.nodeSize + 1,
312-
endPos - 1,
313-
new Slice(Fragment.from(childNodes), 0, 0)
314-
);
315-
} else {
316-
// Inserts a new blockGroup containing the child nodes created earlier.
317-
state.tr.insert(
318-
startPos + contentNode.nodeSize,
319-
state.schema.nodes["blockGroup"].create({}, childNodes)
320-
);
321-
}
322-
}
323-
324-
// Replaces the blockContent node's content if necessary.
325-
if (block.content !== undefined) {
326-
let content: PMNode[] = [];
327-
328-
// Checks if the provided content is a string or InlineContent[] type.
329-
if (typeof block.content === "string") {
330-
// Adds a single text node with no marks to the content.
331-
content.push(state.schema.text(block.content));
332-
} else {
333-
// Adds a text node with the provided styles converted into marks to the content, for each InlineContent
334-
// object.
335-
content = inlineContentToNodes(block.content, state.schema);
336-
}
337-
338-
// Replaces the contents of the blockContent node with the previously created text node(s).
339-
state.tr.replace(
340-
startPos + 1,
341-
startPos + contentNode.nodeSize - 1,
342-
new Slice(Fragment.from(content), 0, 0)
343-
);
344-
}
345-
346-
// Changes the block type and adds the provided props as node attributes. Also preserves all existing node
347-
// attributes that are compatible with the new type.
348-
state.tr.setNodeMarkup(
349-
startPos,
350-
block.type === undefined
351-
? undefined
352-
: state.schema.nodes[block.type],
353-
{
354-
...contentNode.attrs,
355-
...block.props,
356-
}
357-
);
358-
}
359-
360-
return true;
361-
},
362-
// Updates a block to the given specification if it's empty, otherwise creates a new block from that specification
363-
// below it.
364-
BNCreateOrUpdateBlock:
365-
(posInBlock, block) =>
366-
({ state, chain }) => {
367-
const blockInfo = getBlockInfoFromPos(state.doc, posInBlock);
368-
if (blockInfo === undefined) {
369-
return false;
370-
}
371-
372-
const { node, startPos, endPos } = blockInfo;
373-
374-
if (node.textContent.length === 0) {
375-
const oldBlockContentPos = startPos + 1;
376-
377-
return chain()
378-
.BNUpdateBlock(posInBlock, block)
379-
.setTextSelection(oldBlockContentPos)
380-
.run();
381-
} else {
382-
const newBlockInsertionPos = endPos + 1;
383-
const newBlockContentPos = newBlockInsertionPos + 1;
384-
385-
return chain()
386-
.BNCreateBlock(newBlockInsertionPos)
387-
.BNUpdateBlock(newBlockContentPos, block)
388-
.setTextSelection(newBlockContentPos)
389-
.run();
390-
}
391-
},
392358
};
393359
},
394360

0 commit comments

Comments
 (0)