Skip to content

Commit

Permalink
fix: some more error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Palanikannan1437 committed Apr 16, 2024
1 parent f7d7f3d commit bca46ea
Show file tree
Hide file tree
Showing 7 changed files with 429 additions and 367 deletions.
322 changes: 171 additions & 151 deletions packages/editor/core/src/ui/extensions/code/code-block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,85 +130,100 @@ export const CodeBlock = Node.create<CodeBlockOptions>({

// remove code block when at start of document or code block is empty
Backspace: () => {
const { empty, $anchor } = this.editor.state.selection;
const isAtStart = $anchor.pos === 1;
try {
const { empty, $anchor } = this.editor.state.selection;
const isAtStart = $anchor.pos === 1;

if (!empty || $anchor.parent.type.name !== this.name) {
return false;
}
if (!empty || $anchor.parent.type.name !== this.name) {
return false;
}

if (isAtStart || !$anchor.parent.textContent.length) {
return this.editor.commands.clearNodes();
}
if (isAtStart || !$anchor.parent.textContent.length) {
return this.editor.commands.clearNodes();
}

return false;
return false;
} catch (error) {
console.error("Error handling Backspace in code block:", error);
return false;
}
},

// exit node on triple enter
Enter: ({ editor }) => {
if (!this.options.exitOnTripleEnter) {
return false;
}
try {
if (!this.options.exitOnTripleEnter) {
return false;
}

const { state } = editor;
const { selection } = state;
const { $from, empty } = selection;
const { state } = editor;
const { selection } = state;
const { $from, empty } = selection;

if (!empty || $from.parent.type !== this.type) {
return false;
}
if (!empty || $from.parent.type !== this.type) {
return false;
}

const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2;
const endsWithDoubleNewline = $from.parent.textContent.endsWith("\n\n");
const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2;
const endsWithDoubleNewline = $from.parent.textContent.endsWith("\n\n");

if (!isAtEnd || !endsWithDoubleNewline) {
return false;
}
if (!isAtEnd || !endsWithDoubleNewline) {
return false;
}

return editor
.chain()
.command(({ tr }) => {
tr.delete($from.pos - 2, $from.pos);
return editor
.chain()
.command(({ tr }) => {
tr.delete($from.pos - 2, $from.pos);

return true;
})
.exitCode()
.run();
return true;
})
.exitCode()
.run();
} catch (error) {
console.error("Error handling Enter in code block:", error);
return false;
}
},

// exit node on arrow down
ArrowDown: ({ editor }) => {
if (!this.options.exitOnArrowDown) {
return false;
}
try {
if (!this.options.exitOnArrowDown) {
return false;
}

const { state } = editor;
const { selection, doc } = state;
const { $from, empty } = selection;
const { state } = editor;
const { selection, doc } = state;
const { $from, empty } = selection;

if (!empty || $from.parent.type !== this.type) {
return false;
}
if (!empty || $from.parent.type !== this.type) {
return false;
}

const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2;
const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2;

if (!isAtEnd) {
return false;
}
if (!isAtEnd) {
return false;
}

const after = $from.after();
const after = $from.after();

if (after === undefined) {
return false;
}
if (after === undefined) {
return false;
}

const nodeAfter = doc.nodeAt(after);
const nodeAfter = doc.nodeAt(after);

if (nodeAfter) {
if (nodeAfter) {
return false;
}

return editor.commands.exitCode();
} catch (error) {
console.error("Error handling ArrowDown in code block:", error);
return false;
}

return editor.commands.exitCode();
},
};
},
Expand Down Expand Up @@ -237,117 +252,122 @@ export const CodeBlock = Node.create<CodeBlockOptions>({
key: new PluginKey("codeBlockVSCodeHandlerCustom"),
props: {
handlePaste: (view, event) => {
if (!event.clipboardData) {
return false;
}

if (this.editor.isActive(this.type.name)) {
return false;
}

if (this.editor.isActive("code")) {
// Check if it's an inline code block
event.preventDefault();
const text = event.clipboardData.getData("text/plain");

if (!text) {
console.error("Pasted text is empty.");
try {
if (!event.clipboardData) {
return false;
}

const { tr } = view.state;
const { $from, $to } = tr.selection;

if ($from.pos > $to.pos) {
console.error("Invalid selection range.");
if (this.editor.isActive(this.type.name)) {
return false;
}

const docSize = tr.doc.content.size;
if ($from.pos < 0 || $to.pos > docSize) {
console.error("Selection range is out of document bounds.");
return false;
if (this.editor.isActive("code")) {
// Check if it's an inline code block
event.preventDefault();
const text = event.clipboardData.getData("text/plain");

if (!text) {
console.error("Pasted text is empty.");
return false;
}

const { tr } = view.state;
const { $from, $to } = tr.selection;

if ($from.pos > $to.pos) {
console.error("Invalid selection range.");
return false;
}

const docSize = tr.doc.content.size;
if ($from.pos < 0 || $to.pos > docSize) {
console.error("Selection range is out of document bounds.");
return false;
}

// Extend the current selection to replace it with the pasted text
// wrapped in an inline code mark
const codeMark = view.state.schema.marks.code.create();
tr.replaceWith($from.pos, $to.pos, view.state.schema.text(text, [codeMark]));
view.dispatch(tr);
return true;
}

// Extend the current selection to replace it with the pasted text
// wrapped in an inline code mark
const codeMark = view.state.schema.marks.code.create();
tr.replaceWith($from.pos, $to.pos, view.state.schema.text(text, [codeMark]));
view.dispatch(tr);
return true;
}

event.preventDefault();
const text = event.clipboardData.getData("text/plain");
const vscode = event.clipboardData.getData("vscode-editor-data");
const vscodeData = vscode ? JSON.parse(vscode) : undefined;
const language = vscodeData?.mode;

if (vscodeData && language) {
const { tr } = view.state;
const { $from } = tr.selection;

// Check if the current line is empty
const isCurrentLineEmpty = !$from.parent.textContent.trim();

let insertPos;
event.preventDefault();
const text = event.clipboardData.getData("text/plain");
const vscode = event.clipboardData.getData("vscode-editor-data");
const vscodeData = vscode ? JSON.parse(vscode) : undefined;
const language = vscodeData?.mode;

if (vscodeData && language) {
const { tr } = view.state;
const { $from } = tr.selection;

// Check if the current line is empty
const isCurrentLineEmpty = !$from.parent.textContent.trim();

let insertPos;

if (isCurrentLineEmpty) {
// If the current line is empty, use the current position
insertPos = $from.pos - 1;
} else {
// If the current line is not empty, insert below the current block node
insertPos = $from.end($from.depth) + 1;
}

// Ensure insertPos is within document bounds
if (insertPos < 0 || insertPos > tr.doc.content.size) {
console.error("Invalid insert position.");
return false;
}

// Create a new code block node with the pasted content
const textNode = view.state.schema.text(text.replace(/\r\n?/g, "\n"));
const codeBlock = this.type.create({ language }, textNode);
if (insertPos <= tr.doc.content.size) {
tr.insert(insertPos, codeBlock);
view.dispatch(tr);
return true;
}

if (isCurrentLineEmpty) {
// If the current line is empty, use the current position
insertPos = $from.pos - 1;
return false;
} else {
// If the current line is not empty, insert below the current block node
insertPos = $from.end($from.depth) + 1;
}

// Ensure insertPos is within document bounds
if (insertPos < 0 || insertPos > tr.doc.content.size) {
console.error("Invalid insert position.");
// // complicated paste logic, to be handled later
// const containsNewline = text.includes("\n");
// const isCurrentLineEmptyNode = isCurrentLineEmpty(view);
// if (!containsNewline) {
// console.log("run contians n");
// return false;
// }
//
// // Wrap the text in a div
// const html = `<div>${text.replace(/\r?\n/g, "<br>")}</div>`;
// let insertPos = view.state.selection.from;
//
// // Parse the HTML string to a ProseMirror document fragment
// const div = document.createElement("div");
// div.innerHTML = html;
// const domNode = div.firstChild;
// if (!domNode) {
// return false;
// }
// const fragment = DOMParser.fromSchema(view.state.schema).parse(domNode);
//
// if (isCurrentLineEmptyNode) {
// // If the current line is empty, use the current position
// insertPos = view.state.selection.from - 1;
// }
//
// // Insert the fragment into the document
// const transaction = view.state.tr.insert(insertPos, fragment);
// view.dispatch(transaction);
//
// return true;
return false;
}

// Create a new code block node with the pasted content
const textNode = view.state.schema.text(text.replace(/\r\n?/g, "\n"));
const codeBlock = this.type.create({ language }, textNode);
if (insertPos <= tr.doc.content.size) {
tr.insert(insertPos, codeBlock);
view.dispatch(tr);
return true;
}

return false;
} else {
// // complicated paste logic, to be handled later
// const containsNewline = text.includes("\n");
// const isCurrentLineEmptyNode = isCurrentLineEmpty(view);
// if (!containsNewline) {
// console.log("run contians n");
// return false;
// }
//
// // Wrap the text in a div
// const html = `<div>${text.replace(/\r?\n/g, "<br>")}</div>`;
// let insertPos = view.state.selection.from;
//
// // Parse the HTML string to a ProseMirror document fragment
// const div = document.createElement("div");
// div.innerHTML = html;
// const domNode = div.firstChild;
// if (!domNode) {
// return false;
// }
// const fragment = DOMParser.fromSchema(view.state.schema).parse(domNode);
//
// if (isCurrentLineEmptyNode) {
// // If the current line is empty, use the current position
// insertPos = view.state.selection.from - 1;
// }
//
// // Insert the fragment into the document
// const transaction = view.state.tr.insert(insertPos, fragment);
// view.dispatch(transaction);
//
// return true;
} catch (error) {
console.error("Error handling paste in CodeBlock extension:", error);
return false;
}
},
Expand Down
Loading

0 comments on commit bca46ea

Please sign in to comment.