-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Closed
Labels
Open SourceThe issue or pull reuqest is related to the open source packages of Tiptap.The issue or pull reuqest is related to the open source packages of Tiptap.
Description
Affected Packages
Vue TipTap
Version(s)
1.18.0
Bug Description
I need to write a block that could top-level other blocks.
For example, if the cursor is in a table cell and I would create a chunk, then the entire table would be wrapped in a chunk.
My implementation has bugs related to the fact that it is not allowed to merge or split a chunk. Each chunk is unique and has its own identifier.
The most common Uncaught TypeError in the current implementation is: Cannot read properties of null (reading 'nextSibling') and the phantom blocks remaining after deletion, although they are not in the doc.
Please help me fix this plugin, or maybe send me some similar ones. I'd be grateful!
I can't use newer versions of the package
Browser Used
Chrome
Code Example URL
No response
Expected Behavior
- The plugin must enable the creation of a "chunk" block that serves as a top-level container capable of wrapping other blocks.
- When a user initiates the creation of a chunk while the cursor is positioned within a nested or child element (e.g., a table cell), the plugin shall automatically wrap the entire parent structure (e.g., the full table) within the new chunk block.
- This wrapping operation must preserve the integrity and hierarchy of the wrapped blocks, ensuring no loss of content, structure, or attributes during the process.
- The plugin shall prohibit merging of multiple chunks into a single chunk.
- The plugin shall prohibit splitting a single chunk into multiple chunks.
Additional Context (Optional)
export default class Chunk extends Node {
get name() {
return 'chunk';
}
get schema() {
return {
attrs: {
title: {
default: '',
},
cid: {
default: '',
},
},
content: 'block+',
group: 'block',
defining: true,
draggable: false,
parseDOM: [
{
tag: 'chunk',
getAttrs: dom => ({
title: dom.getAttribute('title') '',
cid: dom.getAttribute('cid') '',
}),
},
],
toDOM: node => [
'chunk',
{
title: node.attrs.title,
cid: node.attrs.cid,
class: 'chunk-wrapper',
},
0,
],
};
}
commands({ type }) {
return {
createChunk: (attrs = {}) => (state, dispatch) => {
const blocksToWrap = findTopLevelBlocksToWrap(state);
if (blocksToWrap.length === 0) {
return false;
}
const startPos = blocksToWrap[0].start;
const endPos = blocksToWrap[blocksToWrap.length - 1].end;
const $start = state.doc.resolve(startPos);
const $end = state.doc.resolve(endPos);
const range = $start.blockRange($end);
if (!range) {
return false;
}
if (!type.validContent(state.doc.slice(range.start, range.end).content)) {
return false;
}
const tr = state.tr.wrap(range, [{ type, attrs }]);
if (dispatch) {
dispatch(tr);
}
return true;
},
deleteChunk: () => (state, dispatch) => {
const { $from } = state.selection;
let chunkPos = null;
let chunkNode = null;
for (let { depth } = $from; depth > 0; depth--) {
const node = $from.node(depth);
if (node.type.name === 'chunk') {
chunkNode = node;
chunkPos = $from.before(depth);
break;
}
}
if (!chunkNode) {
return false;
}
const chunkStart = chunkPos;
const chunkEnd = chunkPos + chunkNode.nodeSize;
const { tr } = state;
const chunkContent = chunkNode.content;
tr.replaceWith(chunkStart, chunkEnd, chunkContent);
if (dispatch) {
dispatch(tr);
}
return true;
},
};
}
}
export const findTopLevelBlocksToWrap = state => {
const { $from, $to } = state.selection;
const blocksToWrap = [];
state.doc.descendants((node, pos, parent, index) => {
if (parent === state.doc) {
const nodeStart = pos + 1;
const nodeEnd = pos + node.nodeSize;
if (nodeStart <= $to.pos && nodeEnd >= $from.pos && node.type.isBlock) {
blocksToWrap.push({
node,
start: nodeStart,
end: nodeEnd,
index,
});
}
}
});
blocksToWrap.sort((a, b) => a.index - b.index);
return blocksToWrap;
};
Dependency Updates
- Yes, I've updated all my dependencies.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Open SourceThe issue or pull reuqest is related to the open source packages of Tiptap.The issue or pull reuqest is related to the open source packages of Tiptap.
Type
Fields
Give feedbackNo fields configured for Bug.