UNPKG

@atlaskit/editor-plugin-block-menu

Version:

BlockMenu plugin for @atlaskit/editor-core

147 lines (144 loc) 7.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.transformNode = void 0; var _analytics = require("@atlaskit/editor-common/analytics"); var _expand = require("@atlaskit/editor-common/expand"); var _monitoring = require("@atlaskit/editor-common/monitoring"); var _performanceMeasures = require("@atlaskit/editor-common/performance-measures"); var _selection = require("@atlaskit/editor-common/selection"); var _state = require("@atlaskit/editor-prosemirror/state"); var _transform = require("@atlaskit/editor-prosemirror/transform"); var _editorTables = require("@atlaskit/editor-tables"); var _isNestedNode = require("../ui/utils/isNestedNode"); var _transform2 = require("./transform-node-utils/transform"); var _utils = require("./transform-node-utils/utils"); var transformNode = exports.transformNode = function transformNode(api) { return function (targetType, metadata) { return function (_ref) { var _api$blockControls; var tr = _ref.tr; var preservedSelection = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || (_api$blockControls = _api$blockControls.sharedState.currentState()) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.preservedSelection; if (!preservedSelection) { return tr; } var measureId = "transformNode_".concat(targetType.name, "_").concat(Date.now()); (0, _performanceMeasures.startMeasure)(measureId); var nodes = tr.doc.type.schema.nodes; var _expandSelectionToBlo = (0, _selection.expandSelectionToBlockRange)(preservedSelection), $from = _expandSelectionToBlo.$from, $to = _expandSelectionToBlo.$to; var selectedParent = $from.parent; var isParentLayout = selectedParent.type === nodes.layoutColumn; var isNested = (0, _isNestedNode.isNestedNode)(preservedSelection, '') && !isParentLayout; var isList = (0, _utils.isListNode)(selectedParent); var sourceNodes = (0, _selection.getSourceNodesFromSelectionRange)(tr, preservedSelection); var sourceNodeTypes = {}; sourceNodes.forEach(function (node) { var typeName = node.type.name; sourceNodeTypes[typeName] = (sourceNodeTypes[typeName] || 0) + 1; }); // Check if source node is empty paragraph or heading var isEmptyLine = sourceNodes.length === 1 && (sourceNodes[0].type === nodes.paragraph || sourceNodes[0].type === nodes.heading) && (sourceNodes[0].content.size === 0 || sourceNodes[0].textContent.trim() === ''); try { var resultNodes = (0, _transform2.convertNodesToTargetType)({ sourceNodes: sourceNodes, targetNodeType: targetType, schema: tr.doc.type.schema, isNested: isNested, targetAttrs: metadata === null || metadata === void 0 ? void 0 : metadata.targetAttrs, parentNode: selectedParent }); var content = resultNodes.length > 0 ? resultNodes : sourceNodes; var sliceStart = isList ? $from.pos - 1 : $from.pos; var expand = nodes.expand, nestedExpand = nodes.nestedExpand; content.forEach(function (node) { if (node.type === expand || node.type === nestedExpand) { _expand.expandedState.set(node, true); } }); if (preservedSelection instanceof _state.NodeSelection && preservedSelection.node.type === nodes.mediaSingle) { var _api$blockControls2; // when node is media single, use tr.replaceWith freeze editor, if modify position, tr.replaceWith creates duplicats var deleteFrom = $from.pos; var deleteTo = $to.pos; tr.delete(deleteFrom, deleteTo); // After deletion, recalculate the insertion position to ensure it's valid // especially when mediaSingle with caption is at the bottom of the document var insertPos = Math.min(deleteFrom, tr.doc.content.size); tr.insert(insertPos, content); // when we replace and insert content, we need to manually map the preserved selection // through the transaction, otherwise it will treat the selection as having been deleted // and stop preserving it var oldSize = sourceNodes.reduce(function (sum, node) { return sum + node.nodeSize; }, 0); var newSize = content.reduce(function (sum, node) { return sum + node.nodeSize; }, 0); api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || _api$blockControls2.commands.mapPreservedSelection(new _transform.Mapping([new _transform.StepMap([0, oldSize, newSize])]))({ tr: tr }); } else { tr.replaceWith(sliceStart, $to.pos, content); } if (preservedSelection instanceof _editorTables.CellSelection) { var insertedNode = tr.doc.nodeAt($from.pos); var isSelectable = insertedNode && _state.NodeSelection.isSelectable(insertedNode); if (isSelectable) { var _api$blockControls3; var nodeSelection = _state.NodeSelection.create(tr.doc, $from.pos); tr.setSelection(nodeSelection); api === null || api === void 0 || (_api$blockControls3 = api.blockControls) === null || _api$blockControls3 === void 0 || _api$blockControls3.commands.startPreservingSelection()({ tr: tr }); } } (0, _performanceMeasures.stopMeasure)(measureId, function (duration, startTime) { var _api$analytics; api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || (_api$analytics = _api$analytics.actions) === null || _api$analytics === void 0 || _api$analytics.attachAnalyticsEvent({ action: _analytics.ACTION.TRANSFORMED, actionSubject: _analytics.ACTION_SUBJECT.ELEMENT, attributes: { duration: duration, isEmptyLine: isEmptyLine, isNested: isNested, sourceNodesCount: sourceNodes.length, sourceNodesCountByType: sourceNodeTypes, sourceNodeType: sourceNodes.length === 1 ? sourceNodes[0].type.name : 'multiple', startTime: startTime, targetNodeType: targetType.name, outputNodesCount: content.length, inputMethod: _analytics.INPUT_METHOD.BLOCK_MENU }, eventType: _analytics.EVENT_TYPE.TRACK })(tr); }); } catch (error) { var _api$analytics2; (0, _performanceMeasures.stopMeasure)(measureId); (0, _monitoring.logException)(error, { location: 'editor-plugin-block-menu' }); api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || (_api$analytics2 = _api$analytics2.actions) === null || _api$analytics2 === void 0 || _api$analytics2.attachAnalyticsEvent({ action: _analytics.ACTION.ERRORED, actionSubject: _analytics.ACTION_SUBJECT.ELEMENT, actionSubjectId: _analytics.ACTION_SUBJECT_ID.TRANSFORM, eventType: _analytics.EVENT_TYPE.OPERATIONAL, attributes: { docSize: tr.doc.nodeSize, error: error.message, errorStack: error.stack, from: sourceNodes.length === 1 ? sourceNodes[0].type.name : 'multiple', inputMethod: _analytics.INPUT_METHOD.BLOCK_MENU, selection: preservedSelection.toJSON(), to: targetType.name } })(tr); } return tr; }; }; };