UNPKG

@atlaskit/editor-plugin-synced-block

Version:

SyncedBlock plugin for @atlaskit/editor-core

89 lines (88 loc) 5 kB
import type { INPUT_METHOD } from '@atlaskit/editor-common/analytics'; import { SafePlugin } from '@atlaskit/editor-common/safe-plugin'; import type { ExtractInjectionAPI, PMPluginFactoryParams } from '@atlaskit/editor-common/types'; import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state'; import { PluginKey } from '@atlaskit/editor-prosemirror/state'; import { DecorationSet } from '@atlaskit/editor-prosemirror/view'; import type { SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider'; import type { DeletionMechanism } from '@atlaskit/editor-synced-block-provider/common/types'; import type { SyncedBlockFeedbackContext, SyncedBlockPlugin, SyncedBlockPluginOptions } from '../syncedBlockPluginType'; import type { ActiveFlag, BodiedSyncBlockDeletionStatus, RetryCreationPosMap } from '../types'; export declare const syncedBlockPluginKey: PluginKey; /** * Dedicated transaction-meta {@link PluginKey} the synced-block removal command * sets so {@link getDeleteMechanism} can report a toolbar Delete as * `deleteButton` (otherwise indistinguishable from a keyboard delete — both are * plain ReplaceSteps). A separate key (rather than `syncedBlockPluginKey`, which * carries plugin-state transitions read in `apply()`, or a bare string) keeps * this transient signal uniquely namespaced and isolated. */ export declare const deleteMechanismMetaKey: PluginKey<DeletionMechanism>; /** * Creation-type signals set by {@link createSyncedBlock} on the creating * transaction. The async creation handler forwards them to the store manager, * which attaches them to the `syncedBlockCreate` event. A dedicated key keeps * this transient signal isolated from plugin state. */ export type SyncedBlockCreationMeta = { createdEmpty?: boolean; inputMethod?: INPUT_METHOD; }; export declare const creationMetaKey: PluginKey<SyncedBlockCreationMeta>; type SyncedBlockPluginState = { activeFlag: ActiveFlag; bodiedSyncBlockDeletionStatus?: BodiedSyncBlockDeletionStatus; /** * Tracks whether the document currently contains any synced block (source or * reference). When `false`, downstream work in `appendTransaction`, * `decorations`, and the `contentComponent` short-circuits to avoid the * per-transition feature tax on the ~99.97% of pages that have no synced * blocks (see EDITOR-6586). */ hasSyncedBlocks: boolean; hasUnsavedBodiedSyncBlockChanges?: boolean; /** * Cached previous values for shared-state signals. Used inside `apply()` to * detect when a status change requires a full rebuild of `statusDecorationSet` * instead of a cheap `map()` call. */ prevIsDragging: boolean; prevIsOffline: boolean; prevIsViewMode: boolean; retryCreationPosMap: RetryCreationPosMap; selectionDecorationSet: DecorationSet; /** * Cached decoration set for sync-block status decorations (offline overlay, * view-mode class, creation-loading spinner, drag border). When the perf * gate is ON this is computed in `apply()` and mapped through edits so the * `decorations` prop becomes an O(1) lookup instead of a full * `doc.descendants()` walk every transaction (see EDITOR-6930). */ statusDecorationSet: DecorationSet; syncBlockStore: SyncBlockStoreManager; }; /** * Derive how a source bodiedSyncBlock removal was performed, for the `mechanism` * analytics dimension. Each value names the user action; most-specific wins: * - `undo` / `redo` — history transaction. * - `deleteButton` — the explicit "Delete" control in the synced-block toolbar * (the removal command tags its transaction with {@link deleteMechanismMetaKey}). * - `selectionReplaced` — ReplaceStep on a node-selected block (the * accidental-overwrite path: block selected, then typed/pasted over). * - `keyboardDelete` — ReplaceStep removal at a caret/range selection * (Backspace/Delete key). * - `other` — anything else (unsync, conversion, code-dispatched, or a * structural `ReplaceAroundStep` such as wrap/lift/unwrap). * * Only a plain `ReplaceStep` counts as a direct user deletion. `ReplaceAroundStep` * is used for wrapping/lifting/unwrapping content, not direct removal, so a * removal carried by one is classified as `other` rather than misreported as a * keyboard delete. * * `state` is the pre-transaction state, so its selection reflects what was * selected when the edit was made. */ export declare const getDeleteMechanism: (tr: Transaction, state: EditorState) => DeletionMechanism; export declare const getPromptedFeedbackEntryPoint: (mechanism: DeletionMechanism) => SyncedBlockFeedbackContext['entryPoint'] | undefined; export declare const createPlugin: (options: SyncedBlockPluginOptions | undefined, pmPluginFactoryParams: PMPluginFactoryParams, syncBlockStore: SyncBlockStoreManager, api?: ExtractInjectionAPI<SyncedBlockPlugin>) => SafePlugin<SyncedBlockPluginState>; export {};