@@ -10,145 +10,135 @@ codeInput.plugins.Indent = class extends codeInput.Plugin {
1010
1111 /* Add keystroke events */
1212 afterElementsAdded ( codeInput ) {
13- let textarea = codeInput . querySelector ( "textarea" ) ;
14- textarea . addEventListener ( 'keydown' , ( event ) => { this . check_tab ( codeInput , event ) ; this . check_enter ( codeInput , event ) ; } ) ;
13+ let textarea = codeInput . textareaElement ;
14+ textarea . addEventListener ( 'keydown' , ( event ) => { this . checkTab ( codeInput , event ) ; this . checkEnter ( codeInput , event ) ; } ) ;
1515 }
1616
1717 /* Event handlers */
18- check_tab ( codeInput , event ) {
18+ checkTab ( codeInput , event ) {
1919 if ( event . key != "Tab" ) {
2020 return ;
2121 }
22- let input_element = codeInput . querySelector ( "textarea" ) ;
23- let code = input_element . value ;
22+ let inputElement = codeInput . textareaElement ;
2423 event . preventDefault ( ) ; // stop normal
2524
26- if ( ! event . shiftKey && input_element . selectionStart == input_element . selectionEnd ) {
25+ if ( ! event . shiftKey && inputElement . selectionStart == inputElement . selectionEnd ) {
2726 // Just place a tab here.
2827 document . execCommand ( "insertText" , false , "\t" ) ;
2928
3029 } else {
31- let lines = input_element . value . split ( "\n" ) ;
32- let letter_i = 0 ;
30+ let lines = inputElement . value . split ( "\n" ) ;
31+ let letterI = 0 ;
3332
34- let selection_start = input_element . selectionStart ; // where cursor moves after tab - moving forward by 1 indent
35- let selection_end = input_element . selectionEnd ; // where cursor moves after tab - moving forward by 1 indent
33+ let selectionStartI = inputElement . selectionStart ; // where cursor moves after tab - moving forward by 1 indent
34+ let selectionEndI = inputElement . selectionEnd ; // where cursor moves after tab - moving forward by 1 indent
3635
37- let number_indents = 0 ;
38- let first_line_indents = 0 ;
39-
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
36+ for ( let i = 0 ; i < lines . length ; i ++ ) {
37+ if ( ( selectionStartI <= letterI + lines [ i ] . length && selectionEndI >= letterI + 1 )
38+ || ( selectionStartI == selectionEndI && selectionStartI <= letterI + lines [ i ] . length + 1 && selectionEndI >= letterI ) ) { // + 1 so newlines counted
4439 // Starts before or at last char and ends after or at first char
4540 if ( event . shiftKey ) {
4641 if ( lines [ i ] [ 0 ] == "\t" ) {
4742 // Remove first tab
48- input_element . selectionStart = letter_i ;
49- input_element . selectionEnd = letter_i + 1 ;
43+ inputElement . selectionStart = letterI ;
44+ inputElement . selectionEnd = letterI + 1 ;
5045 document . execCommand ( "delete" , false , "" ) ;
5146
5247 // Change selection
53- if ( selection_start > letter_i ) { // Indented outside selection
54- selection_start -- ;
48+ if ( selectionStartI > letterI ) { // Indented outside selection
49+ selectionStartI -- ;
5550 }
56- selection_end -- ;
57- letter_i -- ;
51+ selectionEndI -- ;
52+ letterI -- ;
5853 }
5954 } else {
6055 // Add tab at start
61- input_element . selectionStart = letter_i ;
62- input_element . selectionEnd = letter_i ;
56+ inputElement . selectionStart = letterI ;
57+ inputElement . selectionEnd = letterI ;
6358 document . execCommand ( "insertText" , false , "\t" ) ;
6459
6560 // Change selection
66- if ( selection_start > letter_i ) { // Indented outside selection
67- selection_start ++ ;
61+ if ( selectionStartI > letterI ) { // Indented outside selection
62+ selectionStartI ++ ;
6863 }
69- selection_end ++ ;
70- letter_i ++ ;
64+ selectionEndI ++ ;
65+ letterI ++ ;
7166 }
7267 }
7368
74- letter_i += lines [ i ] . length + 1 ; // newline counted
69+ letterI += lines [ i ] . length + 1 ; // newline counted
7570 }
76- // input_element.value = lines.join("\n");
7771
7872 // move cursor
79- input_element . selectionStart = selection_start ;
80- input_element . selectionEnd = selection_end ;
73+ inputElement . selectionStart = selectionStartI ;
74+ inputElement . selectionEnd = selectionEndI ;
8175 }
8276
83- codeInput . update ( input_element . value ) ;
77+ codeInput . update ( inputElement . value ) ;
8478 }
8579
86- check_enter ( codeInput , event ) {
80+ checkEnter ( codeInput , event ) {
8781 if ( event . key != "Enter" ) {
8882 return ;
8983 }
90- event . preventDefault ( ) ; // stop normal
84+ event . preventDefault ( ) ; // Stop normal \n only
9185
92- let input_element = codeInput . querySelector ( "textarea" ) ;
93- let lines = input_element . value . split ( "\n" ) ;
94- let letter_i = 0 ;
95- let current_line = lines . length - 1 ;
96- let new_line = "" ;
97- let number_indents = 0 ;
86+ let inputElement = codeInput . querySelector ( "textarea" ) ;
87+ let lines = inputElement . value . split ( "\n" ) ;
88+ let letterI = 0 ;
89+ let currentLineI = lines . length - 1 ;
90+ let newLine = "" ;
91+ let numberIndents = 0 ;
9892
9993 // find the index of the line our cursor is currently on
10094 for ( let i = 0 ; i < lines . length ; i ++ ) {
101- letter_i += lines [ i ] . length + 1 ;
102- if ( input_element . selectionEnd <= letter_i ) {
103- current_line = i ;
95+ letterI += lines [ i ] . length + 1 ;
96+ if ( inputElement . selectionEnd <= letterI ) {
97+ currentLineI = i ;
10498 break ;
10599 }
106100 }
107101
108102 // count the number of indents the current line starts with (up to our cursor position in the line)
109- let cursor_pos_in_line = lines [ current_line ] . length - ( letter_i - input_element . selectionEnd ) + 1 ;
110- for ( let i = 0 ; i < cursor_pos_in_line ; i ++ ) {
111- if ( lines [ current_line ] [ i ] == "\t" ) {
112- number_indents ++ ;
103+ let cursorPosInLine = lines [ currentLineI ] . length - ( letterI - inputElement . selectionEnd ) + 1 ;
104+ for ( let i = 0 ; i < cursorPosInLine ; i ++ ) {
105+ if ( lines [ currentLineI ] [ i ] == "\t" ) {
106+ numberIndents ++ ;
113107 } else {
114108 break ;
115109 }
116110 }
117111
118112 // determine the text before and after the cursor and chop the current line at the new line break
119- let text_after_cursor = "" ;
120- if ( cursor_pos_in_line != lines [ current_line ] . length ) {
121- text_after_cursor = lines [ current_line ] . substring ( cursor_pos_in_line ) ;
122- lines [ current_line ] = lines [ current_line ] . substring ( 0 , cursor_pos_in_line ) ;
113+ let textAfterCursor = "" ;
114+ if ( cursorPosInLine != lines [ currentLineI ] . length ) {
115+ textAfterCursor = lines [ currentLineI ] . substring ( cursorPosInLine ) ;
116+ lines [ currentLineI ] = lines [ currentLineI ] . substring ( 0 , cursorPosInLine ) ;
123117 }
124118
125119 // insert our indents and any text from the previous line that might have been after the line break
126- for ( let i = 0 ; i < number_indents ; i ++ ) {
127- new_line += "\t" ;
120+ for ( let i = 0 ; i < numberIndents ; i ++ ) {
121+ newLine += "\t" ;
128122 }
129123
130124 // save the current cursor position
131- let selection_start = input_element . selectionStart ;
132- let selection_end = input_element . selectionEnd ;
125+ let selectionStartI = inputElement . selectionStart ;
133126
134- document . execCommand ( "insertText" , false , "\n" + new_line ) ; // Write new line, including auto-indentation
127+ document . execCommand ( "insertText" , false , "\n" + newLine ) ; // Write new line, including auto-indentation
135128
136129 // move cursor to new position
137- input_element . selectionStart = selection_start + number_indents + 1 ; // count the indent level and the newline character
138- input_element . selectionEnd = selection_start + number_indents + 1 ;
139-
140- codeInput . update ( input_element . value ) ;
141-
130+ inputElement . selectionStart = selectionStartI + numberIndents + 1 ; // count the indent level and the newline character
131+ inputElement . selectionEnd = inputElement . selectionStart ;
142132
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
133+
134+ // Scroll down to cursor if necessary
135+ let paddingTop = Number ( getComputedStyle ( inputElement ) . paddingTop . replace ( "px" , "" ) ) ;
136+ let lineHeight = Number ( getComputedStyle ( inputElement ) . lineHeight . replace ( "px" , "" ) ) ;
137+ let inputHeight = Number ( getComputedStyle ( inputElement ) . height . replace ( "px" , "" ) ) ;
138+ if ( currentLineI * lineHeight + lineHeight * 2 + paddingTop >= inputElement . scrollTop + inputHeight ) { // Cursor too far down
139+ inputElement . scrollBy ( 0 , Number ( getComputedStyle ( inputElement ) . lineHeight . replace ( "px" , "" ) ) )
152140 }
141+
142+ codeInput . update ( inputElement . value ) ;
153143 }
154144}
0 commit comments