UNPKG

@atlaskit/editor-plugin-limited-mode

Version:

LimitedMode plugin for @atlaskit/editor-core

77 lines (71 loc) 2.88 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 const 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. */ const shouldEnableLimitedModeForDocument = doc => { const nodeCountThreshold = LIMITED_MODE_DEFAULT_NODE_COUNT_THRESHOLD; const 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 let nodeCount = 0; let hasLcm = false; doc.descendants(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 const createPlugin = () => { return new SafePlugin({ key: limitedModePluginKey, view: _view => { return {}; }, state: { init(_config, editorState) { return { documentSizeBreachesThreshold: shouldEnableLimitedModeForDocument(editorState.doc) }; }, 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) }; } } }); };