From 331f8115dca9659e7350d7ce001c97a773bb7b8a Mon Sep 17 00:00:00 2001 From: Charles Gagnon Date: Thu, 17 Jun 2021 13:47:53 -0700 Subject: [PATCH] Fix input validation alert (#15749) * Fix input validation alert * Add override --- src/sql/base/browser/ui/inputBox/inputBox.ts | 32 ++++++++++++++++--- .../modelComponents/inputbox.component.ts | 7 ++-- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/sql/base/browser/ui/inputBox/inputBox.ts b/src/sql/base/browser/ui/inputBox/inputBox.ts index dbe698d146..69b61f346c 100644 --- a/src/sql/base/browser/ui/inputBox/inputBox.ts +++ b/src/sql/base/browser/ui/inputBox/inputBox.ts @@ -3,7 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { InputBox as vsInputBox, IInputOptions, IInputBoxStyles as vsIInputBoxStyles, IMessage } from 'vs/base/browser/ui/inputbox/inputBox'; +import { InputBox as vsInputBox, IInputOptions as vsIInputBoxOptions, IInputBoxStyles as vsIInputBoxStyles, IMessage, MessageType } from 'vs/base/browser/ui/inputbox/inputBox'; import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview'; import { Color } from 'vs/base/common/color'; import { Event, Emitter } from 'vs/base/common/event'; @@ -18,6 +18,15 @@ export interface IInputBoxStyles extends vsIInputBoxStyles { disabledInputForeground?: Color; } +export interface IInputOptions extends vsIInputBoxOptions { + /** + * Whether calls to validate require the force parameter to be set to true + * to run the base VS Input Box validation logic. See validate() override + * for more info. + */ + requireForceValidations?: boolean +} + export class InputBox extends vsInputBox { private enabledInputBackground?: Color; private enabledInputForeground?: Color; @@ -34,8 +43,8 @@ export class InputBox extends vsInputBox { private _isTextAreaInput = false; private _hideErrors = false; - constructor(container: HTMLElement, contextViewProvider: IContextViewProvider, options?: IInputOptions) { - super(container, contextViewProvider, options); + constructor(container: HTMLElement, contextViewProvider: IContextViewProvider, private _sqlOptions?: IInputOptions) { + super(container, contextViewProvider, _sqlOptions); this.enabledInputBackground = this.inputBackground; this.enabledInputForeground = this.inputForeground; this.enabledInputBorder = this.inputBorder; @@ -48,7 +57,7 @@ export class InputBox extends vsInputBox { self._lastLoseFocusValue = self.value; }); - if (options && options.type === 'textarea') { + if (_sqlOptions && _sqlOptions.type === 'textarea') { this._isTextAreaInput = true; } } @@ -137,4 +146,19 @@ export class InputBox extends vsInputBox { this.inputForeground = enabled ? this.enabledInputForeground : this.disabledInputForeground; this.inputBorder = enabled ? this.enabledInputBorder : this.disabledInputBorder; } + + public override validate(force?: boolean): MessageType | undefined { + // We override the validate call here because in some situations we could end up with an "invalid" alert + // being announced incorrectly. For example the InputBox component has its own async validation - and so + // if a change was made to the text then the base VS InputBox would call validate immediately - before + // the async validation was able to trigger and complete and so the state could still be invalid at that + // point + // So instead we allow users of the input box to control whether to let the base input box do its validation + // as normal or whether to require manually calling validate with force === true in order to run the validation + // logic. + if (force || this._sqlOptions?.requireForceValidations !== true) { + return super.validate(); + } + return undefined; + } } diff --git a/src/sql/workbench/browser/modelComponents/inputbox.component.ts b/src/sql/workbench/browser/modelComponents/inputbox.component.ts index ef6e10cb20..9dc5c3ff22 100644 --- a/src/sql/workbench/browser/modelComponents/inputbox.component.ts +++ b/src/sql/workbench/browser/modelComponents/inputbox.component.ts @@ -11,10 +11,10 @@ import { import * as azdata from 'azdata'; import { ComponentBase } from 'sql/workbench/browser/modelComponents/componentBase'; -import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox'; +import { IInputOptions, InputBox } from 'sql/base/browser/ui/inputBox/inputBox'; import { attachInputBoxStyler } from 'sql/platform/theme/common/styler'; -import { IInputOptions, MessageType } from 'vs/base/browser/ui/inputbox/inputBox'; +import { MessageType } from 'vs/base/browser/ui/inputbox/inputBox'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import * as nls from 'vs/nls'; @@ -73,6 +73,7 @@ export default class InputBoxComponent extends ComponentBase { if (e.keyCode === KeyCode.Enter) { @@ -159,7 +160,7 @@ export default class InputBoxComponent extends ComponentBase { await super.validate(); // Let the input validate handle showing/hiding the error message - const valid = this.inputElement.validate() === undefined; + const valid = this.inputElement.validate(true) === undefined; // set aria label based on validity of input if (valid) {