Strict null pass on some base ui files (#4832)

* more strict null checks in base browser code

* revert changes to radiobutton

* fix some more minor things, enable strict null check in pipelines

* formatting

* fix compile errors

* make null undefined

* more null to undefined
This commit is contained in:
Anthony Dresser
2019-04-03 16:18:33 -07:00
committed by GitHub
parent 80a8e1a4da
commit cef5bbb2be
25 changed files with 253 additions and 234 deletions

View File

@@ -41,5 +41,9 @@ steps:
condition: succeededOrFailed() condition: succeededOrFailed()
- script: | - script: |
yarn run tslint yarn tslint
displayName: 'Run TSLint' displayName: 'Run TSLint'
- script: |
yarn strict-null-check
displayName: 'Run Strict Null Check'

View File

@@ -26,5 +26,9 @@ steps:
condition: succeededOrFailed() condition: succeededOrFailed()
- script: | - script: |
yarn run tslint yarn tslint
displayName: 'Run TSLint' displayName: 'Run TSLint'
- script: |
yarn strict-null-check
displayName: 'Run Strict Null Check'

View File

@@ -98,7 +98,7 @@ export class DropdownList extends Dropdown {
* Render the selected label of the dropdown * Render the selected label of the dropdown
*/ */
public renderLabel(): void { public renderLabel(): void {
if (this._options.labelRenderer) { if (this._options.labelRenderer && this.label) {
this._options.labelRenderer(this.label); this._options.labelRenderer(this.label);
} }
} }

View File

@@ -298,7 +298,7 @@ export class Dropdown extends Disposable {
this.$treeContainer.style('outline', `1px solid ${style.contextBorder || this._options.contextBorder}`); this.$treeContainer.style('outline', `1px solid ${style.contextBorder || this._options.contextBorder}`);
} }
private _inputValidator(value: string): IMessage { private _inputValidator(value: string): IMessage | null {
if (this._dataSource.options && !this._dataSource.options.find(i => i.value === value)) { if (this._dataSource.options && !this._dataSource.options.find(i => i.value === value)) {
if (this._options.strictSelection && this._options.errorMessage) { if (this._options.strictSelection && this._options.errorMessage) {
return { return {
@@ -313,7 +313,7 @@ export class Dropdown extends Disposable {
} }
} }
return undefined; return null;
} }
public set enabled(val: boolean) { public set enabled(val: boolean) {

View File

@@ -91,7 +91,7 @@ export class DropdownDataSource implements tree.IDataSource {
export class DropdownFilter extends TreeDefaults.DefaultFilter { export class DropdownFilter extends TreeDefaults.DefaultFilter {
public filterString: string; public filterString: string;
public isVisible(tree: tree.ITree, element: Resource): boolean { public isVisible(tree: tree.ITree | undefined, element: Resource): boolean {
return element.value.toLowerCase().includes(this.filterString.toLowerCase()); return element.value.toLowerCase().includes(this.filterString.toLowerCase());
} }
} }

View File

@@ -141,51 +141,54 @@ export class PanelComponent extends Disposable {
* Select a tab based on index (unrecommended) * Select a tab based on index (unrecommended)
* @param index index of tab in the html * @param index index of tab in the html
*/ */
selectTab(index: number); selectTab(index: number): void;
/** /**
* Select a tab based on the identifier that was passed into the tab * Select a tab based on the identifier that was passed into the tab
* @param identifier specified identifer of the tab * @param identifier specified identifer of the tab
*/ */
selectTab(identifier: string); selectTab(identifier: string): void;
/** /**
* Select a tab directly if you have access to the object * Select a tab directly if you have access to the object
* @param tab tab to navigate to * @param tab tab to navigate to
*/ */
selectTab(tab: TabComponent); selectTab(tab: TabComponent): void;
selectTab(input: TabComponent | number | string) { selectTab(input: TabComponent | number | string): void {
if (this._tabs && this._tabs.length > 0) { if (this._tabs && this._tabs.length > 0) {
let tab: TabComponent; let foundTab: TabComponent | undefined;
if (input instanceof TabComponent) { if (input instanceof TabComponent) {
tab = input; foundTab = input;
} else if (types.isNumber(input)) { } else if (types.isNumber(input)) {
tab = this._tabs.toArray()[input]; foundTab = this._tabs.toArray()[input];
} else if (types.isString(input)) { } else if (types.isString(input)) {
tab = this._tabs.find(i => i.identifier === input); foundTab = this._tabs.find(i => i.identifier === input);
} }
// since we need to compare identifiers in this next step we are going to go through and make sure all tabs have one if (foundTab) {
this._tabs.forEach(i => { const tab = foundTab;
if (!i.identifier) { // since we need to compare identifiers in this next step we are going to go through and make sure all tabs have one
i.identifier = 'tabIndex_' + idPool++; this._tabs.forEach(i => {
} if (!i.identifier) {
}); i.identifier = 'tabIndex_' + idPool++;
}
});
if (this._activeTab && tab === this._activeTab) { if (this._activeTab && tab === this._activeTab) {
this.onTabChange.emit(tab); this.onTabChange.emit(tab);
return; return;
}
this._zone.run(() => {
if (this._activeTab) {
this._activeTab.active = false;
}
this._activeTab = tab;
this.setMostRecentlyUsed(tab);
this._activeTab.active = true;
this.onTabChange.emit(tab);
});
} }
this._zone.run(() => {
if (this._activeTab) {
this._activeTab.active = false;
}
this._activeTab = tab;
this.setMostRecentlyUsed(tab);
this._activeTab.active = true;
this.onTabChange.emit(tab);
});
} }
} }

View File

@@ -47,7 +47,7 @@ export type PanelTabIdentifier = string;
export class TabbedPanel extends Disposable implements IThemable { export class TabbedPanel extends Disposable implements IThemable {
private _tabMap = new Map<PanelTabIdentifier, IInternalPanelTab>(); private _tabMap = new Map<PanelTabIdentifier, IInternalPanelTab>();
private _shownTab: PanelTabIdentifier; private _shownTabId?: PanelTabIdentifier;
public readonly headersize = 35; public readonly headersize = 35;
private header: HTMLElement; private header: HTMLElement;
private tabList: HTMLElement; private tabList: HTMLElement;
@@ -103,7 +103,7 @@ export class TabbedPanel extends Disposable implements IThemable {
internalTab.disposables = []; internalTab.disposables = [];
this._tabMap.set(tab.identifier, internalTab); this._tabMap.set(tab.identifier, internalTab);
this._createTab(internalTab); this._createTab(internalTab);
if (!this._shownTab) { if (!this._shownTabId) {
this.showTab(tab.identifier); this.showTab(tab.identifier);
} }
if (this._tabMap.size > 1 && !this._headerVisible) { if (this._tabMap.size > 1 && !this._headerVisible) {
@@ -147,24 +147,23 @@ export class TabbedPanel extends Disposable implements IThemable {
} }
public showTab(id: PanelTabIdentifier): void { public showTab(id: PanelTabIdentifier): void {
if (this._shownTab && this._shownTab === id) { if (this._shownTabId === id || !this._tabMap.has(id)) {
return; return;
} }
if (this._shownTab) { if (this._shownTabId) {
DOM.removeClass(this._tabMap.get(this._shownTab).label, 'active'); const shownTab = this._tabMap.get(this._shownTabId);
DOM.removeClass(this._tabMap.get(this._shownTab).header, 'active'); if (shownTab) {
this._tabMap.get(this._shownTab).header.setAttribute('aria-selected', 'false'); DOM.removeClass(shownTab.label, 'active');
DOM.removeClass(shownTab.header, 'active');
shownTab.header.setAttribute('aria-selected', 'false');
shownTab.body.remove();
}
} }
let prevTab = this._tabMap.get(this._shownTab); this._shownTabId = id;
if (prevTab) {
prevTab.body.remove();
}
this._shownTab = id;
this.tabHistory.push(id); this.tabHistory.push(id);
let tab = this._tabMap.get(this._shownTab); const tab = this._tabMap.get(this._shownTabId)!; // @anthonydresser we know this can't be undefined since we check further up if the map contains the id
if (!tab.body) { if (!tab.body) {
tab.body = DOM.$('.tab-container'); tab.body = DOM.$('.tab-container');
tab.body.style.width = '100%'; tab.body.style.width = '100%';
@@ -183,7 +182,10 @@ export class TabbedPanel extends Disposable implements IThemable {
} }
public removeTab(tab: PanelTabIdentifier) { public removeTab(tab: PanelTabIdentifier) {
let actualTab = this._tabMap.get(tab); const actualTab = this._tabMap.get(tab);
if (!actualTab) {
return;
}
if (actualTab.view && actualTab.view.remove) { if (actualTab.view && actualTab.view.remove) {
actualTab.view.remove(); actualTab.view.remove();
} }
@@ -195,12 +197,14 @@ export class TabbedPanel extends Disposable implements IThemable {
} }
dispose(actualTab.disposables); dispose(actualTab.disposables);
this._tabMap.delete(tab); this._tabMap.delete(tab);
if (this._shownTab === tab) { if (this._shownTabId === tab) {
this._shownTab = undefined; this._shownTabId = undefined;
while (this._shownTab === undefined && this.tabHistory.length > 0) { while (this._shownTabId === undefined && this.tabHistory.length > 0) {
let lastTab = this.tabHistory.shift(); let lastTab = this.tabHistory.shift();
if (this._tabMap.get(lastTab)) { if (lastTab) {
this.showTab(lastTab); if (this._tabMap.get(lastTab)) {
this.showTab(lastTab);
}
} }
} }
} }
@@ -230,11 +234,13 @@ export class TabbedPanel extends Disposable implements IThemable {
} }
private _layoutCurrentTab(dimension: DOM.Dimension): void { private _layoutCurrentTab(dimension: DOM.Dimension): void {
if (this._shownTab) { if (this._shownTabId) {
let tab = this._tabMap.get(this._shownTab); const tab = this._tabMap.get(this._shownTabId);
tab.body.style.width = dimension.width + 'px'; if (tab) {
tab.body.style.height = dimension.height + 'px'; tab.body.style.width = dimension.width + 'px';
tab.view.layout(dimension); tab.body.style.height = dimension.height + 'px';
tab.view.layout(dimension);
}
} }
} }

View File

@@ -21,7 +21,7 @@ export abstract class TabChild extends Disposable {
}) })
export class TabComponent implements OnDestroy { export class TabComponent implements OnDestroy {
private _child: TabChild; private _child: TabChild;
@ContentChild(TemplateRef) templateRef; @ContentChild(TemplateRef) templateRef: TemplateRef<any>;
@Input() public title: string; @Input() public title: string;
@Input() public canClose: boolean; @Input() public canClose: boolean;
@Input() public actions: Array<Action>; @Input() public actions: Array<Action>;
@@ -32,8 +32,7 @@ export class TabComponent implements OnDestroy {
private rendered = false; private rendered = false;
private destroyed: boolean = false; private destroyed: boolean = false;
@ContentChild(TabChild) public set child(tab: TabChild) {
@ContentChild(TabChild) private set child(tab: TabChild) {
this._child = tab; this._child = tab;
if (this.active && this._child) { if (this.active && this._child) {
this._child.layout(); this._child.layout();

View File

@@ -3,13 +3,9 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
'use strict';
import * as DOM from 'vs/base/browser/dom';
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
import { Color } from 'vs/base/common/color';
import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
import { Event, Emitter } from 'vs/base/common/event'; import { Event, Emitter } from 'vs/base/common/event';
import { Widget } from 'vs/base/browser/ui/widget'; import { Widget } from 'vs/base/browser/ui/widget';
import { withNullAsUndefined } from 'vs/base/common/types';
export interface IRadioButtonOptions { export interface IRadioButtonOptions {
label: string; label: string;
@@ -43,20 +39,24 @@ export class RadioButton extends Widget {
container.appendChild(this._label); container.appendChild(this._label);
} }
public set name(value: string) { public set name(value: string | undefined) {
this.inputElement.setAttribute('name', value); if (value) {
this.inputElement.setAttribute('name', value);
}
} }
public get name(): string { public get name(): string | undefined {
return this.inputElement.getAttribute('name'); return withNullAsUndefined(this.inputElement.getAttribute('name'));
} }
public set value(value: string) { public set value(value: string | undefined) {
this.inputElement.setAttribute('value', value); if (value) {
this.inputElement.setAttribute('value', value);
}
} }
public get value(): string { public get value(): string | undefined {
return this.inputElement.getAttribute('value'); return withNullAsUndefined(this.inputElement.getAttribute('value'));
} }
public set checked(val: boolean) { public set checked(val: boolean) {
@@ -83,4 +83,4 @@ export class RadioButton extends Widget {
this._label.innerText = val; this._label.innerText = val;
} }
} }

View File

@@ -30,7 +30,7 @@ export class ScrollableDirective extends AngularDisposable {
ngOnInit() { ngOnInit() {
this.scrolled = this._el.nativeElement as HTMLElement; this.scrolled = this._el.nativeElement as HTMLElement;
this.parent = this.scrolled.parentElement; this.parent = this.scrolled.parentElement!;
const next = this.scrolled.nextSibling; const next = this.scrolled.nextSibling;
this.parent.removeChild(this.scrolled); this.parent.removeChild(this.scrolled);

View File

@@ -31,8 +31,8 @@ export class HeightMap {
return !last ? 0 : last.top + last.height; return !last ? 0 : last.top + last.height;
} }
public onInsertItems(iterator: INextIterator<IViewItem>, afterItemId: string = null): number { public onInsertItems(iterator: INextIterator<IViewItem>, afterItemId: string | undefined = undefined): number | undefined {
let viewItem: IViewItem; let viewItem: IViewItem | undefined = undefined;
let i: number, j: number; let i: number, j: number;
let totalSize: number; let totalSize: number;
let sizeDiff = 0; let sizeDiff = 0;
@@ -89,10 +89,10 @@ export class HeightMap {
// Contiguous items // Contiguous items
public onRemoveItems(iterator: INextIterator<string>): void { public onRemoveItems(iterator: INextIterator<string>): void {
let itemId: string; let itemId: string | undefined = undefined;
let viewItem: IViewItem; let viewItem: IViewItem;
let startIndex: number = null; let startIndex: number | undefined = undefined;
let i: number; let i = 0;
let sizeDiff = 0; let sizeDiff = 0;
while (itemId = iterator.next()) { while (itemId = iterator.next()) {
@@ -108,12 +108,12 @@ export class HeightMap {
delete this.indexes[itemId]; delete this.indexes[itemId];
this.onRemoveItem(viewItem); this.onRemoveItem(viewItem);
if (startIndex === null) { if (startIndex === undefined) {
startIndex = i; startIndex = i;
} }
} }
if (sizeDiff === 0) { if (sizeDiff === 0 || startIndex === undefined) {
return; return;
} }

View File

@@ -275,7 +275,7 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
// Add sash // Add sash
if (this.options.enableResizing && this.viewItems.length > 1) { if (this.options.enableResizing && this.viewItems.length > 1) {
const orientation = this.orientation === Orientation.VERTICAL ? Orientation.HORIZONTAL : Orientation.VERTICAL; const orientation = this.orientation === Orientation.VERTICAL ? Orientation.HORIZONTAL : Orientation.VERTICAL;
const layoutProvider = this.orientation === Orientation.VERTICAL ? { getHorizontalSashTop: sash => this.getSashPosition(sash) } : { getVerticalSashLeft: sash => this.getSashPosition(sash) }; const layoutProvider = this.orientation === Orientation.VERTICAL ? { getHorizontalSashTop: (sash: Sash) => this.getSashPosition(sash) } : { getVerticalSashLeft: (sash: Sash) => this.getSashPosition(sash) };
const sash = new Sash(this.sashContainer, layoutProvider, { const sash = new Sash(this.sashContainer, layoutProvider, {
orientation, orientation,
orthogonalStartSash: this.orthogonalStartSash, orthogonalStartSash: this.orthogonalStartSash,
@@ -321,8 +321,8 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
// this isn't actually scrolling up or down // this isn't actually scrolling up or down
let scrollTop = this.lastRenderTop; let scrollTop = this.lastRenderTop;
let viewHeight = this.lastRenderHeight; let viewHeight = this.lastRenderHeight;
this.lastRenderTop = undefined; this.lastRenderTop = 0;
this.lastRenderHeight = undefined; this.lastRenderHeight = 0;
this.render(scrollTop, viewHeight); this.render(scrollTop, viewHeight);
} }
@@ -378,7 +378,7 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
// Add sash // Add sash
if (this.options.enableResizing && this.viewItems.length > 1) { if (this.options.enableResizing && this.viewItems.length > 1) {
const orientation = this.orientation === Orientation.VERTICAL ? Orientation.HORIZONTAL : Orientation.VERTICAL; const orientation = this.orientation === Orientation.VERTICAL ? Orientation.HORIZONTAL : Orientation.VERTICAL;
const layoutProvider = this.orientation === Orientation.VERTICAL ? { getHorizontalSashTop: sash => this.getSashPosition(sash) } : { getVerticalSashLeft: sash => this.getSashPosition(sash) }; const layoutProvider = this.orientation === Orientation.VERTICAL ? { getHorizontalSashTop: (sash: Sash) => this.getSashPosition(sash) } : { getVerticalSashLeft: (sash: Sash) => this.getSashPosition(sash) };
const sash = new Sash(this.sashContainer, layoutProvider, { const sash = new Sash(this.sashContainer, layoutProvider, {
orientation, orientation,
orthogonalStartSash: this.orthogonalStartSash, orthogonalStartSash: this.orthogonalStartSash,
@@ -502,8 +502,8 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
const previousSize = Math.max(this.size, this.contentSize); const previousSize = Math.max(this.size, this.contentSize);
this.size = size; this.size = size;
this.contentSize = 0; this.contentSize = 0;
this.lastRenderHeight = undefined; this.lastRenderHeight = 0;
this.lastRenderTop = undefined; this.lastRenderTop = 0;
if (!this.proportions) { if (!this.proportions) {
this.resize(this.viewItems.length - 1, size - previousSize); this.resize(this.viewItems.length - 1, size - previousSize);
@@ -734,14 +734,14 @@ export class ScrollableSplitView extends HeightMap implements IDisposable {
return false; return false;
} }
let elementAfter: HTMLElement = null; let elementAfter: HTMLElement | undefined = undefined;
let itemAfter = <IViewItem>this.itemAfter(item); let itemAfter = <IViewItem>this.itemAfter(item);
if (itemAfter && itemAfter.container) { if (itemAfter && itemAfter.container) {
elementAfter = itemAfter.container; elementAfter = itemAfter.container;
} }
if (elementAfter === null) { if (elementAfter === undefined) {
this.viewContainer.appendChild(item.container); this.viewContainer.appendChild(item.container);
} else { } else {
try { try {

View File

@@ -11,7 +11,7 @@ import { Color } from 'vs/base/common/color';
import { IContextViewProvider, AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview'; import { IContextViewProvider, AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
import * as dom from 'vs/base/browser/dom'; import * as dom from 'vs/base/browser/dom';
import { RenderOptions, renderFormattedText, renderText } from 'vs/base/browser/htmlContentRenderer'; import { RenderOptions, renderFormattedText, renderText } from 'vs/base/browser/htmlContentRenderer';
import { IMessage, MessageType, defaultOpts } from 'vs/base/browser/ui/inputbox/inputBox'; import { IMessage, MessageType } from 'vs/base/browser/ui/inputbox/inputBox';
import aria = require('vs/base/browser/ui/aria/aria'); import aria = require('vs/base/browser/ui/aria/aria');
import nls = require('vs/nls'); import nls = require('vs/nls');
@@ -22,40 +22,51 @@ export interface ISelectBoxStyles extends vsISelectBoxStyles {
disabledSelectForeground?: Color; disabledSelectForeground?: Color;
inputValidationInfoBorder?: Color; inputValidationInfoBorder?: Color;
inputValidationInfoBackground?: Color; inputValidationInfoBackground?: Color;
inputinputValidationInfoForeground?: Color;
inputValidationWarningBorder?: Color; inputValidationWarningBorder?: Color;
inputValidationWarningBackground?: Color; inputValidationWarningBackground?: Color;
inputValidationWarningForeground?: Color;
inputValidationErrorBorder?: Color; inputValidationErrorBorder?: Color;
inputValidationErrorBackground?: Color; inputValidationErrorBackground?: Color;
inputValidationErrorForeground?: Color;
} }
export class SelectBox extends vsSelectBox { export class SelectBox extends vsSelectBox {
private _optionsDictionary; private _optionsDictionary: Map<string, number>;
private _dialogOptions: string[]; private _dialogOptions: string[];
private _selectedOption: string; private _selectedOption: string;
private _selectBoxOptions: ISelectBoxOptions; private _selectBoxOptions?: ISelectBoxOptions;
private enabledSelectBackground: Color; private enabledSelectBackground?: Color;
private enabledSelectForeground: Color; private enabledSelectForeground?: Color;
private enabledSelectBorder: Color; private enabledSelectBorder?: Color;
private disabledSelectBackground: Color; private disabledSelectBackground?: Color;
private disabledSelectForeground: Color; private disabledSelectForeground?: Color;
private disabledSelectBorder: Color; private disabledSelectBorder?: Color;
private contextViewProvider: IContextViewProvider; private contextViewProvider: IContextViewProvider;
private message: IMessage; private message?: IMessage;
private inputValidationInfoBorder: Color;
private inputValidationInfoBackground: Color; private inputValidationInfoBorder?: Color;
private inputValidationWarningBorder: Color; private inputValidationInfoBackground?: Color;
private inputValidationWarningBackground: Color; private inputValidationInfoForeground?: Color;
private inputValidationErrorBorder: Color; private inputValidationWarningBorder?: Color;
private inputValidationErrorBackground: Color; private inputValidationWarningBackground?: Color;
private inputValidationWarningForeground?: Color;
private inputValidationErrorBorder?: Color;
private inputValidationErrorBackground?: Color;
private inputValidationErrorForeground?: Color;
private element: HTMLElement; private element: HTMLElement;
constructor(options: string[], selectedOption: string, contextViewProvider: IContextViewProvider, container?: HTMLElement, selectBoxOptions?: ISelectBoxOptions) { constructor(options: string[], selectedOption: string, contextViewProvider: IContextViewProvider, container?: HTMLElement, selectBoxOptions?: ISelectBoxOptions) {
super(options.map(option => { return { text: option }; }), 0, contextViewProvider, undefined, selectBoxOptions); super(options.map(option => { return { text: option }; }), 0, contextViewProvider, undefined, selectBoxOptions);
this._optionsDictionary = new Array(); this._optionsDictionary = new Map<string, number>();
for (var i = 0; i < options.length; i++) { for (let i = 0; i < options.length; i++) {
this._optionsDictionary[options[i]] = i; this._optionsDictionary.set(options[i], i);
}
const option = this._optionsDictionary.get(selectedOption);
if (option) {
super.select(option);
} }
super.select(this._optionsDictionary[selectedOption]);
this._selectedOption = selectedOption; this._selectedOption = selectedOption;
this._dialogOptions = options; this._dialogOptions = options;
this._register(this.onDidSelect(newInput => { this._register(this.onDidSelect(newInput => {
@@ -66,8 +77,8 @@ export class SelectBox extends vsSelectBox {
this.enabledSelectForeground = this.selectForeground; this.enabledSelectForeground = this.selectForeground;
this.enabledSelectBorder = this.selectBorder; this.enabledSelectBorder = this.selectBorder;
this.disabledSelectBackground = Color.transparent; this.disabledSelectBackground = Color.transparent;
this.disabledSelectForeground = null; this.disabledSelectForeground = undefined;
this.disabledSelectBorder = null; this.disabledSelectBorder = undefined;
this.contextViewProvider = contextViewProvider; this.contextViewProvider = contextViewProvider;
if (container) { if (container) {
this.element = dom.append(container, $('.monaco-selectbox.idle')); this.element = dom.append(container, $('.monaco-selectbox.idle'));
@@ -77,7 +88,7 @@ export class SelectBox extends vsSelectBox {
this.selectElement.setAttribute('role', 'combobox'); this.selectElement.setAttribute('role', 'combobox');
this._selectBoxOptions = selectBoxOptions; this._selectBoxOptions = selectBoxOptions;
var focusTracker = dom.trackFocus(this.selectElement); let focusTracker = dom.trackFocus(this.selectElement);
this._register(focusTracker); this._register(focusTracker);
this._register(focusTracker.onDidBlur(() => this._hideMessage())); this._register(focusTracker.onDidBlur(() => this._hideMessage()));
this._register(focusTracker.onDidFocus(() => this._showMessage())); this._register(focusTracker.onDidFocus(() => this._showMessage()));
@@ -92,16 +103,20 @@ export class SelectBox extends vsSelectBox {
this.disabledSelectForeground = styles.disabledSelectForeground; this.disabledSelectForeground = styles.disabledSelectForeground;
this.inputValidationInfoBorder = styles.inputValidationInfoBorder; this.inputValidationInfoBorder = styles.inputValidationInfoBorder;
this.inputValidationInfoBackground = styles.inputValidationInfoBackground; this.inputValidationInfoBackground = styles.inputValidationInfoBackground;
this.inputValidationInfoForeground = styles.inputinputValidationInfoForeground;
this.inputValidationWarningBorder = styles.inputValidationWarningBorder; this.inputValidationWarningBorder = styles.inputValidationWarningBorder;
this.inputValidationWarningBackground = styles.inputValidationWarningBackground; this.inputValidationWarningBackground = styles.inputValidationWarningBackground;
this.inputValidationWarningForeground = styles.inputValidationWarningForeground;
this.inputValidationErrorBorder = styles.inputValidationErrorBorder; this.inputValidationErrorBorder = styles.inputValidationErrorBorder;
this.inputValidationErrorBackground = styles.inputValidationErrorBackground; this.inputValidationErrorBackground = styles.inputValidationErrorBackground;
this.inputValidationErrorForeground = styles.inputValidationErrorForeground;
this.applyStyles(); this.applyStyles();
} }
public selectWithOptionName(optionName: string): void { public selectWithOptionName(optionName: string): void {
if (this._optionsDictionary[optionName]) { const option = this._optionsDictionary.get(optionName);
this.select(this._optionsDictionary[optionName]); if (option) {
this.select(option);
} else { } else {
this.select(0); this.select(0);
} }
@@ -121,9 +136,9 @@ export class SelectBox extends vsSelectBox {
} else { } else {
stringOptions = options as string[]; stringOptions = options as string[];
} }
this._optionsDictionary = []; this._optionsDictionary = new Map<string, number>();
for (var i = 0; i < stringOptions.length; i++) { for (let i = 0; i < stringOptions.length; i++) {
this._optionsDictionary[stringOptions[i]] = i; this._optionsDictionary.set(stringOptions[i], i);
} }
this._dialogOptions = stringOptions; this._dialogOptions = stringOptions;
super.setOptions(stringOptions.map(option => { return { text: option }; }), selected); super.setOptions(stringOptions.map(option => { return { text: option }; }), selected);
@@ -187,6 +202,7 @@ export class SelectBox extends vsSelectBox {
public _showMessage(): void { public _showMessage(): void {
if (this.message && this.contextViewProvider && this.element) { if (this.message && this.contextViewProvider && this.element) {
const message = this.message;
let div: HTMLElement; let div: HTMLElement;
let layout = () => div.style.width = dom.getTotalWidth(this.selectElement) + 'px'; let layout = () => div.style.width = dom.getTotalWidth(this.selectElement) + 'px';
@@ -202,12 +218,12 @@ export class SelectBox extends vsSelectBox {
className: 'monaco-inputbox-message' className: 'monaco-inputbox-message'
}; };
let spanElement: HTMLElement = (this.message.formatContent let spanElement: HTMLElement = (message.formatContent
? renderFormattedText(this.message.content, renderOptions) ? renderFormattedText(message.content, renderOptions)
: renderText(this.message.content, renderOptions)) as any; : renderText(message.content, renderOptions)) as any;
dom.addClass(spanElement, this.classForType(this.message.type)); dom.addClass(spanElement, this.classForType(message.type));
const styles = this.stylesForType(this.message.type); const styles = this.stylesForType(message.type);
spanElement.style.backgroundColor = styles.background ? styles.background.toString() : null; spanElement.style.backgroundColor = styles.background ? styles.background.toString() : null;
spanElement.style.border = styles.border ? `1px solid ${styles.border}` : null; spanElement.style.border = styles.border ? `1px solid ${styles.border}` : null;
@@ -229,7 +245,7 @@ export class SelectBox extends vsSelectBox {
this._hideMessage(); this._hideMessage();
this.applyStyles(); this.applyStyles();
this.message = null; this.message = undefined;
} }
private _hideMessage(): void { private _hideMessage(): void {
@@ -238,7 +254,7 @@ export class SelectBox extends vsSelectBox {
} }
} }
private classForType(type: MessageType): string { private classForType(type: MessageType | undefined): string {
switch (type) { switch (type) {
case MessageType.INFO: return 'info'; case MessageType.INFO: return 'info';
case MessageType.WARNING: return 'warning'; case MessageType.WARNING: return 'warning';
@@ -246,11 +262,11 @@ export class SelectBox extends vsSelectBox {
} }
} }
private stylesForType(type: MessageType): { border: Color; background: Color } { private stylesForType(type: MessageType | undefined): { border: Color | undefined; background: Color | undefined; foreground: Color | undefined } {
switch (type) { switch (type) {
case MessageType.INFO: return { border: this.inputValidationInfoBorder, background: this.inputValidationInfoBackground }; case MessageType.INFO: return { border: this.inputValidationInfoBorder, background: this.inputValidationInfoBackground, foreground: this.inputValidationInfoForeground };
case MessageType.WARNING: return { border: this.inputValidationWarningBorder, background: this.inputValidationWarningBackground }; case MessageType.WARNING: return { border: this.inputValidationWarningBorder, background: this.inputValidationWarningBackground, foreground: this.inputValidationWarningForeground };
default: return { border: this.inputValidationErrorBorder, background: this.inputValidationErrorBackground }; default: return { border: this.inputValidationErrorBorder, background: this.inputValidationErrorBackground, foreground: this.inputValidationErrorForeground };
} }
} }

View File

@@ -16,7 +16,7 @@ export interface IObservableCollection<T> {
} }
class DataWindow<T> { class DataWindow<T> {
private _data: T[]; private _data: T[] | undefined;
private _length: number = 0; private _length: number = 0;
private _offsetFromDataSource: number = -1; private _offsetFromDataSource: number = -1;
@@ -30,9 +30,6 @@ class DataWindow<T> {
dispose() { dispose() {
this._data = undefined; this._data = undefined;
this.loadFunction = undefined;
this.placeholderItemGenerator = undefined;
this.loadCompleteCallback = undefined;
this.cancellationToken.cancel(); this.cancellationToken.cancel();
} }
@@ -157,7 +154,7 @@ export class VirtualizedCollection<T extends Slick.SlickData> implements IObserv
} }
private getRangeFromCurrent(start: number, end: number): T[] { private getRangeFromCurrent(start: number, end: number): T[] {
let currentData = []; const currentData: Array<T> = [];
for (let i = 0; i < end - start; i++) { for (let i = 0; i < end - start; i++) {
currentData.push(this.getDataFromCurrent(start + i)); currentData.push(this.getDataFromCurrent(start + i));
} }

View File

@@ -21,7 +21,7 @@ export interface ITableStyles extends IListStyles {
} }
export interface ITableSorter<T> { export interface ITableSorter<T> {
sort(args: Slick.OnSortEventArgs<T>); (args: Slick.OnSortEventArgs<T>): void;
} }
export interface ITableConfiguration<T> { export interface ITableConfiguration<T> {

View File

@@ -6,7 +6,6 @@
import 'vs/css!./media/table'; import 'vs/css!./media/table';
import { TableDataView } from './tableDataView'; import { TableDataView } from './tableDataView';
import { IDisposableDataProvider, ITableSorter, ITableMouseEvent, ITableConfiguration, ITableStyles } from 'sql/base/browser/ui/table/interfaces'; import { IDisposableDataProvider, ITableSorter, ITableMouseEvent, ITableConfiguration, ITableStyles } from 'sql/base/browser/ui/table/interfaces';
import { $ } from 'sql/base/browser/builder';
import { IThemable } from 'vs/platform/theme/common/styler'; import { IThemable } from 'vs/platform/theme/common/styler';
import * as DOM from 'vs/base/browser/dom'; import * as DOM from 'vs/base/browser/dom';
@@ -94,7 +93,7 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
if (configuration && configuration.sorter) { if (configuration && configuration.sorter) {
this._sorter = configuration.sorter; this._sorter = configuration.sorter;
this._grid.onSort.subscribe((e, args) => { this._grid.onSort.subscribe((e, args) => {
this._sorter.sort(args); this._sorter(args);
this._grid.invalidate(); this._grid.invalidate();
this._grid.render(); this._grid.render();
}); });
@@ -121,7 +120,7 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
} }
public dispose() { public dispose() {
$(this._container).dispose(); this._container.remove();
super.dispose(); super.dispose();
} }
@@ -146,9 +145,9 @@ export class Table<T extends Slick.SlickData> extends Widget implements IThemabl
return this._grid; return this._grid;
} }
setData(data: Array<T>); setData(data: Array<T>): void;
setData(data: TableDataView<T>); setData(data: TableDataView<T>): void;
setData(data: Array<T> | TableDataView<T>) { setData(data: Array<T> | TableDataView<T>): void {
if (data instanceof TableDataView) { if (data instanceof TableDataView) {
this._data = data; this._data = data;
} else { } else {

View File

@@ -16,22 +16,27 @@ export interface IFindPosition {
row: number; row: number;
} }
function defaultSort<T>(args: Slick.OnSortEventArgs<T>, data: Array<T>): Array<T> { function defaultSort<T extends { [key: string]: any }>(args: Slick.OnSortEventArgs<T>, data: Array<T>): Array<T> {
let field = args.sortCol.field; if (!args.sortCol || !args.sortCol.field) {
let sign = args.sortAsc ? 1 : -1; return data;
let comparer: (a, b) => number; }
const field = args.sortCol.field;
const sign = args.sortAsc ? 1 : -1;
let comparer: (a: T, b: T) => number;
if (types.isString(data[0][field])) { if (types.isString(data[0][field])) {
if (Number(data[0][field]) !== NaN) { if (Number(data[0][field]) !== NaN) {
comparer = (a: number, b: number) => { comparer = (a: T, b: T) => {
let anum = Number(a[field]); let anum = Number(a[field]);
let bnum = Number(b[field]); let bnum = Number(b[field]);
return anum === bnum ? 0 : anum > bnum ? 1 : -1; return anum === bnum ? 0 : anum > bnum ? 1 : -1;
}; };
} else { } else {
comparer = stringCompare; comparer = (a: T, b: T) => {
return stringCompare(a[field], b[field]);
};
} }
} else { } else {
comparer = (a: number, b: number) => { comparer = (a: T, b: T) => {
return a[field] === b[field] ? 0 : (a[field] > b[field] ? 1 : -1); return a[field] === b[field] ? 0 : (a[field] > b[field] ? 1 : -1);
}; };
} }
@@ -44,7 +49,7 @@ export class TableDataView<T extends Slick.SlickData> implements IDisposableData
//Used when filtering is enabled, _allData holds the complete set of data. //Used when filtering is enabled, _allData holds the complete set of data.
private _allData: Array<T>; private _allData: Array<T>;
private _findArray: Array<IFindPosition>; private _findArray: Array<IFindPosition>;
private _findObs: Observable<IFindPosition>; private _findObs: Observable<IFindPosition> | undefined;
private _findIndex: number; private _findIndex: number;
private _filterEnabled: boolean; private _filterEnabled: boolean;
@@ -57,11 +62,14 @@ export class TableDataView<T extends Slick.SlickData> implements IDisposableData
private _onFilterStateChange = new Emitter<void>(); private _onFilterStateChange = new Emitter<void>();
get onFilterStateChange(): Event<void> { return this._onFilterStateChange.event; } get onFilterStateChange(): Event<void> { return this._onFilterStateChange.event; }
private _filterFn: (data: Array<T>) => Array<T>;
private _sortFn: (args: Slick.OnSortEventArgs<T>, data: Array<T>) => Array<T>;
constructor( constructor(
data?: Array<T>, data?: Array<T>,
private _findFn?: (val: T, exp: string) => Array<number>, private _findFn?: (val: T, exp: string) => Array<number>,
private _sortFn?: (args: Slick.OnSortEventArgs<T>, data: Array<T>) => Array<T>, _sortFn?: (args: Slick.OnSortEventArgs<T>, data: Array<T>) => Array<T>,
private _filterFn?: (data: Array<T>) => Array<T> _filterFn?: (data: Array<T>) => Array<T>
) { ) {
if (data) { if (data) {
this._data = data; this._data = data;
@@ -69,13 +77,9 @@ export class TableDataView<T extends Slick.SlickData> implements IDisposableData
this._data = new Array<T>(); this._data = new Array<T>();
} }
if (!_sortFn) { this._sortFn = _sortFn ? _sortFn : defaultSort;
this._sortFn = defaultSort;
}
if (!_filterFn) { this._filterFn = _filterFn ? _filterFn : (dataToFilter) => dataToFilter;
this._filterFn = (dataToFilter) => dataToFilter;
}
this._filterEnabled = false; this._filterEnabled = false;
} }
@@ -119,9 +123,9 @@ export class TableDataView<T extends Slick.SlickData> implements IDisposableData
return this.filterEnabled ? this._allData.length : this._data.length; return this.filterEnabled ? this._allData.length : this._data.length;
} }
push(items: Array<T>); push(items: Array<T>): void;
push(item: T); push(item: T): void;
push(input: T | Array<T>) { push(input: T | Array<T>): void {
let inputArray = new Array(); let inputArray = new Array();
if (Array.isArray(input)) { if (Array.isArray(input)) {
inputArray.push(...input); inputArray.push(...input);
@@ -161,7 +165,7 @@ export class TableDataView<T extends Slick.SlickData> implements IDisposableData
this._findObs = Observable.create((observer: Observer<IFindPosition>) => { this._findObs = Observable.create((observer: Observer<IFindPosition>) => {
for (let i = 0; i < this._data.length; i++) { for (let i = 0; i < this._data.length; i++) {
let item = this._data[i]; let item = this._data[i];
let result = this._findFn(item, exp); let result = this._findFn!(item, exp);
if (result) { if (result) {
result.forEach(pos => { result.forEach(pos => {
let index = { col: pos, row: i }; let index = { col: pos, row: i };
@@ -175,7 +179,7 @@ export class TableDataView<T extends Slick.SlickData> implements IDisposableData
} }
} }
}); });
return this._findObs.take(1).toPromise().then(() => { return this._findObs!.take(1).toPromise().then(() => {
return this._findArray[this._findIndex]; return this._findArray[this._findIndex];
}); });
} else { } else {
@@ -234,9 +238,9 @@ export class TableDataView<T extends Slick.SlickData> implements IDisposableData
} }
dispose() { dispose() {
this._data = undefined; this._data = [];
this._allData = undefined; this._allData = [];
this._findArray = undefined; this._findArray = [];
this._findObs = undefined; this._findObs = undefined;
} }
} }

View File

@@ -3,13 +3,10 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
'use strict';
import 'vs/css!vs/base/browser/ui/actionbar/actionbar'; import 'vs/css!vs/base/browser/ui/actionbar/actionbar';
import { Builder, $ } from 'sql/base/browser/builder'; import { Builder, $ } from 'sql/base/browser/builder';
import { IAction, IActionRunner, ActionRunner } from 'vs/base/common/actions'; import { IAction, IActionRunner, ActionRunner } from 'vs/base/common/actions';
import { EventEmitter } from 'sql/base/common/eventEmitter';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { import {

View File

@@ -80,12 +80,10 @@ export class ProfilerTableEditor extends BaseEditor implements IProfilerControll
parent.appendChild(this._overlay); parent.appendChild(this._overlay);
this._profilerTable = new Table(parent, { this._profilerTable = new Table(parent, {
sorter: { sorter: (args) => {
sort: (args) => { let input = this.input as ProfilerInput;
let input = this.input as ProfilerInput; if (input && input.data) {
if (input && input.data) { input.data.sort(args);
input.data.sort(args);
}
} }
} }
}, { }, {

View File

@@ -70,10 +70,8 @@ export class TopOperationsView implements IPanelView {
this.table = new Table(this.container, { this.table = new Table(this.container, {
columns: topOperationColumns, columns: topOperationColumns,
dataProvider: this.dataView, dataProvider: this.dataView,
sorter: { sorter: (args) => {
sort: (args) => { this.dataView.sort(args);
this.dataView.sort(args);
}
} }
}); });
this.disposables.push(this.table); this.disposables.push(this.table);

View File

@@ -0,0 +1,26 @@
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"noEmit": true,
"strictNullChecks": true,
"moduleResolution": "classic"
},
"include": [
"./typings",
"./vs/**.*.ts",
"./sql/base/browser/ui/breadcrumb/*.ts",
"./sql/base/browser/ui/button/*.ts",
"./sql/base/browser/ui/checkbox/*.ts",
"./sql/base/browser/ui/dropdownList/*.ts",
"./sql/base/browser/ui/inputBox/*.ts",
"./sql/base/browser/ui/listBox/*.ts",
"./sql/base/browser/ui/panel/*.ts",
"./sql/base/browser/ui/radioButton/*.ts",
"./sql/base/browser/ui/scrollable/*.ts",
"./sql/base/browser/ui/selectBox/*.ts",
"./sql/base/browser/ui/table/*.ts",
],
"exclude": [
"node_modules/**"
]
}

View File

@@ -1,35 +0,0 @@
{
"extends": "./tsconfig.strictNullChecks.json",
"include": [
"./typings",
"./vs/base/browser/**/*.ts",
"./vs/base/common/**/*.ts",
"./vs/base/node/**/*.ts",
"./vs/editor/browser/**/*.ts",
"./vs/editor/common/**/*.ts",
"./vs/editor/contrib/codeAction/**/*.ts",
"./vs/editor/contrib/format/**/*.ts",
"./vs/editor/contrib/gotoError/**/*.ts",
"./vs/editor/contrib/inPlaceReplace/**/*.ts",
"./vs/editor/contrib/smartSelect/**/*.ts",
"./vs/editor/contrib/snippet/**/*.ts",
"./vs/editor/contrib/suggest/**/*.ts",
"./vs/editor/test/**/*.ts",
"./sql/base/common/**/*ts",
],
"files": [
// "./sql/base/browser/ui/breadcrumb/breadcrumb.component.ts", // pulls in angular which gives extrenous errors
// "./sql/base/browser/ui/breadcrumb/interfaces.ts", // pulls in angular which gives extrenous errors
"./sql/base/browser/ui/button/button.ts",
"./sql/base/browser/ui/checkbox/checkbox.ts",
// "./sql/base/browser/ui/checkbox/checkbox.component.ts", // pulls in angular which gives extrenous errors
// "./sql/base/browser/ui/dropdownList/dropdownList.ts", // skipping since vscode hasn't checked their dropdown yet
// "./sql/base/browser/ui/editableDropdown/actions.ts", // skipping since vscode hasn't checked their dropdown yet and it isn't in the right place anyways
// "./sql/base/browser/ui/editableDropdown/dropdown.ts", // skipping since vscode hasn't checked their dropdown yet and it isn't in the right place anyways
// "./sql/base/browser/ui/editableDropdown/dropdownTree.ts", // skipping since vscode hasn't checked their dropdown yet and it isn't in the right place anyways
// "./sql/base/browser/ui/editableDropdown/editableDropdown.component.ts", // skipping since vscode hasn't checked their dropdown yet and it isn't in the right place anyways
// "./sql/base/browser/ui/inputBox/inputBox.component.ts", // pulls in angular which gives extrenous errors
// "./sql/base/browser/ui/inputBox/inputBox.ts", // skipping since vscode hasn't checked their inputbox yet
// "./sql/base/browser/ui/listBox/listBox.ts",
]
}

View File

@@ -5469,7 +5469,7 @@ export interface IterableChanges<V> {
* original `Iterable` location, where as `currentIndex` refers to the transient location * original `Iterable` location, where as `currentIndex` refers to the transient location
* of the item, after applying the operations up to this point. * of the item, after applying the operations up to this point.
*/ */
forEachOperation(fn: (record: IterableChangeRecord<V>, previousIndex: number, currentIndex: number) => void): void; forEachOperation(fn: (record: IterableChangeRecord<V>, previousIndex: number | null, currentIndex: number | null) => void): void;
/** /**
* Iterate over changes in the order of original `Iterable` showing where the original items * Iterate over changes in the order of original `Iterable` showing where the original items
* have moved. * have moved.

View File

@@ -74,9 +74,9 @@ export interface ISelectData {
export class SelectBox extends Widget implements ISelectBoxDelegate { export class SelectBox extends Widget implements ISelectBoxDelegate {
// {{SQL CARBON EDIT}} // {{SQL CARBON EDIT}}
protected selectElement: HTMLSelectElement; protected selectElement: HTMLSelectElement;
protected selectBackground: Color; protected selectBackground?: Color;
protected selectForeground: Color; protected selectForeground?: Color;
protected selectBorder: Color; protected selectBorder?: Color;
private styles: ISelectBoxStyles; private styles: ISelectBoxStyles;
private selectBoxDelegate: ISelectBoxDelegate; private selectBoxDelegate: ISelectBoxDelegate;
@@ -137,14 +137,15 @@ export class SelectBox extends Widget implements ISelectBoxDelegate {
public applyStyles(): void { public applyStyles(): void {
this.selectBoxDelegate.applyStyles(); this.selectBoxDelegate.applyStyles();
} }
// {{SQL CARBON EDIT}} // {{SQL CARBON EDIT}}
protected createOption(value: string, disabled?: boolean): HTMLOptionElement { protected createOption(value: string, disabled?: boolean): HTMLOptionElement {
let option = document.createElement('option'); let option = document.createElement('option');
option.value = value; option.value = value;
option.text = value; option.text = value;
option.disabled = disabled; option.disabled = disabled || false;
return option; return option;
} }
} }

View File

@@ -20,6 +20,9 @@ import { ISelectBoxDelegate, ISelectOptionItem, ISelectBoxOptions, ISelectBoxSty
import { isMacintosh } from 'vs/base/common/platform'; import { isMacintosh } from 'vs/base/common/platform';
import { renderMarkdown } from 'vs/base/browser/htmlContentRenderer'; import { renderMarkdown } from 'vs/base/browser/htmlContentRenderer';
// {{SQL CARBON EDIT}} import color
import { Color } from 'vs/base/common/color';
const $ = dom.$; const $ = dom.$;
const SELECT_OPTION_ENTRY_TEMPLATE_ID = 'selectOption.entry.template'; const SELECT_OPTION_ENTRY_TEMPLATE_ID = 'selectOption.entry.template';
@@ -372,23 +375,22 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
// Style parent select // Style parent select
// {{SQL CARBON EDIT}} // {{SQL CARBON EDIT}}
let background = null; let background: Color | undefined = undefined;
let foreground = null; let foreground: Color | undefined = undefined;
let border = null; let border: Color | undefined = undefined;
if (this.selectElement) { if (this.selectElement) {
if (this.selectElement.disabled) { if (this.selectElement.disabled) {
background = (<any>this.styles).disabledSelectBackground ? (<any>this.styles).disabledSelectBackground.toString() : null; background = (<any>this.styles).disabledSelectBackground;
foreground = (<any>this.styles).disabledSelectForeground ? (<any>this.styles).disabledSelectForeground.toString() : null; foreground = (<any>this.styles).disabledSelectForeground;
border = null;
} else { } else {
background = this.styles.selectBackground ? this.styles.selectBackground.toString() : null; background = this.styles.selectBackground;
foreground = this.styles.selectForeground ? this.styles.selectForeground.toString() : null; foreground = this.styles.selectForeground;
border = this.styles.selectBorder ? this.styles.selectBorder.toString() : null; border = this.styles.selectBorder;
} }
this.selectElement.style.backgroundColor = background; this.selectElement.style.backgroundColor = background ? background.toString() : null;
this.selectElement.style.color = foreground; this.selectElement.style.color = foreground ? foreground.toString() : null;
this.selectElement.style.borderColor = border; this.selectElement.style.borderColor = border ? border.toString() : null;
} }
// Style drop down select list (non-native mode only) // Style drop down select list (non-native mode only)