UNPKG

@atlaskit/editor-plugin-code-block

Version:

Code block plugin for @atlaskit/editor-core

258 lines (254 loc) 10.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.copyContentToClipboardWithAnalytics = exports.copyContentToClipboard = exports.changeLanguage = void 0; exports.createInsertCodeBlockTransaction = createInsertCodeBlockTransaction; exports.ignoreFollowingMutations = void 0; exports.insertCodeBlockWithAnalytics = insertCodeBlockWithAnalytics; exports.toggleWordWrapStateForCodeBlockNode = exports.resetShouldIgnoreFollowingMutations = exports.resetCopiedState = exports.removeCodeBlockWithAnalytics = exports.removeCodeBlock = void 0; var _analytics = require("@atlaskit/editor-common/analytics"); var _clipboard = require("@atlaskit/editor-common/clipboard"); var _codeBlock = require("@atlaskit/editor-common/code-block"); var _editorAnalytics = require("@atlaskit/editor-common/editor-analytics"); var _insert = require("@atlaskit/editor-common/insert"); var _transforms = require("@atlaskit/editor-common/transforms"); var _state = require("@atlaskit/editor-prosemirror/state"); var _utils = require("@atlaskit/editor-prosemirror/utils"); var _actions = require("../pm-plugins/actions"); var _codeBlockCopySelectionPlugin = require("../pm-plugins/codeBlockCopySelectionPlugin"); var _pluginKey = require("../pm-plugins/plugin-key"); var _transformToCodeBlock = require("../pm-plugins/transform-to-code-block"); var removeCodeBlockWithAnalytics = exports.removeCodeBlockWithAnalytics = function removeCodeBlockWithAnalytics(editorAnalyticsAPI) { return (0, _editorAnalytics.withAnalytics)(editorAnalyticsAPI, { action: _analytics.ACTION.DELETED, actionSubject: _analytics.ACTION_SUBJECT.CODE_BLOCK, attributes: { inputMethod: _analytics.INPUT_METHOD.FLOATING_TB }, eventType: _analytics.EVENT_TYPE.TRACK })(removeCodeBlock); }; var removeCodeBlock = exports.removeCodeBlock = function removeCodeBlock(state, dispatch) { var nodes = state.schema.nodes, tr = state.tr; if (dispatch) { var removeTr = tr; if ((0, _utils.findSelectedNodeOfType)(nodes.codeBlock)(tr.selection)) { removeTr = (0, _utils.removeSelectedNode)(tr); } else { removeTr = (0, _utils.removeParentNodeOfType)(nodes.codeBlock)(tr); } dispatch(removeTr); } return true; }; var changeLanguage = exports.changeLanguage = function changeLanguage(editorAnalyticsAPI) { return function (language) { return function (state, dispatch) { var _pluginKey$getState; var codeBlock = state.schema.nodes.codeBlock; var pos = (_pluginKey$getState = _pluginKey.pluginKey.getState(state)) === null || _pluginKey$getState === void 0 ? void 0 : _pluginKey$getState.pos; if (typeof pos !== 'number') { return false; } var tr = state.tr.setNodeMarkup(pos, codeBlock, { language: language }).setMeta('scrollIntoView', false); var selection = (0, _utils.isNodeSelection)(state.selection) ? _state.NodeSelection.create(tr.doc, pos) : tr.selection; var result = tr.setSelection(selection); if (dispatch) { editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent({ action: _analytics.ACTION.LANGUAGE_SELECTED, actionSubject: _analytics.ACTION_SUBJECT.CODE_BLOCK, attributes: { language: language }, eventType: _analytics.EVENT_TYPE.TRACK })(result); dispatch(result); } return true; }; }; }; var copyContentToClipboardWithAnalytics = exports.copyContentToClipboardWithAnalytics = function copyContentToClipboardWithAnalytics(editorAnalyticsAPI) { return function (state, dispatch) { var nodes = state.schema.nodes, tr = state.tr; var codeBlock = (0, _utils.findParentNodeOfType)(nodes.codeBlock)(tr.selection); var textContent = codeBlock && codeBlock.node.textContent; if (textContent) { (0, _clipboard.copyToClipboard)(textContent); var copyToClipboardTr = tr; copyToClipboardTr.setMeta(_pluginKey.pluginKey, { type: _actions.ACTIONS.SET_COPIED_TO_CLIPBOARD, data: true }); copyToClipboardTr.setMeta(_codeBlockCopySelectionPlugin.copySelectionPluginKey, 'remove-selection'); if (editorAnalyticsAPI) { var analyticsPayload = (0, _clipboard.getAnalyticsPayload)(state, _analytics.ACTION.COPIED); if (analyticsPayload) { analyticsPayload.attributes.inputMethod = _analytics.INPUT_METHOD.FLOATING_TB; analyticsPayload.attributes.nodeType = codeBlock === null || codeBlock === void 0 ? void 0 : codeBlock.node.type.name; editorAnalyticsAPI.attachAnalyticsEvent(analyticsPayload)(copyToClipboardTr); } } if (dispatch) { dispatch(copyToClipboardTr); } } return true; }; }; var copyContentToClipboard = exports.copyContentToClipboard = function copyContentToClipboard(state, dispatch) { var nodes = state.schema.nodes, tr = state.tr; var codeBlock = (0, _utils.findParentNodeOfType)(nodes.codeBlock)(tr.selection); var textContent = codeBlock && codeBlock.node.textContent; if (textContent) { (0, _clipboard.copyToClipboard)(textContent); var copyToClipboardTr = tr; copyToClipboardTr.setMeta(_pluginKey.pluginKey, { type: _actions.ACTIONS.SET_COPIED_TO_CLIPBOARD, data: true }); copyToClipboardTr.setMeta(_codeBlockCopySelectionPlugin.copySelectionPluginKey, 'remove-selection'); if (dispatch) { dispatch(copyToClipboardTr); } } return true; }; var resetCopiedState = exports.resetCopiedState = function resetCopiedState(state, dispatch) { var tr = state.tr; var codeBlockState = _pluginKey.pluginKey.getState(state); var resetCopiedStateTr = tr; if (codeBlockState && codeBlockState.contentCopied) { resetCopiedStateTr.setMeta(_pluginKey.pluginKey, { type: _actions.ACTIONS.SET_COPIED_TO_CLIPBOARD, data: false }); resetCopiedStateTr.setMeta(_codeBlockCopySelectionPlugin.copySelectionPluginKey, 'remove-selection'); if (dispatch) { dispatch(resetCopiedStateTr); } } else { var clearSelectionStateTransaction = state.tr; clearSelectionStateTransaction.setMeta(_codeBlockCopySelectionPlugin.copySelectionPluginKey, 'remove-selection'); // note: dispatch should always be defined when called from the // floating toolbar. Howver the Command type which floating toolbar uses // (and resetCopiedState) uses suggests it's optional. if (dispatch) { dispatch(clearSelectionStateTransaction); } } return true; }; var ignoreFollowingMutations = exports.ignoreFollowingMutations = function ignoreFollowingMutations(state, dispatch) { var tr = state.tr; var ignoreFollowingMutationsTr = tr; ignoreFollowingMutationsTr.setMeta(_pluginKey.pluginKey, { type: _actions.ACTIONS.SET_SHOULD_IGNORE_FOLLOWING_MUTATIONS, data: true }); if (dispatch) { dispatch(ignoreFollowingMutationsTr); } return true; }; var resetShouldIgnoreFollowingMutations = exports.resetShouldIgnoreFollowingMutations = function resetShouldIgnoreFollowingMutations(state, dispatch) { var tr = state.tr; var ignoreFollowingMutationsTr = tr; ignoreFollowingMutationsTr.setMeta(_pluginKey.pluginKey, { type: _actions.ACTIONS.SET_SHOULD_IGNORE_FOLLOWING_MUTATIONS, data: false }); if (dispatch) { dispatch(ignoreFollowingMutationsTr); } return true; }; /** * This function creates a new transaction that inserts a code block, * if there is text selected it will wrap the current selection if not it will * append the codeblock to the end of the document. */ function createInsertCodeBlockTransaction(_ref) { var state = _ref.state; var tr = state.tr; var from = state.selection.from; var codeBlock = state.schema.nodes.codeBlock; var grandParentNode = state.selection.$from.node(-1); var grandParentNodeType = grandParentNode === null || grandParentNode === void 0 ? void 0 : grandParentNode.type; var parentNodeType = state.selection.$from.parent.type; /** We always want to append a codeBlock unless we're inserting into a paragraph * AND it's a valid child of the grandparent node. * Insert the current selection as codeBlock content unless it contains nodes other * than paragraphs and inline. */ var canInsertCodeBlock = (0, _insert.shouldSplitSelectedNodeOnNodeInsertion)({ parentNodeType: parentNodeType, grandParentNodeType: grandParentNodeType, content: codeBlock.createAndFill() }) && (0, _insert.contentAllowedInCodeBlock)(state); if (canInsertCodeBlock) { tr = (0, _transformToCodeBlock.transformToCodeBlockAction)(state, from, undefined); } else { (0, _utils.safeInsert)(codeBlock.createAndFill())(tr).scrollIntoView(); } return tr; } function insertCodeBlockWithAnalytics(inputMethod, analyticsAPI) { return (0, _editorAnalytics.withAnalytics)(analyticsAPI, { action: _analytics.ACTION.INSERTED, actionSubject: _analytics.ACTION_SUBJECT.DOCUMENT, actionSubjectId: _analytics.ACTION_SUBJECT_ID.CODE_BLOCK, attributes: { inputMethod: inputMethod }, eventType: _analytics.EVENT_TYPE.TRACK })(function (state, dispatch) { var tr = createInsertCodeBlockTransaction({ state: state }); if (dispatch) { dispatch(tr); } return true; }); } /** * Add the given node to the codeBlockWrappedStates WeakMap with the toggle boolean value. */ var toggleWordWrapStateForCodeBlockNode = exports.toggleWordWrapStateForCodeBlockNode = function toggleWordWrapStateForCodeBlockNode(editorAnalyticsAPI) { return function (state, dispatch) { var _findCodeBlock; var codeBlockNode = (_findCodeBlock = (0, _transforms.findCodeBlock)(state)) === null || _findCodeBlock === void 0 ? void 0 : _findCodeBlock.node; var tr = state.tr; if (!_codeBlock.codeBlockWrappedStates || !codeBlockNode) { return false; } var updatedToggleState = !(0, _codeBlock.isCodeBlockWordWrapEnabled)(codeBlockNode); _codeBlock.codeBlockWrappedStates.set(codeBlockNode, updatedToggleState); tr.setMeta(_pluginKey.pluginKey, { type: _actions.ACTIONS.SET_IS_WRAPPED, data: updatedToggleState }); if (dispatch) { editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent({ action: _analytics.ACTION.TOGGLE_CODE_BLOCK_WRAP, actionSubject: _analytics.ACTION_SUBJECT.CODE_BLOCK, attributes: { platform: _analytics.PLATFORMS.WEB, mode: _analytics.MODE.EDITOR, wordWrapEnabled: updatedToggleState, codeBlockNodeSize: codeBlockNode.nodeSize }, eventType: _analytics.EVENT_TYPE.TRACK })(tr); dispatch(tr); } return true; }; };