@@ -18,13 +18,14 @@ import upArrow from '../images/up-arrow.svg?byContent';
1818import exitIcon from '../images/exit.svg?byContent' ;
1919
2020function searchOverlay ( query , caseInsensitive ) {
21- if ( typeof query == 'string' )
21+ if ( typeof query == 'string' ) {
2222 query = new RegExp (
2323 query . replace ( / [ \- \[ \] \/ \{ \} \( \) \* \+ \? \. \\ \^ \$ \| ] / g, '\\$&' ) ,
2424 caseInsensitive ? 'gi' : 'g'
2525 ) ;
26- else if ( ! query . global )
26+ } else if ( ! query . global ) {
2727 query = new RegExp ( query . source , query . ignoreCase ? 'gi' : 'g' ) ;
28+ }
2829
2930 return {
3031 token : function ( stream ) {
@@ -49,6 +50,8 @@ function SearchState() {
4950 this . caseInsensitive = true ;
5051 this . wholeWord = false ;
5152 this . replaceStarted = false ;
53+ this . lastFileName =
54+ document . querySelector ( '.editor__file-name span' ) ?. innerText || null ;
5255}
5356
5457function getSearchState ( cm ) {
@@ -60,6 +63,50 @@ function getSearchCursor(cm, query, pos) {
6063 return cm . getSearchCursor ( query , pos , getSearchState ( cm ) . caseInsensitive ) ;
6164}
6265
66+ function watchFileChanges ( cm , searchState , searchField ) {
67+ let observer = null ;
68+
69+ function setupObserver ( ) {
70+ var fileNameElement = document . querySelector ( '.editor__file-name span' ) ;
71+
72+ if ( ! fileNameElement ) {
73+ setTimeout ( setupObserver , 500 ) ;
74+ return ;
75+ }
76+
77+ if ( observer ) {
78+ return ;
79+ }
80+
81+ observer = new MutationObserver ( ( ) => {
82+ if ( searchField . value . length > 1 ) {
83+ startSearch ( cm , searchState , searchField . value ) ;
84+ }
85+ } ) ;
86+
87+ observer . observe ( fileNameElement , { characterData : true , subtree : true } ) ;
88+ }
89+
90+ function disconnectObserver ( ) {
91+ if ( observer ) {
92+ observer . disconnect ( ) ;
93+ observer = null ;
94+ }
95+ }
96+
97+ setupObserver ( ) ;
98+
99+ setInterval ( ( ) => {
100+ var searchDialog = document . querySelector ( '.CodeMirror-dialog' ) ;
101+ if ( ! searchDialog && observer ) {
102+ disconnectObserver ( ) ;
103+ return ;
104+ } else if ( searchDialog && ! observer ) {
105+ setupObserver ( ) ;
106+ }
107+ } , 500 ) ;
108+ }
109+
63110function isMouseClick ( event ) {
64111 if ( event . detail > 0 ) return true ;
65112 else return false ;
@@ -88,10 +135,11 @@ function persistentDialog(cm, text, deflt, onEnter, replaceOpened, onKeyDown) {
88135
89136 var state = getSearchState ( cm ) ;
90137
138+ watchFileChanges ( cm , getSearchState ( cm ) , searchField ) ;
139+
91140 CodeMirror . on ( searchField , 'keyup' , function ( e ) {
92141 state . replaceStarted = false ;
93142 if ( e . keyCode !== 13 && searchField . value . length > 1 ) {
94- // not enter and more than 1 character to search
95143 startSearch ( cm , getSearchState ( cm ) , searchField . value ) ;
96144 } else if ( searchField . value . length < 1 ) {
97145 cm . display . wrapper . querySelector (
@@ -101,8 +149,8 @@ function persistentDialog(cm, text, deflt, onEnter, replaceOpened, onKeyDown) {
101149 } ) ;
102150
103151 CodeMirror . on ( closeButton , 'click' , function ( ) {
104- clearSearch ( cm ) ;
105152 dialog . parentNode . removeChild ( dialog ) ;
153+ clearSearch ( cm ) ;
106154 cm . focus ( ) ;
107155 } ) ;
108156
@@ -323,7 +371,6 @@ function parseString(string) {
323371function parseQuery ( query , state ) {
324372 var emptyQuery = 'x^' ; // matches nothing
325373 if ( query === '' ) {
326- // empty string matches nothing
327374 query = emptyQuery ;
328375 } else {
329376 if ( state . regexp === false ) {
@@ -349,44 +396,64 @@ function parseQuery(query, state) {
349396}
350397
351398function startSearch ( cm , state , query ) {
352- state . queryText = query ;
353- state . lastQuery = query ;
354- state . query = parseQuery ( query , state ) ;
355- cm . removeOverlay ( state . overlay , state . caseInsensitive ) ;
356- state . overlay = searchOverlay ( state . query , state . caseInsensitive ) ;
357- cm . addOverlay ( state . overlay ) ;
358- if ( cm . showMatchesOnScrollbar ) {
359- if ( state . annotate ) {
360- state . annotate . clear ( ) ;
361- state . annotate = null ;
399+ var searchDialog = document . querySelector ( '.CodeMirror-dialog' ) ;
400+ if ( searchDialog ) {
401+ // check if the file has changed
402+ let currentFileName = document . querySelector ( '.editor__file-name span' )
403+ ?. innerText ;
404+
405+ if ( state . lastFileName !== currentFileName ) {
406+ state . lastFileName = currentFileName ;
407+ state . queryText = null ;
408+ state . lastQuery = null ;
409+ state . query = null ;
410+ cm . removeOverlay ( state . overlay ) ;
411+ state . overlay = null ;
412+
413+ if ( searchDialog ) {
414+ cm . display . wrapper . querySelector (
415+ '.CodeMirror-search-results'
416+ ) . innerText = '0/0' ;
417+ }
362418 }
363- state . annotate = cm . showMatchesOnScrollbar (
364- state . query ,
365- state . caseInsensitive
366- ) ;
367- }
368419
369- //Updating the UI everytime the search input changes
370- var cursor = getSearchCursor ( cm , state . query ) ;
371- cursor . findNext ( ) ;
372- var num_match = cm . state . search . annotate . matches . length ;
373- //no matches found
374- if ( num_match == 0 ) {
375- cm . display . wrapper . querySelector (
376- '.CodeMirror-search-results'
377- ) . innerText = i18n . t ( 'CodemirrorFindAndReplace.NoResults' ) ;
420+ state . queryText = query ;
421+ state . lastQuery = query ;
422+ state . query = parseQuery ( query , state ) ;
378423 cm . removeOverlay ( state . overlay , state . caseInsensitive ) ;
379- } else {
380- var next =
381- cm . state . search . annotate . matches . findIndex ( ( s ) => {
382- return (
383- s . from . ch === cursor . from ( ) . ch && s . from . line === cursor . from ( ) . line
384- ) ;
385- } ) + 1 ;
386- var text_match = next + '/' + num_match ;
387- cm . display . wrapper . querySelector (
388- '.CodeMirror-search-results'
389- ) . innerText = text_match ;
424+ state . overlay = searchOverlay ( state . query , state . caseInsensitive ) ;
425+ cm . addOverlay ( state . overlay ) ;
426+ if ( cm . showMatchesOnScrollbar ) {
427+ if ( state . annotate ) {
428+ state . annotate . clear ( ) ;
429+ state . annotate = null ;
430+ }
431+ state . annotate = cm . showMatchesOnScrollbar (
432+ state . query ,
433+ state . caseInsensitive
434+ ) ;
435+ }
436+
437+ var cursor = getSearchCursor ( cm , state . query ) ;
438+ cursor . findNext ( ) ;
439+ var num_match = cm . state . search . annotate . matches . length ;
440+ if ( num_match == 0 ) {
441+ cm . display . wrapper . querySelector (
442+ '.CodeMirror-search-results'
443+ ) . innerText = i18n . t ( 'CodemirrorFindAndReplace.NoResults' ) ;
444+ cm . removeOverlay ( state . overlay , state . caseInsensitive ) ;
445+ } else {
446+ var next =
447+ cm . state . search . annotate . matches . findIndex ( ( s ) => {
448+ return (
449+ s . from . ch === cursor . from ( ) . ch && s . from . line === cursor . from ( ) . line
450+ ) ;
451+ } ) + 1 ;
452+ var text_match = next + '/' + num_match ;
453+ cm . display . wrapper . querySelector (
454+ '.CodeMirror-search-results'
455+ ) . innerText = text_match ;
456+ }
390457 }
391458}
392459
0 commit comments