Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/browserView/electron-browser/browserFindWidget.ts
5232 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { SimpleFindWidget } from '../../codeEditor/browser/find/simpleFindWidget.js';
7
import { IContextViewService } from '../../../../platform/contextview/browser/contextView.js';
8
import { IContextKey, IContextKeyService, RawContextKey } from '../../../../platform/contextkey/common/contextkey.js';
9
import { IHoverService } from '../../../../platform/hover/browser/hover.js';
10
import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js';
11
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
12
import { IAccessibilityService } from '../../../../platform/accessibility/common/accessibility.js';
13
import { IBrowserViewModel } from '../common/browserView.js';
14
import { localize } from '../../../../nls.js';
15
import { DisposableStore } from '../../../../base/common/lifecycle.js';
16
17
export const CONTEXT_BROWSER_FIND_WIDGET_VISIBLE = new RawContextKey<boolean>('browserFindWidgetVisible', false, localize('browser.findWidgetVisible', "Whether the browser find widget is visible"));
18
export const CONTEXT_BROWSER_FIND_WIDGET_FOCUSED = new RawContextKey<boolean>('browserFindWidgetFocused', false, localize('browser.findWidgetFocused', "Whether the browser find widget is focused"));
19
20
/**
21
* Find widget for the integrated browser view.
22
* Uses the SimpleFindWidget base class and communicates with the browser view model
23
* to perform find operations in the rendered web page.
24
*/
25
export class BrowserFindWidget extends SimpleFindWidget {
26
private _model: IBrowserViewModel | undefined;
27
private readonly _modelDisposables = this._register(new DisposableStore());
28
private readonly _findWidgetVisible: IContextKey<boolean>;
29
private readonly _findWidgetFocused: IContextKey<boolean>;
30
private _lastFindResult: { resultIndex: number; resultCount: number } | undefined;
31
private _hasFoundMatch = false;
32
33
constructor(
34
private readonly container: HTMLElement,
35
@IContextViewService contextViewService: IContextViewService,
36
@IContextKeyService contextKeyService: IContextKeyService,
37
@IHoverService hoverService: IHoverService,
38
@IKeybindingService keybindingService: IKeybindingService,
39
@IConfigurationService configurationService: IConfigurationService,
40
@IAccessibilityService accessibilityService: IAccessibilityService
41
) {
42
super({
43
showCommonFindToggles: true,
44
checkImeCompletionState: true,
45
showResultCount: true,
46
enableSash: true,
47
initialWidth: 350,
48
previousMatchActionId: 'workbench.action.browser.findPrevious',
49
nextMatchActionId: 'workbench.action.browser.findNext',
50
closeWidgetActionId: 'workbench.action.browser.hideFind'
51
}, contextViewService, contextKeyService, hoverService, keybindingService, configurationService, accessibilityService);
52
53
this._findWidgetVisible = CONTEXT_BROWSER_FIND_WIDGET_VISIBLE.bindTo(contextKeyService);
54
this._findWidgetFocused = CONTEXT_BROWSER_FIND_WIDGET_FOCUSED.bindTo(contextKeyService);
55
56
container.appendChild(this.getDomNode());
57
}
58
59
/**
60
* Set the browser view model to use for find operations.
61
* This should be called whenever the editor input changes.
62
*/
63
setModel(model: IBrowserViewModel | undefined): void {
64
this._modelDisposables.clear();
65
this._model = model;
66
this._lastFindResult = undefined;
67
this._hasFoundMatch = false;
68
69
if (model) {
70
this._modelDisposables.add(model.onDidFindInPage(result => {
71
this._lastFindResult = {
72
resultIndex: result.activeMatchOrdinal - 1, // Convert to 0-based index
73
resultCount: result.matches
74
};
75
this._hasFoundMatch = result.matches > 0;
76
this.updateButtons(this._hasFoundMatch);
77
this.updateResultCount();
78
}));
79
80
this._modelDisposables.add(model.onWillDispose(() => {
81
this.setModel(undefined);
82
}));
83
}
84
}
85
86
override reveal(initialInput?: string): void {
87
const wasVisible = this.isVisible();
88
super.reveal(initialInput);
89
this._findWidgetVisible.set(true);
90
this.container.classList.toggle('find-visible', true);
91
92
// Focus the find input
93
this.focusFindBox();
94
95
// If there's existing input and the widget wasn't already visible, trigger a search
96
if (this.inputValue && !wasVisible) {
97
this._onInputChanged();
98
}
99
}
100
101
override hide(): void {
102
super.hide(false);
103
this._findWidgetVisible.reset();
104
this.container.classList.toggle('find-visible', false);
105
106
// Stop find and clear highlights in the browser view
107
this._model?.stopFindInPage(true);
108
this._lastFindResult = undefined;
109
this._hasFoundMatch = false;
110
}
111
112
find(previous: boolean): void {
113
const value = this.inputValue;
114
if (value && this._model) {
115
this._model.findInPage(value, {
116
forward: !previous,
117
recompute: false,
118
matchCase: this._getCaseSensitiveValue()
119
});
120
}
121
}
122
123
findFirst(): void {
124
const value = this.inputValue;
125
if (value && this._model) {
126
this._model.findInPage(value, {
127
forward: true,
128
recompute: true,
129
matchCase: this._getCaseSensitiveValue()
130
});
131
}
132
}
133
134
clear(): void {
135
if (this._model) {
136
this._model.stopFindInPage(false);
137
this._lastFindResult = undefined;
138
this._hasFoundMatch = false;
139
}
140
}
141
142
protected _onInputChanged(): boolean {
143
if (this.inputValue) {
144
this.findFirst();
145
} else if (this._model) {
146
this.clear();
147
}
148
return false;
149
}
150
151
protected async _getResultCount(): Promise<{ resultIndex: number; resultCount: number } | undefined> {
152
return this._lastFindResult;
153
}
154
155
protected _onFocusTrackerFocus(): void {
156
this._findWidgetFocused.set(true);
157
}
158
159
protected _onFocusTrackerBlur(): void {
160
this._findWidgetFocused.reset();
161
}
162
163
protected _onFindInputFocusTrackerFocus(): void {
164
// No-op
165
}
166
167
protected _onFindInputFocusTrackerBlur(): void {
168
// No-op
169
}
170
}
171
172