UNPKG

@atlaskit/editor-plugin-show-diff

Version:

ShowDiff plugin for @atlaskit/editor-core

179 lines (177 loc) 10.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.showDiffPluginKey = exports.createPlugin = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _processRawValue = require("@atlaskit/editor-common/process-raw-value"); var _safePlugin = require("@atlaskit/editor-common/safe-plugin"); var _state2 = require("@atlaskit/editor-prosemirror/state"); var _transform = require("@atlaskit/editor-prosemirror/transform"); var _view = require("@atlaskit/editor-prosemirror/view"); var _platformFeatureFlags = require("@atlaskit/platform-feature-flags"); var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals"); var _calculateDiffDecorations = require("./calculateDiff/calculateDiffDecorations"); var _enforceCustomStepRegisters = require("./enforceCustomStepRegisters"); var _getScrollableDecorations = require("./getScrollableDecorations"); var _NodeViewSerializer = require("./NodeViewSerializer"); var _scrollToActiveDecoration = require("./scrollToActiveDecoration"); function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var showDiffPluginKey = exports.showDiffPluginKey = new _state2.PluginKey('showDiffPlugin'); var createPlugin = exports.createPlugin = function createPlugin(config, getIntl, api) { if ((0, _platformFeatureFlags.fg)('platform_editor_show_diff_equality_fallback')) { (0, _enforceCustomStepRegisters.enforceCustomStepRegisters)(); } var nodeViewSerializer = new _NodeViewSerializer.NodeViewSerializer({}); var setNodeViewSerializer = function setNodeViewSerializer(editorView) { nodeViewSerializer.init({ editorView: editorView }); }; return new _safePlugin.SafePlugin({ key: showDiffPluginKey, state: { init: function init(_, _state) { // We do initial setup after we setup the editor view return _objectSpread({ steps: [], originalDoc: undefined, decorations: _view.DecorationSet.empty, isDisplayingChanges: false }, (0, _expValEquals.expValEquals)('platform_editor_diff_plugin_extended', 'isEnabled', true) ? { isInverted: false, diffType: 'inline' } : {}); }, apply: function apply(tr, currentPluginState, oldState, newState) { var meta = tr.getMeta(showDiffPluginKey); var newPluginState = currentPluginState; if (meta) { if ((meta === null || meta === void 0 ? void 0 : meta.action) === 'SHOW_DIFF') { var _newPluginState, _newPluginState2; // Update the plugin state with the new metadata newPluginState = _objectSpread(_objectSpread(_objectSpread({}, currentPluginState), meta), {}, { isDisplayingChanges: true, activeIndex: undefined }); // Calculate and store decorations in state var decorations = (0, _calculateDiffDecorations.calculateDiffDecorations)(_objectSpread({ state: newState, pluginState: newPluginState, nodeViewSerializer: nodeViewSerializer, colorScheme: config === null || config === void 0 ? void 0 : config.colorScheme, intl: getIntl(), activeIndexPos: (0, _platformFeatureFlags.fg)('platform_editor_show_diff_scroll_navigation') ? newPluginState.activeIndexPos : undefined, api: api }, (0, _expValEquals.expValEquals)('platform_editor_diff_plugin_extended', 'isEnabled', true) ? { isInverted: (_newPluginState = newPluginState) === null || _newPluginState === void 0 ? void 0 : _newPluginState.isInverted, diffType: (_newPluginState2 = newPluginState) === null || _newPluginState2 === void 0 ? void 0 : _newPluginState2.diffType } : {})); // Update the decorations newPluginState.decorations = decorations; } else if ((meta === null || meta === void 0 ? void 0 : meta.action) === 'HIDE_DIFF') { newPluginState = _objectSpread(_objectSpread(_objectSpread({}, currentPluginState), meta), {}, { decorations: _view.DecorationSet.empty, isDisplayingChanges: false, activeIndex: undefined }, (0, _expValEquals.expValEquals)('platform_editor_diff_plugin_extended', 'isEnabled', true) ? { isInverted: false, diffType: 'inline' } : {}); } else if (((meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_NEXT' || (meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_PREVIOUS') && (0, _platformFeatureFlags.fg)('platform_editor_show_diff_scroll_navigation')) { // Update the active index in plugin state and recalculate decorations var _decorations = (0, _getScrollableDecorations.getScrollableDecorations)(currentPluginState.decorations, newState.doc); if (_decorations.length > 0) { var _currentPluginState$a; // Initialize to -1 if undefined so that the first "next" scroll takes us to index 0 (first change). // This allows the UI to start with no selection and only highlight on first user interaction. var nextIndex = (_currentPluginState$a = currentPluginState.activeIndex) !== null && _currentPluginState$a !== void 0 ? _currentPluginState$a : -1; if (meta.action === 'SCROLL_TO_NEXT') { nextIndex = (nextIndex + 1) % _decorations.length; } else { // Handle scrolling backwards from the uninitialized state. // If at -1 (no selection), wrap to the last decoration. if (nextIndex === -1) { nextIndex = _decorations.length - 1; } else { nextIndex = (nextIndex - 1 + _decorations.length) % _decorations.length; } } var activeDecoration = _decorations[nextIndex]; newPluginState = _objectSpread(_objectSpread({}, currentPluginState), {}, { activeIndex: nextIndex, activeIndexPos: activeDecoration ? { from: activeDecoration.from, to: activeDecoration.to } : undefined }); // Recalculate decorations with the new active index var updatedDecorations = (0, _calculateDiffDecorations.calculateDiffDecorations)(_objectSpread({ state: newState, pluginState: newPluginState, nodeViewSerializer: nodeViewSerializer, colorScheme: config === null || config === void 0 ? void 0 : config.colorScheme, intl: getIntl(), activeIndexPos: newPluginState.activeIndexPos, api: api }, (0, _expValEquals.expValEquals)('platform_editor_diff_plugin_extended', 'isEnabled', true) ? { isInverted: newPluginState.isInverted } : {})); newPluginState.decorations = updatedDecorations; } } else { newPluginState = _objectSpread(_objectSpread({}, currentPluginState), meta); } } return _objectSpread(_objectSpread({}, newPluginState), {}, { decorations: newPluginState.decorations.map(tr.mapping, tr.doc) }); } }, view: function view(editorView) { setNodeViewSerializer(editorView); var isFirst = true; var previousActiveIndex; var cancelPendingScrollToDecoration = null; return { update: function update(view) { // If we're using configuration to show diffs we initialise here once we setup the editor view if (config !== null && config !== void 0 && config.originalDoc && config !== null && config !== void 0 && config.steps && config.steps.length > 0 && isFirst) { isFirst = false; view.dispatch(view.state.tr.setMeta(showDiffPluginKey, { action: 'SHOW_DIFF', steps: config.steps.map(function (step) { return _transform.Step.fromJSON(view.state.schema, step); }), originalDoc: (0, _processRawValue.processRawValue)(view.state.schema, config.originalDoc) })); } // Check for any potential scroll side-effects if ((0, _platformFeatureFlags.fg)('platform_editor_show_diff_scroll_navigation')) { var pluginState = showDiffPluginKey.getState(view.state); var activeIndexChanged = (pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex) !== undefined && pluginState.activeIndex !== previousActiveIndex; previousActiveIndex = pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex; if ((pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex) !== undefined && activeIndexChanged) { var _cancelPendingScrollT; (_cancelPendingScrollT = cancelPendingScrollToDecoration) === null || _cancelPendingScrollT === void 0 || _cancelPendingScrollT(); cancelPendingScrollToDecoration = (0, _scrollToActiveDecoration.scrollToActiveDecoration)(view, (0, _getScrollableDecorations.getScrollableDecorations)(pluginState.decorations, view.state.doc), pluginState.activeIndex); } } }, destroy: function destroy() { var _cancelPendingScrollT2; (_cancelPendingScrollT2 = cancelPendingScrollToDecoration) === null || _cancelPendingScrollT2 === void 0 || _cancelPendingScrollT2(); cancelPendingScrollToDecoration = null; } }; }, props: { decorations: function decorations(state) { var pluginState = showDiffPluginKey.getState(state); return pluginState === null || pluginState === void 0 ? void 0 : pluginState.decorations; } } }); };