Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/browser/actions/textInputActions.ts
3296 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 { IAction, Separator, toAction } from '../../../base/common/actions.js';
7
import { localize } from '../../../nls.js';
8
import { IWorkbenchLayoutService } from '../../services/layout/browser/layoutService.js';
9
import { IContextMenuService } from '../../../platform/contextview/browser/contextView.js';
10
import { Disposable } from '../../../base/common/lifecycle.js';
11
import { EventHelper, addDisposableListener, getActiveDocument, getWindow, isHTMLInputElement, isHTMLTextAreaElement } from '../../../base/browser/dom.js';
12
import { IWorkbenchContribution, WorkbenchPhase, registerWorkbenchContribution2 } from '../../common/contributions.js';
13
import { IClipboardService } from '../../../platform/clipboard/common/clipboardService.js';
14
import { StandardMouseEvent } from '../../../base/browser/mouseEvent.js';
15
import { Event as BaseEvent } from '../../../base/common/event.js';
16
import { Lazy } from '../../../base/common/lazy.js';
17
import { ILogService } from '../../../platform/log/common/log.js';
18
19
export function createTextInputActions(clipboardService: IClipboardService, logService: ILogService): IAction[] {
20
return [
21
22
toAction({ id: 'undo', label: localize('undo', "Undo"), run: () => getActiveDocument().execCommand('undo') }),
23
toAction({ id: 'redo', label: localize('redo', "Redo"), run: () => getActiveDocument().execCommand('redo') }),
24
new Separator(),
25
toAction({
26
id: 'editor.action.clipboardCutAction', label: localize('cut', "Cut"), run: () => {
27
logService.trace('TextInputActionsProvider#cut');
28
getActiveDocument().execCommand('cut');
29
}
30
}),
31
toAction({
32
id: 'editor.action.clipboardCopyAction', label: localize('copy', "Copy"), run: () => {
33
logService.trace('TextInputActionsProvider#copy');
34
getActiveDocument().execCommand('copy');
35
}
36
}),
37
toAction({
38
id: 'editor.action.clipboardPasteAction',
39
label: localize('paste', "Paste"),
40
run: async (element: unknown) => {
41
logService.trace('TextInputActionsProvider#paste');
42
const clipboardText = await clipboardService.readText();
43
if (isHTMLTextAreaElement(element) || isHTMLInputElement(element)) {
44
const selectionStart = element.selectionStart || 0;
45
const selectionEnd = element.selectionEnd || 0;
46
47
element.value = `${element.value.substring(0, selectionStart)}${clipboardText}${element.value.substring(selectionEnd, element.value.length)}`;
48
element.selectionStart = selectionStart + clipboardText.length;
49
element.selectionEnd = element.selectionStart;
50
element.dispatchEvent(new Event('input', { bubbles: true, cancelable: true }));
51
}
52
}
53
}),
54
new Separator(),
55
toAction({ id: 'editor.action.selectAll', label: localize('selectAll', "Select All"), run: () => getActiveDocument().execCommand('selectAll') })
56
];
57
}
58
59
export class TextInputActionsProvider extends Disposable implements IWorkbenchContribution {
60
61
static readonly ID = 'workbench.contrib.textInputActionsProvider';
62
63
private readonly textInputActions = new Lazy<IAction[]>(() => createTextInputActions(this.clipboardService, this.logService));
64
65
constructor(
66
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
67
@IContextMenuService private readonly contextMenuService: IContextMenuService,
68
@IClipboardService private readonly clipboardService: IClipboardService,
69
@ILogService private readonly logService: ILogService
70
) {
71
super();
72
73
this.registerListeners();
74
}
75
76
private registerListeners(): void {
77
78
// Context menu support in input/textarea
79
this._register(BaseEvent.runAndSubscribe(this.layoutService.onDidAddContainer, ({ container, disposables }) => {
80
disposables.add(addDisposableListener(container, 'contextmenu', e => this.onContextMenu(getWindow(container), e)));
81
}, { container: this.layoutService.mainContainer, disposables: this._store }));
82
}
83
84
private onContextMenu(targetWindow: Window, e: MouseEvent): void {
85
if (e.defaultPrevented) {
86
return; // make sure to not show these actions by accident if component indicated to prevent
87
}
88
89
const target = e.target;
90
if (!isHTMLTextAreaElement(target) && !isHTMLInputElement(target)) {
91
return; // only for inputs or textareas
92
}
93
94
EventHelper.stop(e, true);
95
96
const event = new StandardMouseEvent(targetWindow, e);
97
98
this.contextMenuService.showContextMenu({
99
getAnchor: () => event,
100
getActions: () => this.textInputActions.value,
101
getActionsContext: () => target,
102
});
103
}
104
}
105
106
registerWorkbenchContribution2(
107
TextInputActionsProvider.ID,
108
TextInputActionsProvider,
109
WorkbenchPhase.BlockRestore // Block to allow right-click into input fields before restore finished
110
);
111
112