UNPKG

@atlaskit/editor-plugin-show-diff

Version:

ShowDiff plugin for @atlaskit/editor-core

178 lines (175 loc) • 9.14 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.showDiffPlugin = void 0; var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _unsafeExpValNoExposure = require("@atlaskit/platform-feature-experiments/unsafe-exp-val-no-exposure"); var _fg = require("@atlaskit/platform-feature-flags/fg"); var _attributions = require("./pm-plugins/decorations/colorSchemes/attributions"); var _getDeletedWidgets2 = require("./pm-plugins/getDeletedWidgets"); var _getScrollableDecorations = require("./pm-plugins/getScrollableDecorations"); var _main = require("./pm-plugins/main"); var _resolveDiffContributors = require("./pm-plugins/resolveDiffContributors"); var _revealAnimation = require("./pm-plugins/revealAnimation"); var _IndicatorBarContentComponent = require("./ui/IndicatorBar/IndicatorBarContentComponent"); var _excluded = ["stepsWithAttribution", "contributorProfiles"]; 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 normalizeShowDiffParams = function normalizeShowDiffParams(params) { if (!params || !('stepsWithAttribution' in params)) { // Clear contributors to prevent leaking from attributed to unattributed diffs. return params ? _objectSpread(_objectSpread({}, params), {}, { stepAttributions: [], contributors: undefined }) : params; } var stepsWithAttribution = params.stepsWithAttribution, contributorProfiles = params.contributorProfiles, rest = (0, _objectWithoutProperties2.default)(params, _excluded); return _objectSpread(_objectSpread({}, rest), {}, { // Resolve at boundary to keep contributor model and attribution format internal. contributors: (0, _attributions.areAttributionColorGatesEnabled)() ? (0, _attributions.resolveContributors)((0, _resolveDiffContributors.resolveDiffContributors)(stepsWithAttribution, contributorProfiles)) : undefined, steps: stepsWithAttribution.map(function (_ref) { var step = _ref.step; return step; }), stepAttributions: stepsWithAttribution.map(function (_ref2) { var stepAttribution = _ref2.stepAttribution; return stepAttribution; }) }); }; var prefersReducedMotion = function prefersReducedMotion() { return typeof window !== 'undefined' && typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches; }; /** * Resolve reveal preconditions once here so decorations and animation share one answer. If * decorations think a reveal is happening but animation doesn't, highlight paints hidden forever. * All preconditions resolved here (not just gate) ensures "unable to animate" means "do not reveal". * * Umbrella experiment: within the AI streaming UX M1 population this behaviour is only enabled * for the treatment cohort. Non-AI callers (track-changes, etc.) are not enrolled and default * to `true`, preserving the pre-umbrella baseline. */ var resolveReveal = function resolveReveal(reveal, editorView) { return ( // Gate first, so it is the primary switch and is always observable once a reveal is requested. reveal && (0, _fg.fg)('platform_editor_diff_reveal_animation') && (0, _unsafeExpValNoExposure.UNSAFE_expValNoExposure)('platform_editor_ai_streaming_ux_experience_m1', 'isEnabled', false) === true && editorView && typeof window !== 'undefined' && !prefersReducedMotion() ? reveal : undefined ); }; var showDiffPlugin = exports.showDiffPlugin = function showDiffPlugin(_ref3) { var api = _ref3.api, config = _ref3.config; // Captured from view lifecycle so read-only actions access state without exposing plugin key. var editorView; var setEditorView = function setEditorView(view) { editorView = view; }; return { name: 'showDiff', actions: { getDeletedWidgets: function getDeletedWidgets(range) { return editorView ? (0, _getDeletedWidgets2.getDeletedWidgets)(editorView.state, range) : []; } }, commands: { showDiff: function showDiff(params) { return function (_ref4) { var _api$userIntent; var tr = _ref4.tr; api === null || api === void 0 || (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 || _api$userIntent.commands.setCurrentUserIntent('viewingDiff')({ tr: tr }); var reveal = resolveReveal(params === null || params === void 0 ? void 0 : params.reveal, editorView); // Capture snapshot BEFORE transaction dispatch (last moment outgoing DOM exists). if (reveal && editorView) { var view = editorView; (0, _revealAnimation.beginReveal)({ editorView: view, reveal: reveal, onComplete: function onComplete() { // Repaint without the reveal so the decorations settle into their resting // style. Kept out of history: this is presentation, not an edit. view.dispatch(view.state.tr.setMeta(_main.showDiffPluginKey, { action: 'REVEAL_COMPLETE' }).setMeta('addToHistory', false)); } }); } return tr.setMeta(_main.showDiffPluginKey, _objectSpread(_objectSpread({}, normalizeShowDiffParams(params)), {}, { reveal: reveal, action: 'SHOW_DIFF' })); }; }, hideDiff: function hideDiff(_ref5) { var _api$userIntent2; var tr = _ref5.tr; if (editorView) { (0, _revealAnimation.cancelReveal)(editorView); } api === null || api === void 0 || (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 || _api$userIntent2.commands.setCurrentUserIntent('default')({ tr: tr }); return tr.setMeta(_main.showDiffPluginKey, { steps: [], stepAttributions: [], contributors: undefined, action: 'HIDE_DIFF' }); }, scrollToNext: function scrollToNext(_ref6) { var tr = _ref6.tr; return tr.setMeta(_main.showDiffPluginKey, { action: 'SCROLL_TO_NEXT' }); }, scrollToPrevious: function scrollToPrevious(_ref7) { var tr = _ref7.tr; return tr.setMeta(_main.showDiffPluginKey, { action: 'SCROLL_TO_PREVIOUS' }); } }, pmPlugins: function pmPlugins() { return [{ name: 'showDiffPlugin', // Contributor tags draw themselves into their own decoration widgets — plain DOM, so // no portal provider is needed here. plugin: function plugin(_ref8) { var getIntl = _ref8.getIntl; return (0, _main.createPlugin)(config, getIntl, api, setEditorView); } }]; }, contentComponent: function contentComponent() { // Rendered here sharing decoration anchor span DOM context (tags mount separately). return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_IndicatorBarContentComponent.IndicatorBarContentComponent, { api: api })); }, getSharedState: function getSharedState(editorState) { if (!editorState) { return { isDisplayingChanges: false, activeIndex: undefined, diffDescriptors: [] }; } var pluginState = _main.showDiffPluginKey.getState(editorState); var decorationCount = (0, _getScrollableDecorations.getScrollableDecorations)(pluginState === null || pluginState === void 0 ? void 0 : pluginState.decorations, editorState.doc); return { isDisplayingChanges: decorationCount.length > 0, activeIndex: pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex, numberOfChanges: decorationCount.length, contributorTags: pluginState === null || pluginState === void 0 ? void 0 : pluginState.contributorTags, diffDescriptors: pluginState === null || pluginState === void 0 ? void 0 : pluginState.diffDescriptors, showIndicators: pluginState === null || pluginState === void 0 ? void 0 : pluginState.showIndicators }; } }; };