mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-30 08:40:29 -04:00
Merge from vscode 2f984aad710215f4e4684a035bb02f55d1a9e2cc (#9819)
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IDisposable, dispose, Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { IExtensionsWorkbenchService, IExtension } from 'vs/workbench/contrib/extensions/common/extensions';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
@@ -14,7 +14,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
||||
import { IListService, WorkbenchAsyncDataTree } from 'vs/platform/list/browser/listService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IThemeService, registerThemingParticipant, IColorTheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
|
||||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { IAsyncDataSource, ITreeNode } from 'vs/base/browser/ui/tree/tree';
|
||||
import { IListVirtualDelegate, IListRenderer } from 'vs/base/browser/ui/list/list';
|
||||
@@ -22,6 +22,64 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { isNonEmptyArray } from 'vs/base/common/arrays';
|
||||
import { IColorMapping } from 'vs/platform/theme/common/styler';
|
||||
import { Renderer, Delegate } from 'vs/workbench/contrib/extensions/browser/extensionsList';
|
||||
import { listFocusForeground, listFocusBackground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
|
||||
export class ExtensionsGridView extends Disposable {
|
||||
|
||||
readonly element: HTMLElement;
|
||||
private readonly renderer: Renderer;
|
||||
private readonly delegate: Delegate;
|
||||
private readonly disposableStore: DisposableStore;
|
||||
|
||||
constructor(
|
||||
parent: HTMLElement,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService
|
||||
) {
|
||||
super();
|
||||
this.element = dom.append(parent, dom.$('.extensions-grid-view'));
|
||||
this.renderer = this.instantiationService.createInstance(Renderer, { onFocus: Event.None, onBlur: Event.None });
|
||||
this.delegate = new Delegate();
|
||||
this.disposableStore = new DisposableStore();
|
||||
}
|
||||
|
||||
setExtensions(extensions: IExtension[]): void {
|
||||
this.disposableStore.clear();
|
||||
extensions.forEach((e, index) => this.renderExtension(e, index));
|
||||
}
|
||||
|
||||
private renderExtension(extension: IExtension, index: number): void {
|
||||
const extensionContainer = dom.append(this.element, dom.$('.extension-container'));
|
||||
extensionContainer.style.height = `${this.delegate.getHeight()}px`;
|
||||
extensionContainer.style.width = `350px`;
|
||||
extensionContainer.setAttribute('tabindex', '0');
|
||||
|
||||
const template = this.renderer.renderTemplate(extensionContainer);
|
||||
this.disposableStore.add(toDisposable(() => this.renderer.disposeTemplate(template)));
|
||||
|
||||
const openExtensionAction = this.instantiationService.createInstance(OpenExtensionAction);
|
||||
openExtensionAction.extension = extension;
|
||||
template.name.setAttribute('tabindex', '0');
|
||||
|
||||
const handleEvent = (e: StandardMouseEvent | StandardKeyboardEvent) => {
|
||||
if (e instanceof StandardKeyboardEvent && e.keyCode !== KeyCode.Enter) {
|
||||
return;
|
||||
}
|
||||
openExtensionAction.run(e.ctrlKey || e.metaKey);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
this.disposableStore.add(dom.addDisposableListener(template.name, dom.EventType.CLICK, (e: MouseEvent) => handleEvent(new StandardMouseEvent(e))));
|
||||
this.disposableStore.add(dom.addDisposableListener(template.name, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => handleEvent(new StandardKeyboardEvent(e))));
|
||||
this.disposableStore.add(dom.addDisposableListener(extensionContainer, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => handleEvent(new StandardKeyboardEvent(e))));
|
||||
|
||||
this.renderer.renderElement(extension, index, template);
|
||||
}
|
||||
}
|
||||
|
||||
export interface IExtensionTemplateData {
|
||||
icon: HTMLImageElement;
|
||||
@@ -101,7 +159,7 @@ export class ExtensionRenderer implements IListRenderer<ITreeNode<IExtensionData
|
||||
author,
|
||||
extensionDisposables,
|
||||
set extensionData(extensionData: IExtensionData) {
|
||||
openExtensionAction.extensionData = extensionData;
|
||||
openExtensionAction.extension = extensionData.extension;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -157,19 +215,19 @@ export class UnknownExtensionRenderer implements IListRenderer<ITreeNode<IExtens
|
||||
|
||||
class OpenExtensionAction extends Action {
|
||||
|
||||
private _extensionData: IExtensionData | undefined;
|
||||
private _extension: IExtension | undefined;
|
||||
|
||||
constructor(@IExtensionsWorkbenchService private readonly extensionsWorkdbenchService: IExtensionsWorkbenchService) {
|
||||
super('extensions.action.openExtension', '');
|
||||
}
|
||||
|
||||
public set extensionData(extension: IExtensionData) {
|
||||
this._extensionData = extension;
|
||||
public set extension(extension: IExtension) {
|
||||
this._extension = extension;
|
||||
}
|
||||
|
||||
run(sideByside: boolean): Promise<any> {
|
||||
if (this._extensionData) {
|
||||
return this.extensionsWorkdbenchService.open(this._extensionData.extension, { sideByside });
|
||||
if (this._extension) {
|
||||
return this.extensionsWorkdbenchService.open(this._extension, { sideByside });
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
@@ -246,24 +304,40 @@ export class ExtensionData implements IExtensionData {
|
||||
|
||||
async getChildren(): Promise<IExtensionData[] | null> {
|
||||
if (this.hasChildren) {
|
||||
const localById = this.extensionsWorkbenchService.local.reduce((result, e) => { result.set(e.identifier.id.toLowerCase(), e); return result; }, new Map<string, IExtension>());
|
||||
const result: IExtension[] = [];
|
||||
const toQuery: string[] = [];
|
||||
for (const extensionId of this.childrenExtensionIds) {
|
||||
const id = extensionId.toLowerCase();
|
||||
const local = localById.get(id);
|
||||
if (local) {
|
||||
result.push(local);
|
||||
} else {
|
||||
toQuery.push(id);
|
||||
}
|
||||
}
|
||||
if (toQuery.length) {
|
||||
const galleryResult = await this.extensionsWorkbenchService.queryGallery({ names: toQuery, pageSize: toQuery.length }, CancellationToken.None);
|
||||
result.push(...galleryResult.firstPage);
|
||||
}
|
||||
const result: IExtension[] = await getExtensions(this.childrenExtensionIds, this.extensionsWorkbenchService);
|
||||
return result.map(extension => new ExtensionData(extension, this, this.getChildrenExtensionIds, this.extensionsWorkbenchService));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getExtensions(extensions: string[], extensionsWorkbenchService: IExtensionsWorkbenchService): Promise<IExtension[]> {
|
||||
const localById = extensionsWorkbenchService.local.reduce((result, e) => { result.set(e.identifier.id.toLowerCase(), e); return result; }, new Map<string, IExtension>());
|
||||
const result: IExtension[] = [];
|
||||
const toQuery: string[] = [];
|
||||
for (const extensionId of extensions) {
|
||||
const id = extensionId.toLowerCase();
|
||||
const local = localById.get(id);
|
||||
if (local) {
|
||||
result.push(local);
|
||||
} else {
|
||||
toQuery.push(id);
|
||||
}
|
||||
}
|
||||
if (toQuery.length) {
|
||||
const galleryResult = await extensionsWorkbenchService.queryGallery({ names: toQuery, pageSize: toQuery.length }, CancellationToken.None);
|
||||
result.push(...galleryResult.firstPage);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) => {
|
||||
const focusBackground = theme.getColor(listFocusBackground);
|
||||
if (focusBackground) {
|
||||
collector.addRule(`.extensions-grid-view .extension-container:focus { background-color: ${focusBackground}; outline: none; }`);
|
||||
}
|
||||
const focusForeground = theme.getColor(listFocusForeground);
|
||||
if (focusForeground) {
|
||||
collector.addRule(`.extensions-grid-view .extension-container:focus { color: ${focusForeground}; }`);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user