提交 d3cb5b21 编写于 作者: C Christof Marti

Validate input on Enter (#48116)

上级 2b4dfcc3
...@@ -28,10 +28,10 @@ import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge'; ...@@ -28,10 +28,10 @@ import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge';
import { attachBadgeStyler, attachProgressBarStyler, attachButtonStyler } from 'vs/platform/theme/common/styler'; import { attachBadgeStyler, attachProgressBarStyler, attachButtonStyler } from 'vs/platform/theme/common/styler';
import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar'; import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
import { chain } from 'vs/base/common/event'; import { chain, debounceEvent } from 'vs/base/common/event';
import { Button } from 'vs/base/browser/ui/button/button'; import { Button } from 'vs/base/browser/ui/button/button';
import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { onUnexpectedError } from 'vs/base/common/errors'; import { onUnexpectedError, canceled } from 'vs/base/common/errors';
const $ = dom.$; const $ = dom.$;
...@@ -69,7 +69,7 @@ interface InputController<R> { ...@@ -69,7 +69,7 @@ interface InputController<R> {
readonly showUI: { [k in keyof QuickInputUI]?: boolean; } & { ok?: boolean; }; readonly showUI: { [k in keyof QuickInputUI]?: boolean; } & { ok?: boolean; };
readonly result: TPromise<R>; readonly result: TPromise<R>;
readonly ready: TPromise<void>; readonly ready: TPromise<void>;
readonly resolve: (ok?: true | Thenable<never>) => void; readonly resolve: (ok?: true | Thenable<never>) => void | TPromise<void>;
} }
class SelectManyController<T extends IPickOpenEntry> implements InputController<T[]> { class SelectManyController<T extends IPickOpenEntry> implements InputController<T[]> {
...@@ -112,13 +112,14 @@ class TextInputController implements InputController<string> { ...@@ -112,13 +112,14 @@ class TextInputController implements InputController<string> {
public showUI = { inputBox: true, message: true }; public showUI = { inputBox: true, message: true };
public result: TPromise<string>; public result: TPromise<string>;
public ready = TPromise.as(null); public ready = TPromise.as(null);
public resolve: (ok?: true | Thenable<never>) => void; public resolveResult: (string) => void;
private validationValue: string; private validationValue: string;
private validation: TPromise<string>;
private disposables: IDisposable[] = []; private disposables: IDisposable[] = [];
constructor(ui: QuickInputUI, parameters: TextInputParameters) { constructor(private ui: QuickInputUI, private parameters: TextInputParameters) {
this.result = new TPromise<string>((resolve, reject, progress) => { this.result = new TPromise<string>((resolve, reject, progress) => {
this.resolve = ok => resolve(ok === true ? ui.inputBox.value : ok); this.resolveResult = resolve;
}); });
this.result.then(() => this.dispose()); this.result.then(() => this.dispose());
...@@ -130,19 +131,51 @@ class TextInputController implements InputController<string> { ...@@ -130,19 +131,51 @@ class TextInputController implements InputController<string> {
ui.message.textContent = defaultMessage; ui.message.textContent = defaultMessage;
if (parameters.validateInput) { if (parameters.validateInput) {
this.disposables.push(ui.inputBox.onDidChange(value => { const onDidChange = debounceEvent(ui.inputBox.onDidChange, (last, cur) => cur, 100);
this.validationValue = value; this.disposables.push(onDidChange(() => {
parameters.validateInput(value) this.updatedValidation()
.then(validationError => { .then(validationError => {
if (this.validationValue === value) { ui.message.textContent = validationError || defaultMessage;
ui.message.textContent = validationError || defaultMessage;
}
}) })
.then(null, onUnexpectedError); .then(null, onUnexpectedError);
})); }));
} }
} }
resolve(ok?: true | Thenable<never>) {
if (ok === true) {
return this.updatedValidation()
.then(validationError => {
if (validationError) {
throw canceled();
}
this.resolveResult(this.ui.inputBox.value);
});
} else {
this.resolveResult(ok);
}
return null;
}
private updatedValidation() {
if (this.parameters.validateInput) {
const value = this.ui.inputBox.value;
if (value !== this.validationValue) {
this.validationValue = value;
this.validation = this.parameters.validateInput(value)
.then(validationError => {
if (this.validationValue !== value) {
throw canceled();
}
return validationError;
});
}
} else if (!this.validation) {
this.validation = TPromise.as(null);
}
return this.validation;
}
private dispose() { private dispose() {
this.disposables = dispose(this.disposables); this.disposables = dispose(this.disposables);
} }
...@@ -315,7 +348,13 @@ export class QuickInputService extends Component implements IQuickInputService { ...@@ -315,7 +348,13 @@ export class QuickInputService extends Component implements IQuickInputService {
private close(ok?: true | Thenable<never>) { private close(ok?: true | Thenable<never>) {
if (this.controller) { if (this.controller) {
this.controller.resolve(ok); const resolved = this.controller.resolve(ok);
if (resolved) {
resolved
.then(() => this.container.style.display = 'none')
.then(null, onUnexpectedError);
return;
}
} }
this.container.style.display = 'none'; this.container.style.display = 'none';
} }
......
...@@ -40,13 +40,13 @@ export class QuickInputBox { ...@@ -40,13 +40,13 @@ export class QuickInputBox {
inputElement.setAttribute('aria-autocomplete', 'list'); inputElement.setAttribute('aria-autocomplete', 'list');
} }
onKeyDown(handler: (event: StandardKeyboardEvent) => void): IDisposable { onKeyDown = (handler: (event: StandardKeyboardEvent) => void): IDisposable => {
return dom.addDisposableListener(this.inputBox.inputElement, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => { return dom.addDisposableListener(this.inputBox.inputElement, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => {
handler(new StandardKeyboardEvent(e)); handler(new StandardKeyboardEvent(e));
}); });
} }
onDidChange(handler: (event: string) => void): IDisposable { onDidChange = (handler: (event: string) => void): IDisposable => {
return this.inputBox.onDidChange(handler); return this.inputBox.onDidChange(handler);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册