feat: Add copy button to code selection, closes #6499
This commit is contained in:
@@ -15,6 +15,7 @@ import {
|
||||
ItalicIcon,
|
||||
OutdentIcon,
|
||||
IndentIcon,
|
||||
CopyIcon,
|
||||
} from "outline-icons";
|
||||
import { EditorState } from "prosemirror-state";
|
||||
import { isInTable } from "prosemirror-tables";
|
||||
@@ -171,5 +172,15 @@ export default function formattingMenuItems(
|
||||
label: isCodeBlock ? dictionary.comment : undefined,
|
||||
active: isMarkActive(schema.marks.comment),
|
||||
},
|
||||
{
|
||||
name: "separator",
|
||||
visible: isCode,
|
||||
},
|
||||
{
|
||||
name: "copyToClipboard",
|
||||
icon: <CopyIcon />,
|
||||
tooltip: dictionary.copy,
|
||||
visible: isCode,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
Schema,
|
||||
Node as ProsemirrorNode,
|
||||
} from "prosemirror-model";
|
||||
import { Command, Plugin, PluginKey } from "prosemirror-state";
|
||||
import { Command, Plugin, PluginKey, TextSelection } from "prosemirror-state";
|
||||
import { Decoration, DecorationSet } from "prosemirror-view";
|
||||
import refractor from "refractor/core";
|
||||
import bash from "refractor/lang/bash";
|
||||
@@ -74,6 +74,7 @@ import Prism from "../extensions/Prism";
|
||||
import { isCode } from "../lib/isCode";
|
||||
import { MarkdownSerializerState } from "../lib/markdown/serializer";
|
||||
import { findParentNode } from "../queries/findParentNode";
|
||||
import getMarkRange from "../queries/getMarkRange";
|
||||
import isInCode from "../queries/isInCode";
|
||||
import Node from "./Node";
|
||||
|
||||
@@ -193,16 +194,37 @@ export default class CodeFence extends Node {
|
||||
...attrs,
|
||||
});
|
||||
},
|
||||
copyToClipboard: (): Command => (state) => {
|
||||
copyToClipboard: (): Command => (state, dispatch) => {
|
||||
const codeBlock = findParentNode(isCode)(state.selection);
|
||||
|
||||
if (!codeBlock) {
|
||||
return false;
|
||||
if (codeBlock) {
|
||||
copy(codeBlock.node.textContent);
|
||||
toast.message(this.options.dictionary.codeCopied);
|
||||
return true;
|
||||
}
|
||||
|
||||
copy(codeBlock.node.textContent);
|
||||
toast.message(this.options.dictionary.codeCopied);
|
||||
return true;
|
||||
const { doc, tr } = state;
|
||||
const range =
|
||||
getMarkRange(
|
||||
doc.resolve(state.selection.from),
|
||||
this.editor.schema.marks.code_inline
|
||||
) ||
|
||||
getMarkRange(
|
||||
doc.resolve(state.selection.to),
|
||||
this.editor.schema.marks.code_inline
|
||||
);
|
||||
|
||||
if (range) {
|
||||
const $end = doc.resolve(range.to);
|
||||
tr.setSelection(new TextSelection($end, $end));
|
||||
dispatch?.(tr);
|
||||
|
||||
copy(tr.doc.textBetween(state.selection.from, state.selection.to));
|
||||
toast.message(this.options.dictionary.codeCopied);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user