in src/vs/workbench/browser/parts/quickinput/quickInput.ts [1005:1176]
private create() {
if (this.ui) {
return;
}
const workbench = this.layoutService.getWorkbenchElement();
const container = dom.append(workbench, $('.quick-input-widget.show-file-icons'));
container.tabIndex = -1;
container.style.display = 'none';
this.titleBar = dom.append(container, $('.quick-input-titlebar'));
const leftActionBar = this._register(new ActionBar(this.titleBar));
leftActionBar.domNode.classList.add('quick-input-left-action-bar');
const title = dom.append(this.titleBar, $('.quick-input-title'));
const rightActionBar = this._register(new ActionBar(this.titleBar));
rightActionBar.domNode.classList.add('quick-input-right-action-bar');
const headerContainer = dom.append(container, $('.quick-input-header'));
const checkAll = <HTMLInputElement>dom.append(headerContainer, $('input.quick-input-check-all'));
checkAll.type = 'checkbox';
this._register(dom.addStandardDisposableListener(checkAll, dom.EventType.CHANGE, e => {
const checked = checkAll.checked;
list.setAllVisibleChecked(checked);
}));
this._register(dom.addDisposableListener(checkAll, dom.EventType.CLICK, e => {
if (e.x || e.y) { // Avoid 'click' triggered by 'space'...
inputBox.setFocus();
}
}));
const extraContainer = dom.append(headerContainer, $('.quick-input-and-message'));
this.filterContainer = dom.append(extraContainer, $('.quick-input-filter'));
const inputBox = this._register(new QuickInputBox(this.filterContainer));
inputBox.setAttribute('aria-describedby', `${this.idPrefix}message`);
this.visibleCountContainer = dom.append(this.filterContainer, $('.quick-input-visible-count'));
this.visibleCountContainer.setAttribute('aria-live', 'polite');
this.visibleCountContainer.setAttribute('aria-atomic', 'true');
const visibleCount = new CountBadge(this.visibleCountContainer, { countFormat: localize({ key: 'quickInput.visibleCount', comment: ['This tells the user how many items are shown in a list of items to select from. The items can be anything. Currently not visible, but read by screen readers.'] }, "{0} Results") });
this.countContainer = dom.append(this.filterContainer, $('.quick-input-count'));
this.countContainer.setAttribute('aria-live', 'polite');
const count = new CountBadge(this.countContainer, { countFormat: localize({ key: 'quickInput.countSelected', comment: ['This tells the user how many items are selected in a list of items to select from. The items can be anything.'] }, "{0} Selected") });
this._register(attachBadgeStyler(count, this.themeService));
this.okContainer = dom.append(headerContainer, $('.quick-input-action'));
this.ok = new Button(this.okContainer);
attachButtonStyler(this.ok, this.themeService);
this.ok.label = localize('ok', "OK");
this._register(this.ok.onDidClick(e => {
this.onDidAcceptEmitter.fire();
}));
this.customButtonContainer = dom.append(headerContainer, $('.quick-input-action'));
const customButton = new Button(this.customButtonContainer);
attachButtonStyler(customButton, this.themeService);
customButton.label = localize('custom', "Custom");
this._register(customButton.onDidClick(e => {
this.onDidCustomEmitter.fire();
}));
const message = dom.append(extraContainer, $(`#${this.idPrefix}message.quick-input-message`));
const progressBar = new ProgressBar(container);
dom.addClass(progressBar.getContainer(), 'quick-input-progress');
this._register(attachProgressBarStyler(progressBar, this.themeService));
const list = this._register(this.instantiationService.createInstance(QuickInputList, container, this.idPrefix + 'list'));
this._register(list.onChangedAllVisibleChecked(checked => {
checkAll.checked = checked;
}));
this._register(list.onChangedVisibleCount(c => {
visibleCount.setCount(c);
}));
this._register(list.onChangedCheckedCount(c => {
count.setCount(c);
}));
this._register(list.onLeave(() => {
// Defer to avoid the input field reacting to the triggering key.
setTimeout(() => {
inputBox.setFocus();
if (this.controller instanceof QuickPick && this.controller.canSelectMany) {
list.clearFocus();
}
}, 0);
}));
this._register(list.onDidChangeFocus(() => {
if (this.comboboxAccessibility) {
this.ui.inputBox.setAttribute('aria-activedescendant', this.ui.list.getActiveDescendant() || '');
}
}));
const focusTracker = dom.trackFocus(container);
this._register(focusTracker);
this._register(focusTracker.onDidBlur(() => {
if (!this.ui.ignoreFocusOut && !this.environmentService.args['sticky-quickopen'] && this.configurationService.getValue(CLOSE_ON_FOCUS_LOST_CONFIG)) {
this.hide(true);
}
}));
this._register(dom.addDisposableListener(container, dom.EventType.FOCUS, (e: FocusEvent) => {
inputBox.setFocus();
}));
this._register(dom.addDisposableListener(container, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => {
const event = new StandardKeyboardEvent(e);
switch (event.keyCode) {
case KeyCode.Enter:
dom.EventHelper.stop(e, true);
this.onDidAcceptEmitter.fire();
break;
case KeyCode.Escape:
dom.EventHelper.stop(e, true);
this.hide();
break;
case KeyCode.Tab:
if (!event.altKey && !event.ctrlKey && !event.metaKey) {
const selectors = ['.action-label.icon'];
if (container.classList.contains('show-checkboxes')) {
selectors.push('input');
} else {
selectors.push('input[type=text]');
}
if (this.ui.list.isDisplayed()) {
selectors.push('.monaco-list');
}
const stops = container.querySelectorAll<HTMLElement>(selectors.join(', '));
if (event.shiftKey && event.target === stops[0]) {
dom.EventHelper.stop(e, true);
stops[stops.length - 1].focus();
} else if (!event.shiftKey && event.target === stops[stops.length - 1]) {
dom.EventHelper.stop(e, true);
stops[0].focus();
}
}
break;
}
}));
this._register(this.quickOpenService.onShow(() => this.hide(true)));
this.ui = {
container,
leftActionBar,
title,
rightActionBar,
checkAll,
inputBox,
visibleCount,
count,
message,
customButton,
progressBar,
list,
onDidAccept: this.onDidAcceptEmitter.event,
onDidCustom: this.onDidCustomEmitter.event,
onDidTriggerButton: this.onDidTriggerButtonEmitter.event,
ignoreFocusOut: false,
keyMods: this.keyMods,
isScreenReaderOptimized: () => this.isScreenReaderOptimized(),
show: controller => this.show(controller),
hide: () => this.hide(),
setVisibilities: visibilities => this.setVisibilities(visibilities),
setComboboxAccessibility: enabled => this.setComboboxAccessibility(enabled),
setEnabled: enabled => this.setEnabled(enabled),
setContextKey: contextKey => this.setContextKey(contextKey),
};
this.updateStyles();
}