UNPKG

@atlaskit/editor-plugin-copy-button

Version:

editor-plugin-copy-button for @atlaskit/editor-core

137 lines (134 loc) 3.94 kB
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin'; import { DecorationSet } from '@atlaskit/editor-prosemirror/view'; import { copyButtonPluginKey } from './plugin-key'; export function getMarkSelectionHelper({ $pos, markType }) { const hasMark = $pos.doc.rangeHasMark($pos.pos, Math.min($pos.pos + 1, $pos.doc.nodeSize), markType); if (!hasMark) { return false; } if ($pos.parent.childCount === 1) { const nodePosition = $pos.pos; const maybeNode = $pos.doc.nodeAt(nodePosition); if (!maybeNode || !maybeNode.isText) { return false; } const start = $pos.pos - $pos.parentOffset; const end = start + maybeNode.nodeSize; return { start, end }; } if ($pos.parent.childCount > 1) { const start = $pos.pos - $pos.textOffset; const maybeTextNode = $pos.doc.nodeAt(start); if (!maybeTextNode || !maybeTextNode.isText) { return false; } const end = start + maybeTextNode.nodeSize; return { start, end }; } return false; } function getMarkSelectionDecorationStartAndEnd({ markType, transaction }) { const anchorPositions = getMarkSelectionHelper({ $pos: transaction.selection.$anchor, markType }); if (anchorPositions) { return { ...anchorPositions, markType }; } const headPositions = getMarkSelectionHelper({ $pos: transaction.selection.$head, markType }); if (headPositions) { return { ...headPositions, markType }; } return undefined; } export function copyButtonPlugin() { return new SafePlugin({ key: copyButtonPluginKey, state: { init() { return { copied: false, markSelection: undefined }; }, apply(tr, currentPluginState) { const meta = tr.getMeta(copyButtonPluginKey); if ((meta === null || meta === void 0 ? void 0 : meta.copied) !== undefined) { return { copied: meta.copied, markSelection: undefined }; } if (meta !== null && meta !== void 0 && meta.showSelection) { return { copied: currentPluginState.copied, markSelection: getMarkSelectionDecorationStartAndEnd({ markType: meta.markType, transaction: tr }) }; } if (meta !== null && meta !== void 0 && meta.removeSelection) { return { copied: currentPluginState.copied, markSelection: undefined }; } if (currentPluginState.markSelection) { return { copied: currentPluginState.copied, markSelection: getMarkSelectionDecorationStartAndEnd({ markType: currentPluginState.markSelection.markType, transaction: tr }) }; } return currentPluginState; } }, props: { decorations(_state) { // Showing visual hints for the hyperlink copy button has been disabled // due to an issue where invalid hyperlink marks cause the floating toolbar // to jump around when the copy button is hovered. // See the following bug for details -- once that is resolved -- the visual // hints can be re enabled. // https://product-fabric.atlassian.net/browse/DTR-722 // const copyButtonPluginState = copyButtonPluginKey.getState( // state, // ) as CopyButtonPluginState; // if (copyButtonPluginState.markSelection) { // const { start, end } = copyButtonPluginState.markSelection; // return DecorationSet.create(state.doc, [ // Decoration.inline(start, end, { // class: 'ProseMirror-fake-text-selection', // }), // ]); // } return DecorationSet.empty; } } }); } export default copyButtonPlugin;