import { NodeType , Schema as EditorSchema } from 'prosemirror-model' ; import { Plugin , PluginKey } from 'prosemirror-state' ; import { includes , uniqueArray } from '@remirror/core-helpers' ; export interface TrailingNodePluginOptions { default nodeName ? : string ; /**
     * The nodes for which this rule should not apply.
     */ ignoredNodes ? : string [ ] ; } const trailingNodePluginKey = new PluginKey < boolean > ( 'trailingNode' ) ; param options export function trailingNode < Schema extends EditorSchema < string , string > = EditorSchema < string , string > > ( options ? ) { const { ignoredNodes = [ ] , nodeName = 'paragraph' } = options ?? { } ; const ignoredNodeNames = uniqueArray ( [ ... ignoredNodes , nodeName ] ) ; let type ; let types ; return new Plugin < boolean , Schema > ( { key : trailingNodePluginKey , appendTransaction ( _ , __ , state ) { const { doc , tr } = state ; const shouldInsertNodeAtEnd = trailingNodePluginKey . getState ( state ) ; const endPosition = doc . content . size ; if ( ! shouldInsertNodeAtEnd ) { return ; } return tr . insert ( endPosition , type . create ( ) ) ; } , state : { init : ( _ , { doc , schema } ) => { const nodeType = schema . nodes [ nodeName ] ; if ( ! nodeType ) { throw new Error ( `Invalid node being used for trailing node extension: '${ nodeName }'` ) ; } type = nodeType ; types = Object . values ( schema . nodes ) . map ( ( node ) => node ) . filter ( ( node ) => ! ignoredNodeNames . includes ( node . name ) ) ; return includes ( types , doc . lastChild ?. type ) ; } , apply : ( tr , value ) => { if ( ! tr . docChanged ) { return value ; } return includes ( types , tr . doc . lastChild ?. type ) ; } , } , } ) ; }