import type { InsertOptions } from '../public/mathfield' ; import { ModeEditor } from './mode-editor' ; import { MathfieldPrivate } from './mathfield-private' ; import { requestUpdate } from './render' ; import { parseLatex } from '../core/core' ; import { Atom } from '../core/atom-class' ; import { ModelPrivate } from '../editor-model/model-private' ; import { range } from '../editor-model/selection-utils' ; import { applyStyleToUnstyledAtoms } from '../editor-model/styling' ; import { contentDidChange } from '../editor-model/listeners' ; export class TextModeEditor extends ModeEditor { constructor ( ) { super ( 'text' ) ; } onPaste ( mathfield , ev ) { if ( ! ev . clipboardData ) return false ; const text = ev . clipboardData . getData ( 'text/plain' ) ; if ( text ) { mathfield . snapshot ( ) ; if ( this . insert ( mathfield . model , text ) ) { requestUpdate ( mathfield ) ; } ev . preventDefault ( ) ; ev . stopPropagation ( ) ; return true ; } return false ; } insert ( model , text , options = { } ) { if ( ! options . insertionMode ) options . insertionMode = 'replaceSelection' ; if ( ! options . selectionMode ) options . selectionMode = 'placeholder' ; if ( ! options . format ) options . format = 'auto' ; options . macros = options . macros ?? model . options . macros ; const { suppressChangeNotifications } = model ; if ( options . suppressChangeNotifications ) { model . suppressChangeNotifications = true ; } const contentWasChanging = model . suppressChangeNotifications ; model . suppressChangeNotifications = true ; if ( options . insertionMode === 'replaceSelection' && ! model . selectionIsCollapsed ) { model . position = model . deleteAtoms ( range ( model . selection ) ) ; } else if ( options . insertionMode === 'replaceAll' ) { model . root . setChildren ( [ ] , 'body' ) ; model . position = 0 ; } else if ( options . insertionMode === 'insertBefore' ) { model . collapseSelection ( 'backward' ) ; } else if ( options . insertionMode === 'insertAfter' ) { model . collapseSelection ( 'forward' ) ; } const newAtoms = convertStringToAtoms ( text ) ; applyStyleToUnstyledAtoms ( newAtoms , options . style ) ; if ( ! newAtoms ) return false ; const cursor = model . at ( model . position ) ; const lastNewAtom = cursor . parent ! . addChildrenAfter ( newAtoms , cursor ) ; model . suppressChangeNotifications = contentWasChanging ; if ( options . selectionMode === 'before' ) { } else if ( options . selectionMode === 'item' ) { model . setSelection ( model . anchor , model . offsetOf ( lastNewAtom ) ) ; } else if ( lastNewAtom ) { model . position = model . offsetOf ( lastNewAtom ) ; } contentDidChange ( model ) ; model . suppressChangeNotifications = suppressChangeNotifications ; return true ; } } function convertStringToAtoms ( s ) { s = s . replace ( /\\/g , '\\textbackslash ' ) ; s = s . replace ( /#/g , '\\#' ) ; s = s . replace ( /\$/g , '\\$' ) ; s = s . replace ( /%/g , '\\%' ) ; s = s . replace ( /&/g , '\\&' ) ; s = s . replace ( /_/g , '\\_' ) ; s = s . replace ( /{/g , '\\textbraceleft ' ) ; s = s . replace ( /}/g , '\\textbraceright ' ) ; s = s . replace ( /\^/g , '\\textasciicircum ' ) ; s = s . replace ( /~/g , '\\textasciitilde ' ) ; s = s . replace ( /£/g , '\\textsterling ' ) ; return parseLatex ( s , { parseMode : 'text' , registers : { } } ) ; } new TextModeEditor ( ) ;