Skip to content

Commit

Permalink
#48430 Use extensionPack property in manifest
Browse files Browse the repository at this point in the history
  • Loading branch information
sandy081 committed Jul 11, 2018
1 parent 3164a57 commit 25539a0
Show file tree
Hide file tree
Showing 9 changed files with 421 additions and 243 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ export interface IExtensionManifest {
categories?: string[];
activationEvents?: string[];
extensionDependencies?: string[];
extensionPack?: string[];
contributes?: IExtensionContributions;
repository?: {
url: string;
Expand All @@ -135,6 +136,7 @@ export interface IExtensionManifest {

export interface IGalleryExtensionProperties {
dependencies?: string[];
extensionPack?: string[];
engine?: string;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ const AssetType = {

const PropertyType = {
Dependency: 'Microsoft.VisualStudio.Code.ExtensionDependencies',
ExtensionPack: 'Microsoft.VisualStudio.Code.ExtensionPack',
Engine: 'Microsoft.VisualStudio.Code.Engine'
};

Expand Down Expand Up @@ -262,8 +263,8 @@ function getVersionAsset(version: IRawGalleryExtensionVersion, type: string): IG
};
}

function getDependencies(version: IRawGalleryExtensionVersion): string[] {
const values = version.properties ? version.properties.filter(p => p.key === PropertyType.Dependency) : [];
function getExtensions(version: IRawGalleryExtensionVersion, property: string): string[] {
const values = version.properties ? version.properties.filter(p => p.key === property) : [];
const value = values.length > 0 && values[0].value;
return value ? value.split(',').map(v => adoptToGalleryExtensionId(v)) : [];
}
Expand Down Expand Up @@ -308,7 +309,8 @@ function toExtension(galleryExtension: IRawGalleryExtension, extensionsGalleryUr
ratingCount: getStatistic(galleryExtension.statistics, 'ratingcount'),
assets,
properties: {
dependencies: getDependencies(version),
dependencies: getExtensions(version, PropertyType.Dependency),
extensionPack: getExtensions(version, PropertyType.ExtensionPack),
engine: getEngine(version)
},
/* __GDPR__FRAGMENT__
Expand Down Expand Up @@ -568,7 +570,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
return this.getLastValidExtensionVersion(rawExtension, rawExtension.versions)
.then(rawVersion => {
if (rawVersion) {
extension.properties.dependencies = getDependencies(rawVersion);
extension.properties.dependencies = getExtensions(rawVersion, PropertyType.Dependency);
extension.properties.engine = getEngine(rawVersion);
extension.assets.download = getVersionAsset(rawVersion, AssetType.VSIX);
extension.version = rawVersion.version;
Expand Down
325 changes: 165 additions & 160 deletions src/vs/platform/extensionManagement/node/extensionManagementService.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -10,47 +10,52 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { TPromise, Promise } from 'vs/base/common/winjs.base';
import { IDataSource, ITree, IRenderer } from 'vs/base/parts/tree/browser/tree';
import { Action } from 'vs/base/common/actions';
import { IExtensionDependencies, IExtensionsWorkbenchService } from 'vs/workbench/parts/extensions/common/extensions';
import { IExtensionsWorkbenchService, IExtension } from 'vs/workbench/parts/extensions/common/extensions';
import { once } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
import { WorkbenchTreeController } from 'vs/platform/list/browser/listService';
import { WorkbenchTreeController, WorkbenchTree, IListService } 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';

export interface IExtensionTemplateData {
icon: HTMLImageElement;
name: HTMLElement;
identifier: HTMLElement;
author: HTMLElement;
extensionDisposables: IDisposable[];
extensionDependencies: IExtensionDependencies;
extensionData: IExtensionData;
}

export interface IUnknownExtensionTemplateData {
identifier: HTMLElement;
}

export interface IExtensionData {
extension: IExtension;
hasChildren: boolean;
getChildren: () => Promise<IExtensionData[]>;
parent: IExtensionData;
}

export class DataSource implements IDataSource {

public getId(tree: ITree, element: IExtensionDependencies): string {
let id = element.identifier;
this.getParent(tree, element).then(parent => {
id = parent ? this.getId(tree, parent) + '/' + id : id;
});
return id;
public getId(tree: ITree, { extension, parent }: IExtensionData): string {
return parent ? this.getId(tree, parent) + '/' + extension.id : extension.id;
}

public hasChildren(tree: ITree, element: IExtensionDependencies): boolean {
return element.hasDependencies;
public hasChildren(tree: ITree, { hasChildren }: IExtensionData): boolean {
return hasChildren;
}

public getChildren(tree: ITree, element: IExtensionDependencies): Promise {
return TPromise.as(element.dependencies);
public getChildren(tree: ITree, extensionData: IExtensionData): Promise {
return extensionData.getChildren();
}

public getParent(tree: ITree, element: IExtensionDependencies): Promise {
return TPromise.as(element.dependent);
public getParent(tree: ITree, { parent }: IExtensionData): Promise {
return TPromise.as(parent);
}
}

Expand All @@ -62,12 +67,12 @@ export class Renderer implements IRenderer {
constructor(@IInstantiationService private instantiationService: IInstantiationService) {
}

public getHeight(tree: ITree, element: IExtensionDependencies): number {
public getHeight(tree: ITree, element: IExtensionData): number {
return 62;
}

public getTemplateId(tree: ITree, element: IExtensionDependencies): string {
return element.extension ? Renderer.EXTENSION_TEMPLATE_ID : Renderer.UNKNOWN_EXTENSION_TEMPLATE_ID;
public getTemplateId(tree: ITree, { extension }: IExtensionData): string {
return extension ? Renderer.EXTENSION_TEMPLATE_ID : Renderer.UNKNOWN_EXTENSION_TEMPLATE_ID;
}

public renderTemplate(tree: ITree, templateId: string, container: HTMLElement): any {
Expand All @@ -78,7 +83,7 @@ export class Renderer implements IRenderer {
}

private renderExtensionTemplate(tree: ITree, container: HTMLElement): IExtensionTemplateData {
dom.addClass(container, 'dependency');
dom.addClass(container, 'extension');

const icon = dom.append(container, dom.$<HTMLImageElement>('img.icon'));
const details = dom.append(container, dom.$('.details'));
Expand All @@ -87,8 +92,8 @@ export class Renderer implements IRenderer {
const name = dom.append(header, dom.$('span.name'));
const openExtensionAction = this.instantiationService.createInstance(OpenExtensionAction);
const extensionDisposables = [dom.addDisposableListener(name, 'click', (e: MouseEvent) => {
tree.setFocus(openExtensionAction.extensionDependencies);
tree.setSelection([openExtensionAction.extensionDependencies]);
tree.setFocus(openExtensionAction.extensionData);
tree.setSelection([openExtensionAction.extensionData]);
openExtensionAction.run(e.ctrlKey || e.metaKey);
e.stopPropagation();
e.preventDefault();
Expand All @@ -103,32 +108,31 @@ export class Renderer implements IRenderer {
identifier,
author,
extensionDisposables,
set extensionDependencies(e: IExtensionDependencies) {
openExtensionAction.extensionDependencies = e;
set extensionData(extensionData: IExtensionData) {
openExtensionAction.extensionData = extensionData;
}
};
}

private renderUnknownExtensionTemplate(tree: ITree, container: HTMLElement): IUnknownExtensionTemplateData {
const messageContainer = dom.append(container, dom.$('div.unknown-dependency'));
const messageContainer = dom.append(container, dom.$('div.unknown-extension'));
dom.append(messageContainer, dom.$('span.error-marker')).textContent = localize('error', "Error");
dom.append(messageContainer, dom.$('span.message')).textContent = localize('Unknown Dependency', "Unknown Dependency:");
dom.append(messageContainer, dom.$('span.message')).textContent = localize('Unknown Extension', "Unknown Extension:");

const identifier = dom.append(messageContainer, dom.$('span.message'));
return { identifier };
}

public renderElement(tree: ITree, element: IExtensionDependencies, templateId: string, templateData: any): void {
public renderElement(tree: ITree, element: IExtensionData, templateId: string, templateData: any): void {
if (templateId === Renderer.EXTENSION_TEMPLATE_ID) {
this.renderExtension(tree, element, templateData);
return;
}
this.renderUnknownExtension(tree, element, templateData);
}

private renderExtension(tree: ITree, element: IExtensionDependencies, data: IExtensionTemplateData): void {
const extension = element.extension;

private renderExtension(tree: ITree, extensionData: IExtensionData, data: IExtensionTemplateData): void {
const extension = extensionData.extension;
const onError = once(domEvent(data.icon, 'error'));
onError(() => data.icon.src = extension.iconUrlFallback, null, data.extensionDisposables);
data.icon.src = extension.iconUrl;
Expand All @@ -143,11 +147,11 @@ export class Renderer implements IRenderer {
data.name.textContent = extension.displayName;
data.identifier.textContent = extension.id;
data.author.textContent = extension.publisherDisplayName;
data.extensionDependencies = element;
data.extensionData = extensionData;
}

private renderUnknownExtension(tree: ITree, element: IExtensionDependencies, data: IUnknownExtensionTemplateData): void {
data.identifier.textContent = element.identifier;
private renderUnknownExtension(tree: ITree, { extension }: IExtensionData, data: IUnknownExtensionTemplateData): void {
data.identifier.textContent = extension.id;
}

public disposeTemplate(tree: ITree, templateId: string, templateData: any): void {
Expand All @@ -169,10 +173,10 @@ export class Controller extends WorkbenchTreeController {
this.downKeyBindingDispatcher.set(KeyMod.CtrlCmd | KeyCode.Enter, (tree: ITree, event: any) => this.openExtension(tree, true));
}

protected onLeftClick(tree: ITree, element: IExtensionDependencies, event: IMouseEvent): boolean {
protected onLeftClick(tree: ITree, element: IExtensionData, event: IMouseEvent): boolean {
let currentFocused = tree.getFocus();
if (super.onLeftClick(tree, element, event)) {
if (element.dependent === null) {
if (element.parent === null) {
if (currentFocused) {
tree.setFocus(currentFocused);
} else {
Expand All @@ -185,7 +189,7 @@ export class Controller extends WorkbenchTreeController {
}

public openExtension(tree: ITree, sideByside: boolean): boolean {
const element: IExtensionDependencies = tree.getFocus();
const element: IExtensionData = tree.getFocus();
if (element.extension) {
this.extensionsWorkdbenchService.open(element.extension, sideByside);
return true;
Expand All @@ -196,21 +200,58 @@ export class Controller extends WorkbenchTreeController {

class OpenExtensionAction extends Action {

private _extensionDependencies: IExtensionDependencies;
private _extension: IExtensionData;

constructor(@IExtensionsWorkbenchService private extensionsWorkdbenchService: IExtensionsWorkbenchService) {
super('extensions.action.openDependency', '');
super('extensions.action.openExtension', '');
}

public set extensionDependencies(extensionDependencies: IExtensionDependencies) {
this._extensionDependencies = extensionDependencies;
public set extensionData(extension: IExtensionData) {
this._extension = extension;
}

public get extensionDependencies(): IExtensionDependencies {
return this._extensionDependencies;
public get extensionData(): IExtensionData {
return this._extension;
}

run(sideByside: boolean): TPromise<any> {
return this.extensionsWorkdbenchService.open(this._extensionDependencies.extension, sideByside);
return this.extensionsWorkdbenchService.open(this.extensionData.extension, sideByside);
}
}

export class ExtensionsTree extends WorkbenchTree {

constructor(
input: IExtensionData,
container: HTMLElement,
@IContextKeyService contextKeyService: IContextKeyService,
@IListService listService: IListService,
@IThemeService themeService: IThemeService,
@IInstantiationService instantiationService: IInstantiationService,
@IConfigurationService configurationService: IConfigurationService
) {
const renderer = instantiationService.createInstance(Renderer);
const controller = instantiationService.createInstance(Controller);

super(
container,
{
dataSource: new DataSource(),
renderer,
controller
}, {
indentPixels: 40,
twistiePixels: 20
},
contextKeyService, listService, themeService, instantiationService, configurationService
);

this.setInput(input);

this.disposables.push(this.onDidChangeSelection(event => {
if (event && event.payload && event.payload.origin === 'keyboard') {
controller.openExtension(this, false);
}
}));
}
}
1 change: 1 addition & 0 deletions src/vs/workbench/parts/extensions/common/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export interface IExtension {
outdated: boolean;
enablementState: EnablementState;
dependencies: string[];
extensionPack: string[];
telemetryData: any;
preview: boolean;
getManifest(): TPromise<IExtensionManifest>;
Expand Down

0 comments on commit 25539a0

Please sign in to comment.