1- import CodeMirror , { Doc , DocConstructor , Editor , EditorConfiguration , EditorFromTextArea } from 'codemirror' ;
1+ import CodeMirror from 'codemirror' ;
22import 'codemirror/mode/markdown/markdown' ;
33import React , { Component } from 'react' ;
4- import { IReactCodeMirrorState } from '../../common/codemirror' ;
5- import { HTMLDivProps , IProps } from '../../common/props' ;
4+ import { DomEvent , IDefineModeOptions , IEventDict , IGetSelectionOptions , IInstance , ISetScrollOptions , ISetSelectionOptions } from '../../common/codemirror' ;
5+ import { IProps } from '../../common/props' ;
66import './codemirror.less' ;
77import './index.less' ;
88
9- export interface IReactCodeMirrorProps extends IProps , HTMLDivProps {
9+ declare let global : any ;
10+ declare let require : any ;
11+
12+ const SERVER_RENDERED = ( typeof navigator === 'undefined' || global . PREVENT_CODEMIRROR_RENDER === true ) ;
13+
14+ let cm : any ;
15+ if ( ! SERVER_RENDERED ) {
16+ // tslint:disable-next-line: no-var-requires
17+ cm = require ( 'codemirror' ) ;
18+ }
19+
20+ export interface ICodeMirror extends IProps {
1021 value ?: string ,
11- options : EditorConfiguration ,
1222 width ?: number | string ,
1323 height ?: number | string ,
24+ className ?: string ;
25+ cursor ?: CodeMirror . Position ;
26+ defineMode ?: IDefineModeOptions ;
27+ editorDidConfigure ?: ( editor : IInstance ) => void ;
28+ editorDidMount ?: ( editor : IInstance , value : string , cb : ( ) => void ) => void ;
29+ editorWillMount ?: ( ) => void ;
30+ editorWillUnmount ?: ( lib : any ) => void ;
31+ onClear ?: ( from : CodeMirror . Position , to : CodeMirror . Position ) => void ;
32+ onBlur ?: DomEvent ;
33+ onChange ?: ( editor : IInstance , data : CodeMirror . EditorChange , value : string ) => void ;
34+ onContextMenu ?: DomEvent ;
35+ onCopy ?: DomEvent ;
36+ onCursor ?: ( editor : IInstance , data : CodeMirror . Position ) => void ;
37+ onCut ?: DomEvent ;
38+ onCursorActivity ?: ( editor : IInstance ) => void ;
39+ onDblClick ?: DomEvent ;
40+ onDragEnter ?: DomEvent ;
41+ onDragLeave ?: DomEvent ;
42+ onDragOver ?: DomEvent
43+ onDragStart ?: DomEvent ;
44+ onDrop ?: DomEvent ;
45+ onFocus ?: DomEvent
46+ onGutterClick ?: ( editor : IInstance , lineNumber : number , gutter : string , event : Event ) => void ;
47+ onKeyDown ?: DomEvent ;
48+ onKeyPress ?: DomEvent ;
49+ onKeyUp ?: DomEvent ;
50+ onMouseDown ?: DomEvent ;
51+ onPaste ?: DomEvent ;
52+ onRenderLine ?: ( editor : IInstance , line : CodeMirror . LineHandle , element : HTMLElement ) => void ;
53+ onScroll ?: ( editor : IInstance , data : CodeMirror . ScrollInfo ) => void ;
54+ onSelection ?: ( editor : IInstance , data : IGetSelectionOptions ) => void ;
55+ onTouchStart ?: DomEvent ;
56+ onUpdate ?: ( editor : IInstance ) => void ;
57+ onViewportChange ?: ( editor : IInstance , start : number , end : number ) => void ;
58+ options ?: CodeMirror . EditorConfiguration
59+ selection ?: { ranges : ISetSelectionOptions [ ] , focus ?: boolean } ;
60+ scroll ?: ISetScrollOptions ;
61+ [ key : string ] : any ,
1462}
1563
16- export default class ReactCodeMirror extends Component < IReactCodeMirrorProps , IReactCodeMirrorState > {
17- public static defaultProps : IReactCodeMirrorProps = {
64+
65+ export default class ReactCodeMirror extends Component < ICodeMirror > {
66+ public static defaultProps : ICodeMirror = {
1867 height : '100%' ,
1968 options : {
2069 lineNumbers : true ,
@@ -25,49 +74,79 @@ export default class ReactCodeMirror extends Component<IReactCodeMirrorProps, IR
2574 width : '100%' ,
2675 }
2776 public textarea ! : HTMLTextAreaElement ;
28- // public editor!: CodeMirror.Editor<Doc>;
29- // public editor!: Doc | Editor | EditorFromTextArea;
3077 public editor ! : any ;
31- // public editor!: CodeMirror.Editor | EditorFromTextArea;
32- // public editor!: Doc | EditorFromTextArea;
33- // public editor!: Doc | EditorFromTextArea;
3478 // public editor!: Doc | Editor | EditorFromTextArea | Editor;
35- public constructor ( props : Readonly < IReactCodeMirrorProps > ) {
79+ public constructor ( props : Readonly < ICodeMirror > ) {
3680 super ( props ) ;
3781 }
3882 public render ( ) {
3983 return (
40- < textarea ref = { ( instance : HTMLTextAreaElement ) => { this . textarea = instance ; } } />
41- )
84+ < textarea ref = { ( instance : HTMLTextAreaElement ) => this . textarea = instance } />
85+ ) ;
86+ }
87+
88+ public componentWillMount ( ) {
89+ if ( SERVER_RENDERED ) {
90+ return ;
91+ }
92+
93+ if ( this . props . editorWillMount ) {
94+ this . props . editorWillMount ( ) ;
95+ }
4296 }
4397
4498 public componentDidMount ( ) {
99+ if ( SERVER_RENDERED ) {
100+ return ;
101+ }
45102 this . renderCodeMirror ( this . props ) ;
46103 }
47104
48- public async componentWillReceiveProps ( nextPros : IReactCodeMirrorProps ) {
105+ public async componentWillReceiveProps ( nextPros : ICodeMirror ) {
49106 this . renderCodeMirror ( nextPros ) ;
50107 }
51108
52- private async renderCodeMirror ( props : IReactCodeMirrorProps ) {
109+ // 将props中所有的事件处理函数映射并保存
110+ public getEventHandleFromProps ( ) : IEventDict {
111+ const propNames = Object . keys ( this . props ) ;
112+ const eventHandle = propNames . filter ( ( prop ) => {
113+ return / ^ o n + / . test ( prop ) ;
114+ } ) ;
115+
116+ const eventDict : IEventDict = { } ;
117+ eventHandle . forEach ( ( ele ) => {
118+ eventDict [ ele ] = ele . replace ( / ^ o n [ A - Z ] / g, s => s . slice ( 2 ) . toLowerCase ( ) ) as string ;
119+ } ) ;
120+
121+ return eventDict ;
122+ }
123+
124+ private renderCodeMirror ( props : ICodeMirror ) {
53125 const { value, width, height, options } = props ;
126+
127+ if ( this . props . defineMode ) {
128+ if ( this . props . defineMode . name && this . props . defineMode . fn ) {
129+ cm . defineMode ( this . props . defineMode . name , this . props . defineMode . fn ) ;
130+ }
131+ }
132+
54133 const editorOption = { tabSize : 2 , lineNumbers : true , ...options , mode : 'markdown' }
55134 // 生成codemirror实例
56- this . editor = CodeMirror . fromTextArea ( this . textarea , editorOption ) ;
135+ this . editor = cm . fromTextArea ( this . textarea , editorOption ) as CodeMirror . EditorFromTextArea ;
57136 // 获取CodeMirror用于获取其中的一些常量
58- // this.codemirror = CodeMirror;
59137 // 事件处理映射
60- // const eventDict = this.getEventHandleFromProps();
61- // Object.keys(eventDict).forEach((event: string) => {
62- // this.editor.on(eventDict[event], this.props[event]);
63- // });
138+ const eventDict = this . getEventHandleFromProps ( ) ;
139+ Object . keys ( eventDict ) . forEach ( ( event : string ) => {
140+ const handle = this . props [ event ] ;
141+ this . editor . on ( eventDict [ event ] , handle ) ;
142+ } ) ;
64143
65- // 初始化值
144+ // Init value
66145 this . editor . setValue ( value || '' ) ;
67146 this . editor . setOption ( name , editorOption . mode ) ;
68147
69148 if ( width || height ) {
70- // 设置尺寸
149+ // Setting size
71150 this . editor . setSize ( width , height ) ;
72151 }
73152 }
0 commit comments