UNPKG

@atlaskit/editor-common

Version:

A package that contains common classes and components for editor and renderer

106 lines (105 loc) 3.81 kB
import * as clipboard from 'clipboard-polyfill'; import { TextSelection } from '@atlaskit/editor-prosemirror/state'; import { ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '../analytics'; import { getAllSelectionAnalyticsPayload, getCellSelectionAnalyticsPayload, getNodeSelectionAnalyticsPayload, getRangeSelectionAnalyticsPayload } from '../selection'; const isClipboardApiSupported = () => !!navigator.clipboard && typeof navigator.clipboard.writeText === 'function'; const isIEClipboardApiSupported = () => window.clipboardData && typeof window.clipboardData.setData === 'function'; export const copyToClipboard = async textToCopy => { if (isClipboardApiSupported()) { try { await navigator.clipboard.writeText(textToCopy); } catch (error) { throw new Error('Clipboard api is not supported'); } } else if (isIEClipboardApiSupported()) { try { await window.clipboardData.setData('text', textToCopy); } catch (error) { throw new Error('IE clipboard api is not supported'); } } else { throw new Error('Clipboard api is not supported'); } }; export const copyHTMLToClipboard = async (elementToCopy, plainTextToCopy) => { // @ts-ignore if (isClipboardApiSupported() && typeof ClipboardItem !== 'undefined') { try { const data = new ClipboardItem({ 'text/plain': new Blob([plainTextToCopy || elementToCopy.innerText], { type: 'text/plain' }), 'text/html': new Blob([elementToCopy.innerHTML], { type: 'text/html' }) }); // @ts-ignore await navigator.clipboard.write([data]); } catch (error) { throw new Error('Clipboard api is not supported'); } } else if (typeof document !== undefined) { // ED-17083 extension copy seems have issue with ClipboardItem API // Hence of use of this polyfill copyHTMLToClipboardPolyfill(elementToCopy, plainTextToCopy); } }; // At the time of development, Firefox doesn't support ClipboardItem API // Hence of use of this polyfill export const copyHTMLToClipboardPolyfill = (elementToCopy, plainTextToCopy) => { const Clipboard = clipboard; const dt = new Clipboard.DT(); dt.setData('text/plain', plainTextToCopy || elementToCopy.innerText); dt.setData('text/html', elementToCopy.innerHTML); Clipboard.write(dt); }; export const getAnalyticsPayload = (state, action) => { const { selection, doc } = state; const selectionAnalyticsPayload = getNodeSelectionAnalyticsPayload(selection) || getRangeSelectionAnalyticsPayload(selection, doc) || getAllSelectionAnalyticsPayload(selection) || getCellSelectionAnalyticsPayload(state); if (selectionAnalyticsPayload) { const { actionSubjectId: selectionActionSubjectId } = selectionAnalyticsPayload; let content = []; switch (selectionActionSubjectId) { case ACTION_SUBJECT_ID.NODE: content.push(selectionAnalyticsPayload.attributes.node); break; case ACTION_SUBJECT_ID.RANGE: content.push(...selectionAnalyticsPayload.attributes.nodes); break; case ACTION_SUBJECT_ID.ALL: content.push('all'); break; case ACTION_SUBJECT_ID.CELL: { const { selectedCells } = selectionAnalyticsPayload.attributes; content.push(...Array(selectedCells).fill('tableCell')); break; } } return { eventType: EVENT_TYPE.TRACK, action, actionSubject: ACTION_SUBJECT.DOCUMENT, attributes: { content } }; } if (selection instanceof TextSelection && selection.$cursor) { return { eventType: EVENT_TYPE.TRACK, action, actionSubject: ACTION_SUBJECT.DOCUMENT, attributes: { content: ['caret'] } }; } };