10
10
11
11
/* Add keystroke events */
12
12
afterElementsAdded ( codeInput ) {
13
- codeInput . check_tab = this . check_tab ;
14
- codeInput . check_enter = this . check_enter ;
15
13
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 ) ; } ) ;
17
15
}
18
16
19
17
/* Event handlers */
20
- check_tab ( event ) {
18
+ check_tab ( codeInput , event ) {
21
19
if ( event . key != "Tab" ) {
22
20
return ;
23
21
}
24
- let input_element = this . querySelector ( "textarea" ) ;
22
+ let input_element = codeInput . querySelector ( "textarea" ) ;
25
23
let code = input_element . value ;
26
24
event . preventDefault ( ) ; // stop normal
27
25
28
26
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" ) ;
39
29
40
30
} else {
41
31
let lines = input_element . value . split ( "\n" ) ;
47
37
let number_indents = 0 ;
48
38
let first_line_indents = 0 ;
49
39
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
55
44
// Starts before or at last char and ends after or at first char
56
45
if ( event . shiftKey ) {
57
46
if ( lines [ i ] [ 0 ] == "\t" ) {
58
47
// 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 -- ;
62
58
}
63
59
} 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
+ }
69
72
}
73
+
74
+ letter_i += lines [ i ] . length + 1 ; // newline counted
70
75
}
71
- input_element . value = lines . join ( "\n" ) ;
76
+ // input_element.value = lines.join("\n");
72
77
73
78
// 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 ;
76
81
}
77
82
78
- this . update ( input_element . value ) ;
83
+ codeInput . update ( input_element . value ) ;
79
84
}
80
85
81
- check_enter ( event ) {
86
+ check_enter ( codeInput , event ) {
82
87
if ( event . key != "Enter" ) {
83
88
return ;
84
89
}
85
90
event . preventDefault ( ) ; // stop normal
86
91
87
- let input_element = this . querySelector ( "textarea" ) ;
92
+ let input_element = codeInput . querySelector ( "textarea" ) ;
88
93
let lines = input_element . value . split ( "\n" ) ;
89
94
let letter_i = 0 ;
90
95
let current_line = lines . length - 1 ;
121
126
for ( let i = 0 ; i < number_indents ; i ++ ) {
122
127
new_line += "\t" ;
123
128
}
124
- new_line += text_after_cursor ;
125
129
126
130
// save the current cursor position
127
131
let selection_start = input_element . selectionStart ;
128
132
let selection_end = input_element . selectionEnd ;
129
133
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
133
135
134
136
// move cursor to new position
135
137
input_element . selectionStart = selection_start + number_indents + 1 ; // count the indent level and the newline character
136
138
input_element . selectionEnd = selection_end + number_indents + 1 ;
137
139
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
+ }
139
153
}
140
154
}
0 commit comments