UNPKG

@atlaskit/editor-plugin-copy-button

Version:

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

163 lines (158 loc) • 7.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createToolbarCopyCommandForMark = createToolbarCopyCommandForMark; exports.createToolbarCopyCommandForNode = void 0; exports.getProvideMarkVisualFeedbackForCopyButtonCommand = getProvideMarkVisualFeedbackForCopyButtonCommand; exports.removeMarkVisualFeedbackForCopyButtonCommand = removeMarkVisualFeedbackForCopyButtonCommand; exports.resetCopiedState = void 0; var _enums = require("@atlaskit/editor-common/analytics/types/enums"); var _clipboard = require("@atlaskit/editor-common/clipboard"); var _copyButton = require("@atlaskit/editor-common/copy-button"); var _pluginKey = require("./plugin-key"); function createToolbarCopyCommandForMark(markType, editorAnalyticsApi) { function command(state, dispatch) { var textNode = state.tr.selection.$head.parent.maybeChild(state.tr.selection.$head.index()); if (!textNode) { return false; } if (dispatch) { // As calling copyHTMLToClipboard causes side effects -- we only run this when // dispatch is provided -- as otherwise the consumer is only testing to see if // the action is availble. var domNode = (0, _copyButton.toDOM)(textNode, state.schema); if (domNode) { var div = document.createElement('div'); var p = document.createElement('p'); div.appendChild(p); p.appendChild(domNode); // The "1 1" refers to the start and end depth of the slice // since we're copying the text inside a paragraph, it will always be 1 1 // https://github.com/ProseMirror/prosemirror-view/blob/master/src/clipboard.ts#L32 // Ignored via go/ees005 // eslint-disable-next-line @atlaskit/editor/no-as-casting div.firstChild.setAttribute('data-pm-slice', '1 1 []'); // If we're copying a hyperlink, we'd copy the url as the fallback plain text // Ignored via go/ees005 // eslint-disable-next-line @atlaskit/editor/no-as-casting var linkUrl = domNode.getAttribute('href'); (0, _clipboard.copyHTMLToClipboard)(div, markType.name === 'link' && linkUrl ? linkUrl : undefined); } var copyToClipboardTr = state.tr; copyToClipboardTr.setMeta(_pluginKey.copyButtonPluginKey, { copied: true }); var analyticsPayload = (0, _clipboard.getAnalyticsPayload)(state, _enums.ACTION.COPIED); if (analyticsPayload && editorAnalyticsApi) { var _editorAnalyticsApi$a; analyticsPayload.attributes.inputMethod = _enums.INPUT_METHOD.FLOATING_TB; analyticsPayload.attributes.markType = markType.name; editorAnalyticsApi === null || editorAnalyticsApi === void 0 || (_editorAnalyticsApi$a = editorAnalyticsApi.attachAnalyticsEvent) === null || _editorAnalyticsApi$a === void 0 || _editorAnalyticsApi$a.call(editorAnalyticsApi, analyticsPayload)(copyToClipboardTr); } dispatch(copyToClipboardTr); } return true; } return command; } function getProvideMarkVisualFeedbackForCopyButtonCommand(markType) { function provideMarkVisualFeedbackForCopyButtonCommand(state, dispatch) { var tr = state.tr; tr.setMeta(_pluginKey.copyButtonPluginKey, { showSelection: true, markType: markType }); if (dispatch) { dispatch(tr); } return true; } return provideMarkVisualFeedbackForCopyButtonCommand; } function removeMarkVisualFeedbackForCopyButtonCommand(state, dispatch) { var tr = state.tr; tr.setMeta(_pluginKey.copyButtonPluginKey, { removeSelection: true }); var copyButtonState = _pluginKey.copyButtonPluginKey.getState(state); if (copyButtonState !== null && copyButtonState !== void 0 && copyButtonState.copied) { tr.setMeta(_pluginKey.copyButtonPluginKey, { copied: false }); } if (dispatch) { dispatch(tr); } return true; } var createToolbarCopyCommandForNode = exports.createToolbarCopyCommandForNode = function createToolbarCopyCommandForNode(nodeType, editorAnalyticsApi, api, onClickMessage) { return function (state, dispatch) { var tr = state.tr, schema = state.schema; // This command should only be triggered by the Copy button in the floating toolbar // which is only visible when selection is inside the target node var contentNodeWithPos = (0, _copyButton.getSelectedNodeOrNodeParentByNodeType)({ nodeType: nodeType, selection: tr.selection }); if (!contentNodeWithPos) { return false; } var copyToClipboardTr = tr; copyToClipboardTr.setMeta(_pluginKey.copyButtonPluginKey, { copied: true }); var analyticsPayload = (0, _clipboard.getAnalyticsPayload)(state, _enums.ACTION.COPIED); if (analyticsPayload && editorAnalyticsApi) { var _editorAnalyticsApi$a2; analyticsPayload.attributes.inputMethod = _enums.INPUT_METHOD.FLOATING_TB; analyticsPayload.attributes.nodeType = contentNodeWithPos.node.type.name; editorAnalyticsApi === null || editorAnalyticsApi === void 0 || (_editorAnalyticsApi$a2 = editorAnalyticsApi.attachAnalyticsEvent) === null || _editorAnalyticsApi$a2 === void 0 || _editorAnalyticsApi$a2.call(editorAnalyticsApi, analyticsPayload)(copyToClipboardTr); } if (dispatch) { // As calling copyHTMLToClipboard causes side effects -- we only run this when // dispatch is provided -- as otherwise the consumer is only testing to see if // the action is availble. var domNode = (0, _copyButton.toDOM)(contentNodeWithPos.node, schema); (0, _copyButton.copyDomNode)(domNode, contentNodeWithPos.node.type, tr.selection); copyToClipboardTr.setMeta('scrollIntoView', false); dispatch(copyToClipboardTr); } /** * A11y-10275 This prop api drilled from the plugin all the way down to the usage * because it's the safest way to ensure accessibilityUtils is available and not * undefined. * * see thread https://atlassian.slack.com/archives/C02CDUS3SUS/p1744256326459569 */ if (onClickMessage) { var _api$accessibilityUti; api === null || api === void 0 || (_api$accessibilityUti = api.accessibilityUtils) === null || _api$accessibilityUti === void 0 || _api$accessibilityUti.actions.ariaNotify(onClickMessage, { priority: 'important' }); } return true; }; }; var resetCopiedState = exports.resetCopiedState = function resetCopiedState(nodeType, hoverDecoration, onMouseLeave) { return function (state, dispatch) { var customTr = state.tr; // Avoid multipe dispatch // https://product-fabric.atlassian.net/wiki/spaces/E/pages/2241659456/All+about+dispatch+and+why+there+shouldn+t+be+multiple#How-do-I-avoid-them%3F var customDispatch = function customDispatch(tr) { customTr = tr; }; onMouseLeave ? onMouseLeave(state, customDispatch) : hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(nodeType, false)(state, customDispatch); var copyButtonState = _pluginKey.copyButtonPluginKey.getState(state); if (copyButtonState !== null && copyButtonState !== void 0 && copyButtonState.copied) { customTr.setMeta(_pluginKey.copyButtonPluginKey, { copied: false }); } if (dispatch) { dispatch(customTr); } return true; }; };