mirror of https://github.com/halo-dev/halo
[release-2.14] fix: code block content insertion location error (#5773)
* fix: code block content insertion location error * fix: code block content insertion location error --------- Co-authored-by: LIlGG <1103069291@qq.com>pull/5774/head
parent
dea79b2154
commit
8de668bb1a
|
@ -6,7 +6,13 @@ import {
|
||||||
findParentNode,
|
findParentNode,
|
||||||
VueNodeViewRenderer,
|
VueNodeViewRenderer,
|
||||||
} from "@/tiptap/vue-3";
|
} from "@/tiptap/vue-3";
|
||||||
import { EditorState, TextSelection, type Transaction } from "@/tiptap/pm";
|
import {
|
||||||
|
EditorState,
|
||||||
|
Plugin,
|
||||||
|
PluginKey,
|
||||||
|
TextSelection,
|
||||||
|
type Transaction,
|
||||||
|
} from "@/tiptap/pm";
|
||||||
import CodeBlockLowlight from "@tiptap/extension-code-block-lowlight";
|
import CodeBlockLowlight from "@tiptap/extension-code-block-lowlight";
|
||||||
import type { CodeBlockLowlightOptions } from "@tiptap/extension-code-block-lowlight";
|
import type { CodeBlockLowlightOptions } from "@tiptap/extension-code-block-lowlight";
|
||||||
import CodeBlockViewRenderer from "./CodeBlockViewRenderer.vue";
|
import CodeBlockViewRenderer from "./CodeBlockViewRenderer.vue";
|
||||||
|
@ -237,4 +243,70 @@ export default CodeBlockLowlight.extend<
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
addProseMirrorPlugins() {
|
||||||
|
return [
|
||||||
|
// Solve the paste problem. Because the upstream has not been
|
||||||
|
// able to deal with this problem for a long time, it is
|
||||||
|
// handled manually locally.
|
||||||
|
// see: https://github.com/ueberdosis/tiptap/pull/3606
|
||||||
|
new Plugin({
|
||||||
|
key: new PluginKey("codeBlockVSCodeHandlerFixPaste"),
|
||||||
|
props: {
|
||||||
|
handlePaste: (view, event) => {
|
||||||
|
if (!event.clipboardData) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// don’t 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, schema } = view.state;
|
||||||
|
|
||||||
|
// add text to code block
|
||||||
|
// strip carriage return chars from text pasted as code
|
||||||
|
// see: https://github.com/ProseMirror/prosemirror-view/commit/a50a6bcceb4ce52ac8fcc6162488d8875613aacd
|
||||||
|
const contentTextNode = schema.text(text.replace(/\r\n?/g, "\n"));
|
||||||
|
|
||||||
|
// create an empty code block
|
||||||
|
tr.replaceSelectionWith(
|
||||||
|
this.type.create({ language }, contentTextNode)
|
||||||
|
);
|
||||||
|
|
||||||
|
const { selection } = tr;
|
||||||
|
// Whether the current position is code block, if not, move forward to code block.
|
||||||
|
let codeBlockPos = Math.max(0, selection.from - 1);
|
||||||
|
while (
|
||||||
|
codeBlockPos > 0 &&
|
||||||
|
tr.doc.resolve(codeBlockPos).parent.type.name !== this.type.name
|
||||||
|
) {
|
||||||
|
codeBlockPos--;
|
||||||
|
}
|
||||||
|
// put cursor inside the newly created code block
|
||||||
|
tr.setSelection(TextSelection.near(tr.doc.resolve(codeBlockPos)));
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
...(this.parent?.() || []),
|
||||||
|
];
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue