prosemirror-suggest
Advanced tools
Comparing version 1.0.0-next.3 to 1.0.0-next.4
# prosemirror-suggest | ||
## 1.0.0-next.4 | ||
> 2020-08-01 | ||
### Major Changes | ||
- 4463d117: **Rename `Suggestion` to `Suggester`** | ||
The name `Suggestion` implies something offered to a user. For example typing `@a` offers a | ||
suggestion to tag a certain username. Using `Suggestion` as the name for the configuration object | ||
is confusing. Going forward `Suggester` will be used as the name of the configuration object. | ||
The `Suggester` configures the editor to behave in a desired way so that it can provide | ||
suggestions to end users. | ||
**Make `prosemirror-state` and `prosemirror-keymap` peerDependencies.** | ||
Make all `@type/*` peer dependencies optional. | ||
Remove `@remirror/core-utils` from dependencies to avoid bloating the size. | ||
- 6c6d524e: **Breaking Changes** 💥 | ||
Rename `contains` to `containsNodesOfType`. | ||
Make `isValidPresetConstructor` internal only. | ||
Remove `EMPTY_CSS_VALUE`, `CSS_ROTATE_PATTERN` from `@remirror/core-constants`. | ||
Remove method: | ||
`clean() | coerce() | fragment() | markFactory() | nodeFactory() | offsetTags() | sequence() | slice() | text() | isTaggedNode() | replaceSelection()` | ||
and type: | ||
`BaseFactoryParameter | MarkWithAttributes | MarkWithoutAttributes | NodeWithAttributes | NodeWithoutAttributes | TagTracker | TaggedContent | TaggedContentItem | TaggedContentWithText | Tags` | ||
exports from `jest-remirror`. | ||
Remove `SPECIAL_INPUT_KEYS | SPECIAL_KEYS | SPECIAL_MENU_KEYS | SPECIAL_TOGGLE_BUTTON_KEYS` from | ||
`multishift`. | ||
### Minor Changes | ||
- 068d2e07: Allow runtime additions to the `prosemirror-suggest` plugin. | ||
You can now add suggester configurations to active suggest plugin instances. The name is used as | ||
an identifier and identical names will automatically be replaced. | ||
- 4eb56ecd: Make `removed` and `setMarkRemoved()` methods public on `SuggestState`. | ||
### Patch Changes | ||
- a7037832: Use exact versions for `@remirror` package `dependencies` and `peerDepedencies`. | ||
Closes #435 | ||
- dcccc5fc: Add browser entrypoint to packages and shrink bundle size. | ||
- 231f664b: Upgrade dependencies. | ||
- 6c6d524e: Remove use of `export *` for better tree shaking. | ||
Closes #406 | ||
- Updated dependencies [6528323e] | ||
- Updated dependencies [a7037832] | ||
- Updated dependencies [dcccc5fc] | ||
- Updated dependencies [231f664b] | ||
- Updated dependencies [6c6d524e] | ||
- Updated dependencies [6c6d524e] | ||
- @remirror/core-types@1.0.0-next.16 | ||
- @remirror/core-constants@1.0.0-next.16 | ||
- @remirror/core-helpers@1.0.0-next.16 | ||
## 1.0.0-next.3 | ||
@@ -4,0 +73,0 @@ |
@@ -37,5 +37,5 @@ /** | ||
* | ||
* `prosemirror-suggest` uses configuration objects called `Suggestion`'s to | ||
* `prosemirror-suggest` uses configuration objects called `Suggester`'s to | ||
* define the behaviour of the suggesters you create. By calling the exported | ||
* `suggest` method with all required `Suggestion`'s the functionality is added | ||
* `suggest` method with all required `Suggester`'s the functionality is added | ||
* to the editor in one plugin. | ||
@@ -48,3 +48,3 @@ * | ||
* ```ts | ||
* import { Suggestion, suggest } from 'prosemirror-suggest'; | ||
* import { Suggester, suggest } from 'prosemirror-suggest'; | ||
* | ||
@@ -56,3 +56,3 @@ * const maxResults = 10; | ||
* | ||
* const suggestEmojis: Suggestion = { | ||
* const suggestEmojis: Suggester = { | ||
* // By default decorations are used to highlight the currently matched | ||
@@ -115,7 +115,7 @@ * // suggestion in the dom. | ||
* // Create the plugin with the above configuration. It also supports multiple plugins being added. | ||
* const suggestionPlugin = suggest(suggestEmojis); | ||
* const suggestPlugin = suggest(suggestEmojis); | ||
* | ||
* // Include the plugin in the created editor state. | ||
* const state = EditorState.create({schema, | ||
* plugins: [suggestionPlugin], | ||
* plugins: [suggestPlugin], | ||
* }); | ||
@@ -151,6 +151,7 @@ * ``` | ||
*/ | ||
export * from './suggest-plugin'; | ||
export * from './suggest-types'; | ||
export * from './suggest-constants'; | ||
export * from './suggest-predicates'; | ||
export * from './suggest-helpers'; | ||
export type { SuggestState } from './suggest-plugin'; | ||
export { addSuggester, getSuggestPluginState, removeSuggester, suggest } from './suggest-plugin'; | ||
export type { AddIgnoredParameter, CompareMatchParameter, CreateSuggestCommandParameter, DocChangedParameter, FromToEndParameter, KeyboardEventParameter, MatchValue, OnKeyDownParameter, ReasonMatchParameter, ReasonParameter, RemoveIgnoredParameter, SuggestCallbackParameter, SuggestChangeHandlerMethod, SuggestChangeHandlerParameter, SuggestCharacterEntryMethod, SuggestCharacterEntryParameter, SuggestCommandParameter, SuggestExitHandlerMethod, SuggestExitHandlerParameter, SuggestIgnoreParameter, SuggestKeyBinding, SuggestKeyBindingMap, SuggestKeyBindingParameter, SuggestMarkParameter, SuggestReasonMap, SuggestReplacementType, SuggestStateMatch, SuggestStateMatchParameter, SuggestStateMatchReason, Suggester, SuggesterParameter, } from './suggest-types'; | ||
export { ChangeReason, ExitReason, DEFAULT_SUGGESTER } from './suggest-constants'; | ||
export { isChange, isChangeReason, isEntry, isExit, isExitReason, isInvalidSplitReason, isJump, isJumpReason, isMove, isRemovedReason, isSelectionExitReason, isSplitReason, isValidMatch, selectionOutsideMatch, } from './suggest-predicates'; | ||
export { createRegexFromSuggester, escapeChar, getRegexPrefix, regexToString, } from './suggest-helpers'; |
@@ -1,2 +0,2 @@ | ||
import { Suggestion } from './suggest-types'; | ||
import type { Suggester } from './suggest-types'; | ||
export declare const escapeChar: (char: string) => any; | ||
@@ -19,2 +19,2 @@ /** | ||
*/ | ||
export declare const createRegexFromSuggestion: ({ char, matchOffset, startOfLine, supportedCharacters, }: Pick<Required<Suggestion>, 'startOfLine' | 'char' | 'supportedCharacters' | 'matchOffset'>, flags?: string) => RegExp; | ||
export declare const createRegexFromSuggester: ({ char, matchOffset, startOfLine, supportedCharacters, }: Pick<Required<Suggester>, 'startOfLine' | 'char' | 'supportedCharacters' | 'matchOffset'>, flags?: string) => RegExp; |
import { Plugin } from 'prosemirror-state'; | ||
import { EditorSchema, EditorState } from '@remirror/core-types'; | ||
import type { EditorSchema, EditorState } from '@remirror/core-types'; | ||
import { SuggestState } from './suggest-state'; | ||
import { Suggestion } from './suggest-types'; | ||
import type { Suggester } from './suggest-types'; | ||
/** | ||
@@ -10,9 +10,21 @@ * Get the state of the suggest plugin. | ||
*/ | ||
export declare function getSuggestPluginState<Schema extends EditorSchema = any>(state: EditorState<Schema>): SuggestState; | ||
export declare function getSuggestPluginState(state: EditorState): SuggestState; | ||
/** | ||
* This creates a suggestion plugin with all the suggesters provided. | ||
* Add a new suggester or replace it if the name already exists in the existing | ||
* configuration. | ||
* | ||
* Will return a function for disposing of the added suggester. | ||
*/ | ||
export declare function addSuggester<Schema extends EditorSchema = any>(state: EditorState<Schema>, suggester: Suggester): () => void; | ||
/** | ||
* Remove a suggester if it exists. Pass in the name or the full suggester | ||
* object. | ||
*/ | ||
export declare function removeSuggester<Schema extends EditorSchema = any>(state: EditorState<Schema>, suggester: Suggester | string): void; | ||
/** | ||
* This creates a suggest plugin with all the suggesters provided. | ||
* | ||
* @remarks | ||
* | ||
* In the following example we're creating an emoji suggestion plugin that | ||
* In the following example we're creating an emoji suggest plugin that | ||
* responds to the colon character with a query and presents a list of matching | ||
@@ -22,3 +34,3 @@ * emojis based on the query typed so far. | ||
* ```ts | ||
* import { Suggestion, suggest } from 'prosemirror-suggest'; | ||
* import { Suggester, suggest } from 'prosemirror-suggest'; | ||
* | ||
@@ -30,3 +42,3 @@ * const maxResults = 10; | ||
* | ||
* const suggestEmojis: Suggestion = { | ||
* const suggestEmojis: Suggester = { | ||
* // By default decorations are used to highlight the currently matched | ||
@@ -89,7 +101,7 @@ * // suggestion in the dom. | ||
* // Create the plugin with the above configuration. It also supports multiple plugins being added. | ||
* const suggestionPlugin = suggest(suggestEmojis); | ||
* const suggesterPlugin = suggest(suggestEmojis); | ||
* | ||
* // Include the plugin in the created editor state. | ||
* const state = EditorState.create({schema, | ||
* plugins: [suggestionPlugin], | ||
* plugins: [suggesterPlugin], | ||
* }); | ||
@@ -104,4 +116,4 @@ * ``` | ||
* | ||
* Only one suggestion can match at any given time. The order and specificity of | ||
* the regex parameters help determines which suggestion will be active. | ||
* Only one suggester can match at any given time. The order and specificity of | ||
* the regex parameters help determines which suggester will be active. | ||
* | ||
@@ -111,2 +123,3 @@ * @param suggesters - a list of suggesters in the order they should be | ||
*/ | ||
export declare function suggest<Schema extends EditorSchema = any>(...suggesters: Suggestion[]): Plugin<SuggestState, Schema>; | ||
export declare function suggest<Schema extends EditorSchema = any>(...suggesters: Suggester[]): Plugin<SuggestState, Schema>; | ||
export type { SuggestState }; |
@@ -1,4 +0,4 @@ | ||
import { SelectionParameter } from '@remirror/core-types'; | ||
import type { SelectionParameter } from '@remirror/core-types'; | ||
import { ChangeReason, ExitReason } from './suggest-constants'; | ||
import { CompareMatchParameter, SuggestReasonMap, SuggestStateMatch, SuggestStateMatchParameter } from './suggest-types'; | ||
import type { CompareMatchParameter, SuggestReasonMap, SuggestStateMatch, SuggestStateMatchParameter } from './suggest-types'; | ||
/** | ||
@@ -5,0 +5,0 @@ * Is this a change in the current suggestion (added or deleted characters)? |
import { DecorationSet, EditorView } from 'prosemirror-view'; | ||
import { CompareStateParameter, EditorSchema, EditorState, FromToParameter, TextParameter, TransactionParameter } from '@remirror/core-types'; | ||
import { AddIgnoredParameter, RemoveIgnoredParameter, Suggestion, SuggestStateMatch } from './suggest-types'; | ||
import type { CompareStateParameter, EditorSchema, EditorState, FromToParameter, TextParameter, TransactionParameter } from '@remirror/core-types'; | ||
import type { AddIgnoredParameter, RemoveIgnoredParameter, Suggester, SuggestStateMatch } from './suggest-types'; | ||
/** | ||
* The suggestion state which manages the list of suggesters. | ||
* The `prosemirror-suggest` state which manages the list of suggesters. | ||
*/ | ||
@@ -12,20 +12,4 @@ export declare class SuggestState { | ||
*/ | ||
static create(suggesters: Suggestion[]): SuggestState; | ||
static create(suggesters: Suggester[]): SuggestState; | ||
/** | ||
* The suggesters that have been registered for the suggesters plugin. | ||
*/ | ||
private readonly suggesters; | ||
/** | ||
* Keeps track of the current state. | ||
*/ | ||
private next?; | ||
/** | ||
* Holds onto the previous active state. | ||
*/ | ||
private prev?; | ||
/** | ||
* The handler matches which are passed into `onChange` / `onExit` handlers. | ||
*/ | ||
private handlerMatches; | ||
/** | ||
* Holds a copy of the view | ||
@@ -35,8 +19,6 @@ */ | ||
/** | ||
* The set of ignored decorations | ||
*/ | ||
private ignored; | ||
/** | ||
* Lets us know whether the most recent change was to remove a mention. | ||
* True when the most recent change was to remove a mention. | ||
* | ||
* @remarks | ||
* | ||
* This is needed because sometimes removing a prosemirror `Mark` has no | ||
@@ -47,5 +29,5 @@ * effect. Hence we need to keep track of whether it's removed and then later | ||
*/ | ||
private removed; | ||
get removed(): boolean; | ||
/** | ||
* Returns the current active suggestion state field if one exists | ||
* Returns the current active suggester state field if one exists | ||
*/ | ||
@@ -66,3 +48,3 @@ get match(): Readonly<SuggestStateMatch> | undefined; | ||
*/ | ||
constructor(suggesters: Suggestion[]); | ||
constructor(suggesters: Suggester[]); | ||
/** | ||
@@ -76,3 +58,3 @@ * Initialize the SuggestState with a view which is stored for use later. | ||
*/ | ||
private readonly setRemovedTrue; | ||
readonly setMarkRemoved: () => void; | ||
/** | ||
@@ -91,5 +73,9 @@ * The actions created by the extension. | ||
/** | ||
* Check whether the exit callback is valid at this time. | ||
*/ | ||
private shouldRunExit; | ||
/** | ||
* Manages the view updates. | ||
*/ | ||
private readonly onViewUpdate; | ||
private onViewUpdate; | ||
/** | ||
@@ -100,3 +86,3 @@ * Update the current ignored decorations based on the latest changes to the | ||
private mapIgnoredDecorations; | ||
ignoreNextExit: () => void; | ||
readonly ignoreNextExit: () => void; | ||
/** | ||
@@ -112,3 +98,3 @@ * Ignores the match specified. Until the match is deleted no more `onChange`, | ||
*/ | ||
addIgnored: ({ from, char, name, specific }: AddIgnoredParameter) => void; | ||
readonly addIgnored: ({ from, char, name, specific }: AddIgnoredParameter) => void; | ||
/** | ||
@@ -122,3 +108,3 @@ * Removes a single match character from the ignored decorations. | ||
*/ | ||
removeIgnored: ({ from, char, name }: RemoveIgnoredParameter) => void; | ||
readonly removeIgnored: ({ from, char, name }: RemoveIgnoredParameter) => void; | ||
/** | ||
@@ -128,3 +114,3 @@ * Removes all the ignored decorations so that suggesters can active their | ||
*/ | ||
clearIgnored: (name?: string) => void; | ||
readonly clearIgnored: (name?: string) => void; | ||
private shouldIgnoreMatch; | ||
@@ -140,6 +126,14 @@ /** | ||
/** | ||
* Add a new suggest or replace it if it already exists. | ||
*/ | ||
addSuggester(suggester: Suggester): () => void; | ||
/** | ||
* Remove a suggester if it exists. | ||
*/ | ||
removeSuggester(suggester: Suggester | string): void; | ||
/** | ||
* Used to handle the view property of the plugin spec. | ||
*/ | ||
viewHandler(): { | ||
update: () => void; | ||
update: any; | ||
}; | ||
@@ -146,0 +140,0 @@ toJSON(): Readonly<SuggestStateMatch<import("@remirror/core-types").AnyFunction<void>>>; |
@@ -1,5 +0,5 @@ | ||
import { AnyFunction, EditorViewParameter, FromToParameter, TextParameter } from '@remirror/core-types'; | ||
import { ChangeReason, ExitReason } from './suggest-constants'; | ||
import type { AnyFunction, EditorViewParameter, FromToParameter, TextParameter } from '@remirror/core-types'; | ||
import type { ChangeReason, ExitReason } from './suggest-constants'; | ||
/** | ||
* This `Suggestion` interface defines all the options required to create a | ||
* This `Suggester` interface defines all the options required to create a | ||
* suggestion within your editor. | ||
@@ -11,6 +11,6 @@ * | ||
* | ||
* @typeParam Command - the command method a {@link Suggestion} makes available | ||
* @typeParam Command - the command method a {@link Suggester} makes available | ||
* to its handlers. | ||
*/ | ||
export interface Suggestion<Command extends AnyFunction<void> = AnyFunction<void>> { | ||
export interface Suggester<Command extends AnyFunction<void> = AnyFunction<void>> { | ||
/** | ||
@@ -27,3 +27,3 @@ * The activation character(s) to match against. | ||
* eventually matched suggester will depend on the order in which the | ||
* suggestions are added to the plugin. | ||
* suggesters are added to the plugin. | ||
*/ | ||
@@ -49,3 +49,3 @@ char: string; | ||
/** | ||
* A regex containing all supported characters when within a suggestion. | ||
* A regex containing all supported characters when within an active suggester. | ||
* | ||
@@ -60,3 +60,3 @@ * @defaultValue `/[\w\d_]+/` | ||
* | ||
* This will be used when {@link Suggestion.invalidPrefixCharacters} is not | ||
* This will be used when {@link Suggester.invalidPrefixCharacters} is not | ||
* provided. | ||
@@ -103,4 +103,3 @@ * | ||
/** | ||
* Class name to use for the decoration (while the suggestion is still being | ||
* written) | ||
* Class name to use for the decoration while the suggester is active. | ||
* | ||
@@ -117,3 +116,3 @@ * @defaultValue 'suggest' | ||
/** | ||
* Set a class for the ignored suggestion decoration. | ||
* Set a class for the ignored suggester decoration. | ||
* | ||
@@ -124,3 +123,3 @@ * @defaultValue '' | ||
/** | ||
* Set a tag for the ignored suggestion decoration. | ||
* Set a tag for the ignored suggester decoration. | ||
* | ||
@@ -131,7 +130,7 @@ * @defaultValue 'span' | ||
/** | ||
* When true, decorations are not created when this mention is being edited.. | ||
* When true, decorations are not created when this mention is being edited. | ||
*/ | ||
noDecorations?: boolean; | ||
/** | ||
* Called whenever a suggestion becomes active or changes in any way. | ||
* Called whenever a suggester becomes active or changes in any way. | ||
* | ||
@@ -147,3 +146,3 @@ * @remarks | ||
/** | ||
* Called whenever a suggestion is exited with the pre-exit match value. | ||
* Called whenever a suggester is exited with the pre-exit match value. | ||
* | ||
@@ -188,3 +187,3 @@ * @remarks | ||
* Suggested actions are useful for developing plugins and extensions which | ||
* provide useful defaults for managing the suggestion lifecycle. | ||
* provide useful defaults based on changes happening to the suggester. | ||
*/ | ||
@@ -213,3 +212,3 @@ createCommand?: (parameter: CreateSuggestCommandParameter) => Command; | ||
*/ | ||
export interface RemoveIgnoredParameter extends Pick<Suggestion, 'char' | 'name'> { | ||
export interface RemoveIgnoredParameter extends Pick<Suggester, 'char' | 'name'> { | ||
/** | ||
@@ -222,3 +221,3 @@ * The starting point of the match that should be ignored. | ||
* A parameter builder interface describing the ignore methods available to the | ||
* {@link Suggestion} handlers. | ||
* {@link Suggester} handlers. | ||
*/ | ||
@@ -249,3 +248,3 @@ export interface SuggestIgnoreParameter { | ||
* onExit: ({ addIgnored, range: { from }, suggester: { char, name } }: SuggestExitHandlerParameter) => { | ||
* addIgnored({ from, char, name }); // Ignore this suggestion | ||
* addIgnored({ from, char, name }); // Ignore this suggester | ||
* }, | ||
@@ -262,9 +261,13 @@ * } | ||
/** | ||
* Use this method to skip the next `onExit` callback. This is useful when | ||
* you manually call a command which applies the suggestion outside of the | ||
* `onExit` callback. When that happens on exit will be called again by default | ||
* and if you don't have the logic set up properly it will rerun your exit | ||
* command. This can lead to mismatched transaction errors since the `onExit` | ||
* handler is provided the last known value and this is no longer valid. | ||
* Use this method to skip the next `onExit` callback. | ||
* | ||
* @remarks | ||
* | ||
* This is useful when you manually call a command which applies the | ||
* suggestion outside of the `onExit` callback. When that happens `onExit` | ||
* will still be triggered and if you don't have the logic set | ||
* up properly it will rerun your exit command. This can lead to mismatched | ||
* transaction errors since the `onExit` handler is provided the last active | ||
* range and query and these values no longer valid. | ||
* | ||
* This helper method can be applied to make life easier. Call it when running | ||
@@ -313,6 +316,6 @@ * a command in a click handler or key binding and you don't have to worry | ||
* | ||
* @typeParam Command - the command method a {@link Suggestion} makes available | ||
* @typeParam Command - the command method a {@link Suggester} makes available | ||
* to its handlers. | ||
*/ | ||
export interface SuggestStateMatch<Command extends AnyFunction<void> = AnyFunction<void>> extends SuggestionParameter<Command> { | ||
export interface SuggestStateMatch<Command extends AnyFunction<void> = AnyFunction<void>> extends SuggesterParameter<Command> { | ||
/** | ||
@@ -339,2 +342,13 @@ * Range of current match; for example `@foo|bar` (where | is the cursor) | ||
} | ||
export interface DocChangedParameter { | ||
/** | ||
* - `true` when there was a changed in the editor content. | ||
* - `false` when only the selection changed. | ||
* | ||
* TODO currently unused. Should be used to differentiate between a cursor | ||
* exit using the keyboard navigation and a document update change typing | ||
* invalid character, space, etc... | ||
*/ | ||
docChanged: boolean; | ||
} | ||
/** | ||
@@ -388,3 +402,3 @@ * A parameter builder interface describing match found by the suggest plugin. | ||
/** | ||
* The parameters required by the {@link Suggestion.onKeyDown}. | ||
* The parameters required by the {@link Suggester.onKeyDown}. | ||
* | ||
@@ -423,5 +437,5 @@ * @remarks | ||
/** | ||
* The parameters passed to the {@link Suggestion.onChange} method. | ||
* The parameters passed to the {@link Suggester.onChange} method. | ||
* | ||
* @typeParam Command - the command method a {@link Suggestion} makes available | ||
* @typeParam Command - the command method a {@link Suggester} makes available | ||
* to its handlers. | ||
@@ -433,5 +447,5 @@ */ | ||
/** | ||
* The parameters passed to the {@link Suggestion.onExit} method. | ||
* The parameters passed to the {@link Suggester.onExit} method. | ||
* | ||
* @typeParam Command - the command method a {@link Suggestion} makes available | ||
* @typeParam Command - the command method a {@link Suggester} makes available | ||
* to its handlers. | ||
@@ -443,5 +457,5 @@ */ | ||
/** | ||
* The parameters passed to the {@link Suggestion.onCharacterEntry} method. | ||
* The parameters passed to the {@link Suggester.onCharacterEntry} method. | ||
* | ||
* @typeParam Command - the command method a {@link Suggestion} makes available | ||
* @typeParam Command - the command method a {@link Suggester} makes available | ||
* to its handlers. | ||
@@ -462,3 +476,3 @@ */ | ||
* | ||
* @typeParam Command - the command method a {@link Suggestion} makes available | ||
* @typeParam Command - the command method a {@link Suggester} makes available | ||
* to its handlers. | ||
@@ -476,3 +490,3 @@ */ | ||
* | ||
* @typeParam Command - the command method a {@link Suggestion} makes available | ||
* @typeParam Command - the command method a {@link Suggester} makes available | ||
* to its handlers. | ||
@@ -482,5 +496,5 @@ */ | ||
/** | ||
* The keybindings shape for the {@link Suggestion.keyBindings} property. | ||
* The keybindings shape for the {@link Suggester.keyBindings} property. | ||
* | ||
* @typeParam Command - the command method a {@link Suggestion} makes available | ||
* @typeParam Command - the command method a {@link Suggester} makes available | ||
* to its handlers. | ||
@@ -492,3 +506,3 @@ */ | ||
* | ||
* @typeParam Command - the command method a {@link Suggestion} makes available | ||
* @typeParam Command - the command method a {@link Suggester} makes available | ||
* to its handlers. | ||
@@ -503,7 +517,7 @@ */ | ||
} | ||
export interface SuggestionParameter<Command extends AnyFunction<void> = AnyFunction<void>> { | ||
export interface SuggesterParameter<Command extends AnyFunction<void> = AnyFunction<void>> { | ||
/** | ||
* The suggester to use for finding matches. | ||
*/ | ||
suggester: Required<Suggestion<Command>>; | ||
suggester: Required<Suggester<Command>>; | ||
} | ||
@@ -531,3 +545,3 @@ export interface SuggestStateMatchReason<Reason> extends SuggestStateMatch, ReasonParameter<Reason> { | ||
* | ||
* This is used to build parameters for {@link Suggestion} handler methods. | ||
* This is used to build parameters for {@link Suggester} handler methods. | ||
* | ||
@@ -534,0 +548,0 @@ * @typeParam Reason - Whether this is change or an exit reason. |
@@ -1,3 +0,3 @@ | ||
import { EditorStateParameter, ProsemirrorCommandFunction, ResolvedPosParameter } from '@remirror/core-types'; | ||
import { CompareMatchParameter, Suggestion, SuggestKeyBindingMap, SuggestKeyBindingParameter, SuggestReasonMap, SuggestStateMatch } from './suggest-types'; | ||
import type { EditorStateParameter, ProsemirrorCommandFunction, ResolvedPosParameter } from '@remirror/core-types'; | ||
import type { CompareMatchParameter, DocChangedParameter, Suggester, SuggestKeyBindingMap, SuggestKeyBindingParameter, SuggestReasonMap, SuggestStateMatch } from './suggest-types'; | ||
interface TransformKeyBindingsParameter { | ||
@@ -11,3 +11,3 @@ /** | ||
*/ | ||
suggestionParameter: SuggestKeyBindingParameter; | ||
suggestParameter: SuggestKeyBindingParameter; | ||
} | ||
@@ -28,9 +28,10 @@ /** | ||
*/ | ||
export declare function runKeyBindings(bindings: SuggestKeyBindingMap, suggestionParameter: SuggestKeyBindingParameter): boolean; | ||
interface FindFromSuggestionsParameter extends ResolvedPosParameter { | ||
export declare function runKeyBindings(bindings: SuggestKeyBindingMap, suggestParameter: SuggestKeyBindingParameter): boolean; | ||
interface FindFromSuggestersParameter extends ResolvedPosParameter, DocChangedParameter { | ||
/** | ||
* The matchers to search through. | ||
*/ | ||
suggesters: Array<Required<Suggestion>>; | ||
suggesters: Array<Required<Suggester>>; | ||
} | ||
declare type FindReasonParameter = EditorStateParameter & ResolvedPosParameter & Partial<CompareMatchParameter>; | ||
/** | ||
@@ -40,7 +41,7 @@ * Creates an array of the actions taken based on the current prev and next | ||
*/ | ||
export declare const findReason: ({ prev, next, state, $pos, }: EditorStateParameter & ResolvedPosParameter & Partial<CompareMatchParameter>) => SuggestReasonMap; | ||
export declare function findReason(parameter: FindReasonParameter): SuggestReasonMap; | ||
/** | ||
* Find a match for the provided matchers | ||
*/ | ||
export declare function findFromSuggestions({ suggesters, $pos, }: FindFromSuggestionsParameter): SuggestStateMatch | undefined; | ||
export declare function findFromSuggesters(parameter: FindFromSuggestersParameter): SuggestStateMatch | undefined; | ||
export {}; |
@@ -8,3 +8,2 @@ 'use strict'; | ||
var prosemirrorState = require('prosemirror-state'); | ||
var coreUtils = require('@remirror/core-utils'); | ||
var _defineProperty = _interopDefault(require('@babel/runtime/helpers/defineProperty')); | ||
@@ -21,9 +20,2 @@ var _classPrivateFieldSet = _interopDefault(require('@babel/runtime/helpers/classPrivateFieldSet')); | ||
var DEFAULT_SUGGEST_ACTIONS = { | ||
command: coreHelpers.noop, | ||
create: coreHelpers.noop, | ||
remove: coreHelpers.noop, | ||
update: coreHelpers.noop | ||
}; | ||
var defaultHandler = () => false; | ||
@@ -175,3 +167,3 @@ | ||
var createRegexFromSuggestion = function createRegexFromSuggestion(_ref) { | ||
var createRegexFromSuggester = function createRegexFromSuggester(_ref) { | ||
var char = _ref.char, | ||
@@ -205,2 +197,3 @@ matchOffset = _ref.matchOffset, | ||
} | ||
/** | ||
@@ -212,8 +205,6 @@ * Checks to see if the text before the matching character is a valid prefix. | ||
*/ | ||
function isPrefixValid(prefix, options) { | ||
var invalidPrefixCharacters = options.invalidPrefixCharacters, | ||
validPrefixCharacters = options.validPrefixCharacters; | ||
var isPrefixValid = (prefix, _ref) => { | ||
var invalidPrefixCharacters = _ref.invalidPrefixCharacters, | ||
validPrefixCharacters = _ref.validPrefixCharacters; | ||
if (!coreHelpers.isUndefined(invalidPrefixCharacters)) { | ||
@@ -229,3 +220,3 @@ var regex = new RegExp(regexToString(invalidPrefixCharacters)); | ||
} | ||
}; | ||
} | ||
/** | ||
@@ -238,9 +229,8 @@ * Find the position of a mention for a given selection and character | ||
var findPosition = (_ref2) => { | ||
var text = _ref2.text, | ||
regexp = _ref2.regexp, | ||
$pos = _ref2.$pos, | ||
char = _ref2.char, | ||
suggester = _ref2.suggester; | ||
var position; | ||
function findPosition(parameter) { | ||
var text = parameter.text, | ||
regexp = parameter.regexp, | ||
$pos = parameter.$pos, | ||
char = parameter.char, | ||
suggester = parameter.suggester; | ||
var cursor = $pos.pos; // The current cursor position | ||
@@ -250,2 +240,3 @@ | ||
var position; | ||
coreHelpers.findMatches(text, regexp).forEach(match => { | ||
@@ -288,12 +279,11 @@ // Check the character before the current match to ensure it is not one of | ||
return position; | ||
}; | ||
} | ||
/** | ||
* Checks if any matches exist at the current selection for so that the | ||
* suggesters be activated or deactivated. | ||
* Checks if any matches exist at the current selection so that the | ||
* suggesters can be activated or deactivated. | ||
*/ | ||
function findMatch(_ref3) { | ||
var $pos = _ref3.$pos, | ||
suggester = _ref3.suggester; | ||
function findMatch(parameter) { | ||
var $pos = parameter.$pos, | ||
suggester = parameter.suggester; | ||
var char = suggester.char, | ||
@@ -305,3 +295,3 @@ name = suggester.name, | ||
var regexp = createRegexFromSuggestion({ | ||
var regexp = createRegexFromSuggester({ | ||
char, | ||
@@ -324,2 +314,3 @@ matchOffset, | ||
} | ||
/** | ||
@@ -332,10 +323,8 @@ * Checks the provided match and generates a new match. This is useful for | ||
*/ | ||
function recheckMatch(parameter) { | ||
var state = parameter.state, | ||
match = parameter.match; | ||
var recheckMatch = (_ref4) => { | ||
var state = _ref4.state, | ||
match = _ref4.match; | ||
try { | ||
// Wrapped in try catch because it's possible for everything to be deleted | ||
// Wrapped in try/catch because it's possible for everything to be deleted | ||
// and the doc.resolve will fail. | ||
@@ -349,3 +338,4 @@ return findMatch({ | ||
} | ||
}; | ||
} | ||
/** | ||
@@ -358,10 +348,7 @@ * Check whether the insert action occurred at the end, in the middle or caused | ||
*/ | ||
function createInsertReason(parameter) { | ||
var prev = parameter.prev, | ||
next = parameter.next, | ||
state = parameter.state; // Has the text been removed? TODO how to tests for deletions mid document? | ||
var createInsertReason = (_ref5) => { | ||
var prev = _ref5.prev, | ||
next = _ref5.next, | ||
state = _ref5.state; | ||
// Has the text been removed? TODO how to tests for deletions mid document? | ||
if (!next && prev.range.from >= state.doc.nodeSize) { | ||
@@ -407,12 +394,11 @@ return { | ||
return {}; | ||
}; | ||
} | ||
/** | ||
* Find the reason for the Jump | ||
*/ | ||
var findJumpReason = (_ref6) => { | ||
var prev = _ref6.prev, | ||
next = _ref6.next, | ||
state = _ref6.state; | ||
function findJumpReason(parameter) { | ||
var prev = parameter.prev, | ||
next = parameter.next, | ||
state = parameter.state; | ||
var value = coreHelpers.object(); | ||
@@ -424,3 +410,3 @@ var updatedPrevious = recheckMatch({ | ||
var _ref7 = updatedPrevious && updatedPrevious.queryText.full !== prev.queryText.full // has query changed | ||
var _ref = updatedPrevious && updatedPrevious.queryText.full !== prev.queryText.full // has query changed | ||
? createInsertReason({ | ||
@@ -431,3 +417,3 @@ prev, | ||
}) : value, | ||
exit = _ref7.exit; | ||
exit = _ref.exit; | ||
@@ -459,3 +445,4 @@ var isJumpForward = prev.range.from < next.range.from; | ||
}; | ||
}; | ||
} | ||
/** | ||
@@ -467,8 +454,6 @@ * Find the reason for the exit. | ||
*/ | ||
var findExitReason = (_ref8) => { | ||
var match = _ref8.match, | ||
state = _ref8.state, | ||
$pos = _ref8.$pos; | ||
function findExitReason(parameter) { | ||
var match = parameter.match, | ||
state = parameter.state, | ||
$pos = parameter.$pos; | ||
var selection = state.selection; | ||
@@ -489,3 +474,3 @@ var updatedPrevious = recheckMatch({ | ||
if (!coreUtils.isSelectionEmpty(state) && (selection.from <= match.range.from || selection.to >= match.range.end)) { | ||
if (!state.selection.empty && (selection.from <= match.range.from || selection.to >= match.range.end)) { | ||
return { | ||
@@ -520,3 +505,3 @@ exit: createMatchWithReason({ | ||
return {}; | ||
}; | ||
} | ||
@@ -529,3 +514,3 @@ /** | ||
var bindings = parameter.bindings, | ||
suggestionParameter = parameter.suggestionParameter; | ||
suggestParameter = parameter.suggestParameter; | ||
var transformed = coreHelpers.object(); | ||
@@ -542,3 +527,3 @@ | ||
transformed[key] = () => coreHelpers.bool(binding(suggestionParameter)); | ||
transformed[key] = () => coreHelpers.bool(binding(suggestParameter)); | ||
}; | ||
@@ -567,7 +552,7 @@ | ||
function runKeyBindings(bindings, suggestionParameter) { | ||
function runKeyBindings(bindings, suggestParameter) { | ||
return prosemirrorKeymap.keydownHandler(transformKeyBindings({ | ||
bindings, | ||
suggestionParameter | ||
}))(suggestionParameter.view, suggestionParameter.event); | ||
suggestParameter | ||
}))(suggestParameter.view, suggestParameter.event); | ||
} | ||
@@ -579,7 +564,7 @@ | ||
*/ | ||
var findReason = (_ref9) => { | ||
var prev = _ref9.prev, | ||
next = _ref9.next, | ||
state = _ref9.state, | ||
$pos = _ref9.$pos; | ||
function findReason(parameter) { | ||
var prev = parameter.prev, | ||
next = parameter.next, | ||
state = parameter.state, | ||
$pos = parameter.$pos; | ||
var value = coreHelpers.object(); | ||
@@ -636,3 +621,3 @@ | ||
match: compare.next, | ||
reason: coreUtils.isSelectionEmpty(state) ? exports.ChangeReason.Move : exports.ChangeReason.SelectionInside | ||
reason: state.selection.empty ? exports.ChangeReason.Move : exports.ChangeReason.SelectionInside | ||
}) | ||
@@ -643,3 +628,3 @@ }; | ||
return value; | ||
}; | ||
} | ||
/** | ||
@@ -649,7 +634,6 @@ * Find a match for the provided matchers | ||
function findFromSuggestions(_ref10) { | ||
var suggesters = _ref10.suggesters, | ||
$pos = _ref10.$pos; | ||
function findFromSuggesters(parameter) { | ||
var suggesters = parameter.suggesters, | ||
$pos = parameter.$pos; // Find the first match and break when done | ||
// Find the first match and break when done | ||
var _iterator2 = _createForOfIteratorHelper(suggesters), | ||
@@ -688,7 +672,21 @@ _step2; | ||
/** | ||
* The suggestion state which manages the list of suggesters. | ||
* The `prosemirror-suggest` state which manages the list of suggesters. | ||
*/ | ||
var _docChanged = /*#__PURE__*/new WeakMap(); | ||
var _ignoreNextExit = /*#__PURE__*/new WeakMap(); | ||
var _suggesters = /*#__PURE__*/new WeakMap(); | ||
var _next = /*#__PURE__*/new WeakMap(); | ||
var _prev = /*#__PURE__*/new WeakMap(); | ||
var _handlerMatches = /*#__PURE__*/new WeakMap(); | ||
var _ignored = /*#__PURE__*/new WeakMap(); | ||
var _removed = /*#__PURE__*/new WeakMap(); | ||
class SuggestState { | ||
@@ -701,8 +699,27 @@ /** | ||
} | ||
/** | ||
* True when the doc changed in the most recently applied transaction. | ||
*/ | ||
/** | ||
* Returns the current active suggestion state field if one exists | ||
* True when the most recent change was to remove a mention. | ||
* | ||
* @remarks | ||
* | ||
* This is needed because sometimes removing a prosemirror `Mark` has no | ||
* effect. Hence we need to keep track of whether it's removed and then later | ||
* in the apply step check that a removal has happened and reset the | ||
* `handlerMatches` to prevent an infinite loop. | ||
*/ | ||
get removed() { | ||
return _classPrivateFieldGet(this, _removed); | ||
} | ||
/** | ||
* Returns the current active suggester state field if one exists | ||
*/ | ||
get match() { | ||
return this.next ? this.next : this.prev && this.handlerMatches.exit ? this.prev : undefined; | ||
return _classPrivateFieldGet(this, _next) ? _classPrivateFieldGet(this, _next) : _classPrivateFieldGet(this, _prev) && _classPrivateFieldGet(this, _handlerMatches).exit ? _classPrivateFieldGet(this, _prev) : undefined; | ||
} | ||
@@ -725,2 +742,7 @@ /** | ||
constructor(suggesters) { | ||
_docChanged.set(this, { | ||
writable: true, | ||
value: false | ||
}); | ||
_ignoreNextExit.set(this, { | ||
@@ -731,68 +753,34 @@ writable: true, | ||
_defineProperty(this, "handlerMatches", coreHelpers.object()); | ||
_suggesters.set(this, { | ||
writable: true, | ||
value: void 0 | ||
}); | ||
_defineProperty(this, "ignored", prosemirrorView.DecorationSet.empty); | ||
_next.set(this, { | ||
writable: true, | ||
value: void 0 | ||
}); | ||
_defineProperty(this, "removed", false); | ||
_prev.set(this, { | ||
writable: true, | ||
value: void 0 | ||
}); | ||
_defineProperty(this, "setRemovedTrue", () => { | ||
this.removed = true; | ||
_handlerMatches.set(this, { | ||
writable: true, | ||
value: coreHelpers.object() | ||
}); | ||
_defineProperty(this, "onViewUpdate", () => { | ||
var match = this.match, | ||
_this$handlerMatches = this.handlerMatches, | ||
change = _this$handlerMatches.change, | ||
exit = _this$handlerMatches.exit; | ||
_ignored.set(this, { | ||
writable: true, | ||
value: prosemirrorView.DecorationSet.empty | ||
}); | ||
var shouldRunExit = () => { | ||
if (_classPrivateFieldGet(this, _ignoreNextExit)) { | ||
_classPrivateFieldSet(this, _ignoreNextExit, false); | ||
_removed.set(this, { | ||
writable: true, | ||
value: false | ||
}); | ||
return false; | ||
} | ||
return true; | ||
}; // Cancel update when a suggestion isn't active | ||
if (!change && !exit || !isValidMatch(match)) { | ||
return; | ||
} // When a jump happens run the action that involves the | ||
// position that occurs later in the document. This is so that changes don't | ||
// affect previous positions. | ||
if (change && exit && isJumpReason({ | ||
change, | ||
exit | ||
})) { | ||
var exitParameters = this.createReasonParameter(exit); | ||
var changeParameters = this.createReasonParameter(change); | ||
var movedForwards = exit.range.from < change.range.from; | ||
if (movedForwards) { | ||
change.suggester.onChange(changeParameters); | ||
shouldRunExit() && exit.suggester.onExit(exitParameters); | ||
} else { | ||
shouldRunExit() && exit.suggester.onExit(exitParameters); | ||
change.suggester.onChange(changeParameters); | ||
} | ||
this.removed = false; | ||
return; | ||
} | ||
if (change) { | ||
change.suggester.onChange(this.createReasonParameter(change)); | ||
} | ||
if (exit && shouldRunExit()) { | ||
exit.suggester.onExit(this.createReasonParameter(exit)); | ||
this.removed = false; | ||
if (isInvalidSplitReason(exit.reason)) { | ||
this.handlerMatches = coreHelpers.object(); | ||
} | ||
} | ||
_defineProperty(this, "setMarkRemoved", () => { | ||
_classPrivateFieldSet(this, _removed, true); | ||
}); | ||
@@ -811,4 +799,5 @@ | ||
var to = from + char.length; | ||
var suggester = this.suggesters.find(value => value.name === name); | ||
var suggester = _classPrivateFieldGet(this, _suggesters).find(value => value.name === name); | ||
if (!suggester) { | ||
@@ -828,3 +817,4 @@ throw new Error("No suggester exists for the name provided: ".concat(name)); | ||
}); | ||
this.ignored = this.ignored.add(this.view.state.doc, [decoration]); | ||
_classPrivateFieldSet(this, _ignored, _classPrivateFieldGet(this, _ignored).add(this.view.state.doc, [decoration])); | ||
}); | ||
@@ -836,3 +826,5 @@ | ||
name = _ref2.name; | ||
var decorations = this.ignored.find(from, from + char.length); | ||
var decorations = _classPrivateFieldGet(this, _ignored).find(from, from + char.length); | ||
var decoration = decorations[0]; | ||
@@ -844,3 +836,3 @@ | ||
this.ignored = this.ignored.remove([decoration]); | ||
_classPrivateFieldSet(this, _ignored, _classPrivateFieldGet(this, _ignored).remove([decoration])); | ||
}); | ||
@@ -850,3 +842,4 @@ | ||
if (name) { | ||
var decorations = this.ignored.find(); | ||
var decorations = _classPrivateFieldGet(this, _ignored).find(); | ||
var decorationsToClear = decorations.filter((_ref3) => { | ||
@@ -856,21 +849,12 @@ var spec = _ref3.spec; | ||
}); | ||
this.ignored = this.ignored.remove(decorationsToClear); | ||
_classPrivateFieldSet(this, _ignored, _classPrivateFieldGet(this, _ignored).remove(decorationsToClear)); | ||
} else { | ||
this.ignored = prosemirrorView.DecorationSet.empty; | ||
_classPrivateFieldSet(this, _ignored, prosemirrorView.DecorationSet.empty); | ||
} | ||
}); | ||
var names = []; | ||
this.suggesters = suggesters.map(suggester => { | ||
if (names.includes(suggester.name)) { | ||
throw new Error("A suggester already exists with the name '".concat(suggester.name, "'. The name provided must be unique.")); | ||
} | ||
var mapper = createSuggesterMapper(); | ||
var clone = _objectSpread$1(_objectSpread$1({}, DEFAULT_SUGGESTER), suggester); // Preserve any descriptors (getters and setters) | ||
mergeDescriptors(clone, suggester); | ||
names.push(suggester.name); | ||
return clone; | ||
}); | ||
_classPrivateFieldSet(this, _suggesters, suggesters.map(mapper)); | ||
} | ||
@@ -900,3 +884,3 @@ /** | ||
view: this.view, | ||
setMarkRemoved: this.setRemovedTrue, | ||
setMarkRemoved: this.setMarkRemoved, | ||
addIgnored: this.addIgnored, | ||
@@ -932,2 +916,16 @@ clearIgnored: this.clearIgnored, | ||
/** | ||
* Check whether the exit callback is valid at this time. | ||
*/ | ||
shouldRunExit() { | ||
if (_classPrivateFieldGet(this, _ignoreNextExit)) { | ||
_classPrivateFieldSet(this, _ignoreNextExit, false); | ||
return false; | ||
} | ||
return true; | ||
} | ||
/** | ||
* Manages the view updates. | ||
@@ -937,2 +935,51 @@ */ | ||
onViewUpdate() { | ||
var _classPrivateFieldGet2 = _classPrivateFieldGet(this, _handlerMatches), | ||
change = _classPrivateFieldGet2.change, | ||
exit = _classPrivateFieldGet2.exit; | ||
var match = this.match; // Cancel update when a suggester isn't active | ||
if (!change && !exit || !isValidMatch(match)) { | ||
return; | ||
} // When a jump happens run the action that involves the | ||
// position that occurs later in the document. This is so that changes don't | ||
// affect previous positions. | ||
if (change && exit && isJumpReason({ | ||
change, | ||
exit | ||
})) { | ||
var exitParameters = this.createReasonParameter(exit); | ||
var changeParameters = this.createReasonParameter(change); | ||
var movedForwards = exit.range.from < change.range.from; | ||
if (movedForwards) { | ||
change.suggester.onChange(changeParameters); | ||
this.shouldRunExit() && exit.suggester.onExit(exitParameters); | ||
} else { | ||
this.shouldRunExit() && exit.suggester.onExit(exitParameters); | ||
change.suggester.onChange(changeParameters); | ||
} | ||
_classPrivateFieldSet(this, _removed, false); | ||
return; | ||
} | ||
if (change) { | ||
change.suggester.onChange(this.createReasonParameter(change)); | ||
} | ||
if (exit && this.shouldRunExit()) { | ||
exit.suggester.onExit(this.createReasonParameter(exit)); | ||
_classPrivateFieldSet(this, _removed, false); | ||
if (isInvalidSplitReason(exit.reason)) { | ||
_classPrivateFieldSet(this, _handlerMatches, coreHelpers.object()); | ||
} | ||
} | ||
} | ||
/** | ||
@@ -942,5 +989,8 @@ * Update the current ignored decorations based on the latest changes to the | ||
*/ | ||
mapIgnoredDecorations(tr) { | ||
// Map over and update the ignored decorations. | ||
var ignored = this.ignored.map(tr.mapping, tr.doc); | ||
var ignored = _classPrivateFieldGet(this, _ignored).map(tr.mapping, tr.doc); | ||
var decorations = ignored.find(); // For suggesters with multiple characters it is possible for a `paste` or | ||
@@ -962,3 +1012,4 @@ // any edit action within the decoration to expand the ignored section. We | ||
}); | ||
this.ignored = ignored.remove(invalid); | ||
_classPrivateFieldSet(this, _ignored, ignored.remove(invalid)); | ||
} | ||
@@ -969,3 +1020,5 @@ | ||
name = _ref5.suggester.name; | ||
var decorations = this.ignored.find(); | ||
var decorations = _classPrivateFieldGet(this, _ignored).find(); | ||
return decorations.some((_ref6) => { | ||
@@ -989,5 +1042,7 @@ var spec = _ref6.spec, | ||
resetState() { | ||
this.handlerMatches = coreHelpers.object(); | ||
this.next = undefined; | ||
this.removed = false; | ||
_classPrivateFieldSet(this, _handlerMatches, coreHelpers.object()); | ||
_classPrivateFieldSet(this, _next, undefined); | ||
_classPrivateFieldSet(this, _removed, false); | ||
} | ||
@@ -999,19 +1054,53 @@ /** | ||
updateReasons(_ref7) { | ||
var $pos = _ref7.$pos, | ||
state = _ref7.state; | ||
var match = findFromSuggestions({ | ||
suggesters: this.suggesters, | ||
$pos | ||
}); | ||
this.next = match && this.shouldIgnoreMatch(match) ? undefined : match; // Store the matches with reasons | ||
updateReasons(parameter) { | ||
var $pos = parameter.$pos, | ||
state = parameter.state; | ||
this.handlerMatches = findReason({ | ||
next: this.next, | ||
prev: this.prev, | ||
var docChanged = _classPrivateFieldGet(this, _docChanged); | ||
var match = findFromSuggesters({ | ||
suggesters: _classPrivateFieldGet(this, _suggesters), | ||
$pos, | ||
docChanged | ||
}); // Track the next match if not being ignored. | ||
_classPrivateFieldSet(this, _next, match && this.shouldIgnoreMatch(match) ? undefined : match); // Store the matches with reasons | ||
_classPrivateFieldSet(this, _handlerMatches, findReason({ | ||
next: _classPrivateFieldGet(this, _next), | ||
prev: _classPrivateFieldGet(this, _prev), | ||
state, | ||
$pos | ||
}); | ||
})); | ||
} | ||
/** | ||
* Add a new suggest or replace it if it already exists. | ||
*/ | ||
addSuggester(suggester) { | ||
var previous = _classPrivateFieldGet(this, _suggesters).find(item => item.name === suggester.name); | ||
var mapper = createSuggesterMapper(); | ||
if (previous) { | ||
_classPrivateFieldSet(this, _suggesters, _classPrivateFieldGet(this, _suggesters).map(item => item === previous ? mapper(suggester) : item)); | ||
} else { | ||
_classPrivateFieldSet(this, _suggesters, [..._classPrivateFieldGet(this, _suggesters), mapper(suggester)]); | ||
} | ||
return () => this.removeSuggester(suggester.name); | ||
} | ||
/** | ||
* Remove a suggester if it exists. | ||
*/ | ||
removeSuggester(suggester) { | ||
var name = coreHelpers.isString(suggester) ? suggester : suggester.name; | ||
_classPrivateFieldSet(this, _suggesters, _classPrivateFieldGet(this, _suggesters).filter(item => item.name !== name)); | ||
} | ||
/** | ||
* Used to handle the view property of the plugin spec. | ||
@@ -1023,3 +1112,3 @@ */ | ||
return { | ||
update: this.onViewUpdate | ||
update: this.onViewUpdate.bind(this) | ||
}; | ||
@@ -1038,19 +1127,27 @@ } | ||
apply(_ref8) { | ||
var tr = _ref8.tr, | ||
newState = _ref8.newState; | ||
var exit = this.handlerMatches.exit; | ||
apply(_ref7) { | ||
var tr = _ref7.tr, | ||
newState = _ref7.newState; | ||
if (!coreUtils.hasTransactionChanged(tr) && !this.removed) { | ||
var _classPrivateFieldGet3 = _classPrivateFieldGet(this, _handlerMatches), | ||
exit = _classPrivateFieldGet3.exit; | ||
var transactionHasChanged = tr.docChanged || tr.selectionSet; | ||
if (!transactionHasChanged && !_classPrivateFieldGet(this, _removed)) { | ||
return this; | ||
} | ||
this.mapIgnoredDecorations(tr); // If the previous run was an exit reset the suggestion matches | ||
_classPrivateFieldSet(this, _docChanged, tr.docChanged); | ||
this.mapIgnoredDecorations(tr); // If the previous run was an exit, reset the suggester matches. | ||
if (exit) { | ||
this.resetState(); | ||
} | ||
} // Track the previous match. | ||
this.prev = this.next; // Match against the current selection position | ||
_classPrivateFieldSet(this, _prev, _classPrivateFieldGet(this, _next)); // Match against the current selection position | ||
this.updateReasons({ | ||
@@ -1080,3 +1177,3 @@ $pos: tr.selection.$from, | ||
event, | ||
setMarkRemoved: this.setRemovedTrue | ||
setMarkRemoved: this.setMarkRemoved | ||
}, this.createParameter(match)); // TODO recalculating the keybindings on every update this is a performance bottleneck | ||
@@ -1092,6 +1189,6 @@ | ||
handleTextInput(_ref9) { | ||
var text = _ref9.text, | ||
from = _ref9.from, | ||
to = _ref9.to; | ||
handleTextInput(_ref8) { | ||
var text = _ref8.text, | ||
from = _ref8.from, | ||
to = _ref8.to; | ||
var match = this.match; | ||
@@ -1120,7 +1217,7 @@ | ||
if (!isValidMatch(match)) { | ||
return this.ignored; | ||
return _classPrivateFieldGet(this, _ignored); | ||
} | ||
if (match.suggester.noDecorations) { | ||
return this.ignored; | ||
return _classPrivateFieldGet(this, _ignored); | ||
} | ||
@@ -1131,9 +1228,9 @@ | ||
name = _match$suggester.name, | ||
decorationsTag = _match$suggester.suggestTag, | ||
suggestionClassName = _match$suggester.suggestClassName; | ||
suggestTag = _match$suggester.suggestTag, | ||
suggestClassName = _match$suggester.suggestClassName; | ||
var from = range.from, | ||
end = range.end; | ||
return this.shouldIgnoreMatch(match) ? this.ignored : this.ignored.add(state.doc, [prosemirrorView.Decoration.inline(from, end, { | ||
nodeName: decorationsTag, | ||
class: name ? "".concat(suggestionClassName, " ").concat(suggestionClassName, "-").concat(name) : suggestionClassName | ||
return this.shouldIgnoreMatch(match) ? _classPrivateFieldGet(this, _ignored) : _classPrivateFieldGet(this, _ignored).add(state.doc, [prosemirrorView.Decoration.inline(from, end, { | ||
nodeName: suggestTag, | ||
class: name ? "".concat(suggestClassName, " ").concat(suggestClassName, "-").concat(name) : suggestClassName | ||
})]); | ||
@@ -1144,2 +1241,18 @@ } | ||
function createSuggesterMapper() { | ||
var names = new Set(); | ||
return suggester => { | ||
if (names.has(suggester.name)) { | ||
throw new Error("A suggester already exists with the name '".concat(suggester.name, "'. The name provided must be unique.")); | ||
} | ||
var clone = _objectSpread$1(_objectSpread$1({}, DEFAULT_SUGGESTER), suggester); // Preserve any descriptors (getters and setters) | ||
mergeDescriptors(clone, suggester); | ||
names.add(suggester.name); | ||
return clone; | ||
}; | ||
} | ||
var suggestPluginKey = /*#__PURE__*/new prosemirrorState.PluginKey('suggest'); | ||
@@ -1153,10 +1266,28 @@ /** | ||
function getSuggestPluginState(state) { | ||
return coreUtils.getPluginState(suggestPluginKey, state); | ||
return suggestPluginKey.getState(state); | ||
} | ||
/** | ||
* This creates a suggestion plugin with all the suggesters provided. | ||
* Add a new suggester or replace it if the name already exists in the existing | ||
* configuration. | ||
* | ||
* Will return a function for disposing of the added suggester. | ||
*/ | ||
function addSuggester(state, suggester) { | ||
return getSuggestPluginState(state).addSuggester(suggester); | ||
} | ||
/** | ||
* Remove a suggester if it exists. Pass in the name or the full suggester | ||
* object. | ||
*/ | ||
function removeSuggester(state, suggester) { | ||
return getSuggestPluginState(state).removeSuggester(suggester); | ||
} | ||
/** | ||
* This creates a suggest plugin with all the suggesters provided. | ||
* | ||
* @remarks | ||
* | ||
* In the following example we're creating an emoji suggestion plugin that | ||
* In the following example we're creating an emoji suggest plugin that | ||
* responds to the colon character with a query and presents a list of matching | ||
@@ -1166,3 +1297,3 @@ * emojis based on the query typed so far. | ||
* ```ts | ||
* import { Suggestion, suggest } from 'prosemirror-suggest'; | ||
* import { Suggester, suggest } from 'prosemirror-suggest'; | ||
* | ||
@@ -1174,3 +1305,3 @@ * const maxResults = 10; | ||
* | ||
* const suggestEmojis: Suggestion = { | ||
* const suggestEmojis: Suggester = { | ||
* // By default decorations are used to highlight the currently matched | ||
@@ -1233,7 +1364,7 @@ * // suggestion in the dom. | ||
* // Create the plugin with the above configuration. It also supports multiple plugins being added. | ||
* const suggestionPlugin = suggest(suggestEmojis); | ||
* const suggesterPlugin = suggest(suggestEmojis); | ||
* | ||
* // Include the plugin in the created editor state. | ||
* const state = EditorState.create({schema, | ||
* plugins: [suggestionPlugin], | ||
* plugins: [suggesterPlugin], | ||
* }); | ||
@@ -1248,4 +1379,4 @@ * ``` | ||
* | ||
* Only one suggestion can match at any given time. The order and specificity of | ||
* the regex parameters help determines which suggestion will be active. | ||
* Only one suggester can match at any given time. The order and specificity of | ||
* the regex parameters help determines which suggester will be active. | ||
* | ||
@@ -1283,3 +1414,3 @@ * @param suggesters - a list of suggesters in the order they should be | ||
props: { | ||
// Call the keydown hook if suggestion is active. | ||
// Call the keydown hook if suggester is active. | ||
handleKeyDown: (_, event) => { | ||
@@ -1306,4 +1437,4 @@ return pluginState.handleKeyDown(event); | ||
exports.DEFAULT_SUGGESTER = DEFAULT_SUGGESTER; | ||
exports.DEFAULT_SUGGEST_ACTIONS = DEFAULT_SUGGEST_ACTIONS; | ||
exports.createRegexFromSuggestion = createRegexFromSuggestion; | ||
exports.addSuggester = addSuggester; | ||
exports.createRegexFromSuggester = createRegexFromSuggester; | ||
exports.escapeChar = escapeChar; | ||
@@ -1326,3 +1457,4 @@ exports.getRegexPrefix = getRegexPrefix; | ||
exports.regexToString = regexToString; | ||
exports.removeSuggester = removeSuggester; | ||
exports.selectionOutsideMatch = selectionOutsideMatch; | ||
exports.suggest = suggest; |
@@ -11,8 +11,3 @@ "use strict"; | ||
var prosemirrorState = require("prosemirror-state"), coreUtils = require("@remirror/core-utils"), _defineProperty = _interopDefault(require("@babel/runtime/helpers/defineProperty")), _classPrivateFieldSet = _interopDefault(require("@babel/runtime/helpers/classPrivateFieldSet")), _classPrivateFieldGet = _interopDefault(require("@babel/runtime/helpers/classPrivateFieldGet")), mergeDescriptors = _interopDefault(require("merge-descriptors")), prosemirrorView = require("prosemirror-view"), coreHelpers = require("@remirror/core-helpers"), _slicedToArray = _interopDefault(require("@babel/runtime/helpers/slicedToArray")), prosemirrorKeymap = require("prosemirror-keymap"), coreConstants = require("@remirror/core-constants"), escapeStringRegex = _interopDefault(require("escape-string-regexp")), DEFAULT_SUGGEST_ACTIONS = { | ||
command: coreHelpers.noop, | ||
create: coreHelpers.noop, | ||
remove: coreHelpers.noop, | ||
update: coreHelpers.noop | ||
}, defaultHandler = () => !1, DEFAULT_SUGGESTER = { | ||
var prosemirrorState = require("prosemirror-state"), _defineProperty = _interopDefault(require("@babel/runtime/helpers/defineProperty")), _classPrivateFieldSet = _interopDefault(require("@babel/runtime/helpers/classPrivateFieldSet")), _classPrivateFieldGet = _interopDefault(require("@babel/runtime/helpers/classPrivateFieldGet")), mergeDescriptors = _interopDefault(require("merge-descriptors")), prosemirrorView = require("prosemirror-view"), coreHelpers = require("@remirror/core-helpers"), _slicedToArray = _interopDefault(require("@babel/runtime/helpers/slicedToArray")), prosemirrorKeymap = require("prosemirror-keymap"), coreConstants = require("@remirror/core-constants"), escapeStringRegex = _interopDefault(require("escape-string-regexp")), defaultHandler = () => !1, DEFAULT_SUGGESTER = { | ||
appendText: "", | ||
@@ -56,3 +51,3 @@ createCommand: () => coreHelpers.noop, | ||
return match && (selection.from < match.range.from || selection.from > match.range.end); | ||
}, escapeChar = char => escapeStringRegex(char), regexToString = regexOrString => coreHelpers.isRegExp(regexOrString) ? regexOrString.source : regexOrString, getRegexPrefix = onlyStartOfLine => onlyStartOfLine ? "^" : "", getRegexSupportedCharacters = (supportedCharacters, matchOffset) => "(?:".concat(regexToString(supportedCharacters), "){").concat(matchOffset, ",}"), createRegexFromSuggestion = function(_ref) { | ||
}, escapeChar = char => escapeStringRegex(char), regexToString = regexOrString => coreHelpers.isRegExp(regexOrString) ? regexOrString.source : regexOrString, getRegexPrefix = onlyStartOfLine => onlyStartOfLine ? "^" : "", getRegexSupportedCharacters = (supportedCharacters, matchOffset) => "(?:".concat(regexToString(supportedCharacters), "){").concat(matchOffset, ",}"), createRegexFromSuggester = function(_ref) { | ||
var char = _ref.char, matchOffset = _ref.matchOffset, startOfLine = _ref.startOfLine, supportedCharacters = _ref.supportedCharacters, flags = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : "gm"; | ||
@@ -152,10 +147,11 @@ return new RegExp("".concat(getRegexPrefix(startOfLine)).concat(escapeChar(char)).concat(getRegexSupportedCharacters(supportedCharacters, matchOffset)), flags); | ||
var isPrefixValid = (prefix, _ref) => { | ||
var invalidPrefixCharacters = _ref.invalidPrefixCharacters, validPrefixCharacters = _ref.validPrefixCharacters; | ||
function isPrefixValid(prefix, options) { | ||
var invalidPrefixCharacters = options.invalidPrefixCharacters, validPrefixCharacters = options.validPrefixCharacters; | ||
return coreHelpers.isUndefined(invalidPrefixCharacters) ? new RegExp(regexToString(validPrefixCharacters)).test(prefix) : !new RegExp(regexToString(invalidPrefixCharacters)).test(prefix); | ||
}, findPosition = _ref2 => { | ||
var position, text = _ref2.text, regexp = _ref2.regexp, $pos = _ref2.$pos, char = _ref2.char, suggester = _ref2.suggester, cursor = $pos.pos, start = $pos.start(); | ||
} | ||
function findPosition(parameter) { | ||
var position, text = parameter.text, regexp = parameter.regexp, $pos = parameter.$pos, char = parameter.char, suggester = parameter.suggester, cursor = $pos.pos, start = $pos.start(); | ||
return coreHelpers.findMatches(text, regexp).forEach(match => { | ||
var matchPrefix = match.input.slice(Math.max(0, match.index - 1), match.index); | ||
if (isPrefixValid(matchPrefix, suggester)) { | ||
if (isPrefixValid(match.input.slice(Math.max(0, match.index - 1), match.index), suggester)) { | ||
var from = match.index + start, end = from + match[0].length, to = Math.min(end, cursor), matchLength = to - from; | ||
@@ -180,6 +176,6 @@ from < cursor && end >= cursor && (position = { | ||
}), position; | ||
}; | ||
} | ||
function findMatch(_ref3) { | ||
var $pos = _ref3.$pos, suggester = _ref3.suggester, char = suggester.char, name = suggester.name, startOfLine = suggester.startOfLine, supportedCharacters = suggester.supportedCharacters, matchOffset = suggester.matchOffset, regexp = createRegexFromSuggestion({ | ||
function findMatch(parameter) { | ||
var $pos = parameter.$pos, suggester = parameter.suggester, char = suggester.char, name = suggester.name, startOfLine = suggester.startOfLine, supportedCharacters = suggester.supportedCharacters, matchOffset = suggester.matchOffset, regexp = createRegexFromSuggester({ | ||
char: char, | ||
@@ -189,6 +185,6 @@ matchOffset: matchOffset, | ||
supportedCharacters: supportedCharacters | ||
}), text = $pos.doc.textBetween($pos.before(), $pos.end(), coreConstants.NULL_CHARACTER, coreConstants.NULL_CHARACTER); | ||
}); | ||
return findPosition({ | ||
suggester: suggester, | ||
text: text, | ||
text: $pos.doc.textBetween($pos.before(), $pos.end(), coreConstants.NULL_CHARACTER, coreConstants.NULL_CHARACTER), | ||
regexp: regexp, | ||
@@ -201,4 +197,4 @@ $pos: $pos, | ||
var recheckMatch = _ref4 => { | ||
var state = _ref4.state, match = _ref4.match; | ||
function recheckMatch(parameter) { | ||
var state = parameter.state, match = parameter.match; | ||
try { | ||
@@ -212,4 +208,6 @@ return findMatch({ | ||
} | ||
}, createInsertReason = _ref5 => { | ||
var prev = _ref5.prev, next = _ref5.next, state = _ref5.state; | ||
} | ||
function createInsertReason(parameter) { | ||
var prev = parameter.prev, next = parameter.next, state = parameter.state; | ||
return !next && prev.range.from >= state.doc.nodeSize ? { | ||
@@ -236,4 +234,6 @@ exit: createMatchWithReason({ | ||
}; | ||
}, findJumpReason = _ref6 => { | ||
var prev = _ref6.prev, next = _ref6.next, state = _ref6.state, value = coreHelpers.object(), updatedPrevious = recheckMatch({ | ||
} | ||
function findJumpReason(parameter) { | ||
var prev = parameter.prev, next = parameter.next, state = parameter.state, value = coreHelpers.object(), updatedPrevious = recheckMatch({ | ||
state: state, | ||
@@ -265,8 +265,10 @@ match: prev | ||
}; | ||
}, findExitReason = _ref8 => { | ||
var match = _ref8.match, state = _ref8.state, $pos = _ref8.$pos, selection = state.selection, updatedPrevious = recheckMatch({ | ||
} | ||
function findExitReason(parameter) { | ||
var match = parameter.match, state = parameter.state, $pos = parameter.$pos, selection = state.selection, updatedPrevious = recheckMatch({ | ||
match: match, | ||
state: state | ||
}); | ||
return updatedPrevious && updatedPrevious.queryText.full === match.queryText.full ? !coreUtils.isSelectionEmpty(state) && (selection.from <= match.range.from || selection.to >= match.range.end) ? { | ||
return updatedPrevious && updatedPrevious.queryText.full === match.queryText.full ? !state.selection.empty && (selection.from <= match.range.from || selection.to >= match.range.end) ? { | ||
exit: createMatchWithReason({ | ||
@@ -291,10 +293,10 @@ match: match, | ||
}); | ||
}; | ||
} | ||
function transformKeyBindings(parameter) { | ||
var _step, bindings = parameter.bindings, suggestionParameter = parameter.suggestionParameter, transformed = coreHelpers.object(), _iterator = _createForOfIteratorHelper(coreHelpers.entries(bindings)); | ||
var _step, bindings = parameter.bindings, suggestParameter = parameter.suggestParameter, transformed = coreHelpers.object(), _iterator = _createForOfIteratorHelper(coreHelpers.entries(bindings)); | ||
try { | ||
var _loop = function() { | ||
var _step$value = _slicedToArray(_step.value, 2), key = _step$value[0], binding = _step$value[1]; | ||
transformed[key] = () => coreHelpers.bool(binding(suggestionParameter)); | ||
transformed[key] = () => coreHelpers.bool(binding(suggestParameter)); | ||
}; | ||
@@ -310,11 +312,11 @@ for (_iterator.s(); !(_step = _iterator.n()).done; ) _loop(); | ||
function runKeyBindings(bindings, suggestionParameter) { | ||
function runKeyBindings(bindings, suggestParameter) { | ||
return prosemirrorKeymap.keydownHandler(transformKeyBindings({ | ||
bindings: bindings, | ||
suggestionParameter: suggestionParameter | ||
}))(suggestionParameter.view, suggestionParameter.event); | ||
suggestParameter: suggestParameter | ||
}))(suggestParameter.view, suggestParameter.event); | ||
} | ||
var findReason = _ref9 => { | ||
var prev = _ref9.prev, next = _ref9.next, state = _ref9.state, $pos = _ref9.$pos, value = coreHelpers.object(); | ||
function findReason(parameter) { | ||
var prev = parameter.prev, next = parameter.next, state = parameter.state, $pos = parameter.$pos, value = coreHelpers.object(); | ||
if (!prev && !next) return value; | ||
@@ -346,9 +348,9 @@ var compare = { | ||
match: compare.next, | ||
reason: coreUtils.isSelectionEmpty(state) ? exports.ChangeReason.Move : exports.ChangeReason.SelectionInside | ||
reason: state.selection.empty ? exports.ChangeReason.Move : exports.ChangeReason.SelectionInside | ||
}) | ||
} : value; | ||
}; | ||
} | ||
function findFromSuggestions(_ref10) { | ||
var _step2, suggesters = _ref10.suggesters, $pos = _ref10.$pos, _iterator2 = _createForOfIteratorHelper(suggesters); | ||
function findFromSuggesters(parameter) { | ||
var _step2, suggesters = parameter.suggesters, $pos = parameter.$pos, _iterator2 = _createForOfIteratorHelper(suggesters); | ||
try { | ||
@@ -397,3 +399,3 @@ for (_iterator2.s(); !(_step2 = _iterator2.n()).done; ) { | ||
var _ignoreNextExit = new WeakMap; | ||
var _docChanged = new WeakMap, _ignoreNextExit = new WeakMap, _suggesters = new WeakMap, _next = new WeakMap, _prev = new WeakMap, _handlerMatches = new WeakMap, _ignored = new WeakMap, _removed = new WeakMap; | ||
@@ -404,32 +406,39 @@ class SuggestState { | ||
} | ||
get removed() { | ||
return _classPrivateFieldGet(this, _removed); | ||
} | ||
get match() { | ||
return this.next ? this.next : this.prev && this.handlerMatches.exit ? this.prev : void 0; | ||
return _classPrivateFieldGet(this, _next) ? _classPrivateFieldGet(this, _next) : _classPrivateFieldGet(this, _prev) && _classPrivateFieldGet(this, _handlerMatches).exit ? _classPrivateFieldGet(this, _prev) : void 0; | ||
} | ||
constructor(suggesters) { | ||
_ignoreNextExit.set(this, { | ||
_docChanged.set(this, { | ||
writable: !0, | ||
value: !1 | ||
}), _defineProperty(this, "handlerMatches", coreHelpers.object()), _defineProperty(this, "ignored", prosemirrorView.DecorationSet.empty), | ||
_defineProperty(this, "removed", !1), _defineProperty(this, "setRemovedTrue", () => { | ||
this.removed = !0; | ||
}), _defineProperty(this, "onViewUpdate", () => { | ||
var match = this.match, _this$handlerMatches = this.handlerMatches, change = _this$handlerMatches.change, exit = _this$handlerMatches.exit, shouldRunExit = () => !_classPrivateFieldGet(this, _ignoreNextExit) || (_classPrivateFieldSet(this, _ignoreNextExit, !1), | ||
!1); | ||
if ((change || exit) && isValidMatch(match)) { | ||
if (change && exit && isJumpReason({ | ||
change: change, | ||
exit: exit | ||
})) { | ||
var exitParameters = this.createReasonParameter(exit), changeParameters = this.createReasonParameter(change); | ||
return exit.range.from < change.range.from ? (change.suggester.onChange(changeParameters), | ||
shouldRunExit() && exit.suggester.onExit(exitParameters)) : (shouldRunExit() && exit.suggester.onExit(exitParameters), | ||
change.suggester.onChange(changeParameters)), void (this.removed = !1); | ||
} | ||
change && change.suggester.onChange(this.createReasonParameter(change)), exit && shouldRunExit() && (exit.suggester.onExit(this.createReasonParameter(exit)), | ||
this.removed = !1, isInvalidSplitReason(exit.reason) && (this.handlerMatches = coreHelpers.object())); | ||
} | ||
}), _ignoreNextExit.set(this, { | ||
writable: !0, | ||
value: !1 | ||
}), _suggesters.set(this, { | ||
writable: !0, | ||
value: void 0 | ||
}), _next.set(this, { | ||
writable: !0, | ||
value: void 0 | ||
}), _prev.set(this, { | ||
writable: !0, | ||
value: void 0 | ||
}), _handlerMatches.set(this, { | ||
writable: !0, | ||
value: coreHelpers.object() | ||
}), _ignored.set(this, { | ||
writable: !0, | ||
value: prosemirrorView.DecorationSet.empty | ||
}), _removed.set(this, { | ||
writable: !0, | ||
value: !1 | ||
}), _defineProperty(this, "setMarkRemoved", () => { | ||
_classPrivateFieldSet(this, _removed, !0); | ||
}), _defineProperty(this, "ignoreNextExit", () => { | ||
_classPrivateFieldSet(this, _ignoreNextExit, !0); | ||
}), _defineProperty(this, "addIgnored", _ref => { | ||
var from = _ref.from, char = _ref.char, name = _ref.name, _ref$specific = _ref.specific, specific = void 0 !== _ref$specific && _ref$specific, to = from + char.length, suggester = this.suggesters.find(value => value.name === name); | ||
var from = _ref.from, char = _ref.char, name = _ref.name, _ref$specific = _ref.specific, specific = void 0 !== _ref$specific && _ref$specific, to = from + char.length, suggester = _classPrivateFieldGet(this, _suggesters).find(value => value.name === name); | ||
if (!suggester) throw new Error("No suggester exists for the name provided: ".concat(name)); | ||
@@ -445,18 +454,14 @@ var attributes = suggester.ignoredClassName ? { | ||
}); | ||
this.ignored = this.ignored.add(this.view.state.doc, [ decoration ]); | ||
_classPrivateFieldSet(this, _ignored, _classPrivateFieldGet(this, _ignored).add(this.view.state.doc, [ decoration ])); | ||
}), _defineProperty(this, "removeIgnored", _ref2 => { | ||
var from = _ref2.from, char = _ref2.char, name = _ref2.name, decoration = this.ignored.find(from, from + char.length)[0]; | ||
coreHelpers.bool(decoration) && decoration.spec.name === name && (this.ignored = this.ignored.remove([ decoration ])); | ||
var from = _ref2.from, char = _ref2.char, name = _ref2.name, decoration = _classPrivateFieldGet(this, _ignored).find(from, from + char.length)[0]; | ||
coreHelpers.bool(decoration) && decoration.spec.name === name && _classPrivateFieldSet(this, _ignored, _classPrivateFieldGet(this, _ignored).remove([ decoration ])); | ||
}), _defineProperty(this, "clearIgnored", name => { | ||
if (name) { | ||
var decorationsToClear = this.ignored.find().filter(_ref3 => _ref3.spec.name === name); | ||
this.ignored = this.ignored.remove(decorationsToClear); | ||
} else this.ignored = prosemirrorView.DecorationSet.empty; | ||
var decorationsToClear = _classPrivateFieldGet(this, _ignored).find().filter(_ref3 => _ref3.spec.name === name); | ||
_classPrivateFieldSet(this, _ignored, _classPrivateFieldGet(this, _ignored).remove(decorationsToClear)); | ||
} else _classPrivateFieldSet(this, _ignored, prosemirrorView.DecorationSet.empty); | ||
}); | ||
var names = []; | ||
this.suggesters = suggesters.map(suggester => { | ||
if (names.includes(suggester.name)) throw new Error("A suggester already exists with the name '".concat(suggester.name, "'. The name provided must be unique.")); | ||
var clone = _objectSpread$1(_objectSpread$1({}, DEFAULT_SUGGESTER), suggester); | ||
return mergeDescriptors(clone, suggester), names.push(suggester.name), clone; | ||
}); | ||
var mapper = createSuggesterMapper(); | ||
_classPrivateFieldSet(this, _suggesters, suggesters.map(mapper)); | ||
} | ||
@@ -471,3 +476,3 @@ init(view) { | ||
view: this.view, | ||
setMarkRemoved: this.setRemovedTrue, | ||
setMarkRemoved: this.setMarkRemoved, | ||
addIgnored: this.addIgnored, | ||
@@ -492,12 +497,32 @@ clearIgnored: this.clearIgnored, | ||
} | ||
shouldRunExit() { | ||
return !_classPrivateFieldGet(this, _ignoreNextExit) || (_classPrivateFieldSet(this, _ignoreNextExit, !1), | ||
!1); | ||
} | ||
onViewUpdate() { | ||
var _classPrivateFieldGet2 = _classPrivateFieldGet(this, _handlerMatches), change = _classPrivateFieldGet2.change, exit = _classPrivateFieldGet2.exit, match = this.match; | ||
if ((change || exit) && isValidMatch(match)) { | ||
if (change && exit && isJumpReason({ | ||
change: change, | ||
exit: exit | ||
})) { | ||
var exitParameters = this.createReasonParameter(exit), changeParameters = this.createReasonParameter(change); | ||
return exit.range.from < change.range.from ? (change.suggester.onChange(changeParameters), | ||
this.shouldRunExit() && exit.suggester.onExit(exitParameters)) : (this.shouldRunExit() && exit.suggester.onExit(exitParameters), | ||
change.suggester.onChange(changeParameters)), void _classPrivateFieldSet(this, _removed, !1); | ||
} | ||
change && change.suggester.onChange(this.createReasonParameter(change)), exit && this.shouldRunExit() && (exit.suggester.onExit(this.createReasonParameter(exit)), | ||
_classPrivateFieldSet(this, _removed, !1), isInvalidSplitReason(exit.reason) && _classPrivateFieldSet(this, _handlerMatches, coreHelpers.object())); | ||
} | ||
} | ||
mapIgnoredDecorations(tr) { | ||
var ignored = this.ignored.map(tr.mapping, tr.doc), invalid = ignored.find().filter(_ref4 => { | ||
var ignored = _classPrivateFieldGet(this, _ignored).map(tr.mapping, tr.doc), invalid = ignored.find().filter(_ref4 => { | ||
var from = _ref4.from; | ||
return _ref4.to - from !== _ref4.spec.char.length; | ||
}); | ||
this.ignored = ignored.remove(invalid); | ||
_classPrivateFieldSet(this, _ignored, ignored.remove(invalid)); | ||
} | ||
shouldIgnoreMatch(_ref5) { | ||
var range = _ref5.range, name = _ref5.suggester.name; | ||
return this.ignored.find().some(_ref6 => { | ||
return _classPrivateFieldGet(this, _ignored).find().some(_ref6 => { | ||
var spec = _ref6.spec; | ||
@@ -508,19 +533,31 @@ return _ref6.from === range.from && (!spec.specific || spec.name === name); | ||
resetState() { | ||
this.handlerMatches = coreHelpers.object(), this.next = void 0, this.removed = !1; | ||
_classPrivateFieldSet(this, _handlerMatches, coreHelpers.object()), _classPrivateFieldSet(this, _next, void 0), | ||
_classPrivateFieldSet(this, _removed, !1); | ||
} | ||
updateReasons(_ref7) { | ||
var $pos = _ref7.$pos, state = _ref7.state, match = findFromSuggestions({ | ||
suggesters: this.suggesters, | ||
$pos: $pos | ||
updateReasons(parameter) { | ||
var $pos = parameter.$pos, state = parameter.state, docChanged = _classPrivateFieldGet(this, _docChanged), match = findFromSuggesters({ | ||
suggesters: _classPrivateFieldGet(this, _suggesters), | ||
$pos: $pos, | ||
docChanged: docChanged | ||
}); | ||
this.next = match && this.shouldIgnoreMatch(match) ? void 0 : match, this.handlerMatches = findReason({ | ||
next: this.next, | ||
prev: this.prev, | ||
_classPrivateFieldSet(this, _next, match && this.shouldIgnoreMatch(match) ? void 0 : match), | ||
_classPrivateFieldSet(this, _handlerMatches, findReason({ | ||
next: _classPrivateFieldGet(this, _next), | ||
prev: _classPrivateFieldGet(this, _prev), | ||
state: state, | ||
$pos: $pos | ||
}); | ||
})); | ||
} | ||
addSuggester(suggester) { | ||
var previous = _classPrivateFieldGet(this, _suggesters).find(item => item.name === suggester.name), mapper = createSuggesterMapper(); | ||
return _classPrivateFieldSet(this, _suggesters, previous ? _classPrivateFieldGet(this, _suggesters).map(item => item === previous ? mapper(suggester) : item) : [ ..._classPrivateFieldGet(this, _suggesters), mapper(suggester) ]), | ||
() => this.removeSuggester(suggester.name); | ||
} | ||
removeSuggester(suggester) { | ||
var name = coreHelpers.isString(suggester) ? suggester : suggester.name; | ||
_classPrivateFieldSet(this, _suggesters, _classPrivateFieldGet(this, _suggesters).filter(item => item.name !== name)); | ||
} | ||
viewHandler() { | ||
return { | ||
update: this.onViewUpdate | ||
update: this.onViewUpdate.bind(this) | ||
}; | ||
@@ -531,6 +568,7 @@ } | ||
} | ||
apply(_ref8) { | ||
var tr = _ref8.tr, newState = _ref8.newState, exit = this.handlerMatches.exit; | ||
return coreUtils.hasTransactionChanged(tr) || this.removed ? (this.mapIgnoredDecorations(tr), | ||
exit && this.resetState(), this.prev = this.next, this.updateReasons({ | ||
apply(_ref7) { | ||
var tr = _ref7.tr, newState = _ref7.newState, exit = _classPrivateFieldGet(this, _handlerMatches).exit; | ||
return tr.docChanged || tr.selectionSet || _classPrivateFieldGet(this, _removed) ? (_classPrivateFieldSet(this, _docChanged, tr.docChanged), | ||
this.mapIgnoredDecorations(tr), exit && this.resetState(), _classPrivateFieldSet(this, _prev, _classPrivateFieldGet(this, _next)), | ||
this.updateReasons({ | ||
$pos: tr.selection.$from, | ||
@@ -545,8 +583,8 @@ state: newState | ||
event: event, | ||
setMarkRemoved: this.setRemovedTrue | ||
setMarkRemoved: this.setMarkRemoved | ||
}, this.createParameter(match)); | ||
return runKeyBindings(coreHelpers.isFunction(keyBindings) ? keyBindings() : keyBindings, parameter); | ||
} | ||
handleTextInput(_ref9) { | ||
var text = _ref9.text, from = _ref9.from, to = _ref9.to, match = this.match; | ||
handleTextInput(_ref8) { | ||
var text = _ref8.text, from = _ref8.from, to = _ref8.to, match = this.match; | ||
return !!isValidMatch(match) && (0, match.suggester.onCharacterEntry)(_objectSpread$1(_objectSpread$1({}, this.createParameter(match)), {}, { | ||
@@ -560,8 +598,8 @@ from: from, | ||
var match = this.match; | ||
if (!isValidMatch(match)) return this.ignored; | ||
if (match.suggester.noDecorations) return this.ignored; | ||
var range = match.range, _match$suggester = match.suggester, name = _match$suggester.name, decorationsTag = _match$suggester.suggestTag, suggestionClassName = _match$suggester.suggestClassName, from = range.from, end = range.end; | ||
return this.shouldIgnoreMatch(match) ? this.ignored : this.ignored.add(state.doc, [ prosemirrorView.Decoration.inline(from, end, { | ||
nodeName: decorationsTag, | ||
class: name ? "".concat(suggestionClassName, " ").concat(suggestionClassName, "-").concat(name) : suggestionClassName | ||
if (!isValidMatch(match)) return _classPrivateFieldGet(this, _ignored); | ||
if (match.suggester.noDecorations) return _classPrivateFieldGet(this, _ignored); | ||
var range = match.range, _match$suggester = match.suggester, name = _match$suggester.name, suggestTag = _match$suggester.suggestTag, suggestClassName = _match$suggester.suggestClassName, from = range.from, end = range.end; | ||
return this.shouldIgnoreMatch(match) ? _classPrivateFieldGet(this, _ignored) : _classPrivateFieldGet(this, _ignored).add(state.doc, [ prosemirrorView.Decoration.inline(from, end, { | ||
nodeName: suggestTag, | ||
class: name ? "".concat(suggestClassName, " ").concat(suggestClassName, "-").concat(name) : suggestClassName | ||
}) ]); | ||
@@ -571,8 +609,25 @@ } | ||
function createSuggesterMapper() { | ||
var names = new Set; | ||
return suggester => { | ||
if (names.has(suggester.name)) throw new Error("A suggester already exists with the name '".concat(suggester.name, "'. The name provided must be unique.")); | ||
var clone = _objectSpread$1(_objectSpread$1({}, DEFAULT_SUGGESTER), suggester); | ||
return mergeDescriptors(clone, suggester), names.add(suggester.name), clone; | ||
}; | ||
} | ||
var suggestPluginKey = new prosemirrorState.PluginKey("suggest"); | ||
function getSuggestPluginState(state) { | ||
return coreUtils.getPluginState(suggestPluginKey, state); | ||
return suggestPluginKey.getState(state); | ||
} | ||
function addSuggester(state, suggester) { | ||
return getSuggestPluginState(state).addSuggester(suggester); | ||
} | ||
function removeSuggester(state, suggester) { | ||
return getSuggestPluginState(state).removeSuggester(suggester); | ||
} | ||
function suggest() { | ||
@@ -604,4 +659,4 @@ for (var _len = arguments.length, suggesters = new Array(_len), _key = 0; _key < _len; _key++) suggesters[_key] = arguments[_key]; | ||
exports.DEFAULT_SUGGESTER = DEFAULT_SUGGESTER, exports.DEFAULT_SUGGEST_ACTIONS = DEFAULT_SUGGEST_ACTIONS, | ||
exports.createRegexFromSuggestion = createRegexFromSuggestion, exports.escapeChar = escapeChar, | ||
exports.DEFAULT_SUGGESTER = DEFAULT_SUGGESTER, exports.addSuggester = addSuggester, | ||
exports.createRegexFromSuggester = createRegexFromSuggester, exports.escapeChar = escapeChar, | ||
exports.getRegexPrefix = getRegexPrefix, exports.getSuggestPluginState = getSuggestPluginState, | ||
@@ -613,2 +668,3 @@ exports.isChange = isChange, exports.isChangeReason = isChangeReason, exports.isEntry = isEntry, | ||
exports.isSplitReason = isSplitReason, exports.isValidMatch = isValidMatch, exports.regexToString = regexToString, | ||
exports.selectionOutsideMatch = selectionOutsideMatch, exports.suggest = suggest; | ||
exports.removeSuggester = removeSuggester, exports.selectionOutsideMatch = selectionOutsideMatch, | ||
exports.suggest = suggest; |
import { Plugin, PluginKey } from 'prosemirror-state'; | ||
import { isSelectionEmpty, hasTransactionChanged, getPluginState } from '@remirror/core-utils'; | ||
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty'; | ||
@@ -14,9 +13,2 @@ import _classPrivateFieldSet from '@babel/runtime/helpers/esm/classPrivateFieldSet'; | ||
var DEFAULT_SUGGEST_ACTIONS = { | ||
command: noop, | ||
create: noop, | ||
remove: noop, | ||
update: noop | ||
}; | ||
var defaultHandler = () => false; | ||
@@ -175,3 +167,3 @@ | ||
var createRegexFromSuggestion = function createRegexFromSuggestion(_ref) { | ||
var createRegexFromSuggester = function createRegexFromSuggester(_ref) { | ||
var char = _ref.char, | ||
@@ -205,2 +197,3 @@ matchOffset = _ref.matchOffset, | ||
} | ||
/** | ||
@@ -212,8 +205,6 @@ * Checks to see if the text before the matching character is a valid prefix. | ||
*/ | ||
function isPrefixValid(prefix, options) { | ||
var invalidPrefixCharacters = options.invalidPrefixCharacters, | ||
validPrefixCharacters = options.validPrefixCharacters; | ||
var isPrefixValid = (prefix, _ref) => { | ||
var invalidPrefixCharacters = _ref.invalidPrefixCharacters, | ||
validPrefixCharacters = _ref.validPrefixCharacters; | ||
if (!isUndefined(invalidPrefixCharacters)) { | ||
@@ -229,3 +220,3 @@ var regex = new RegExp(regexToString(invalidPrefixCharacters)); | ||
} | ||
}; | ||
} | ||
/** | ||
@@ -238,9 +229,8 @@ * Find the position of a mention for a given selection and character | ||
var findPosition = (_ref2) => { | ||
var text = _ref2.text, | ||
regexp = _ref2.regexp, | ||
$pos = _ref2.$pos, | ||
char = _ref2.char, | ||
suggester = _ref2.suggester; | ||
var position; | ||
function findPosition(parameter) { | ||
var text = parameter.text, | ||
regexp = parameter.regexp, | ||
$pos = parameter.$pos, | ||
char = parameter.char, | ||
suggester = parameter.suggester; | ||
var cursor = $pos.pos; // The current cursor position | ||
@@ -250,2 +240,3 @@ | ||
var position; | ||
findMatches(text, regexp).forEach(match => { | ||
@@ -288,12 +279,11 @@ // Check the character before the current match to ensure it is not one of | ||
return position; | ||
}; | ||
} | ||
/** | ||
* Checks if any matches exist at the current selection for so that the | ||
* suggesters be activated or deactivated. | ||
* Checks if any matches exist at the current selection so that the | ||
* suggesters can be activated or deactivated. | ||
*/ | ||
function findMatch(_ref3) { | ||
var $pos = _ref3.$pos, | ||
suggester = _ref3.suggester; | ||
function findMatch(parameter) { | ||
var $pos = parameter.$pos, | ||
suggester = parameter.suggester; | ||
var char = suggester.char, | ||
@@ -305,3 +295,3 @@ name = suggester.name, | ||
var regexp = createRegexFromSuggestion({ | ||
var regexp = createRegexFromSuggester({ | ||
char, | ||
@@ -324,2 +314,3 @@ matchOffset, | ||
} | ||
/** | ||
@@ -332,10 +323,8 @@ * Checks the provided match and generates a new match. This is useful for | ||
*/ | ||
function recheckMatch(parameter) { | ||
var state = parameter.state, | ||
match = parameter.match; | ||
var recheckMatch = (_ref4) => { | ||
var state = _ref4.state, | ||
match = _ref4.match; | ||
try { | ||
// Wrapped in try catch because it's possible for everything to be deleted | ||
// Wrapped in try/catch because it's possible for everything to be deleted | ||
// and the doc.resolve will fail. | ||
@@ -349,3 +338,4 @@ return findMatch({ | ||
} | ||
}; | ||
} | ||
/** | ||
@@ -358,10 +348,7 @@ * Check whether the insert action occurred at the end, in the middle or caused | ||
*/ | ||
function createInsertReason(parameter) { | ||
var prev = parameter.prev, | ||
next = parameter.next, | ||
state = parameter.state; // Has the text been removed? TODO how to tests for deletions mid document? | ||
var createInsertReason = (_ref5) => { | ||
var prev = _ref5.prev, | ||
next = _ref5.next, | ||
state = _ref5.state; | ||
// Has the text been removed? TODO how to tests for deletions mid document? | ||
if (!next && prev.range.from >= state.doc.nodeSize) { | ||
@@ -407,12 +394,11 @@ return { | ||
return {}; | ||
}; | ||
} | ||
/** | ||
* Find the reason for the Jump | ||
*/ | ||
var findJumpReason = (_ref6) => { | ||
var prev = _ref6.prev, | ||
next = _ref6.next, | ||
state = _ref6.state; | ||
function findJumpReason(parameter) { | ||
var prev = parameter.prev, | ||
next = parameter.next, | ||
state = parameter.state; | ||
var value = object(); | ||
@@ -424,3 +410,3 @@ var updatedPrevious = recheckMatch({ | ||
var _ref7 = updatedPrevious && updatedPrevious.queryText.full !== prev.queryText.full // has query changed | ||
var _ref = updatedPrevious && updatedPrevious.queryText.full !== prev.queryText.full // has query changed | ||
? createInsertReason({ | ||
@@ -431,3 +417,3 @@ prev, | ||
}) : value, | ||
exit = _ref7.exit; | ||
exit = _ref.exit; | ||
@@ -459,3 +445,4 @@ var isJumpForward = prev.range.from < next.range.from; | ||
}; | ||
}; | ||
} | ||
/** | ||
@@ -467,8 +454,6 @@ * Find the reason for the exit. | ||
*/ | ||
var findExitReason = (_ref8) => { | ||
var match = _ref8.match, | ||
state = _ref8.state, | ||
$pos = _ref8.$pos; | ||
function findExitReason(parameter) { | ||
var match = parameter.match, | ||
state = parameter.state, | ||
$pos = parameter.$pos; | ||
var selection = state.selection; | ||
@@ -489,3 +474,3 @@ var updatedPrevious = recheckMatch({ | ||
if (!isSelectionEmpty(state) && (selection.from <= match.range.from || selection.to >= match.range.end)) { | ||
if (!state.selection.empty && (selection.from <= match.range.from || selection.to >= match.range.end)) { | ||
return { | ||
@@ -520,3 +505,3 @@ exit: createMatchWithReason({ | ||
return {}; | ||
}; | ||
} | ||
@@ -529,3 +514,3 @@ /** | ||
var bindings = parameter.bindings, | ||
suggestionParameter = parameter.suggestionParameter; | ||
suggestParameter = parameter.suggestParameter; | ||
var transformed = object(); | ||
@@ -542,3 +527,3 @@ | ||
transformed[key] = () => bool(binding(suggestionParameter)); | ||
transformed[key] = () => bool(binding(suggestParameter)); | ||
}; | ||
@@ -567,7 +552,7 @@ | ||
function runKeyBindings(bindings, suggestionParameter) { | ||
function runKeyBindings(bindings, suggestParameter) { | ||
return keydownHandler(transformKeyBindings({ | ||
bindings, | ||
suggestionParameter | ||
}))(suggestionParameter.view, suggestionParameter.event); | ||
suggestParameter | ||
}))(suggestParameter.view, suggestParameter.event); | ||
} | ||
@@ -579,7 +564,7 @@ | ||
*/ | ||
var findReason = (_ref9) => { | ||
var prev = _ref9.prev, | ||
next = _ref9.next, | ||
state = _ref9.state, | ||
$pos = _ref9.$pos; | ||
function findReason(parameter) { | ||
var prev = parameter.prev, | ||
next = parameter.next, | ||
state = parameter.state, | ||
$pos = parameter.$pos; | ||
var value = object(); | ||
@@ -636,3 +621,3 @@ | ||
match: compare.next, | ||
reason: isSelectionEmpty(state) ? ChangeReason.Move : ChangeReason.SelectionInside | ||
reason: state.selection.empty ? ChangeReason.Move : ChangeReason.SelectionInside | ||
}) | ||
@@ -643,3 +628,3 @@ }; | ||
return value; | ||
}; | ||
} | ||
/** | ||
@@ -649,7 +634,6 @@ * Find a match for the provided matchers | ||
function findFromSuggestions(_ref10) { | ||
var suggesters = _ref10.suggesters, | ||
$pos = _ref10.$pos; | ||
function findFromSuggesters(parameter) { | ||
var suggesters = parameter.suggesters, | ||
$pos = parameter.$pos; // Find the first match and break when done | ||
// Find the first match and break when done | ||
var _iterator2 = _createForOfIteratorHelper(suggesters), | ||
@@ -688,7 +672,21 @@ _step2; | ||
/** | ||
* The suggestion state which manages the list of suggesters. | ||
* The `prosemirror-suggest` state which manages the list of suggesters. | ||
*/ | ||
var _docChanged = /*#__PURE__*/new WeakMap(); | ||
var _ignoreNextExit = /*#__PURE__*/new WeakMap(); | ||
var _suggesters = /*#__PURE__*/new WeakMap(); | ||
var _next = /*#__PURE__*/new WeakMap(); | ||
var _prev = /*#__PURE__*/new WeakMap(); | ||
var _handlerMatches = /*#__PURE__*/new WeakMap(); | ||
var _ignored = /*#__PURE__*/new WeakMap(); | ||
var _removed = /*#__PURE__*/new WeakMap(); | ||
class SuggestState { | ||
@@ -701,8 +699,27 @@ /** | ||
} | ||
/** | ||
* True when the doc changed in the most recently applied transaction. | ||
*/ | ||
/** | ||
* Returns the current active suggestion state field if one exists | ||
* True when the most recent change was to remove a mention. | ||
* | ||
* @remarks | ||
* | ||
* This is needed because sometimes removing a prosemirror `Mark` has no | ||
* effect. Hence we need to keep track of whether it's removed and then later | ||
* in the apply step check that a removal has happened and reset the | ||
* `handlerMatches` to prevent an infinite loop. | ||
*/ | ||
get removed() { | ||
return _classPrivateFieldGet(this, _removed); | ||
} | ||
/** | ||
* Returns the current active suggester state field if one exists | ||
*/ | ||
get match() { | ||
return this.next ? this.next : this.prev && this.handlerMatches.exit ? this.prev : undefined; | ||
return _classPrivateFieldGet(this, _next) ? _classPrivateFieldGet(this, _next) : _classPrivateFieldGet(this, _prev) && _classPrivateFieldGet(this, _handlerMatches).exit ? _classPrivateFieldGet(this, _prev) : undefined; | ||
} | ||
@@ -725,2 +742,7 @@ /** | ||
constructor(suggesters) { | ||
_docChanged.set(this, { | ||
writable: true, | ||
value: false | ||
}); | ||
_ignoreNextExit.set(this, { | ||
@@ -731,68 +753,34 @@ writable: true, | ||
_defineProperty(this, "handlerMatches", object()); | ||
_suggesters.set(this, { | ||
writable: true, | ||
value: void 0 | ||
}); | ||
_defineProperty(this, "ignored", DecorationSet.empty); | ||
_next.set(this, { | ||
writable: true, | ||
value: void 0 | ||
}); | ||
_defineProperty(this, "removed", false); | ||
_prev.set(this, { | ||
writable: true, | ||
value: void 0 | ||
}); | ||
_defineProperty(this, "setRemovedTrue", () => { | ||
this.removed = true; | ||
_handlerMatches.set(this, { | ||
writable: true, | ||
value: object() | ||
}); | ||
_defineProperty(this, "onViewUpdate", () => { | ||
var match = this.match, | ||
_this$handlerMatches = this.handlerMatches, | ||
change = _this$handlerMatches.change, | ||
exit = _this$handlerMatches.exit; | ||
_ignored.set(this, { | ||
writable: true, | ||
value: DecorationSet.empty | ||
}); | ||
var shouldRunExit = () => { | ||
if (_classPrivateFieldGet(this, _ignoreNextExit)) { | ||
_classPrivateFieldSet(this, _ignoreNextExit, false); | ||
_removed.set(this, { | ||
writable: true, | ||
value: false | ||
}); | ||
return false; | ||
} | ||
return true; | ||
}; // Cancel update when a suggestion isn't active | ||
if (!change && !exit || !isValidMatch(match)) { | ||
return; | ||
} // When a jump happens run the action that involves the | ||
// position that occurs later in the document. This is so that changes don't | ||
// affect previous positions. | ||
if (change && exit && isJumpReason({ | ||
change, | ||
exit | ||
})) { | ||
var exitParameters = this.createReasonParameter(exit); | ||
var changeParameters = this.createReasonParameter(change); | ||
var movedForwards = exit.range.from < change.range.from; | ||
if (movedForwards) { | ||
change.suggester.onChange(changeParameters); | ||
shouldRunExit() && exit.suggester.onExit(exitParameters); | ||
} else { | ||
shouldRunExit() && exit.suggester.onExit(exitParameters); | ||
change.suggester.onChange(changeParameters); | ||
} | ||
this.removed = false; | ||
return; | ||
} | ||
if (change) { | ||
change.suggester.onChange(this.createReasonParameter(change)); | ||
} | ||
if (exit && shouldRunExit()) { | ||
exit.suggester.onExit(this.createReasonParameter(exit)); | ||
this.removed = false; | ||
if (isInvalidSplitReason(exit.reason)) { | ||
this.handlerMatches = object(); | ||
} | ||
} | ||
_defineProperty(this, "setMarkRemoved", () => { | ||
_classPrivateFieldSet(this, _removed, true); | ||
}); | ||
@@ -811,4 +799,5 @@ | ||
var to = from + char.length; | ||
var suggester = this.suggesters.find(value => value.name === name); | ||
var suggester = _classPrivateFieldGet(this, _suggesters).find(value => value.name === name); | ||
if (!suggester) { | ||
@@ -828,3 +817,4 @@ throw new Error("No suggester exists for the name provided: ".concat(name)); | ||
}); | ||
this.ignored = this.ignored.add(this.view.state.doc, [decoration]); | ||
_classPrivateFieldSet(this, _ignored, _classPrivateFieldGet(this, _ignored).add(this.view.state.doc, [decoration])); | ||
}); | ||
@@ -836,3 +826,5 @@ | ||
name = _ref2.name; | ||
var decorations = this.ignored.find(from, from + char.length); | ||
var decorations = _classPrivateFieldGet(this, _ignored).find(from, from + char.length); | ||
var decoration = decorations[0]; | ||
@@ -844,3 +836,3 @@ | ||
this.ignored = this.ignored.remove([decoration]); | ||
_classPrivateFieldSet(this, _ignored, _classPrivateFieldGet(this, _ignored).remove([decoration])); | ||
}); | ||
@@ -850,3 +842,4 @@ | ||
if (name) { | ||
var decorations = this.ignored.find(); | ||
var decorations = _classPrivateFieldGet(this, _ignored).find(); | ||
var decorationsToClear = decorations.filter((_ref3) => { | ||
@@ -856,21 +849,12 @@ var spec = _ref3.spec; | ||
}); | ||
this.ignored = this.ignored.remove(decorationsToClear); | ||
_classPrivateFieldSet(this, _ignored, _classPrivateFieldGet(this, _ignored).remove(decorationsToClear)); | ||
} else { | ||
this.ignored = DecorationSet.empty; | ||
_classPrivateFieldSet(this, _ignored, DecorationSet.empty); | ||
} | ||
}); | ||
var names = []; | ||
this.suggesters = suggesters.map(suggester => { | ||
if (names.includes(suggester.name)) { | ||
throw new Error("A suggester already exists with the name '".concat(suggester.name, "'. The name provided must be unique.")); | ||
} | ||
var mapper = createSuggesterMapper(); | ||
var clone = _objectSpread$1(_objectSpread$1({}, DEFAULT_SUGGESTER), suggester); // Preserve any descriptors (getters and setters) | ||
mergeDescriptors(clone, suggester); | ||
names.push(suggester.name); | ||
return clone; | ||
}); | ||
_classPrivateFieldSet(this, _suggesters, suggesters.map(mapper)); | ||
} | ||
@@ -900,3 +884,3 @@ /** | ||
view: this.view, | ||
setMarkRemoved: this.setRemovedTrue, | ||
setMarkRemoved: this.setMarkRemoved, | ||
addIgnored: this.addIgnored, | ||
@@ -932,2 +916,16 @@ clearIgnored: this.clearIgnored, | ||
/** | ||
* Check whether the exit callback is valid at this time. | ||
*/ | ||
shouldRunExit() { | ||
if (_classPrivateFieldGet(this, _ignoreNextExit)) { | ||
_classPrivateFieldSet(this, _ignoreNextExit, false); | ||
return false; | ||
} | ||
return true; | ||
} | ||
/** | ||
* Manages the view updates. | ||
@@ -937,2 +935,51 @@ */ | ||
onViewUpdate() { | ||
var _classPrivateFieldGet2 = _classPrivateFieldGet(this, _handlerMatches), | ||
change = _classPrivateFieldGet2.change, | ||
exit = _classPrivateFieldGet2.exit; | ||
var match = this.match; // Cancel update when a suggester isn't active | ||
if (!change && !exit || !isValidMatch(match)) { | ||
return; | ||
} // When a jump happens run the action that involves the | ||
// position that occurs later in the document. This is so that changes don't | ||
// affect previous positions. | ||
if (change && exit && isJumpReason({ | ||
change, | ||
exit | ||
})) { | ||
var exitParameters = this.createReasonParameter(exit); | ||
var changeParameters = this.createReasonParameter(change); | ||
var movedForwards = exit.range.from < change.range.from; | ||
if (movedForwards) { | ||
change.suggester.onChange(changeParameters); | ||
this.shouldRunExit() && exit.suggester.onExit(exitParameters); | ||
} else { | ||
this.shouldRunExit() && exit.suggester.onExit(exitParameters); | ||
change.suggester.onChange(changeParameters); | ||
} | ||
_classPrivateFieldSet(this, _removed, false); | ||
return; | ||
} | ||
if (change) { | ||
change.suggester.onChange(this.createReasonParameter(change)); | ||
} | ||
if (exit && this.shouldRunExit()) { | ||
exit.suggester.onExit(this.createReasonParameter(exit)); | ||
_classPrivateFieldSet(this, _removed, false); | ||
if (isInvalidSplitReason(exit.reason)) { | ||
_classPrivateFieldSet(this, _handlerMatches, object()); | ||
} | ||
} | ||
} | ||
/** | ||
@@ -942,5 +989,8 @@ * Update the current ignored decorations based on the latest changes to the | ||
*/ | ||
mapIgnoredDecorations(tr) { | ||
// Map over and update the ignored decorations. | ||
var ignored = this.ignored.map(tr.mapping, tr.doc); | ||
var ignored = _classPrivateFieldGet(this, _ignored).map(tr.mapping, tr.doc); | ||
var decorations = ignored.find(); // For suggesters with multiple characters it is possible for a `paste` or | ||
@@ -962,3 +1012,4 @@ // any edit action within the decoration to expand the ignored section. We | ||
}); | ||
this.ignored = ignored.remove(invalid); | ||
_classPrivateFieldSet(this, _ignored, ignored.remove(invalid)); | ||
} | ||
@@ -969,3 +1020,5 @@ | ||
name = _ref5.suggester.name; | ||
var decorations = this.ignored.find(); | ||
var decorations = _classPrivateFieldGet(this, _ignored).find(); | ||
return decorations.some((_ref6) => { | ||
@@ -989,5 +1042,7 @@ var spec = _ref6.spec, | ||
resetState() { | ||
this.handlerMatches = object(); | ||
this.next = undefined; | ||
this.removed = false; | ||
_classPrivateFieldSet(this, _handlerMatches, object()); | ||
_classPrivateFieldSet(this, _next, undefined); | ||
_classPrivateFieldSet(this, _removed, false); | ||
} | ||
@@ -999,19 +1054,53 @@ /** | ||
updateReasons(_ref7) { | ||
var $pos = _ref7.$pos, | ||
state = _ref7.state; | ||
var match = findFromSuggestions({ | ||
suggesters: this.suggesters, | ||
$pos | ||
}); | ||
this.next = match && this.shouldIgnoreMatch(match) ? undefined : match; // Store the matches with reasons | ||
updateReasons(parameter) { | ||
var $pos = parameter.$pos, | ||
state = parameter.state; | ||
this.handlerMatches = findReason({ | ||
next: this.next, | ||
prev: this.prev, | ||
var docChanged = _classPrivateFieldGet(this, _docChanged); | ||
var match = findFromSuggesters({ | ||
suggesters: _classPrivateFieldGet(this, _suggesters), | ||
$pos, | ||
docChanged | ||
}); // Track the next match if not being ignored. | ||
_classPrivateFieldSet(this, _next, match && this.shouldIgnoreMatch(match) ? undefined : match); // Store the matches with reasons | ||
_classPrivateFieldSet(this, _handlerMatches, findReason({ | ||
next: _classPrivateFieldGet(this, _next), | ||
prev: _classPrivateFieldGet(this, _prev), | ||
state, | ||
$pos | ||
}); | ||
})); | ||
} | ||
/** | ||
* Add a new suggest or replace it if it already exists. | ||
*/ | ||
addSuggester(suggester) { | ||
var previous = _classPrivateFieldGet(this, _suggesters).find(item => item.name === suggester.name); | ||
var mapper = createSuggesterMapper(); | ||
if (previous) { | ||
_classPrivateFieldSet(this, _suggesters, _classPrivateFieldGet(this, _suggesters).map(item => item === previous ? mapper(suggester) : item)); | ||
} else { | ||
_classPrivateFieldSet(this, _suggesters, [..._classPrivateFieldGet(this, _suggesters), mapper(suggester)]); | ||
} | ||
return () => this.removeSuggester(suggester.name); | ||
} | ||
/** | ||
* Remove a suggester if it exists. | ||
*/ | ||
removeSuggester(suggester) { | ||
var name = isString(suggester) ? suggester : suggester.name; | ||
_classPrivateFieldSet(this, _suggesters, _classPrivateFieldGet(this, _suggesters).filter(item => item.name !== name)); | ||
} | ||
/** | ||
* Used to handle the view property of the plugin spec. | ||
@@ -1023,3 +1112,3 @@ */ | ||
return { | ||
update: this.onViewUpdate | ||
update: this.onViewUpdate.bind(this) | ||
}; | ||
@@ -1038,19 +1127,27 @@ } | ||
apply(_ref8) { | ||
var tr = _ref8.tr, | ||
newState = _ref8.newState; | ||
var exit = this.handlerMatches.exit; | ||
apply(_ref7) { | ||
var tr = _ref7.tr, | ||
newState = _ref7.newState; | ||
if (!hasTransactionChanged(tr) && !this.removed) { | ||
var _classPrivateFieldGet3 = _classPrivateFieldGet(this, _handlerMatches), | ||
exit = _classPrivateFieldGet3.exit; | ||
var transactionHasChanged = tr.docChanged || tr.selectionSet; | ||
if (!transactionHasChanged && !_classPrivateFieldGet(this, _removed)) { | ||
return this; | ||
} | ||
this.mapIgnoredDecorations(tr); // If the previous run was an exit reset the suggestion matches | ||
_classPrivateFieldSet(this, _docChanged, tr.docChanged); | ||
this.mapIgnoredDecorations(tr); // If the previous run was an exit, reset the suggester matches. | ||
if (exit) { | ||
this.resetState(); | ||
} | ||
} // Track the previous match. | ||
this.prev = this.next; // Match against the current selection position | ||
_classPrivateFieldSet(this, _prev, _classPrivateFieldGet(this, _next)); // Match against the current selection position | ||
this.updateReasons({ | ||
@@ -1080,3 +1177,3 @@ $pos: tr.selection.$from, | ||
event, | ||
setMarkRemoved: this.setRemovedTrue | ||
setMarkRemoved: this.setMarkRemoved | ||
}, this.createParameter(match)); // TODO recalculating the keybindings on every update this is a performance bottleneck | ||
@@ -1092,6 +1189,6 @@ | ||
handleTextInput(_ref9) { | ||
var text = _ref9.text, | ||
from = _ref9.from, | ||
to = _ref9.to; | ||
handleTextInput(_ref8) { | ||
var text = _ref8.text, | ||
from = _ref8.from, | ||
to = _ref8.to; | ||
var match = this.match; | ||
@@ -1120,7 +1217,7 @@ | ||
if (!isValidMatch(match)) { | ||
return this.ignored; | ||
return _classPrivateFieldGet(this, _ignored); | ||
} | ||
if (match.suggester.noDecorations) { | ||
return this.ignored; | ||
return _classPrivateFieldGet(this, _ignored); | ||
} | ||
@@ -1131,9 +1228,9 @@ | ||
name = _match$suggester.name, | ||
decorationsTag = _match$suggester.suggestTag, | ||
suggestionClassName = _match$suggester.suggestClassName; | ||
suggestTag = _match$suggester.suggestTag, | ||
suggestClassName = _match$suggester.suggestClassName; | ||
var from = range.from, | ||
end = range.end; | ||
return this.shouldIgnoreMatch(match) ? this.ignored : this.ignored.add(state.doc, [Decoration.inline(from, end, { | ||
nodeName: decorationsTag, | ||
class: name ? "".concat(suggestionClassName, " ").concat(suggestionClassName, "-").concat(name) : suggestionClassName | ||
return this.shouldIgnoreMatch(match) ? _classPrivateFieldGet(this, _ignored) : _classPrivateFieldGet(this, _ignored).add(state.doc, [Decoration.inline(from, end, { | ||
nodeName: suggestTag, | ||
class: name ? "".concat(suggestClassName, " ").concat(suggestClassName, "-").concat(name) : suggestClassName | ||
})]); | ||
@@ -1144,2 +1241,18 @@ } | ||
function createSuggesterMapper() { | ||
var names = new Set(); | ||
return suggester => { | ||
if (names.has(suggester.name)) { | ||
throw new Error("A suggester already exists with the name '".concat(suggester.name, "'. The name provided must be unique.")); | ||
} | ||
var clone = _objectSpread$1(_objectSpread$1({}, DEFAULT_SUGGESTER), suggester); // Preserve any descriptors (getters and setters) | ||
mergeDescriptors(clone, suggester); | ||
names.add(suggester.name); | ||
return clone; | ||
}; | ||
} | ||
var suggestPluginKey = /*#__PURE__*/new PluginKey('suggest'); | ||
@@ -1153,10 +1266,28 @@ /** | ||
function getSuggestPluginState(state) { | ||
return getPluginState(suggestPluginKey, state); | ||
return suggestPluginKey.getState(state); | ||
} | ||
/** | ||
* This creates a suggestion plugin with all the suggesters provided. | ||
* Add a new suggester or replace it if the name already exists in the existing | ||
* configuration. | ||
* | ||
* Will return a function for disposing of the added suggester. | ||
*/ | ||
function addSuggester(state, suggester) { | ||
return getSuggestPluginState(state).addSuggester(suggester); | ||
} | ||
/** | ||
* Remove a suggester if it exists. Pass in the name or the full suggester | ||
* object. | ||
*/ | ||
function removeSuggester(state, suggester) { | ||
return getSuggestPluginState(state).removeSuggester(suggester); | ||
} | ||
/** | ||
* This creates a suggest plugin with all the suggesters provided. | ||
* | ||
* @remarks | ||
* | ||
* In the following example we're creating an emoji suggestion plugin that | ||
* In the following example we're creating an emoji suggest plugin that | ||
* responds to the colon character with a query and presents a list of matching | ||
@@ -1166,3 +1297,3 @@ * emojis based on the query typed so far. | ||
* ```ts | ||
* import { Suggestion, suggest } from 'prosemirror-suggest'; | ||
* import { Suggester, suggest } from 'prosemirror-suggest'; | ||
* | ||
@@ -1174,3 +1305,3 @@ * const maxResults = 10; | ||
* | ||
* const suggestEmojis: Suggestion = { | ||
* const suggestEmojis: Suggester = { | ||
* // By default decorations are used to highlight the currently matched | ||
@@ -1233,7 +1364,7 @@ * // suggestion in the dom. | ||
* // Create the plugin with the above configuration. It also supports multiple plugins being added. | ||
* const suggestionPlugin = suggest(suggestEmojis); | ||
* const suggesterPlugin = suggest(suggestEmojis); | ||
* | ||
* // Include the plugin in the created editor state. | ||
* const state = EditorState.create({schema, | ||
* plugins: [suggestionPlugin], | ||
* plugins: [suggesterPlugin], | ||
* }); | ||
@@ -1248,4 +1379,4 @@ * ``` | ||
* | ||
* Only one suggestion can match at any given time. The order and specificity of | ||
* the regex parameters help determines which suggestion will be active. | ||
* Only one suggester can match at any given time. The order and specificity of | ||
* the regex parameters help determines which suggester will be active. | ||
* | ||
@@ -1283,3 +1414,3 @@ * @param suggesters - a list of suggesters in the order they should be | ||
props: { | ||
// Call the keydown hook if suggestion is active. | ||
// Call the keydown hook if suggester is active. | ||
handleKeyDown: (_, event) => { | ||
@@ -1305,2 +1436,2 @@ return pluginState.handleKeyDown(event); | ||
export { ChangeReason, DEFAULT_SUGGESTER, DEFAULT_SUGGEST_ACTIONS, ExitReason, createRegexFromSuggestion, escapeChar, getRegexPrefix, getSuggestPluginState, isChange, isChangeReason, isEntry, isExit, isExitReason, isInvalidSplitReason, isJump, isJumpReason, isMove, isRemovedReason, isSelectionExitReason, isSplitReason, isValidMatch, regexToString, selectionOutsideMatch, suggest }; | ||
export { ChangeReason, DEFAULT_SUGGESTER, ExitReason, addSuggester, createRegexFromSuggester, escapeChar, getRegexPrefix, getSuggestPluginState, isChange, isChangeReason, isEntry, isExit, isExitReason, isInvalidSplitReason, isJump, isJumpReason, isMove, isRemovedReason, isSelectionExitReason, isSplitReason, isValidMatch, regexToString, removeSuggester, selectionOutsideMatch, suggest }; |
{ | ||
"name": "prosemirror-suggest", | ||
"version": "1.0.0-next.3", | ||
"version": "1.0.0-next.4", | ||
"description": "Primitives for building your prosemirror suggestion and autocomplete functionality", | ||
@@ -14,2 +14,6 @@ "homepage": "https://github.com/remirror/remirror/tree/HEAD/packages/prosemirror-suggest", | ||
"module": "dist/prosemirror-suggest.esm.js", | ||
"browser": { | ||
"./dist/prosemirror-suggest.cjs.js": "./dist/prosemirror-suggest.browser.cjs.js", | ||
"./dist/prosemirror-suggest.esm.js": "./dist/prosemirror-suggest.browser.esm.js" | ||
}, | ||
"types": "dist/prosemirror-suggest.cjs.d.ts", | ||
@@ -20,22 +24,37 @@ "files": [ | ||
"dependencies": { | ||
"@babel/runtime": "^7.10.5", | ||
"@remirror/core-constants": "^1.0.0-next.4", | ||
"@remirror/core-helpers": "^1.0.0-next.4", | ||
"@remirror/core-types": "^1.0.0-next.4", | ||
"@remirror/core-utils": "^1.0.0-next.8", | ||
"@babel/runtime": "^7.11.0", | ||
"@remirror/core-constants": "1.0.0-next.16", | ||
"@remirror/core-helpers": "1.0.0-next.16", | ||
"@remirror/core-types": "1.0.0-next.16", | ||
"@types/merge-descriptors": "1.0.1", | ||
"escape-string-regexp": "^4.0.0", | ||
"merge-descriptors": "1.0.1" | ||
}, | ||
"devDependencies": { | ||
"@types/prosemirror-keymap": "^1.0.3", | ||
"@types/prosemirror-state": "^1.2.5", | ||
"@types/prosemirror-view": "^1.15.0", | ||
"escape-string-regexp": "^4.0.0", | ||
"merge-descriptors": "1.0.1", | ||
"prosemirror-keymap": "^1.1.4", | ||
"prosemirror-state": "^1.3.3" | ||
}, | ||
"devDependencies": { | ||
"prosemirror-state": "^1.3.3", | ||
"prosemirror-view": "^1.15.2" | ||
}, | ||
"peerDependencies": { | ||
"@types/prosemirror-keymap": "^1.0.3", | ||
"@types/prosemirror-state": "^1.2.5", | ||
"@types/prosemirror-view": "^1.15.0", | ||
"prosemirror-keymap": "^1.1.4", | ||
"prosemirror-state": "^1.3.3", | ||
"prosemirror-view": "^1.14.9" | ||
}, | ||
"peerDependenciesMeta": { | ||
"@types/prosemirror-keymap": { | ||
"optional": true | ||
}, | ||
"@types/prosemirror-state": { | ||
"optional": true | ||
}, | ||
"@types/prosemirror-view": { | ||
"optional": true | ||
} | ||
}, | ||
"publishConfig": { | ||
@@ -45,4 +64,4 @@ "access": "public" | ||
"meta": { | ||
"sizeLimit": "50 KB" | ||
"sizeLimit": "10 KB" | ||
} | ||
} |
221
readme.md
# prosemirror-suggest | ||
[![npm bundle size (scoped)](https://img.shields.io/bundlephobia/minzip/prosemirror-suggest.svg?)](https://bundlephobia.com/result?p=prosemirror-suggest) | ||
[![npm](https://img.shields.io/npm/dm/prosemirror-suggest.svg?&logo=npm)](https://www.npmjs.com/package/prosemirror-suggest) | ||
> Primitives for building your prosemirror suggestion and autocomplete functionality. | ||
Primitives for building your prosemirror suggestion and autocomplete functionality. | ||
[![Version][version]][npm] [![Weekly Downloads][downloads-badge]][npm] | ||
[![Bundled size][size-badge]][size] [![Typed Codebase][typescript]](./src/index.ts) | ||
![MIT License][license] | ||
[version]: https://flat.badgen.net/npm/v/prosemirror-suggest | ||
[npm]: https://npmjs.com/package/prosemirror-suggest | ||
[license]: https://flat.badgen.net/badge/license/MIT/purple | ||
[size]: https://bundlephobia.com/result?p=prosemirror-suggest | ||
[size-badge]: https://flat.badgen.net/bundlephobia/minzip/prosemirror-suggest | ||
[typescript]: https://flat.badgen.net/badge/icon/TypeScript?icon=typescript&label | ||
[downloads-badge]: https://badgen.net/npm/dw/prosemirror-suggest/red?icon=npm | ||
<br /> | ||
## The problem | ||
@@ -23,17 +34,27 @@ | ||
<br /> | ||
## Installation | ||
`prosemirror-view` is a peer dependency of `prosemirror-suggest` and needs to be installed as well. | ||
```bash | ||
# yarn | ||
yarn add prosemirror-suggest prosemirror-view prosemirror-state prosemirror-keymap | ||
```bash | ||
yarn add prosemirror-suggest prosemirror-view # yarn | ||
pnpm add prosemirror-suggest prosemirror-view # pnpm | ||
npm add prosemirror-suggest prosemirror-view # npm | ||
# pnpm | ||
pnpm add prosemirror-suggest prosemirror-view prosemirror-state prosemirror-keymap | ||
# npm | ||
npm install prosemirror-suggest prosemirror-view prosemirror-state prosemirror-keymap | ||
``` | ||
The installation requires the installation of the peer dependencies | ||
`prosemirror-view prosemirror-state prosemirror-keymap` to avoid version clashes. | ||
<br /> | ||
## Getting Started | ||
`prosemirror-suggest` uses configuration objects called `Suggestion`<!-- -->'s to define the | ||
`prosemirror-suggest` uses configuration objects called `Suggester`<!-- -->'s to define the | ||
behaviour of the suggesters you create. By calling the exported `suggest` method with all required | ||
`Suggestion`<!-- -->'s the functionality is added to the editor in one plugin. | ||
`Suggester`<!-- -->'s the functionality is added to the editor in one plugin. | ||
@@ -44,3 +65,3 @@ In the following example we're creating an emoji suggestion plugin that responds to the colon | ||
```ts | ||
import { Suggestion, suggest } from 'prosemirror-suggest'; | ||
import { Suggester, suggest } from 'prosemirror-suggest'; | ||
@@ -52,3 +73,3 @@ const maxResults = 10; | ||
const suggestEmojis: Suggestion = { | ||
const suggestEmojis: Suggester = { | ||
// By default decorations are used to highlight the currently matched | ||
@@ -149,3 +170,3 @@ // suggestion in the dom. | ||
```ts | ||
suggest: (...suggesters: Suggestion[]) => Plugin; | ||
suggest: (...suggesters: Suggester[]) => Plugin; | ||
``` | ||
@@ -161,10 +182,10 @@ | ||
Only one suggestion can match at any given time. The order and specificity of the regex parameters | ||
help determines which suggestion will be active. | ||
Only one suggester can match at any given time. The order and specificity of the regex parameters | ||
help determines which suggester will be active. | ||
<br /> | ||
### `Suggestion` | ||
### `Suggester` | ||
This `Suggestion` interface defines all the options required to create a suggestion within your | ||
This `Suggester` interface defines all the options required to create a suggester within your | ||
editor. | ||
@@ -175,3 +196,3 @@ | ||
```typescript | ||
export interface Suggestion<GCommand extends AnyFunction<void> = AnyFunction<void>> | ||
export interface Suggester<GCommand extends AnyFunction<void> = AnyFunction<void>> | ||
``` | ||
@@ -181,31 +202,29 @@ | ||
| Property | Type | Description | | ||
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | | ||
| [appendText](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.appendtext.md) | <code>string</code> | Text to append after the mention has been added. | | ||
| [char](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.char.md) | <code>string</code> | The activation character(s) to match against. | | ||
| [ignoredClassName](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.ignoredclassname.md) | <code>string</code> | Set a class for the ignored suggestion decoration. | | ||
| [ignoredTag](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.ignoredtag.md) | <code>string</code> | Set a tag for the ignored suggestion decoration. | | ||
| [invalidPrefixCharacters](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.invalidprefixcharacters.md) | <code>RegExp | string</code> | A regex expression used to invalidate the text directly before the match. | | ||
| [keyBindings](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.keybindings.md) | <code>SuggestKeyBindingMap<GCommand></code> | An object that describes how certain key bindings should be handled. | | ||
| [matchOffset](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.matchoffset.md) | <code>number</code> | Sets the characters that need to be present after the initial character match before a match is triggered. | | ||
| [name](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.name.md) | <code>string</code> | A unique identifier for the suggester. | | ||
| [noDecorations](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.nodecorations.md) | <code>boolean</code> | When true, decorations are not created when this mention is being edited.. | | ||
| [startOfLine](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.startofline.md) | <code>boolean</code> | Whether to only match from the start of the line | | ||
| [suggestClassName](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.suggestclassname.md) | <code>string</code> | Class name to use for the decoration (while the suggestion is still being written) | | ||
| [suggestTag](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.suggesttag.md) | <code>string</code> | Tag for the prosemirror decoration which wraps an active match. | | ||
| [supportedCharacters](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.supportedcharacters.md) | <code>RegExp | string</code> | A regex containing all supported characters when within a suggestion. | | ||
| [validPrefixCharacters](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.validprefixcharacters.md) | <code>RegExp | string</code> | A regex expression used to validate the text directly before the match. | | ||
| Property | Type | Description | | ||
| ------------------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | | ||
| `appendText` | <code>string</code> | Text to append after the mention has been added. | | ||
| `char` | <code>string</code> | The activation character(s) to match against. | | ||
| `ignoredClassName` | <code>string</code> | Set a class for the ignored suggester decoration. | | ||
| `ignoredTag` | <code>string</code> | Set a tag for the ignored suggester decoration. | | ||
| `invalidPrefixCharacters` | <code>RegExp | string</code> | A regex expression used to invalidate the text directly before the match. | | ||
| `keyBindings` | <code>SuggestKeyBindingMap<GCommand></code> | An object that describes how certain key bindings should be handled. | | ||
| `matchOffset` | <code>number</code> | Sets the characters that need to be present after the initial character match before a match is triggered. | | ||
| `name` | <code>string</code> | A unique identifier for the suggester. | | ||
| `noDecorations` | <code>boolean</code> | When true, decorations are not created when this mention is being edited.. | | ||
| `startOfLine` | <code>boolean</code> | Whether to only match from the start of the line | | ||
| `suggestClassName` | <code>string</code> | Class name to use for the decoration (while the suggester is still being written) | | ||
| `suggestTag` | <code>string</code> | Tag for the prosemirror decoration which wraps an active match. | | ||
| `supportedCharacters` | <code>RegExp | string</code> | A regex containing all supported characters when within a suggester. | | ||
| `validPrefixCharacters` | <code>RegExp | string</code> | A regex expression used to validate the text directly before the match. | | ||
#### Methods | ||
| Method | Description | | ||
| ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | ||
| [createCommand(params)](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.createcommand.md) | Create the suggested actions which are made available to the <code>onExit</code> and on<code>onChange</code> handlers. | | ||
| [onChange(params)](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.onchange.md) | Called whenever a suggestion becomes active or changes in anyway. | | ||
| [onCharacterEntry(params)](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.oncharacterentry.md) | Called for each character entry and can be used to disable certain characters. | | ||
| [onExit(params)](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.onexit.md) | Called when a suggestion is exited with the pre-exit match value. | | ||
| Method | Description | | ||
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | ||
| `createCommand(params)` | Create the suggested actions which are made available to the <code>onExit</code> and on<code>onChange</code> handlers. | | ||
| `onChange(params)` | Called whenever a suggester becomes active or changes in anyway. | | ||
| `onCharacterEntry(params)` | Called for each character entry and can be used to disable certain characters. | | ||
| `onExit(params)` | Called when a suggester is exited with the pre-exit match value. | | ||
The options are passed to the | ||
[suggest](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggest.md) | ||
method which uses them. | ||
The options are passed to the `suggest` method which uses them. | ||
@@ -218,68 +237,68 @@ <br /> | ||
| Enumeration | Description | | ||
| --------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | | ||
| [ChangeReason](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.changereason.md) | The potential reason for changes | | ||
| [ExitReason](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.exitreason.md) | The potential reasons for an exit of a mention. | | ||
| Enumeration | Description | | ||
| -------------- | ----------------------------------------------- | | ||
| `ChangeReason` | The potential reason for changes | | ||
| `ExitReason` | The potential reasons for an exit of a mention. | | ||
### Interfaces | ||
| Interface | Description | | ||
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| [AddIgnoredParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.addignoredparams.md) | The parameters needed for the [SuggestIgnoreParameter.addIgnored()](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggestignoreparams.addignored.md) action method available to the suggest plugin handlers. | | ||
| [CompareMatchParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.comparematchparams.md) | A parameter builder interface which compares the previous and next match. | | ||
| [CreateSuggestCommandParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.createsuggestcommandparams.md) | The parameters passed into the <code>createSuggest</code> suggester property. | | ||
| [FromToEndParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.fromtoendparams.md) | A parameter builder interface describing a <code>from</code>/<code>to</code>/<code>end</code> range. | | ||
| [KeyboardEventParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.keyboardeventparams.md) | A parameter builder interface describing the event which triggers the keyboard event handler. | | ||
| [MatchValue](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.matchvalue.md) | The match value with the full and partial text. | | ||
| [OnKeyDownParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.onkeydownparams.md) | The parameters required by the . | | ||
| [ReasonMatchParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.reasonmatchparams.md) | A parameter builder interface which adds the match property. | | ||
| [ReasonParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.reasonparams.md) | A parameter builder interface indicating the reason the handler was called. | | ||
| [RemoveIgnoredParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.removeignoredparams.md) | The parameters needed for the action method available to the suggest plugin handlers. | | ||
| [SuggestCallbackParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggestcallbackparams.md) | | | ||
| [SuggestChangeHandlerParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggestchangehandlerparams.md) | The parameters passed to the [Suggestion.onChange()](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.onchange.md) method. | | ||
| [SuggestCharacterEntryParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggestcharacterentryparams.md) | The parameters passed to the [Suggestion.onCharacterEntry()](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.oncharacterentry.md) method. | | ||
| [SuggestCommandParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggestcommandparams.md) | A parameter builder interface which adds the command property. | | ||
| [Suggestion](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.md) | This <code>Suggestion</code> interface defines all the options required to create a suggestion within your editor. | | ||
| [SuggestionParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggesterparams.md) | | | ||
| [SuggestExitHandlerParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggestexithandlerparams.md) | The parameters passed to the [Suggestion.onExit()](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.onexit.md) method. | | ||
| [SuggestIgnoreParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggestignoreparams.md) | A parameter builder interface describing the ignore methods available to the [Suggestion](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.md) handlers. | | ||
| [SuggestKeyBindingParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggestkeybindingparams.md) | The parameters required by the [SuggestKeyBinding](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggestkeybinding.md) method. | | ||
| [SuggestMarkParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggestmarkparams.md) | A special parameter needed when creating editable suggester using prosemirror <code>Marks</code>. The method should be called when removing a suggestion that was identified by a prosemirror <code>Mark</code>. | | ||
| [SuggestReasonMap](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggestreasonmap.md) | A mapping of the handler matches with their reasons for occurring within the suggest state. | | ||
| [SuggestStateMatch](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggeststatematch.md) | Describes the properties of a match which includes range and the text as well as information of the suggester that created the match. | | ||
| [SuggestStateMatchParameter](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggeststatematchparams.md) | A parameter builder interface describing match found by the suggest plugin. | | ||
| [SuggestStateMatchReason](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggeststatematchreason.md) | | | ||
| Interface | Description | | ||
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| `AddIgnoredParameter` | The parameters needed for the `SuggestIgnoreParameter.addIgnored()` action method available to the suggest plugin handlers. | | ||
| `CompareMatchParameter` | A parameter builder interface which compares the previous and next match. | | ||
| `CreateSuggestCommandParameter` | The parameters passed into the <code>createSuggest</code> suggester property. | | ||
| `FromToEndParameter` | A parameter builder interface describing a <code>from</code>/<code>to</code>/<code>end</code> range. | | ||
| `KeyboardEventParameter` | A parameter builder interface describing the event which triggers the keyboard event handler. | | ||
| `MatchValue` | The match value with the full and partial text. | | ||
| `OnKeyDownParameter` | The parameters required by the . | | ||
| `ReasonMatchParameter` | A parameter builder interface which adds the match property. | | ||
| `ReasonParameter` | A parameter builder interface indicating the reason the handler was called. | | ||
| `RemoveIgnoredParameter` | The parameters needed for the action method available to the suggest plugin handlers. | | ||
| `SuggestCallbackParameter` | | | ||
| `SuggestChangeHandlerParameter` | The parameters passed to the `Suggester.onChange()` method. | | ||
| `SuggestCharacterEntryParameter` | The parameters passed to the `Suggester.onCharacterEntry()` method. | | ||
| `SuggestCommandParameter` | A parameter builder interface which adds the command property. | | ||
| `Suggester` | This <code>Suggester</code> interface defines all the options required to create a suggestion within your editor. | | ||
| `SuggesterParameter` | | | ||
| `SuggestExitHandlerParameter` | The parameters passed to the `Suggester.onExit()` method. | | ||
| `SuggestIgnoreParameter` | A parameter builder interface describing the ignore methods available to the `Suggester` handlers. | | ||
| `SuggestKeyBindingParameter` | The parameters required by the `SuggestKeyBinding` method. | | ||
| `SuggestMarkParameter` | A special parameter needed when creating editable suggester using prosemirror <code>Marks</code>. The method should be called when removing a suggester that was identified by a prosemirror <code>Mark</code>. | | ||
| `SuggestReasonMap` | A mapping of the handler matches with their reasons for occurring within the suggest state. | | ||
| `SuggestStateMatch` | Describes the properties of a match which includes range and the text as well as information of the suggester that created the match. | | ||
| `SuggestStateMatchParameter` | A parameter builder interface describing match found by the suggest plugin. | | ||
| `SuggestStateMatchReason` | | | ||
### Variables | ||
| Variable | Description | | ||
| ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| [createRegexFromSuggestion](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.createregexfromsuggester.md) | Create a regex expression to evaluate matches directly from the suggester properties. | | ||
| [DEFAULT_SUGGEST_ACTIONS](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.default_suggest_actions.md) | | | ||
| [DEFAULT_SUGGESTER](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.default_suggester.md) | | | ||
| [escapeChar](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.escapechar.md) | | | ||
| [getRegexPrefix](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.getregexprefix.md) | Find regex prefix when depending on whether the mention only supports the start of a line or not | | ||
| [getSuggestPluginState](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.getsuggestpluginstate.md) | Get the state of the suggest plugin. | | ||
| [isChange](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.ischange.md) | Is this a change in the current suggestion (added or deleted characters)? | | ||
| [isChangeReason](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.ischangereason.md) | | | ||
| [isEntry](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.isentry.md) | Are we entering a new suggestion? | | ||
| [isExit](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.isexit.md) | Are we exiting a suggestion? | | ||
| [isExitReason](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.isexitreason.md) | Check that the passed in value is an ExitReason | | ||
| [isInvalidSplitReason](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.isinvalidsplitreason.md) | Checks that the reason was caused by a split at a point where there is no query. | | ||
| [isJump](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.isjump.md) | Is this a jump from one suggestion to another? | | ||
| [isJumpReason](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.isjumpreason.md) | Checks to see if this is a jump reason. | | ||
| [isMove](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.ismove.md) | Has the cursor moved within the current suggestion (added or deleted characters)? | | ||
| [isRemovedReason](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.isremovedreason.md) | Checks that the reason was caused by a deletion. | | ||
| [isSplitReason](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.issplitreason.md) | Checks that the reason passed is a split reason. This typically means that we should default to a partial update / creation of the mention. | | ||
| [isValidMatch](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.isvalidmatch.md) | True when the match is currently active (i.e. it's query has a value) | | ||
| [regexToString](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.regextostring.md) | Convert a RegExp into a string | | ||
| [selectionOutsideMatch](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.selectionoutsidematch.md) | True when the current selection is outside the match. | | ||
| [suggest](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggest.md) | This creates a suggestion plugin with all the suggesters provided. | | ||
| Variable | Description | | ||
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| `createRegexFromSuggester` | Create a regex expression to evaluate matches directly from the suggester properties. | | ||
| `DEFAULT_SUGGEST_ACTIONS` | | | ||
| `DEFAULT_SUGGESTER` | | | ||
| `escapeChar` | | | ||
| `getRegexPrefix` | Find regex prefix when depending on whether the mention only supports the start of a line or not | | ||
| `getSuggestPluginState` | Get the state of the suggest plugin. | | ||
| `isChange` | Is this a change in the current suggestion (added or deleted characters)? | | ||
| `isChangeReason` | | | ||
| `isEntry` | Are we entering a new suggestion? | | ||
| `isExit` | Are we exiting a suggestion? | | ||
| `isExitReason` | Check that the passed in value is an ExitReason | | ||
| `isInvalidSplitReason` | Checks that the reason was caused by a split at a point where there is no query. | | ||
| `isJump` | Is this a jump from one suggestion to another? | | ||
| `isJumpReason` | Checks to see if this is a jump reason. | | ||
| `isMove` | Has the cursor moved within the current suggestion (added or deleted characters)? | | ||
| `isRemovedReason` | Checks that the reason was caused by a deletion. | | ||
| `isSplitReason` | Checks that the reason passed is a split reason. This typically means that we should default to a partial update / creation of the mention. | | ||
| `isValidMatch` | True when the match is currently active (i.e. it's query has a value) | | ||
| `regexToString` | Convert a RegExp into a string | | ||
| `selectionOutsideMatch` | True when the current selection is outside the match. | | ||
| `suggest` | This creates a suggestion plugin with all the suggesters provided. | | ||
### Type Aliases | ||
| Type Alias | Description | | ||
| ----------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| [SuggestKeyBinding](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggestkeybinding.md) | A method for performing actions when a certain key / pattern is pressed. | | ||
| [SuggestKeyBindingMap](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggestkeybindingmap.md) | The keybindings shape for the [Suggestion.keyBindings](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggester.keybindings.md) property. | | ||
| [SuggestReplacementType](https://github.com/remirror/remirror/blob/master/docs/api/prosemirror-suggest/prosemirror-suggest.suggestreplacementtype.md) | Determines whether to replace the full match or the partial match (up to the cursor position). | | ||
| Type Alias | Description | | ||
| ------------------------ | ---------------------------------------------------------------------------------------------- | | ||
| `SuggestKeyBinding` | A method for performing actions when a certain key / pattern is pressed. | | ||
| `SuggestKeyBindingMap` | The keybindings shape for the `Suggester.keyBindings` property. | | ||
| `SuggestReplacementType` | Determines whether to replace the full match or the partial match (up to the cursor position). | |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
271145
13
19
6500
297
6
+ Added@remirror/core-constants@1.0.0-next.16(transitive)
+ Added@remirror/core-helpers@1.0.0-next.16(transitive)
+ Added@remirror/core-types@1.0.0-next.16(transitive)
+ Added@remirror/pm@1.0.0-next.16(transitive)
+ Addedprosemirror-commands@1.6.2(transitive)
+ Addedprosemirror-dropcursor@1.8.1(transitive)
+ Addedprosemirror-gapcursor@1.3.2(transitive)
+ Addedprosemirror-history@1.4.1(transitive)
+ Addedprosemirror-inputrules@1.4.0(transitive)
+ Addedprosemirror-schema-list@1.5.0(transitive)
+ Addedprosemirror-tables@1.6.1(transitive)
+ Addedprosemirror-transform@1.10.2(transitive)
+ Addedthrottle-debounce@2.3.0(transitive)
+ Addedtype-fest@0.16.0(transitive)
- Removed@remirror/core-utils@^1.0.0-next.8
- Removed@types/prosemirror-keymap@^1.0.3
- Removed@types/prosemirror-state@^1.2.5
- Removed@types/prosemirror-view@^1.15.0
- Removedprosemirror-keymap@^1.1.4
- Removedprosemirror-state@^1.3.3
- Removed@linaria/core@3.0.0-beta.13(transitive)
- Removed@lingui/core@3.17.2(transitive)
- Removed@messageformat/parser@5.1.0(transitive)
- Removed@remirror/core-constants@1.0.2(transitive)
- Removed@remirror/core-helpers@1.0.6(transitive)
- Removed@remirror/core-types@1.0.4(transitive)
- Removed@remirror/core-utils@1.1.11(transitive)
- Removed@remirror/messages@1.0.7(transitive)
- Removed@remirror/pm@1.0.22(transitive)
- Removed@remirror/types@0.1.1(transitive)
- Removed@types/min-document@2.19.2(transitive)
- Removed@types/prosemirror-collab@1.3.0(transitive)
- Removedcss-in-js-utils@3.1.0(transitive)
- Removeddash-get@1.0.2(transitive)
- Removeddom-walk@0.1.2(transitive)
- Removedhyphenate-style-name@1.1.0(transitive)
- Removedmake-plural@6.2.2(transitive)
- Removedmin-document@2.19.0(transitive)
- Removedmoo@0.5.2(transitive)
- Removedorderedmap@1.1.8(transitive)
- Removedparenthesis@3.1.8(transitive)
- Removedprosemirror-collab@1.2.2(transitive)
- Removedprosemirror-commands@1.2.2(transitive)
- Removedprosemirror-dropcursor@1.4.0(transitive)
- Removedprosemirror-gapcursor@1.2.2(transitive)
- Removedprosemirror-history@1.2.0(transitive)
- Removedprosemirror-inputrules@1.1.3(transitive)
- Removedprosemirror-keymap@1.1.5(transitive)
- Removedprosemirror-model@1.16.1(transitive)
- Removedprosemirror-paste-rules@1.1.3(transitive)
- Removedprosemirror-schema-list@1.1.6(transitive)
- Removedprosemirror-state@1.3.4(transitive)
- Removedprosemirror-suggest@1.1.4(transitive)
- Removedprosemirror-tables@1.1.2(transitive)
- Removedprosemirror-trailing-node@1.0.11(transitive)
- Removedprosemirror-transform@1.4.2(transitive)
- Removedprosemirror-view@1.23.13(transitive)
- Removedthrottle-debounce@3.0.1(transitive)
- Removedtype-fest@1.4.0(transitive)
Updated@babel/runtime@^7.11.0