Skip to content

Commit

Permalink
fix(Clipboard): copy only text content from codeblock (#204)
Browse files Browse the repository at this point in the history
  • Loading branch information
d3m1d0v authored Mar 1, 2024
1 parent c7f4442 commit 39dd5d3
Showing 1 changed file with 22 additions and 10 deletions.
32 changes: 22 additions & 10 deletions src/extensions/behavior/Clipboard/clipboard.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Fragment, Schema, Slice} from 'prosemirror-model';
import {Fragment, Node, ResolvedPos, Schema, Slice} from 'prosemirror-model';
import {EditorState, Plugin, Selection} from 'prosemirror-state';
import type {EditorView} from 'prosemirror-view';

Expand Down Expand Up @@ -192,20 +192,28 @@ function getSliceFromMarkupFragment(fragment: Fragment) {

type SerializeResult = {
text: string;
html: string;
markup: string;
html?: string;
markup?: string;
};
function serializeSelected(view: EditorView, serializer: Serializer): SerializeResult | null {
if (view.state.selection.empty) return null;
const sel = view.state.selection;

if (sel.empty) return null;

if (getSharedDepthNode(sel).type.spec.code) {
const fragment = sel.content().content;
return {text: fragment.textBetween(0, fragment.size)};
}

const markup = serializer.serialize(getCopyContent(view.state).content);
const {dom, text} = serializeForClipboard(view, view.state.selection.content());
const {dom, text} = serializeForClipboard(view, sel.content());
return {markup, text, html: dom.innerHTML};
}

function setClipboardData(data: DataTransfer, result: SerializeResult) {
data.clearData();
data.setData(DataTransferType.Yfm, result.markup);
data.setData(DataTransferType.Html, result.html);
if (typeof result.markup === 'string') data.setData(DataTransferType.Yfm, result.markup);
if (typeof result.html === 'string') data.setData(DataTransferType.Html, result.html);
data.setData(DataTransferType.Text, result.text);
}

Expand Down Expand Up @@ -297,9 +305,13 @@ function createFragmentFromInlineSelection(state: EditorState) {
* e.g. if select part of cut title it creates slice with yfm-cut –> yfm-cut-title -> selected text
* it works well with simple nodes, but to handle cases as described above, custom logic needed
*/
function getSelectionContent({$from, to}: Selection) {
const sharedNodeType = $from.node($from.sharedDepth(to)).type;
function getSelectionContent(sel: Selection) {
const sharedNodeType = getSharedDepthNode(sel).type;
const sharedNodeComplex = sharedNodeType.spec.complex;
const includeParents = sharedNodeComplex && sharedNodeComplex !== 'leaf';
return $from.doc.slice($from.pos, to, includeParents);
return sel.$from.doc.slice(sel.$from.pos, sel.to, includeParents);
}

function getSharedDepthNode({$from, $to}: {$from: ResolvedPos; $to: ResolvedPos}): Node {
return $from.node($from.sharedDepth($to.pos));
}

0 comments on commit 39dd5d3

Please sign in to comment.