UNPKG

@atlaskit/editor-common

Version:

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

180 lines (179 loc) • 5.97 kB
// Ignored via go/ees005 // eslint-disable-next-line import/no-namespace import * as clipboard from 'clipboard-polyfill'; import { TextSelection } from '@atlaskit/editor-prosemirror/state'; import { ACTION, 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 = () => // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-explicit-any window.clipboardData && typeof window.clipboardData.setData === 'function'; const isExtensionNode = node => { if (node === 'extension' || node === 'bodiedExtension' || node === 'inlineExtension' || node === 'multiBodiedExtension') { return true; } return false; }; 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 { // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-explicit-any 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 (!!document && typeof document === 'object') { try { // ED-17083 extension copy seems have issue with ClipboardItem API // Hence of use of this polyfill copyHTMLToClipboardPolyfill(elementToCopy, plainTextToCopy); } catch (error) { // eslint-disable-next-line no-console console.log(error); } } }; // At the time of development, Firefox doesn't support ClipboardItem API // Hence of use of this polyfill export const copyHTMLToClipboardPolyfill = async (elementToCopy, plainTextToCopy) => { const dt = new clipboard.ClipboardItem({ 'text/html': new Blob([elementToCopy.innerHTML], { type: 'text/html' }), 'text/plain': new Blob([plainTextToCopy || elementToCopy.innerText], { type: 'text/plain' }) }); await 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) { var _attributes; const { actionSubjectId: selectionActionSubjectId } = selectionAnalyticsPayload; const node = (_attributes = selectionAnalyticsPayload.attributes) === null || _attributes === void 0 ? void 0 : _attributes.node; const content = []; let extensionType; let extensionKey; switch (selectionActionSubjectId) { case ACTION_SUBJECT_ID.NODE: if (node) { content.push(node); if (isExtensionNode(node)) { extensionType = selection.node.attrs.extensionType; extensionKey = selection.node.attrs.extensionKey; } } break; case ACTION_SUBJECT_ID.RANGE: // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion content.push(...selectionAnalyticsPayload.attributes.nodes); break; case ACTION_SUBJECT_ID.ALL: content.push('all'); break; case ACTION_SUBJECT_ID.CELL: { // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const { selectedCells } = selectionAnalyticsPayload.attributes; content.push(...Array(selectedCells).fill('tableCell')); break; } } if (isExtensionNode(node)) { return { eventType: EVENT_TYPE.TRACK, action, actionSubject: ACTION_SUBJECT.DOCUMENT, attributes: { content, extensionKey, extensionType } }; } 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'] } }; } }; export const getNodeCopiedAnalyticsPayload = (node, inputMethod) => { const nodeType = node.type.name; let extensionType; let extensionKey; if (isExtensionNode(nodeType)) { extensionType = node.attrs.extensionType; extensionKey = node.attrs.extensionKey; } const payload = { eventType: EVENT_TYPE.TRACK, action: ACTION.COPIED, actionSubject: ACTION_SUBJECT.DOCUMENT, attributes: { content: [nodeType], inputMethod, nodeType, ...(extensionType ? { extensionType } : {}), ...(extensionKey ? { extensionKey } : {}) } }; return payload; };