@@ -123,84 +123,79 @@ function aux_demo(input_id, input_files, main_file, output_id, process_func) {
123123
124124 for ( let textarea_id in editor_by_textarea_id ) {
125125 let editor = editor_by_textarea_id [ textarea_id ] ;
126- let startedJobId = 0 ;
127- let finishedJobId = 0 ;
128- editor . on ( 'change' , async function ( ) {
129- // Yield until we finish duplicated change events (#1254)
130- startedJobId += 1 ;
131- const currJobId = startedJobId ;
132- while ( finishedJobId < currJobId - 1 ) {
133- await new Promise ( resolve => setTimeout ( resolve , 10 ) ) ;
134- }
135-
136- try {
137- // Clean out the existing textareas and tabs.
138- // There should be only one.
139- let tab_header = output . getElementsByClassName ( 'tab-header' ) [ 0 ] ;
140- let last_selected ;
141- while ( tab_header . firstChild ) {
142- let child = tab_header . firstChild ;
143- if ( child . className == 'selected' ) {
144- last_selected = child . innerHTML ;
126+ // Serialize processing of change events, otherwise they can interfere with each other.
127+ let ongoingChange = Promise . resolve ( true ) ;
128+ editor . on ( 'change' , ( ) => {
129+ return ( ongoingChange = ongoingChange . then ( async ( ) => {
130+ try {
131+ // Clean out the existing textareas and tabs.
132+ // There should be only one.
133+ let tab_header = output . getElementsByClassName ( 'tab-header' ) [ 0 ] ;
134+ let last_selected ;
135+ while ( tab_header . firstChild ) {
136+ let child = tab_header . firstChild ;
137+ if ( child . className == 'selected' ) {
138+ last_selected = child . innerHTML ;
139+ }
140+ tab_header . removeChild ( child ) ;
145141 }
146- tab_header . removeChild ( child ) ;
147- }
148142
149- let condemned_textareas = output . getElementsByTagName ( 'TEXTAREA' ) ;
150- let last_scroll = 0 ;
151- while ( condemned_textareas [ 0 ] ) {
152- if ( condemned_textareas [ 0 ] . classList . contains ( 'selected' ) ) {
153- last_scroll = condemned_textareas [ 0 ] . scrollTop ;
143+ let condemned_textareas = output . getElementsByTagName ( 'TEXTAREA' ) ;
144+ let last_scroll = 0 ;
145+ while ( condemned_textareas [ 0 ] ) {
146+ if ( condemned_textareas [ 0 ] . classList . contains ( 'selected' ) ) {
147+ last_scroll = condemned_textareas [ 0 ] . scrollTop ;
148+ }
149+ output . removeChild ( condemned_textareas [ 0 ] ) ;
154150 }
155- output . removeChild ( condemned_textareas [ 0 ] ) ;
156- }
157151
158152
159- let input_files_content = { } ;
160- for ( let id in input_files ) {
161- let file = input_files [ id ] ;
162- let file_editor = editor_by_textarea_id [ id ] ;
163- input_files_content [ file ] = file_editor . getValue ( ) ;
164- }
165- function add_textarea_and_tab ( filename , selected , scroll , output_content , output_class ) {
166- let output_textarea = document . createElement ( 'TEXTAREA' ) ;
167- let id = 'output-' + counter ++ ;
168- output_textarea . setAttribute ( 'id' , id ) ;
169- output_textarea . value = output_content ;
170- output . appendChild ( output_textarea ) ;
153+ let input_files_content = { } ;
154+ for ( let id in input_files ) {
155+ let file = input_files [ id ] ;
156+ let file_editor = editor_by_textarea_id [ id ] ;
157+ input_files_content [ file ] = file_editor . getValue ( ) ;
158+ }
159+ function add_textarea_and_tab ( filename , selected , scroll , output_content , output_class ) {
160+ let output_textarea = document . createElement ( 'TEXTAREA' ) ;
161+ let id = 'output-' + counter ++ ;
162+ output_textarea . setAttribute ( 'id' , id ) ;
163+ output_textarea . value = output_content ;
164+ output . appendChild ( output_textarea ) ;
171165
172- let selected_class = 'unselected' ;
173- if ( filename == selected ) {
174- selected_class = 'selected' ;
175- output_textarea . scrollTop = scroll ;
166+ let selected_class = 'unselected' ;
167+ if ( filename == selected ) {
168+ selected_class = 'selected' ;
169+ output_textarea . scrollTop = scroll ;
170+ }
171+ output_textarea . className = selected_class + ' ' + output_class ;
172+ let max_height = 300 ;
173+ for ( let id in editor_by_textarea_id ) {
174+ let editor_div = editor_by_textarea_id [ id ] . getWrapperElement ( ) ;
175+ max_height = Math . max ( max_height , editor_div . offsetHeight ) ;
176+ }
177+ resize_textarea_max ( max_height , output_textarea ) ;
178+
179+ let output_tab = document . createElement ( 'DIV' ) ;
180+ tab_header . appendChild ( output_tab ) ;
181+ output_tab . className = selected_class ;
182+ output_tab . onclick = function ( ) { tab_output_click ( this , output_textarea . id ) ; } ;
183+ output_tab . innerHTML = filename ;
176184 }
177- output_textarea . className = selected_class + ' ' + output_class ;
178- let max_height = 300 ;
179- for ( let id in editor_by_textarea_id ) {
180- let editor_div = editor_by_textarea_id [ id ] . getWrapperElement ( ) ;
181- max_height = Math . max ( max_height , editor_div . offsetHeight ) ;
185+ try {
186+ await process_func (
187+ main_file , input_files_content , last_selected , last_scroll , add_textarea_and_tab ) ;
188+ } catch ( e ) {
189+ if ( typeof e === 'string' ) {
190+ // Remove last \n
191+ e = e . replace ( / \n $ / , '' ) ;
192+ }
193+ add_textarea_and_tab ( last_selected , last_selected , last_scroll , e , 'code-error' ) ;
182194 }
183- resize_textarea_max ( max_height , output_textarea ) ;
184-
185- let output_tab = document . createElement ( 'DIV' ) ;
186- tab_header . appendChild ( output_tab ) ;
187- output_tab . className = selected_class ;
188- output_tab . onclick = function ( ) { tab_output_click ( this , output_textarea . id ) ; } ;
189- output_tab . innerHTML = filename ;
190- }
191- try {
192- await process_func (
193- main_file , input_files_content , last_selected , last_scroll , add_textarea_and_tab ) ;
194195 } catch ( e ) {
195- if ( typeof e === 'string' ) {
196- // Remove last \n
197- e = e . replace ( / \n $ / , '' ) ;
198- }
199- add_textarea_and_tab ( last_selected , last_selected , last_scroll , e , 'code-error' ) ;
196+ console . error ( `error while processing CodeMirror edit/change: ${ e } ` ) ;
200197 }
201- } finally {
202- finishedJobId = Math . max ( finishedJobId , currJobId ) ;
203- }
198+ } ) ) ;
204199 } ) ;
205200 }
206201
0 commit comments