@@ -8,7 +8,8 @@ import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
88import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar' ;
99import { Button , IButtonOptions } from 'vs/base/browser/ui/button/button' ;
1010import { FindInput , IFindInputOptions } from 'vs/base/browser/ui/findinput/findInput' ;
11- import { HistoryInputBox , IMessage } from 'vs/base/browser/ui/inputbox/inputBox' ;
11+ import { ReplaceInput } from 'vs/base/browser/ui/findinput/replaceInput' ;
12+ import { IMessage } from 'vs/base/browser/ui/inputbox/inputBox' ;
1213import { Widget } from 'vs/base/browser/ui/widget' ;
1314import { Action } from 'vs/base/common/actions' ;
1415import { Delayer } from 'vs/base/common/async' ;
@@ -24,16 +25,15 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView
2425import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding' ;
2526import { KeybindingsRegistry , KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry' ;
2627import { ISearchConfigurationProperties } from 'vs/workbench/services/search/common/search' ;
27- import { attachFindInputBoxStyler , attachInputBoxStyler } from 'vs/platform/theme/common/styler' ;
28+ import { attachFindReplaceInputBoxStyler } from 'vs/platform/theme/common/styler' ;
2829import { IThemeService } from 'vs/platform/theme/common/themeService' ;
29- import { ContextScopedFindInput , ContextScopedHistoryInputBox } from 'vs/platform/browser/contextScopedHistoryWidget' ;
30+ import { ContextScopedFindInput , ContextScopedReplaceInput } from 'vs/platform/browser/contextScopedHistoryWidget' ;
3031import { appendKeyBindingLabel , isSearchViewFocused } from 'vs/workbench/contrib/search/browser/searchActions' ;
3132import * as Constants from 'vs/workbench/contrib/search/common/constants' ;
3233import { IPanelService } from 'vs/workbench/services/panel/common/panelService' ;
3334import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet' ;
3435import { IEditorOptions } from 'vs/editor/common/config/editorOptions' ;
3536import { IAccessibilityService , AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility' ;
36- import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox' ;
3737import { isMacintosh } from 'vs/base/common/platform' ;
3838
3939export interface ISearchWidgetOptions {
@@ -79,6 +79,22 @@ class ReplaceAllAction extends Action {
7979
8080const ctrlKeyMod = ( isMacintosh ? KeyMod . WinCtrl : KeyMod . CtrlCmd ) ;
8181
82+ function stopPropagationForMultiLineUpwards ( event : IKeyboardEvent , value : string , textarea : HTMLTextAreaElement | null ) {
83+ const isMultiline = ! ! value . match ( / \n / ) ;
84+ if ( textarea && isMultiline && textarea . selectionStart > 0 ) {
85+ event . stopPropagation ( ) ;
86+ return ;
87+ }
88+ }
89+
90+ function stopPropagationForMultiLineDownwards ( event : IKeyboardEvent , value : string , textarea : HTMLTextAreaElement | null ) {
91+ const isMultiline = ! ! value . match ( / \n / ) ;
92+ if ( textarea && isMultiline && textarea . selectionEnd < textarea . value . length ) {
93+ event . stopPropagation ( ) ;
94+ return ;
95+ }
96+ }
97+
8298export class SearchWidget extends Widget {
8399
84100 private static readonly REPLACE_ALL_DISABLED_LABEL = nls . localize ( 'search.action.replaceAll.disabled.label' , "Replace All (Submit Search to Enable)" ) ;
@@ -94,15 +110,14 @@ export class SearchWidget extends Widget {
94110 private searchInputBoxFocused : IContextKey < boolean > ;
95111
96112 private replaceContainer ! : HTMLElement ;
97- replaceInput ! : HistoryInputBox ;
113+ replaceInput ! : ReplaceInput ;
114+ replaceInputFocusTracker ! : dom . IFocusTracker ;
115+ private replaceInputBoxFocused : IContextKey < boolean > ;
98116 private toggleReplaceButton ! : Button ;
99117 private replaceAllAction ! : ReplaceAllAction ;
100118 private replaceActive : IContextKey < boolean > ;
101119 private replaceActionBar ! : ActionBar ;
102- replaceInputFocusTracker ! : dom . IFocusTracker ;
103- private replaceInputBoxFocused : IContextKey < boolean > ;
104120 private _replaceHistoryDelayer : Delayer < void > ;
105- private _preserveCase ! : Checkbox ;
106121
107122 private ignoreGlobalFindBufferOnNextFocus = false ;
108123 private previousGlobalFindBufferValue : string | null = null ;
@@ -180,12 +195,12 @@ export class SearchWidget extends Widget {
180195 setWidth ( width : number ) {
181196 this . searchInput . inputBox . layout ( ) ;
182197 this . replaceInput . width = width - 28 ;
183- this . replaceInput . layout ( ) ;
198+ this . replaceInput . inputBox . layout ( ) ;
184199 }
185200
186201 clear ( ) {
187202 this . searchInput . clear ( ) ;
188- this . replaceInput . value = '' ;
203+ this . replaceInput . setValue ( '' ) ;
189204 this . setReplaceAllActionState ( false ) ;
190205 }
191206
@@ -198,7 +213,7 @@ export class SearchWidget extends Widget {
198213 }
199214
200215 getReplaceValue ( ) : string {
201- return this . replaceInput . value ;
216+ return this . replaceInput . getValue ( ) ;
202217 }
203218
204219 toggleReplace ( show ?: boolean ) : void {
@@ -212,7 +227,7 @@ export class SearchWidget extends Widget {
212227 }
213228
214229 getReplaceHistory ( ) : string [ ] {
215- return this . replaceInput . getHistory ( ) ;
230+ return this . replaceInput . inputBox . getHistory ( ) ;
216231 }
217232
218233 clearHistory ( ) : void {
@@ -228,19 +243,19 @@ export class SearchWidget extends Widget {
228243 }
229244
230245 showNextReplaceTerm ( ) {
231- this . replaceInput . showNextValue ( ) ;
246+ this . replaceInput . inputBox . showNextValue ( ) ;
232247 }
233248
234249 showPreviousReplaceTerm ( ) {
235- this . replaceInput . showPreviousValue ( ) ;
250+ this . replaceInput . inputBox . showPreviousValue ( ) ;
236251 }
237252
238253 searchInputHasFocus ( ) : boolean {
239254 return ! ! this . searchInputBoxFocused . get ( ) ;
240255 }
241256
242257 replaceInputHasFocus ( ) : boolean {
243- return this . replaceInput . hasFocus ( ) ;
258+ return this . replaceInput . inputBox . hasFocus ( ) ;
244259 }
245260
246261 focusReplaceAllAction ( ) : void {
@@ -301,7 +316,7 @@ export class SearchWidget extends Widget {
301316
302317 const searchInputContainer = dom . append ( parent , dom . $ ( '.search-container.input-box' ) ) ;
303318 this . searchInput = this . _register ( new ContextScopedFindInput ( searchInputContainer , this . contextViewService , inputOptions , this . contextKeyService , true ) ) ;
304- this . _register ( attachFindInputBoxStyler ( this . searchInput , this . themeService ) ) ;
319+ this . _register ( attachFindReplaceInputBoxStyler ( this . searchInput , this . themeService ) ) ;
305320 this . searchInput . onKeyDown ( ( keyboardEvent : IKeyboardEvent ) => this . onSearchInputKeyDown ( keyboardEvent ) ) ;
306321 this . searchInput . setValue ( options . value || '' ) ;
307322 this . searchInput . setRegex ( ! ! options . isRegex ) ;
@@ -316,7 +331,7 @@ export class SearchWidget extends Widget {
316331 this . _register ( this . searchInput . inputBox . onDidHeightChange ( ( ) => this . _onDidHeightChange . fire ( ) ) ) ;
317332
318333 this . _register ( this . onReplaceValueChanged ( ( ) => {
319- this . _replaceHistoryDelayer . trigger ( ( ) => this . replaceInput . addToHistory ( ) ) ;
334+ this . _replaceHistoryDelayer . trigger ( ( ) => this . replaceInput . inputBox . addToHistory ( ) ) ;
320335 } ) ) ;
321336
322337 this . searchInputFocusTracker = this . _register ( dom . trackFocus ( this . searchInput . inputBox . inputElement ) ) ;
@@ -344,38 +359,24 @@ export class SearchWidget extends Widget {
344359 this . replaceContainer = dom . append ( parent , dom . $ ( '.replace-container.disabled' ) ) ;
345360 const replaceBox = dom . append ( this . replaceContainer , dom . $ ( '.replace-input' ) ) ;
346361
347- this . replaceInput = this . _register ( new ContextScopedHistoryInputBox ( replaceBox , this . contextViewService , {
348- ariaLabel : nls . localize ( 'label.Replace' , 'Replace: Type replace term and press Enter to preview or Escape to cancel' ) ,
362+ this . replaceInput = this . _register ( new ContextScopedReplaceInput ( replaceBox , this . contextViewService , {
363+ label : nls . localize ( 'label.Replace' , 'Replace: Type replace term and press Enter to preview or Escape to cancel' ) ,
349364 placeholder : nls . localize ( 'search.replace.placeHolder' , "Replace" ) ,
350- history : options . replaceHistory || [ ] ,
365+ history : options . replaceHistory ,
351366 flexibleHeight : true
352- } , this . contextKeyService ) ) ;
367+ } , this . contextKeyService , true ) ) ;
353368
354- this . _preserveCase = this . _register ( new Checkbox ( {
355- actionClassName : 'monaco-preserve-case' ,
356- title : nls . localize ( 'label.preserveCaseCheckbox' , "Preserve Case" ) ,
357- isChecked : ! ! options . preserveCase ,
358- } ) ) ;
359-
360- this . _register ( this . _preserveCase . onChange ( viaKeyboard => {
369+ this . _register ( this . replaceInput . onDidOptionChange ( viaKeyboard => {
361370 if ( ! viaKeyboard ) {
362- this . replaceInput . focus ( ) ;
363- this . _onPreserveCaseChange . fire ( this . _preserveCase . checked ) ;
371+ this . _onPreserveCaseChange . fire ( this . replaceInput . getPreserveCase ( ) ) ;
364372 }
365373 } ) ) ;
366374
367- const controls = document . createElement ( 'div' ) ;
368- controls . className = 'controls' ;
369- controls . style . display = 'block' ;
370- controls . appendChild ( this . _preserveCase . domNode ) ;
371- replaceBox . appendChild ( controls ) ;
372- this . replaceInput . paddingRight = this . _preserveCase . width ( ) ;
373-
374- this . _register ( attachInputBoxStyler ( this . replaceInput , this . themeService ) ) ;
375- this . onkeydown ( this . replaceInput . inputElement , ( keyboardEvent ) => this . onReplaceInputKeyDown ( keyboardEvent ) ) ;
376- this . replaceInput . value = options . replaceValue || '' ;
377- this . _register ( this . replaceInput . onDidChange ( ( ) => this . _onReplaceValueChanged . fire ( ) ) ) ;
378- this . _register ( this . replaceInput . onDidHeightChange ( ( ) => this . _onDidHeightChange . fire ( ) ) ) ;
375+ this . _register ( attachFindReplaceInputBoxStyler ( this . replaceInput , this . themeService ) ) ;
376+ this . replaceInput . onKeyDown ( ( keyboardEvent ) => this . onReplaceInputKeyDown ( keyboardEvent ) ) ;
377+ this . replaceInput . setValue ( options . replaceValue || '' ) ;
378+ this . _register ( this . replaceInput . inputBox . onDidChange ( ( ) => this . _onReplaceValueChanged . fire ( ) ) ) ;
379+ this . _register ( this . replaceInput . inputBox . onDidHeightChange ( ( ) => this . _onDidHeightChange . fire ( ) ) ) ;
379380
380381 this . replaceAllAction = ReplaceAllAction . INSTANCE ;
381382 this . replaceAllAction . searchWidget = this ;
@@ -384,7 +385,7 @@ export class SearchWidget extends Widget {
384385 this . replaceActionBar . push ( [ this . replaceAllAction ] , { icon : true , label : false } ) ;
385386 this . onkeydown ( this . replaceActionBar . domNode , ( keyboardEvent ) => this . onReplaceActionbarKeyDown ( keyboardEvent ) ) ;
386387
387- this . replaceInputFocusTracker = this . _register ( dom . trackFocus ( this . replaceInput . inputElement ) ) ;
388+ this . replaceInputFocusTracker = this . _register ( dom . trackFocus ( this . replaceInput . inputBox . inputElement ) ) ;
388389 this . _register ( this . replaceInputFocusTracker . onDidFocus ( ( ) => this . replaceInputBoxFocused . set ( true ) ) ) ;
389390 this . _register ( this . replaceInputFocusTracker . onDidBlur ( ( ) => this . replaceInputBoxFocused . set ( false ) ) ) ;
390391 }
@@ -417,7 +418,7 @@ export class SearchWidget extends Widget {
417418 if ( currentState !== newState ) {
418419 this . replaceActive . set ( newState ) ;
419420 this . _onReplaceStateChange . fire ( newState ) ;
420- this . replaceInput . layout ( ) ;
421+ this . replaceInput . inputBox . layout ( ) ;
421422 }
422423 }
423424
@@ -475,19 +476,11 @@ export class SearchWidget extends Widget {
475476 }
476477
477478 else if ( keyboardEvent . equals ( KeyCode . UpArrow ) ) {
478- const ta = this . searchInput . domNode . querySelector ( 'textarea' ) ;
479- const isMultiline = ! ! this . searchInput . getValue ( ) . match ( / \n / ) ;
480- if ( ta && isMultiline && ta . selectionStart > 0 ) {
481- keyboardEvent . stopPropagation ( ) ;
482- }
479+ stopPropagationForMultiLineUpwards ( keyboardEvent , this . searchInput . getValue ( ) , this . searchInput . domNode . querySelector ( 'textarea' ) ) ;
483480 }
484481
485482 else if ( keyboardEvent . equals ( KeyCode . DownArrow ) ) {
486- const ta = this . searchInput . domNode . querySelector ( 'textarea' ) ;
487- const isMultiline = ! ! this . searchInput . getValue ( ) . match ( / \n / ) ;
488- if ( ta && isMultiline && ta . selectionEnd < ta . value . length ) {
489- keyboardEvent . stopPropagation ( ) ;
490- }
483+ stopPropagationForMultiLineDownwards ( keyboardEvent , this . searchInput . getValue ( ) , this . searchInput . domNode . querySelector ( 'textarea' ) ) ;
491484 }
492485 }
493486
@@ -513,7 +506,7 @@ export class SearchWidget extends Widget {
513506
514507 private onReplaceInputKeyDown ( keyboardEvent : IKeyboardEvent ) {
515508 if ( keyboardEvent . equals ( ctrlKeyMod | KeyCode . Enter ) ) {
516- this . searchInput . inputBox . insertAtCursor ( '\n' ) ;
509+ this . replaceInput . inputBox . insertAtCursor ( '\n' ) ;
517510 keyboardEvent . preventDefault ( ) ;
518511 }
519512
@@ -533,17 +526,11 @@ export class SearchWidget extends Widget {
533526 }
534527
535528 else if ( keyboardEvent . equals ( KeyCode . UpArrow ) ) {
536- const ta = this . searchInput . domNode . querySelector ( 'textarea' ) ;
537- if ( ta && ta . selectionStart > 0 ) {
538- keyboardEvent . stopPropagation ( ) ;
539- }
529+ stopPropagationForMultiLineUpwards ( keyboardEvent , this . replaceInput . getValue ( ) , this . replaceInput . domNode . querySelector ( 'textarea' ) ) ;
540530 }
541531
542532 else if ( keyboardEvent . equals ( KeyCode . DownArrow ) ) {
543- const ta = this . searchInput . domNode . querySelector ( 'textarea' ) ;
544- if ( ta && ta . selectionEnd < ta . value . length ) {
545- keyboardEvent . stopPropagation ( ) ;
546- }
533+ stopPropagationForMultiLineDownwards ( keyboardEvent , this . replaceInput . getValue ( ) , this . replaceInput . domNode . querySelector ( 'textarea' ) ) ;
547534 }
548535 }
549536
0 commit comments