UNPKG

@atlaskit/editor-plugin-limited-mode

Version:

LimitedMode plugin for @atlaskit/editor-core

77 lines (71 loc) 2.98 kB
import { LIMITED_MODE_DEFAULT_DOC_SIZE_THRESHOLD, LIMITED_MODE_DEFAULT_NODE_COUNT_THRESHOLD } from '@atlaskit/editor-common/limited-mode-document-thresholds'; import { SafePlugin } from '@atlaskit/editor-common/safe-plugin'; import { PluginKey } from '@atlaskit/editor-prosemirror/state'; export var limitedModePluginKey = new PluginKey('limitedModePlugin'); /** * Determines whether limited mode should be enabled for a document. * If this logic changes, update the duplicate in `editor-common/src/node-anchor/node-anchor-provider.ts` to avoid drift. * * Limited mode is activated when ANY of the following conditions are met: * 1. Document size exceeds `LIMITED_MODE_DEFAULT_DOC_SIZE_THRESHOLD` * 2. Node count exceeds `LIMITED_MODE_DEFAULT_NODE_COUNT_THRESHOLD` * 3. Document contains a legacy-content macro (LCM) * * Performance optimisations: * - Doc size is checked first (O(1)) - if it exceeds threshold, we skip traversal entirely. * - If we find an LCM during traversal, we exit early since limited mode will be enabled. */ var shouldEnableLimitedModeForDocument = function shouldEnableLimitedModeForDocument(doc) { var nodeCountThreshold = LIMITED_MODE_DEFAULT_NODE_COUNT_THRESHOLD; var docSizeThreshold = LIMITED_MODE_DEFAULT_DOC_SIZE_THRESHOLD; // Early exit: doc size exceeds threshold - O(1), no traversal needed if (doc.nodeSize > docSizeThreshold) { return true; } // Single traversal for node count and LCM detection var nodeCount = 0; var hasLcm = false; doc.descendants(function (node) { var _node$attrs; nodeCount += 1; if (((_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.extensionKey) === 'legacy-content') { hasLcm = true; // Early exit: LCM found — limited mode will be enabled return false; } }); // LCM condition takes precedence (if we early exited traversal, this is why) if (hasLcm) { return true; } // Check node count threshold if (nodeCount > nodeCountThreshold) { return true; } return false; }; export var createPlugin = function createPlugin() { return new SafePlugin({ key: limitedModePluginKey, view: function view(_view) { return {}; }, state: { init: function init(_config, editorState) { return { documentSizeBreachesThreshold: shouldEnableLimitedModeForDocument(editorState.doc) }; }, apply: function apply(tr, currentPluginState, _oldState, _newState) { // Don't check the document size if we're already in limited mode. // We ALWAYS want to re-check the document size if we're replacing the document (e.g. live-to-live page navigation). if (currentPluginState.documentSizeBreachesThreshold && !tr.getMeta('replaceDocument')) { return currentPluginState; } return { documentSizeBreachesThreshold: shouldEnableLimitedModeForDocument(tr.doc) }; } } }); };