import { EditorState , Transaction } from 'prosemirror-state' ; import { EditorView } from 'prosemirror-view' ; import { chainCommands , createParagraphNear , liftEmptyBlock , newlineInCode , splitBlock } from 'prosemirror-commands' ; import { DOMParser } from 'prosemirror-model' ; import MarkCommand from './commands/Mark' ; import ListCommand from './commands/ListItem' ; import LinkCommand , { LinkAttrs } from './commands/Link' ; import HeadingCommand , { HeadingLevels } from './commands/Heading' ; import ImageCommand , { ImageAttrs } from './commands/Image' ; import TextColorCommand from './commands/TextColor' ; import TextAlignCommand , { Align } from './commands/TextAlign' ; const execMark = ( name , toggle = false ) => { return ( state , dispatch ) => { const command = new MarkCommand ( name ) ; if ( ! toggle ) { return command . apply ( ) ( state , dispatch ) ; } return command . toggle ( ) ( state , dispatch ) ; } ; } ; class EditorCommands { private view : EditorView ; private state : EditorState ; private tr : Transaction ; constructor ( view ) { if ( ! view ) { throw Error ( 'NgxEditor: Required view to initialize commands.' ) ; } this . view = view ; this . state = view . state ; this . tr = this . view . state . tr ; } private applyTrx = ( tr ? ) => { this . state = this . state . apply ( tr ?? this . tr ) ; this . tr = this . state . tr ; this . tr . setMeta ( 'APPLIED_TRX' , true ) ; } ; private dispatch = ( tr ) : void => { this . applyTrx ( tr ) ; } ; exec ( ) { if ( ! this . tr . getMeta ( 'APPLIED_TRX' ) ) { return false ; } const forceEmit = ! this . view . state . doc . eq ( this . state . doc ) ; this . view . updateState ( this . state ) ; const tr = this . tr . setMeta ( 'FORCE_EMIT' , forceEmit ) ; this . view . dispatch ( tr ) ; return true ; } focus ( ) { this . view . focus ( ) ; return this ; } scrollIntoView ( ) { this . tr . scrollIntoView ( ) ; this . applyTrx ( ) ; return this ; } insertText ( text ) { this . tr . insertText ( text ) ; this . applyTrx ( ) ; return this ; } insertNewLine ( ) { const newLineCommands = [ newlineInCode , createParagraphNear , liftEmptyBlock , splitBlock ] ; chainCommands ( ... newLineCommands ) ( this . state , this . dispatch ) ; return this ; } applyMark ( name ) { execMark ( name , false ) ( this . state , this . dispatch ) ; return this ; } toggleMark ( name ) { execMark ( name , true ) ( this . state , this . dispatch ) ; return this ; } bold ( ) { execMark ( 'strong' ) ( this . state , this . dispatch ) ; return this ; } toggleBold ( ) { execMark ( 'strong' , true ) ( this . state , this . dispatch ) ; return this ; } italics ( ) { execMark ( 'em' ) ( this . state , this . dispatch ) ; return this ; } toggleItalics ( ) { execMark ( 'em' , true ) ( this . state , this . dispatch ) ; return this ; } underline ( ) { execMark ( 'u' ) ( this . state , this . dispatch ) ; return this ; } toggleUnderline ( ) { execMark ( 'u' , true ) ( this . state , this . dispatch ) ; return this ; } strike ( ) { execMark ( 's' ) ( this . state , this . dispatch ) ; return this ; } toggleStrike ( ) { execMark ( 's' , true ) ( this . state , this . dispatch ) ; return this ; } code ( ) { execMark ( 'code' ) ( this . state , this . dispatch ) ; return this ; } toggleCode ( ) { execMark ( 'code' , true ) ( this . state , this . dispatch ) ; return this ; } toggleOrderedList ( ) { const command = new ListCommand ( false ) ; command . toggle ( ) ( this . state , this . dispatch ) ; return this ; } toggleBulletList ( ) { const command = new ListCommand ( true ) ; command . toggle ( ) ( this . state , this . dispatch ) ; return this ; } toggleHeading ( level ) { const command = new HeadingCommand ( level ) ; command . toggle ( ) ( this . state , this . dispatch ) ; return this ; } insertLink ( text , attrs ) { const command = new LinkCommand ( ) ; command . insert ( text , attrs ) ( this . state , this . dispatch ) ; return this ; } updateLink ( attrs ) { const command = new LinkCommand ( ) ; command . update ( attrs ) ( this . state , this . dispatch ) ; return this ; } insertImage ( src , attrs = { } ) { const command = new ImageCommand ( ) ; command . insert ( src , attrs ) ( this . state , this . dispatch ) ; return this ; } textColor ( color ) { const command = new TextColorCommand ( 'text_color' ) ; command . apply ( { color } ) ( this . state , this . dispatch ) ; return this ; } backgroundColor ( color ) { const command = new TextColorCommand ( 'text_background_color' ) ; command . apply ( { backgroundColor : color } ) ( this . state , this . dispatch ) ; return this ; } removeTextColor ( ) { const command = new TextColorCommand ( 'text_color' ) ; command . remove ( ) ( this . state , this . dispatch ) ; return this ; } removeBackgroundColor ( ) { const command = new TextColorCommand ( 'text_background_color' ) ; command . remove ( ) ( this . state , this . dispatch ) ; return this ; } align ( p ) { const command = new TextAlignCommand ( p ) ; command . toggle ( ) ( this . state , this . dispatch ) ; return this ; } insertHTML ( html ) { const { selection , schema , tr } = this . state ; const { from , to } = selection ; const element = document . createElement ( 'div' ) ; element . innerHTML = html . trim ( ) ; const slice = DOMParser . fromSchema ( schema ) . parseSlice ( element ) ; const transaction = tr . replaceRange ( from , to , slice ) ; this . applyTrx ( transaction ) ; return this ; } } export default EditorCommands ;