tiptap: fix paste code

This commit is contained in:
fantasticit 2022-07-05 11:56:37 +08:00
parent 45d2026a43
commit 24f8f07f41
2 changed files with 7 additions and 63 deletions

View File

@ -242,59 +242,6 @@ export const BuiltInCodeBlock = Node.create<CodeBlockOptions>({
}), }),
]; ];
}, },
addProseMirrorPlugins() {
return [
// this plugin creates a code block for pasted content from VS Code
// we can also detect the copied code language
new Plugin({
key: new PluginKey('codeBlockVSCodeHandler'),
props: {
handlePaste: (view, event) => {
if (!event.clipboardData) {
return false;
}
// dont create a new code block within code blocks
if (this.editor.isActive(this.type.name)) {
return false;
}
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 (!text || !language) {
return false;
}
const { tr } = view.state;
// create an empty code block
tr.replaceSelectionWith(this.type.create({ language }));
// put cursor inside the newly created code block
tr.setSelection(TextSelection.near(tr.doc.resolve(Math.max(0, tr.selection.from - 2))));
// add text to code block
// strip carriage return chars from text pasted as code
// see: https://github.com/ProseMirror/prosemirror-view/commit/a50a6bcceb4ce52ac8fcc6162488d8875613aacd
tr.insertText(text.replace(/\r\n?/g, '\n'));
// store meta information
// this is useful for other plugins that depends on the paste event
// like the paste rule plugin
tr.setMeta('paste', true);
view.dispatch(tr);
return true;
},
},
}),
];
},
}); });
export interface CodeBlockLowlightOptions extends CodeBlockOptions { export interface CodeBlockLowlightOptions extends CodeBlockOptions {

View File

@ -2,7 +2,7 @@ import { Extension } from '@tiptap/core';
import { safeJSONParse } from 'helpers/json'; import { safeJSONParse } from 'helpers/json';
import { toggleMark } from 'prosemirror-commands'; import { toggleMark } from 'prosemirror-commands';
import { DOMParser, Fragment, Schema } from 'prosemirror-model'; import { DOMParser, Fragment, Schema } from 'prosemirror-model';
import { Plugin, PluginKey } from 'prosemirror-state'; import { Plugin, PluginKey, TextSelection } from 'prosemirror-state';
import { EXTENSION_PRIORITY_HIGHEST } from 'tiptap/core/constants'; import { EXTENSION_PRIORITY_HIGHEST } from 'tiptap/core/constants';
import { import {
debug, debug,
@ -132,15 +132,12 @@ export const Paste = Extension.create<IPasteOptions>({
if (pasteCodeLanguage && pasteCodeLanguage !== 'markdown') { if (pasteCodeLanguage && pasteCodeLanguage !== 'markdown') {
event.preventDefault(); event.preventDefault();
view.dispatch( const { tr } = view.state;
view.state.tr tr.replaceSelectionWith(view.state.schema.nodes.codeBlock.create({ language: pasteCodeLanguage }));
.replaceSelectionWith( tr.setSelection(TextSelection.near(tr.doc.resolve(Math.max(0, tr.selection.from - 2))));
view.state.schema.nodes.codeBlock.create({ tr.insertText(text.replace(/\r\n?/g, '\n'));
language: Object.keys(LANGUAGES).includes(vscodeMeta.mode) ? vscodeMeta.mode : null, tr.setMeta('paste', true);
}) view.dispatch(tr);
)
.insertText(text)
);
return true; return true;
} }