11import '@github/markdown-toolbar-element' ;
2+ import $ from 'jquery' ;
23import { attachTribute } from '../tribute.js' ;
34import { hideElem , showElem } from '../../utils/dom.js' ;
45import { initEasyMDEImagePaste , initTextareaImagePaste } from './ImagePaste.js' ;
5- import $ from 'jquery' ;
66import { initMarkupContent } from '../../markup/content.js' ;
77import { handleGlobalEnterQuickSubmit } from './QuickSubmit.js' ;
88import { attachRefIssueContextPopup } from '../contextpopup.js' ;
@@ -39,31 +39,57 @@ class ComboMarkdownEditor {
3939 }
4040
4141 async init ( ) {
42+ this . prepareEasyMDEToolbarActions ( ) ;
43+
44+ this . setupTab ( ) ;
45+ this . setupDropzone ( ) ;
46+
47+ this . setupTextarea ( ) ;
48+
49+ await attachTribute ( this . textarea , { mentions : true , emoji : true } ) ;
50+
51+ if ( this . userPreferredEditor === 'easymde' ) {
52+ await this . switchToEasyMDE ( ) ;
53+ }
54+ }
55+
56+ applyEditorHeights ( el , heights ) {
57+ if ( ! heights ) return ;
58+ if ( heights . minHeight ) el . style . minHeight = heights . minHeight ;
59+ if ( heights . height ) el . style . height = heights . height ;
60+ if ( heights . maxHeight ) el . style . maxHeight = heights . maxHeight ;
61+ }
62+
63+ setupTextarea ( ) {
4264 this . textarea = this . container . querySelector ( '.markdown-text-editor' ) ;
4365 this . textarea . _giteaComboMarkdownEditor = this ;
44- this . textarea . id = `_combo_markdown_editor_${ String ( elementIdCounter ) } ` ;
45- this . textarea . addEventListener ( 'input' , ( e ) => { this . options ?. onContentChanged ?. ( this , e ) } ) ;
66+ this . textarea . id = `_combo_markdown_editor_${ String ( elementIdCounter ++ ) } ` ;
67+ this . textarea . addEventListener ( 'input' , ( e ) => {
68+ this . textareaAutoResize ( ) ;
69+ this . options ?. onContentChanged ?. ( this , e ) ;
70+ } ) ;
71+ this . applyEditorHeights ( this . textarea , this . options . editorHeights ) ;
72+ this . textareaAutoResize ( ) ;
4673 this . textareaMarkdownToolbar = this . container . querySelector ( 'markdown-toolbar' ) ;
4774 this . textareaMarkdownToolbar . setAttribute ( 'for' , this . textarea . id ) ;
4875
49- elementIdCounter ++ ;
50-
5176 this . switchToEasyMDEButton = this . container . querySelector ( '.markdown-switch-easymde' ) ;
5277 this . switchToEasyMDEButton ?. addEventListener ( 'click' , async ( e ) => {
5378 e . preventDefault ( ) ;
79+ this . userPreferredEditor = 'easymde' ;
5480 await this . switchToEasyMDE ( ) ;
5581 } ) ;
5682
57- await attachTribute ( this . textarea , { mentions : true , emoji : true } ) ;
83+ if ( this . dropzone ) {
84+ initTextareaImagePaste ( this . textarea , this . dropzone ) ;
85+ }
86+ }
5887
88+ setupDropzone ( ) {
5989 const dropzoneParentContainer = this . container . getAttribute ( 'data-dropzone-parent-container' ) ;
6090 if ( dropzoneParentContainer ) {
6191 this . dropzone = this . container . closest ( this . container . getAttribute ( 'data-dropzone-parent-container' ) ) ?. querySelector ( '.dropzone' ) ;
62- initTextareaImagePaste ( this . textarea , this . dropzone ) ;
6392 }
64-
65- this . setupTab ( ) ;
66- this . prepareEasyMDEToolbarActions ( ) ;
6793 }
6894
6995 setupTab ( ) {
@@ -134,7 +160,10 @@ class ComboMarkdownEditor {
134160 title : 'Add Checkbox (checked)' ,
135161 } ,
136162 'gitea-switch-to-textarea' : {
137- action : this . switchToTextarea . bind ( this ) ,
163+ action : ( ) => {
164+ this . userPreferredEditor = 'textarea' ;
165+ this . switchToTextarea ( ) ;
166+ } ,
138167 className : 'fa fa-file' ,
139168 title : 'Revert to simple textarea' ,
140169 } ,
@@ -169,7 +198,7 @@ class ComboMarkdownEditor {
169198 return processed ;
170199 }
171200
172- async switchToTextarea ( ) {
201+ switchToTextarea ( ) {
173202 showElem ( this . textareaMarkdownToolbar ) ;
174203 if ( this . easyMDE ) {
175204 this . easyMDE . toTextArea ( ) ;
@@ -218,6 +247,7 @@ class ComboMarkdownEditor {
218247 }
219248 } ,
220249 } ) ;
250+ this . applyEditorHeights ( this . container . querySelector ( '.CodeMirror-scroll' ) , this . options . editorHeights ) ;
221251 await attachTribute ( this . easyMDE . codemirror . getInputField ( ) , { mentions : true , emoji : true } ) ;
222252 initEasyMDEImagePaste ( this . easyMDE , this . dropzone ) ;
223253 hideElem ( this . textareaMarkdownToolbar ) ;
@@ -235,6 +265,7 @@ class ComboMarkdownEditor {
235265 this . easyMDE . value ( v ) ;
236266 } else {
237267 this . textarea . value = v ;
268+ this . textareaAutoResize ( ) ;
238269 }
239270 }
240271
@@ -246,6 +277,24 @@ class ComboMarkdownEditor {
246277 }
247278 }
248279
280+ textareaAutoResize ( ) {
281+ if ( this . textareaInitalHeight === undefined ) {
282+ this . textareaInitalHeight = this . textarea . offsetHeight ;
283+ }
284+ const offset = this . textarea . offsetHeight - this . textarea . clientHeight ;
285+ if ( ! this . lastValue || Math . abs ( this . lastValue . length - this . textarea . value . length ) > 2 ) {
286+ // the value has changed a lot, so reset the height to calculate the real scroll height, it might cause UI flickering
287+ this . textarea . style . height = 'auto' ;
288+ } else {
289+ // try to shrink a little to see if a line is deleted (since the value doesn't change much), it won't cause UI flickering
290+ // the magic number is a general number which fits most line-height styles.
291+ this . textarea . style . height = `${ this . textarea . scrollHeight + offset - 40 } px` ;
292+ }
293+ // make sure the height is not smaller than the initial height
294+ this . textarea . style . height = `${ Math . max ( this . textareaInitalHeight , this . textarea . scrollHeight + offset ) } px` ;
295+ this . lastValue = this . textarea . value ;
296+ }
297+
249298 moveCursorToEnd ( ) {
250299 this . textarea . focus ( ) ;
251300 this . textarea . setSelectionRange ( this . textarea . value . length , this . textarea . value . length ) ;
@@ -254,6 +303,13 @@ class ComboMarkdownEditor {
254303 this . easyMDE . codemirror . setCursor ( this . easyMDE . codemirror . lineCount ( ) , 0 ) ;
255304 }
256305 }
306+
307+ get userPreferredEditor ( ) {
308+ return window . localStorage . getItem ( `markdown-editor-${ this . options . useScene ?? 'default' } ` ) ;
309+ }
310+ set userPreferredEditor ( s ) {
311+ window . localStorage . setItem ( `markdown-editor-${ this . options . useScene ?? 'default' } ` , s ) ;
312+ }
257313}
258314
259315export function getComboMarkdownEditor ( el ) {
0 commit comments