UNPKG

@atlaskit/editor-plugin-collab-edit

Version:

Collab Edit plugin for @atlaskit/editor-core

108 lines (105 loc) 5.14 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.initialize = void 0; var _memoizeOne = _interopRequireDefault(require("memoize-one")); var _transform = require("@atlaskit/editor-prosemirror/transform"); var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals"); var _pluginKey = require("../main/plugin-key"); var _trackNcsInitialization = require("../track-ncs-initialization"); var _handlers = require("./handlers"); var initCollab = function initCollab(collabEditProvider, view) { if (collabEditProvider.initialize) { collabEditProvider.initialize(function () { return view.state; }, function (json) { return _transform.Step.fromJSON(view.state.schema, json); }); } }; var initNewCollab = function initNewCollab(collabEditProvider, view, editorApi, onSyncUpError) { collabEditProvider.setup({ getState: function getState() { return view.state; }, editorApi: editorApi, onSyncUpError: onSyncUpError }); }; var initCollabMemo = (0, _memoizeOne.default)(initCollab); var initialize = exports.initialize = function initialize(_ref) { var options = _ref.options, providerFactory = _ref.providerFactory, view = _ref.view, featureFlags = _ref.featureFlags, editorAnalyticsApi = _ref.editorAnalyticsApi, pluginInjectionApi = _ref.pluginInjectionApi; return function (provider) { // eslint-disable-next-line prefer-const var cleanup; var pluginState = _pluginKey.pluginKey.getState(view.state); if (pluginState !== null && pluginState !== void 0 && pluginState.isReady && cleanup) { cleanup(); } cleanup = (0, _handlers.subscribe)(view, provider, options, featureFlags, providerFactory, editorAnalyticsApi); // Initialize provider if (options.useNativePlugin) { // ED-13912 For NCS we don't want to use memoizeOne because it causes // infinite text while changing page-width initNewCollab(provider, view, pluginInjectionApi, options.onSyncUpError); } else { /** * We only want to initialise once, if we reload/reconfigure this plugin * We dont want to re-init collab, it would break existing sessions */ initCollabMemo(provider, view); } // Rebind path: if the provider has already initialised (i.e. this view() // is running because the editor preset was reconfigured or the EditorView // was recreated mid-session, e.g. on a rich-text → markdown-mode flip), // the provider's `init` event has already fired and won't fire again. // Without intervention the freshly-attached collab plugin view never sees // `collabInitialised`, so `filterTransaction` silently drops every // doc-changing transaction and the editor appears read-only. // // PM `state.reconfigure` preserves plugin state by key, so in many cases // the plugin state survives and no action is needed; we only seed when // state was actually lost (e.g. EditorView recreated from scratch). // // Gated behind `cc-markdown-mode` (the same experiment that drives the // preset rebuild on convert); when off, behaviour is unchanged. Uses // `expValEquals` (not `*NoExposure`) so the editor's statsig client // enrols the user — otherwise an early rebind can race the FE-side // exposure and read the default (false), defeating the gate. The // experiment check is last so legacy providers (no `getInitPayload`) // short-circuit and don't fire an exposure. if (provider.getInitPayload && (0, _expValEquals.expValEquals)('cc-markdown-mode', 'isEnabled', true)) { var cachedInit = provider.getInitPayload(); if (cachedInit) { // Defer one microtask so the new pluginView is fully registered // before we dispatch (mirrors the timing of a real `init` event). Promise.resolve().then(function () { if (view.isDestroyed) { return; } var currentCollabState = _pluginKey.pluginKey.getState(view.state); var currentTrackState = _trackNcsInitialization.trackNCSInitializationPluginKey.getState(view.state); // State was preserved across reconfigure → nothing to do. if (currentCollabState !== null && currentCollabState !== void 0 && currentCollabState.isReady && currentTrackState !== null && currentTrackState !== void 0 && currentTrackState.collabInitialisedAt) { return; } // Seed the freshly-attached pluginView so `isReady` flips to true, // `data-has-collab-initialised` becomes "true", and downstream // listeners (analytics, sweet-state, track-ncs) re-receive init. // Note: we intentionally do NOT replay `handleInit` (which would // call `replaceDocument`) — the document is already in the editor // and replacing it would clobber any in-flight local steps. view.dispatch(view.state.tr.setMeta('collabInitialised', true)); }); } } return cleanup; }; };