@@ -10,7 +10,7 @@ import { IAction } from 'vs/base/common/actions';
10
10
import { ThrottledDelayer } from 'vs/base/common/async' ;
11
11
import { streamToBuffer } from 'vs/base/common/buffer' ;
12
12
import { CancellationTokenSource } from 'vs/base/common/cancellation' ;
13
- import { Emitter } from 'vs/base/common/event' ;
13
+ import { Emitter , Event } from 'vs/base/common/event' ;
14
14
import { Disposable , IDisposable , toDisposable } from 'vs/base/common/lifecycle' ;
15
15
import { Schemas } from 'vs/base/common/network' ;
16
16
import { URI } from 'vs/base/common/uri' ;
@@ -22,6 +22,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
22
22
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView' ;
23
23
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions' ;
24
24
import { IFileService } from 'vs/platform/files/common/files' ;
25
+ import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation' ;
25
26
import { ILogService } from 'vs/platform/log/common/log' ;
26
27
import { INotificationService } from 'vs/platform/notification/common/notification' ;
27
28
import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver' ;
@@ -32,6 +33,7 @@ import { asWebviewUri, decodeAuthority, webviewGenericCspSource, webviewRootReso
32
33
import { loadLocalResource , WebviewResourceResponse } from 'vs/workbench/contrib/webview/browser/resourceLoading' ;
33
34
import { WebviewThemeDataProvider } from 'vs/workbench/contrib/webview/browser/themeing' ;
34
35
import { areWebviewContentOptionsEqual , Webview , WebviewContentOptions , WebviewExtensionDescription , WebviewMessageReceivedEvent , WebviewOptions } from 'vs/workbench/contrib/webview/browser/webview' ;
36
+ import { WebviewFindDelegate , WebviewFindWidget } from 'vs/workbench/contrib/webview/browser/webviewFindWidget' ;
35
37
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService' ;
36
38
37
39
export const enum WebviewMessageChannels {
@@ -41,6 +43,7 @@ export const enum WebviewMessageChannels {
41
43
didFocus = 'did-focus' ,
42
44
didBlur = 'did-blur' ,
43
45
didLoad = 'did-load' ,
46
+ didFind = 'did-find' ,
44
47
doUpdateState = 'do-update-state' ,
45
48
doReload = 'do-reload' ,
46
49
setConfirmBeforeClose = 'set-confirm-before-close' ,
@@ -88,7 +91,7 @@ namespace WebviewState {
88
91
export type State = typeof Ready | Initializing ;
89
92
}
90
93
91
- export class IFrameWebview extends Disposable implements Webview {
94
+ export class IFrameWebview extends Disposable implements Webview , WebviewFindDelegate {
92
95
93
96
protected get platform ( ) : string { return 'browser' ; }
94
97
@@ -129,6 +132,9 @@ export class IFrameWebview extends Disposable implements Webview {
129
132
130
133
private readonly _messageHandlers = new Map < string , Set < ( data : any ) => void > > ( ) ;
131
134
135
+ protected readonly _webviewFindWidget : WebviewFindWidget | undefined ;
136
+ public readonly checkImeCompletionState = true ;
137
+
132
138
constructor (
133
139
public readonly id : string ,
134
140
private readonly options : WebviewOptions ,
@@ -145,6 +151,7 @@ export class IFrameWebview extends Disposable implements Webview {
145
151
@IRemoteAuthorityResolverService private readonly _remoteAuthorityResolverService : IRemoteAuthorityResolverService ,
146
152
@ITelemetryService private readonly _telemetryService : ITelemetryService ,
147
153
@ITunnelService private readonly _tunnelService : ITunnelService ,
154
+ @IInstantiationService instantiationService : IInstantiationService ,
148
155
) {
149
156
super ( ) ;
150
157
@@ -215,6 +222,10 @@ export class IFrameWebview extends Disposable implements Webview {
215
222
this . handleFocusChange ( false ) ;
216
223
} ) ) ;
217
224
225
+ this . _register ( this . on ( WebviewMessageChannels . didFind , ( didFind : boolean ) => {
226
+ this . _hasFindResult . fire ( didFind ) ;
227
+ } ) ) ;
228
+
218
229
this . _register ( this . on < { message : string } > ( WebviewMessageChannels . fatalError , ( e ) => {
219
230
notificationService . error ( localize ( 'fatalErrorMessage' , "Error loading webview: {0}" , e . message ) ) ;
220
231
} ) ) ;
@@ -312,6 +323,11 @@ export class IFrameWebview extends Disposable implements Webview {
312
323
}
313
324
} ) ) ;
314
325
326
+ if ( options . enableFindWidget ) {
327
+ this . _webviewFindWidget = this . _register ( instantiationService . createInstance ( WebviewFindWidget , this ) ) ;
328
+ this . styledFindWidget ( ) ;
329
+ }
330
+
315
331
this . initElement ( extension , options ) ;
316
332
}
317
333
@@ -416,9 +432,14 @@ export class IFrameWebview extends Disposable implements Webview {
416
432
}
417
433
418
434
public mountTo ( parent : HTMLElement ) {
419
- if ( this . element ) {
420
- parent . appendChild ( this . element ) ;
435
+ if ( ! this . element ) {
436
+ return ;
421
437
}
438
+
439
+ if ( this . _webviewFindWidget ) {
440
+ parent . appendChild ( this . _webviewFindWidget . getDomNode ( ) ! ) ;
441
+ }
442
+ parent . appendChild ( this . element ) ;
422
443
}
423
444
424
445
protected get webviewContentEndpoint ( ) : string {
@@ -584,6 +605,12 @@ export class IFrameWebview extends Disposable implements Webview {
584
605
}
585
606
586
607
this . _send ( 'styles' , { styles, activeTheme, themeName : themeLabel } ) ;
608
+
609
+ this . styledFindWidget ( ) ;
610
+ }
611
+
612
+ private styledFindWidget ( ) {
613
+ this . _webviewFindWidget ?. updateTheme ( this . webviewThemeDataProvider . getTheme ( ) ) ;
587
614
}
588
615
589
616
private handleFocusChange ( isFocused : boolean ) : void {
@@ -755,15 +782,51 @@ export class IFrameWebview extends Disposable implements Webview {
755
782
} ) ;
756
783
}
757
784
758
- public showFind ( ) : void {
759
- // noop
785
+ protected readonly _hasFindResult = this . _register ( new Emitter < boolean > ( ) ) ;
786
+ public readonly hasFindResult : Event < boolean > = this . _hasFindResult . event ;
787
+
788
+ protected readonly _onDidStopFind = this . _register ( new Emitter < void > ( ) ) ;
789
+ public readonly onDidStopFind : Event < void > = this . _onDidStopFind . event ;
790
+
791
+ /**
792
+ * Webviews expose a stateful find API.
793
+ * Successive calls to find will move forward or backward through onFindResults
794
+ * depending on the supplied options.
795
+ *
796
+ * @param value The string to search for. Empty strings are ignored.
797
+ */
798
+ public find ( value : string , previous : boolean ) : void {
799
+ if ( ! this . element ) {
800
+ return ;
801
+ }
802
+
803
+ this . _send ( 'find' , { value, previous } ) ;
804
+ }
805
+
806
+ public startFind ( value : string ) {
807
+ if ( ! value || ! this . element ) {
808
+ return ;
809
+ }
810
+ this . _send ( 'find' , { value } ) ;
811
+ }
812
+
813
+ public stopFind ( keepSelection ?: boolean ) : void {
814
+ if ( ! this . element ) {
815
+ return ;
816
+ }
817
+ this . _send ( 'find-stop' , { keepSelection } ) ;
818
+ this . _onDidStopFind . fire ( ) ;
819
+ }
820
+
821
+ public showFind ( ) {
822
+ this . _webviewFindWidget ?. reveal ( ) ;
760
823
}
761
824
762
- public hideFind ( ) : void {
763
- // noop
825
+ public hideFind ( ) {
826
+ this . _webviewFindWidget ?. hide ( ) ;
764
827
}
765
828
766
- public runFindAction ( previous : boolean ) : void {
767
- // noop
829
+ public runFindAction ( previous : boolean ) {
830
+ this . _webviewFindWidget ?. find ( previous ) ;
768
831
}
769
832
}
0 commit comments