1010
1111 /* Add keystroke events */
1212 afterElementsAdded ( codeInput ) {
13- codeInput . check_tab = this . check_tab ;
14- codeInput . check_enter = this . check_enter ;
1513 let textarea = codeInput . querySelector ( "textarea" ) ;
16- textarea . addEventListener ( 'keydown' , ( event ) => { textarea . parentElement . check_tab ( event ) ; textarea . parentElement . check_enter ( event ) } ) ;
14+ textarea . addEventListener ( 'keydown' , ( event ) => { this . check_tab ( codeInput , event ) ; this . check_enter ( codeInput , event ) ; } ) ;
1715 }
1816
1917 /* Event handlers */
20- check_tab ( event ) {
18+ check_tab ( codeInput , event ) {
2119 if ( event . key != "Tab" ) {
2220 return ;
2321 }
24- let input_element = this . querySelector ( "textarea" ) ;
22+ let input_element = codeInput . querySelector ( "textarea" ) ;
2523 let code = input_element . value ;
2624 event . preventDefault ( ) ; // stop normal
2725
2826 if ( ! event . shiftKey && input_element . selectionStart == input_element . selectionEnd ) {
29- // Shift always means dedent - this places a tab here.
30- let before_selection = code . slice ( 0 , input_element . selectionStart ) ; // text before tab
31- let after_selection = code . slice ( input_element . selectionEnd , input_element . value . length ) ; // text after tab
32-
33- let cursor_pos = input_element . selectionEnd + 1 ; // where cursor moves after tab - moving forward by 1 char to after tab
34- input_element . value = before_selection + "\t" + after_selection ; // add tab char
35-
36- // move cursor
37- input_element . selectionStart = cursor_pos ;
38- input_element . selectionEnd = cursor_pos ;
27+ // Just place a tab here.
28+ document . execCommand ( "insertText" , false , "\t" ) ;
3929
4030 } else {
4131 let lines = input_element . value . split ( "\n" ) ;
4737 let number_indents = 0 ;
4838 let first_line_indents = 0 ;
4939
50- for ( let i = 0 ; i < lines . length ; i ++ ) {
51- letter_i += lines [ i ] . length + 1 ; // newline counted
52-
53- console . log ( lines [ i ] , ": start" , input_element . selectionStart , letter_i , "&& end" , input_element . selectionEnd , letter_i - lines [ i ] . length )
54- if ( input_element . selectionStart <= letter_i && input_element . selectionEnd >= letter_i - lines [ i ] . length ) {
40+ for ( let i = 0 ; i < lines . length ; i ++ ) {
41+ // console.log(lines[i], ": start", selection_start, letter_i + lines[i].length + 1, "&& end", selection_end , letter_i + 1)
42+ if ( ( selection_start <= letter_i + lines [ i ] . length && selection_end >= letter_i + 1 )
43+ || ( selection_start == selection_end && selection_start <= letter_i + lines [ i ] . length + 1 && selection_end >= letter_i ) ) { // + 1 so newlines counted
5544 // Starts before or at last char and ends after or at first char
5645 if ( event . shiftKey ) {
5746 if ( lines [ i ] [ 0 ] == "\t" ) {
5847 // Remove first tab
59- lines [ i ] = lines [ i ] . slice ( 1 ) ;
60- if ( number_indents == 0 ) first_line_indents -- ;
61- number_indents -- ;
48+ input_element . selectionStart = letter_i ;
49+ input_element . selectionEnd = letter_i + 1 ;
50+ document . execCommand ( "delete" , false , "" ) ;
51+
52+ // Change selection
53+ if ( selection_start > letter_i ) { // Indented outside selection
54+ selection_start -- ;
55+ }
56+ selection_end -- ;
57+ letter_i -- ;
6258 }
6359 } else {
64- lines [ i ] = "\t" + lines [ i ] ;
65- if ( number_indents == 0 ) first_line_indents ++ ;
66- number_indents ++ ;
67- }
68-
60+ // Add tab at start
61+ input_element . selectionStart = letter_i ;
62+ input_element . selectionEnd = letter_i ;
63+ document . execCommand ( "insertText" , false , "\t" ) ;
64+
65+ // Change selection
66+ if ( selection_start > letter_i ) { // Indented outside selection
67+ selection_start ++ ;
68+ }
69+ selection_end ++ ;
70+ letter_i ++ ;
71+ }
6972 }
73+
74+ letter_i += lines [ i ] . length + 1 ; // newline counted
7075 }
71- input_element . value = lines . join ( "\n" ) ;
76+ // input_element.value = lines.join("\n");
7277
7378 // move cursor
74- input_element . selectionStart = selection_start + first_line_indents ;
75- input_element . selectionEnd = selection_end + number_indents ;
79+ input_element . selectionStart = selection_start ;
80+ input_element . selectionEnd = selection_end ;
7681 }
7782
78- this . update ( input_element . value ) ;
83+ codeInput . update ( input_element . value ) ;
7984 }
8085
81- check_enter ( event ) {
86+ check_enter ( codeInput , event ) {
8287 if ( event . key != "Enter" ) {
8388 return ;
8489 }
8590 event . preventDefault ( ) ; // stop normal
8691
87- let input_element = this . querySelector ( "textarea" ) ;
92+ let input_element = codeInput . querySelector ( "textarea" ) ;
8893 let lines = input_element . value . split ( "\n" ) ;
8994 let letter_i = 0 ;
9095 let current_line = lines . length - 1 ;
121126 for ( let i = 0 ; i < number_indents ; i ++ ) {
122127 new_line += "\t" ;
123128 }
124- new_line += text_after_cursor ;
125129
126130 // save the current cursor position
127131 let selection_start = input_element . selectionStart ;
128132 let selection_end = input_element . selectionEnd ;
129133
130- // splice our new line into the list of existing lines and join them all back up
131- lines . splice ( current_line + 1 , 0 , new_line ) ;
132- input_element . value = lines . join ( "\n" ) ;
134+ document . execCommand ( "insertText" , false , "\n" + new_line ) ; // Write new line, including auto-indentation
133135
134136 // move cursor to new position
135137 input_element . selectionStart = selection_start + number_indents + 1 ; // count the indent level and the newline character
136138 input_element . selectionEnd = selection_end + number_indents + 1 ;
137139
138- this . update ( input_element . value ) ;
140+ codeInput . update ( input_element . value ) ;
141+
142+
143+ // Update scrolls
144+ input_element . scrollLeft = 0 ;
145+ // Move down 1 line
146+ let lineHeight = Number ( getComputedStyle ( input_element ) . lineHeight . split ( 0 , - 2 ) ) ;
147+ // console.log(getComputedStyle(input_element).lineHeight);
148+ if ( lineHeight == NaN && getComputedStyle ( input_element ) . lineHeight . split ( - 2 ) == "px" ) {
149+ input_element . scrollTop += lineHeight ;
150+ } else {
151+ input_element . scrollTop += 20 ; // px
152+ }
139153 }
140154}
0 commit comments