提交 144d6066 编写于 作者: S Sandeep Somavarapu

#89962 Enhance extension pack representation

- add count badge in extension viewlet
- show extensions in details page
上级 02e0c603
......@@ -40,7 +40,7 @@ import { Color } from 'vs/base/common/color';
import { assign } from 'vs/base/common/objects';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { CancellationToken } from 'vs/base/common/cancellation';
import { ExtensionsTree, ExtensionData } from 'vs/workbench/contrib/extensions/browser/extensionsViewer';
import { ExtensionsTree, ExtensionData, ExtensionsGridView, getExtensions } from 'vs/workbench/contrib/extensions/browser/extensionsViewer';
import { ShowCurrentReleaseNotesActionId } from 'vs/workbench/contrib/update/common/update';
import { KeybindingParser } from 'vs/base/common/keybindingParser';
import { IStorageService } from 'vs/platform/storage/common/storage';
......@@ -131,7 +131,6 @@ const NavbarSection = {
Contributions: 'contributions',
Changelog: 'changelog',
Dependencies: 'dependencies',
ExtensionPack: 'extensionPack'
};
interface ILayoutParticipant {
......@@ -435,9 +434,6 @@ export class ExtensionEditor extends BaseEditor {
if (manifest) {
combinedInstallAction.manifest = manifest;
}
if (extension.extensionPack.length) {
template.navbar.push(NavbarSection.ExtensionPack, localize('extensionPack', "Extension Pack"), localize('extensionsPack', "Set of extensions that can be installed together"));
}
if (manifest && manifest.contributes) {
template.navbar.push(NavbarSection.Contributions, localize('contributions', "Feature Contributions"), localize('contributionstooltip', "Lists contributions to VS Code by this extension"));
}
......@@ -575,7 +571,6 @@ export class ExtensionEditor extends BaseEditor {
case NavbarSection.Contributions: return this.openContributions(template);
case NavbarSection.Changelog: return this.openChangelog(template);
case NavbarSection.Dependencies: return this.openDependencies(extension, template);
case NavbarSection.ExtensionPack: return this.openExtensionPack(extension, template);
}
return Promise.resolve(null);
}
......@@ -830,10 +825,37 @@ export class ExtensionEditor extends BaseEditor {
</html>`;
}
private openReadme(template: IExtensionEditorTemplate): Promise<IActiveElement> {
private async openReadme(template: IExtensionEditorTemplate): Promise<IActiveElement> {
const manifest = await this.extensionManifest!.get().promise;
if (manifest && manifest.extensionPack && manifest.extensionPack.length) {
return this.openExtensionPackReadme(manifest, template);
}
return this.openMarkdown(this.extensionReadme!.get(), localize('noReadme', "No README available."), template);
}
private async openExtensionPackReadme(manifest: IExtensionManifest, template: IExtensionEditorTemplate): Promise<IActiveElement> {
const extensionPackReadme = append(template.content, $('div', { class: 'extension-pack-readme' }));
extensionPackReadme.style.margin = '0 auto';
extensionPackReadme.style.maxWidth = '882px';
const extensionPack = append(extensionPackReadme, $('div', { class: 'extension-pack' }));
toggleClass(extensionPackReadme, 'narrow', manifest.extensionPack!.length <= 2);
const extensionPackHeader = append(extensionPack, $('div.header'));
extensionPackHeader.textContent = localize('extension pack', "Extension Pack ({0})", manifest.extensionPack!.length);
const extensionPackContent = append(extensionPack, $('div', { class: 'extension-pack-content' }));
extensionPackContent.setAttribute('tabindex', '0');
append(extensionPack, $('div.footer'));
const readmeContent = append(extensionPackReadme, $('div.readme-content'));
await Promise.all([
this.renderExtensionPack(manifest, extensionPackContent),
this.openMarkdown(this.extensionReadme!.get(), localize('noReadme', "No README available."), { ...template, ...{ content: readmeContent } }),
]);
return { focus: () => extensionPackContent.focus() };
}
private openChangelog(template: IExtensionEditorTemplate): Promise<IActiveElement> {
return this.openMarkdown(this.extensionChangelog!.get(), localize('noChangelog', "No Changelog available."), template);
}
......@@ -915,28 +937,19 @@ export class ExtensionEditor extends BaseEditor {
return Promise.resolve({ focus() { dependenciesTree.domFocus(); } });
}
private openExtensionPack(extension: IExtension, template: IExtensionEditorTemplate): Promise<IActiveElement> {
private async renderExtensionPack(manifest: IExtensionManifest, parent: HTMLElement): Promise<void> {
const content = $('div', { class: 'subcontent' });
const scrollableContent = new DomScrollableElement(content, {});
append(template.content, scrollableContent.getDomNode());
this.contentDisposables.add(scrollableContent);
const scrollableContent = new DomScrollableElement(content, { useShadows: false });
append(parent, scrollableContent.getDomNode());
const extensionsPackTree = this.instantiationService.createInstance(ExtensionsTree,
new ExtensionData(extension, null, extension => extension.extensionPack || [], this.extensionsWorkbenchService), content,
{
listBackground: editorBackground
});
const layout = () => {
scrollableContent.scanDomNode();
const scrollDimensions = scrollableContent.getScrollDimensions();
extensionsPackTree.layout(scrollDimensions.height);
};
const removeLayoutParticipant = arrays.insert(this.layoutParticipants, { layout });
this.contentDisposables.add(toDisposable(removeLayoutParticipant));
this.contentDisposables.add(extensionsPackTree);
const extensionsGridView = this.instantiationService.createInstance(ExtensionsGridView, content);
const extensions: IExtension[] = await getExtensions(manifest.extensionPack!, this.extensionsWorkbenchService);
extensionsGridView.setExtensions(extensions);
scrollableContent.scanDomNode();
return Promise.resolve({ focus() { extensionsPackTree.domFocus(); } });
this.contentDisposables.add(scrollableContent);
this.contentDisposables.add(extensionsGridView);
this.contentDisposables.add(toDisposable(arrays.insert(this.layoutParticipants, { layout: () => scrollableContent.scanDomNode() })));
}
private renderSettings(container: HTMLElement, manifest: IExtensionManifest, onDetailsToggle: Function): boolean {
......
......@@ -3187,49 +3187,49 @@ export const extensionButtonProminentHoverBackground = registerColor('extensionB
registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) => {
const foregroundColor = theme.getColor(foreground);
if (foregroundColor) {
collector.addRule(`.extension .monaco-action-bar .action-item .action-label.extension-action.built-in-status { border-color: ${foregroundColor}; }`);
collector.addRule(`.extension-list-item .monaco-action-bar .action-item .action-label.extension-action.built-in-status { border-color: ${foregroundColor}; }`);
collector.addRule(`.extension-editor .monaco-action-bar .action-item .action-label.extension-action.built-in-status { border-color: ${foregroundColor}; }`);
}
const buttonBackgroundColor = theme.getColor(buttonBackground);
if (buttonBackgroundColor) {
collector.addRule(`.extension .monaco-action-bar .action-item .action-label.extension-action { background-color: ${buttonBackgroundColor}; }`);
collector.addRule(`.extension-list-item .monaco-action-bar .action-item .action-label.extension-action { background-color: ${buttonBackgroundColor}; }`);
collector.addRule(`.extension-editor .monaco-action-bar .action-item .action-label.extension-action { background-color: ${buttonBackgroundColor}; }`);
}
const buttonForegroundColor = theme.getColor(buttonForeground);
if (buttonForegroundColor) {
collector.addRule(`.extension .monaco-action-bar .action-item .action-label.extension-action { color: ${buttonForegroundColor}; }`);
collector.addRule(`.extension-list-item .monaco-action-bar .action-item .action-label.extension-action { color: ${buttonForegroundColor}; }`);
collector.addRule(`.extension-editor .monaco-action-bar .action-item .action-label.extension-action { color: ${buttonForegroundColor}; }`);
}
const buttonHoverBackgroundColor = theme.getColor(buttonHoverBackground);
if (buttonHoverBackgroundColor) {
collector.addRule(`.extension .monaco-action-bar .action-item:hover .action-label.extension-action { background-color: ${buttonHoverBackgroundColor}; }`);
collector.addRule(`.extension-list-item .monaco-action-bar .action-item:hover .action-label.extension-action { background-color: ${buttonHoverBackgroundColor}; }`);
collector.addRule(`.extension-editor .monaco-action-bar .action-item:hover .action-label.extension-action { background-color: ${buttonHoverBackgroundColor}; }`);
}
const contrastBorderColor = theme.getColor(contrastBorder);
if (contrastBorderColor) {
collector.addRule(`.extension .monaco-action-bar .action-item .action-label.extension-action { border: 1px solid ${contrastBorderColor}; }`);
collector.addRule(`.extension-list-item .monaco-action-bar .action-item .action-label.extension-action { border: 1px solid ${contrastBorderColor}; }`);
collector.addRule(`.extension-editor .monaco-action-bar .action-item .action-label.extension-action { border: 1px solid ${contrastBorderColor}; }`);
}
const extensionButtonProminentBackgroundColor = theme.getColor(extensionButtonProminentBackground);
if (extensionButtonProminentBackground) {
collector.addRule(`.extension .monaco-action-bar .action-item .action-label.extension-action.prominent { background-color: ${extensionButtonProminentBackgroundColor}; }`);
collector.addRule(`.extension-list-item .monaco-action-bar .action-item .action-label.extension-action.prominent { background-color: ${extensionButtonProminentBackgroundColor}; }`);
collector.addRule(`.extension-editor .monaco-action-bar .action-item .action-label.extension-action.prominent { background-color: ${extensionButtonProminentBackgroundColor}; }`);
}
const extensionButtonProminentForegroundColor = theme.getColor(extensionButtonProminentForeground);
if (extensionButtonProminentForeground) {
collector.addRule(`.extension .monaco-action-bar .action-item .action-label.extension-action.prominent { color: ${extensionButtonProminentForegroundColor}; }`);
collector.addRule(`.extension-list-item .monaco-action-bar .action-item .action-label.extension-action.prominent { color: ${extensionButtonProminentForegroundColor}; }`);
collector.addRule(`.extension-editor .monaco-action-bar .action-item .action-label.extension-action.prominent { color: ${extensionButtonProminentForegroundColor}; }`);
}
const extensionButtonProminentHoverBackgroundColor = theme.getColor(extensionButtonProminentHoverBackground);
if (extensionButtonProminentHoverBackground) {
collector.addRule(`.extension .monaco-action-bar .action-item:hover .action-label.extension-action.prominent { background-color: ${extensionButtonProminentHoverBackgroundColor}; }`);
collector.addRule(`.extension-list-item .monaco-action-bar .action-item:hover .action-label.extension-action.prominent { background-color: ${extensionButtonProminentHoverBackgroundColor}; }`);
collector.addRule(`.extension-editor .monaco-action-bar .action-item:hover .action-label.extension-action.prominent { background-color: ${extensionButtonProminentHoverBackgroundColor}; }`);
}
});
......@@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/extension';
import { localize } from 'vs/nls';
import { append, $, addClass, removeClass, toggleClass } from 'vs/base/browser/dom';
import { IDisposable, dispose, combinedDisposable } from 'vs/base/common/lifecycle';
......@@ -16,7 +17,7 @@ import { domEvent } from 'vs/base/browser/event';
import { IExtension, ExtensionContainers, ExtensionState, IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions';
import { InstallAction, UpdateAction, ManageExtensionAction, ReloadAction, MaliciousStatusLabelAction, ExtensionActionViewItem, StatusLabelAction, RemoteInstallAction, SystemDisabledWarningAction, ExtensionToolTipAction, LocalInstallAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { Label, RatingsWidget, InstallCountWidget, RecommendationWidget, RemoteBadgeWidget, TooltipWidget } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets';
import { Label, RatingsWidget, InstallCountWidget, RecommendationWidget, RemoteBadgeWidget, TooltipWidget, ExtensionPackCountWidget as ExtensionPackBadgeWidget } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { INotificationService } from 'vs/platform/notification/common/notification';
......@@ -68,10 +69,11 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
renderTemplate(root: HTMLElement): ITemplateData {
const recommendationWidget = this.instantiationService.createInstance(RecommendationWidget, root);
const element = append(root, $('.extension'));
const element = append(root, $('.extension-list-item'));
const iconContainer = append(element, $('.icon-container'));
const icon = append(iconContainer, $<HTMLImageElement>('img.icon'));
const iconRemoteBadgeWidget = this.instantiationService.createInstance(RemoteBadgeWidget, iconContainer, false);
const extensionPackBadgeWidget = this.instantiationService.createInstance(ExtensionPackBadgeWidget, iconContainer);
const details = append(element, $('.details'));
const headerContainer = append(details, $('.header-container'));
const header = append(headerContainer, $('.header'));
......@@ -115,6 +117,7 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
const widgets = [
recommendationWidget,
iconRemoteBadgeWidget,
extensionPackBadgeWidget,
headerRemoteBadgeWidget,
tooltipWidget,
this.instantiationService.createInstance(Label, version, (e: IExtension) => e.version),
......
......@@ -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,52 @@ 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';
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;
this.disposableStore.add(dom.addDisposableListener(template.name, 'click', (e: MouseEvent) => {
openExtensionAction.run(e.ctrlKey || e.metaKey);
e.stopPropagation();
e.preventDefault();
}));
this.renderer.renderElement(extension, index, template);
}
}
export interface IExtensionTemplateData {
icon: HTMLImageElement;
......@@ -101,7 +147,7 @@ export class ExtensionRenderer implements IListRenderer<ITreeNode<IExtensionData
author,
extensionDisposables,
set extensionData(extensionData: IExtensionData) {
openExtensionAction.extensionData = extensionData;
openExtensionAction.extension = extensionData.extension;
}
};
}
......@@ -157,19 +203,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 +292,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}; }`);
}
});
......@@ -6,7 +6,7 @@
import 'vs/css!./media/extensionsWidgets';
import { Disposable, toDisposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle';
import { IExtension, IExtensionsWorkbenchService, IExtensionContainer } from 'vs/workbench/contrib/extensions/common/extensions';
import { append, $, addClass } from 'vs/base/browser/dom';
import { append, $, addClass, removeNode } from 'vs/base/browser/dom';
import * as platform from 'vs/base/common/platform';
import { localize } from 'vs/nls';
import { IExtensionTipsService, IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
......@@ -16,6 +16,7 @@ import { IThemeService, IColorTheme } from 'vs/platform/theme/common/themeServic
import { EXTENSION_BADGE_REMOTE_BACKGROUND, EXTENSION_BADGE_REMOTE_FOREGROUND } from 'vs/workbench/common/theme';
import { Emitter, Event } from 'vs/base/common/event';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge';
export abstract class ExtensionWidget extends Disposable implements IExtensionContainer {
private _extension: IExtension | null = null;
......@@ -222,7 +223,7 @@ export class RecommendationWidget extends ExtensionWidget {
}
const extRecommendations = this.extensionTipsService.getAllRecommendationsWithReason();
if (extRecommendations[this.extension.identifier.id.toLowerCase()]) {
this.element = append(this.parent, $('div.bookmark'));
this.element = append(this.parent, $('div.extension-bookmark'));
const recommendation = append(this.element, $('.recommendation'));
append(recommendation, $('span.codicon.codicon-star'));
const applyBookmarkStyle = (theme: IColorTheme) => {
......@@ -285,7 +286,7 @@ class RemoteBadge extends Disposable {
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService
) {
super();
this.element = $('div.extension-remote-badge');
this.element = $('div.extension-badge.extension-remote-badge');
this.render();
}
......@@ -315,3 +316,32 @@ class RemoteBadge extends Disposable {
}
}
}
export class ExtensionPackCountWidget extends ExtensionWidget {
private element: HTMLElement | undefined;
constructor(
private readonly parent: HTMLElement,
) {
super();
this.render();
this._register(toDisposable(() => this.clear()));
}
private clear(): void {
if (this.element) {
removeNode(this.element);
}
}
render(): void {
this.clear();
if (!this.extension || !this.extension.extensionPack.length) {
return;
}
this.element = append(this.parent, $('.extension-badge.extension-pack-badge'));
const countBadge = new CountBadge(this.element);
countBadge.setCount(this.extension.extensionPack.length);
}
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.extension-list-item {
box-sizing: border-box;
width: 100%;
height: 100%;
padding: 0 0 0 16px;
overflow: hidden;
display: flex;
}
.extension-list-item > .icon-container {
position: relative;
}
.extension-list-item > .icon-container > .icon {
width: 42px;
height: 42px;
padding: 10px 14px 10px 0;
flex-shrink: 0;
object-fit: contain;
}
.extension-list-item > .icon-container .extension-badge {
position: absolute;
bottom: 5px;
width: 22px;
height: 22px;
line-height: 22px;
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
}
.extension-list-item > .icon-container .extension-badge.extension-remote-badge {
right: 5px;
}
.extension-list-item > .icon-container .extension-remote-badge .codicon {
color: currentColor;
}
.extension-list-item > .details {
flex: 1;
padding: 4px 0;
overflow: hidden;
}
.extension-list-item > .details > .header-container {
height: 19px;
display: flex;
overflow: hidden;
padding-right: 11px;
}
.extension-list-item > .details > .header-container > .header {
display: flex;
align-items: baseline;
flex-wrap: nowrap;
overflow: hidden;
flex: 1;
min-width: 0;
}
.extension-list-item > .details > .header-container > .header > .name {
font-weight: bold;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.extension-list-item > .details > .header-container > .header > .version {
opacity: 0.85;
font-size: 80%;
padding-left: 6px;
min-width: fit-content;
min-width: -moz-fit-content;
}
.extension-list-item > .details > .header-container > .header > .version {
flex: 1;
}
.extension-list-item > .details > .header-container > .header > .install-count,
.extension-list-item > .details > .header-container > .header > .ratings {
display: flex;
align-items: center;
}
.extension-list-item > .details > .header-container > .header > .install-count:not(:empty) {
font-size: 80%;
margin: 0 6px;
}
.extension-list-item > .details > .header-container > .header .codicon {
font-size: 120%;
margin-right: 2px;
-webkit-mask: inherit;
}
.extension-list-item > .details > .header-container > .header > .ratings {
text-align: right;
}
.extension-list-item > .details > .header-container > .header > .extension-remote-badge-container {
margin-left: 6px;
display: none;
}
.extension-list-item > .details > .header-container > .header .extension-remote-badge .codicon {
margin-right: 0;
}
.extension-list-item > .details > .header-container > .header .extension-remote-badge {
width: 14px;
height: 14px;
line-height: 14px;
border-radius: 20px;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.extension-list-item > .details > .header-container > .header .extension-remote-badge > .codicon {
font-size: 12px;
color: currentColor;
}
.extension-list-item > .details > .description {
padding-right: 11px;
}
.extension-list-item > .details > .footer {
display: flex;
justify-content: flex-end;
padding-right: 7px;
height: 24px;
overflow: hidden;
}
.extension-list-item > .details > .footer > .author {
flex: 1;
font-size: 90%;
opacity: 0.9;
font-weight: 600;
}
.extension-list-item > .details > .footer > .sync-ignored {
font-size: 11px;
}
.extension-list-item > .details > .footer > .sync-ignored > .codicon {
font-size: 14px;
vertical-align: text-top;
}
.extension-list-item > .details > .footer > .monaco-action-bar > .actions-container {
flex-wrap: wrap-reverse;
}
.extension-list-item > .details > .footer > .monaco-action-bar > .actions-container .extension-action {
max-width: 150px;
}
.extension-list-item > .details > .footer > .monaco-action-bar .action-label {
margin-top: 0.3em;
margin-left: 0.3em;
line-height: 14px;
}
.extension-list-item > .details > .footer > .monaco-action-bar .action-label:not(:empty) {
opacity: 0.9;
}
.extension-list-item > .details >.footer > .monaco-action-bar .action-item .action-label.system-disable.codicon-info,
.extension-list-item > .details >.footer > .monaco-action-bar .action-item .action-label.system-disable.codicon-warning {
margin-top: 0.25em;
margin-left: 0.1em;
}
.extension-list-item > .details > .footer > .monaco-action-bar .action-item .action-label.extension-action.manage.hide {
display: none;
}
.extension-list-item > .details > .footer > .monaco-action-bar .action-item .action-label.extension-action.manage {
height: 18px;
width: 10px;
border: none;
color: inherit;
background: none;
outline-offset: 0px;
margin-top: 0.25em;
}
.extension-list-item .ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
......@@ -55,55 +55,3 @@
background-color: transparent;
font-style: italic;
}
.extension-editor > .header > .details > .actions > .monaco-action-bar > .actions-container > .action-item > .action-label.disable-status {
margin-left: 0;
margin-top: 6px;
padding-left: 0;
}
.extension-editor > .header > .details > .actions > .monaco-action-bar > .actions-container > .action-item > .action-label.system-disable {
margin-right: 0.15em;
}
.extensions-viewlet>.extensions .extension>.details>.footer>.monaco-action-bar .action-item .action-label.system-disable.codicon-info,
.extensions-viewlet>.extensions .extension>.details>.footer>.monaco-action-bar .action-item .action-label.system-disable.codicon-warning {
margin-top: 0.25em;
margin-left: 0.1em;
}
.monaco-action-bar .action-item .action-label.system-disable.codicon {
opacity: 1;
height: 18px;
width: 10px;
}
.extension-editor>.header>.details>.actions>.monaco-action-bar .action-item .action-label.extension-status-label,
.extension-editor>.header>.details>.actions>.monaco-action-bar .action-item .action-label.disable-status,
.extension-editor>.header>.details>.actions>.monaco-action-bar .action-item .action-label.malicious-status {
font-weight: normal;
}
.extension-editor>.header>.details>.actions>.monaco-action-bar .action-item .action-label.extension-status-label:hover,
.extension-editor>.header>.details>.actions>.monaco-action-bar .action-item .action-label.disable-status:hover,
.extension-editor>.header>.details>.actions>.monaco-action-bar .action-item .action-label.malicious-status:hover {
opacity: 0.9;
}
.extensions-viewlet>.extensions .extension>.details>.footer>.monaco-action-bar .action-item .action-label.extension-action.manage.hide {
display: none;
}
.extensions-viewlet>.extensions .extension>.details>.footer>.monaco-action-bar .action-item .action-label.extension-action.manage {
height: 18px;
width: 10px;
border: none;
color: inherit;
background: none;
outline-offset: 0px;
margin-top: 0.25em;
}
.extension-editor > .header.recommended > .details > .recommendation > .monaco-action-bar .actions-container {
justify-content: flex-start;
}
......@@ -183,6 +183,7 @@
margin-top: 5px;
margin-right: 4px;
}
.extension-editor > .header > .details > .subtext-container > .monaco-action-bar .action-label {
margin-top: 4px;
margin-left: 4px;
......@@ -190,6 +191,38 @@
padding-bottom: 2px;
}
.extension-editor > .header > .details > .actions > .monaco-action-bar > .actions-container > .action-item > .action-label.disable-status {
margin-left: 0;
margin-top: 6px;
padding-left: 0;
}
.extension-editor > .header > .details > .actions > .monaco-action-bar > .actions-container > .action-item > .action-label.system-disable {
margin-right: 0.15em;
}
.monaco-action-bar .action-item .action-label.system-disable.codicon {
opacity: 1;
height: 18px;
width: 10px;
}
.extension-editor>.header>.details>.actions>.monaco-action-bar .action-item .action-label.extension-status-label,
.extension-editor>.header>.details>.actions>.monaco-action-bar .action-item .action-label.disable-status,
.extension-editor>.header>.details>.actions>.monaco-action-bar .action-item .action-label.malicious-status {
font-weight: normal;
}
.extension-editor>.header>.details>.actions>.monaco-action-bar .action-item .action-label.extension-status-label:hover,
.extension-editor>.header>.details>.actions>.monaco-action-bar .action-item .action-label.disable-status:hover,
.extension-editor>.header>.details>.actions>.monaco-action-bar .action-item .action-label.malicious-status:hover {
opacity: 0.9;
}
.extension-editor > .header.recommended > .details > .recommendation > .monaco-action-bar .actions-container {
justify-content: flex-start;
}
.extension-editor > .body {
flex: 1;
overflow: hidden;
......@@ -247,6 +280,52 @@
margin-left: 20px;
}
.extension-editor > .body > .content > .extension-pack-readme {
height: 100%;
}
.extension-editor > .body > .content > .extension-pack-readme > .extension-pack {
height: 224px;
padding-left: 20px;
}
.extension-editor > .body > .content > .extension-pack-readme.narrow > .extension-pack {
height: 142px;
}
.extension-editor > .body > .content > .extension-pack-readme > .readme-content {
height: calc(100% - 224px);
}
.extension-editor > .body > .content > .extension-pack-readme.narrow > .readme-content {
height: calc(100% - 142px);
}
.extension-editor > .body > .content > .extension-pack-readme > .extension-pack > .header,
.extension-editor > .body > .content > .extension-pack-readme > .extension-pack > .footer {
margin-bottom: 10px;
margin-right: 30px;
font-weight: bold;
font-size: 120%;
border-bottom: 1px solid rgba(128, 128, 128, 0.22);
padding: 4px 6px;
line-height: 22px;
}
.extension-editor > .body > .content > .extension-pack-readme > .extension-pack > .extension-pack-content {
height: calc(100% - 60px);
}
.extension-editor > .body > .content > .extension-pack-readme > .extension-pack > .extension-pack-content > .monaco-scrollable-element {
height: 100%;
}
.extension-editor > .body > .content .extension-pack-readme > .extension-pack > .extension-pack-content > .monaco-scrollable-element > .subcontent {
height: 100%;
overflow-y: scroll;
box-sizing: border-box;
}
.extension-editor > .body > .content > .monaco-scrollable-element > .subcontent {
height: 100%;
padding: 20px;
......@@ -398,3 +477,25 @@
font-weight: 600;
opacity: 0.6;
}
.extension-editor .extensions-grid-view {
display: flex;
flex-wrap: wrap;
}
.extension-editor .extensions-grid-view > .extension-container {
margin: 0 10px 20px 0;
}
.extension-editor .extensions-grid-view .extension-list-item {
cursor: default;
}
.extension-editor .extensions-grid-view .extension-list-item > .details .header > .name {
cursor: pointer;
}
.extension-editor .extensions-grid-view > .extension-container:focus > .extension-list-item > .details .header > .name,
.extension-editor .extensions-grid-view > .extension-container:focus > .extension-list-item > .details .header > .name:hover {
text-decoration: underline;
}
......@@ -74,241 +74,47 @@
flex-shrink: 0;
}
.extensions-viewlet > .extensions .monaco-list-row > .bookmark {
display: inline-block;
height: 20px;
width: 20px;
}
.extensions-viewlet > .extensions .monaco-list-row > .bookmark > .recommendation {
border-right: 20px solid transparent;
border-top: 20px solid;
box-sizing: border-box;
}
.extensions-viewlet > .extensions .monaco-list-row > .bookmark > .recommendation > .codicon {
.extensions-viewlet > .extensions .extension-list-item {
position: absolute;
top: 1px;
left: 1px;
color: inherit;
font-size: 80%;
}
.extensions-viewlet > .extensions .extension {
box-sizing: border-box;
width: 100%;
height: 100%;
padding: 0 0 0 16px;
overflow: hidden;
display: flex;
position: absolute;
top: 0;
}
.extensions-viewlet > .extensions .extension.loading {
.extensions-viewlet > .extensions .extension-list-item.loading {
background: url('loading.svg') center center no-repeat;
}
.extensions-viewlet > .extensions .monaco-list-row > .extension > .icon-container {
position: relative;
}
.extensions-viewlet > .extensions .extension > .icon-container > .icon {
width: 42px;
height: 42px;
padding: 10px 14px 10px 0;
flex-shrink: 0;
object-fit: contain;
}
.extensions-viewlet > .extensions .monaco-list-row > .extension > .icon-container .extension-remote-badge {
position: absolute;
right: 5px;
bottom: 5px;
width: 22px;
height: 22px;
line-height: 22px;
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
}
.extensions-viewlet > .extensions .monaco-list-row > .extension > .icon-container .extension-remote-badge .codicon {
color: currentColor;
}
.extensions-viewlet > .extensions .monaco-list-row > .extension > .details > .header-container > .header > .extension-remote-badge-container {
margin-left: 6px;
}
.extensions-viewlet > .extensions .monaco-list-row > .extension > .details > .header-container > .header .extension-remote-badge {
width: 14px;
height: 14px;
line-height: 14px;
border-radius: 20px;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.extensions-viewlet > .extensions .monaco-list-row > .extension > .details > .header-container > .header .extension-remote-badge > .codicon {
font-size: 12px;
color: currentColor;
}
.extensions-viewlet.narrow > .extensions .extension > .icon-container,
.extensions-viewlet > .extensions .extension.loading > .icon-container {
.extensions-viewlet.narrow > .extensions .extension-list-item > .icon-container,
.extensions-viewlet > .extensions .extension-list-item.loading > .icon-container {
display: none;
}
.extensions-viewlet > .extensions .extension > .details {
flex: 1;
padding: 4px 0;
overflow: hidden;
}
.extensions-viewlet > .extensions .extension > .details > .header-container {
height: 19px;
display: flex;
overflow: hidden;
padding-right: 11px;
}
.extensions-viewlet > .extensions .extension > .details > .header-container > .header {
display: flex;
align-items: baseline;
flex-wrap: nowrap;
overflow: hidden;
flex: 1;
min-width: 0;
}
.extensions-viewlet > .extensions .extension > .details > .header-container > .header > .name {
font-weight: bold;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.extensions-viewlet > .extensions .extension > .details > .header-container > .header > .version {
opacity: 0.85;
font-size: 80%;
padding-left: 6px;
min-width: fit-content;
min-width: -moz-fit-content;
}
.extensions-viewlet:not(.narrow) > .extensions .extension > .details > .header-container > .header > .version {
flex: 1;
}
.extensions-viewlet > .extensions .extension > .details > .header-container > .header > .install-count,
.extensions-viewlet > .extensions .extension > .details > .header-container > .header > .ratings {
display: flex;
align-items: center;
}
.extensions-viewlet > .extensions .extension > .details > .header-container > .header > .install-count:not(:empty) {
font-size: 80%;
margin: 0 6px;
}
.extensions-viewlet > .extensions .extension > .details > .header-container > .header .codicon {
font-size: 120%;
margin-right: 2px;
-webkit-mask: inherit;
}
.extensions-viewlet>.extensions .extension>.details>.header-container>.header .extension-remote-badge .codicon {
margin-right: 0;
}
.extensions-viewlet > .extensions .extension > .details > .header-container > .header > .ratings {
text-align: right;
}
.extensions-viewlet:not(.narrow) > .extensions .extension > .details > .header-container > .header > .extension-remote-badge-container,
.extensions-viewlet.narrow > .extensions .extension > .details > .header-container > .header > .ratings,
.extensions-viewlet.narrow > .extensions .extension > .details > .header-container > .header > .install-count {
.extensions-viewlet:not(.narrow) > .extensions .extension-list-item > .details > .header-container > .header > .extension-remote-badge-container,
.extensions-viewlet.narrow > .extensions .extension-list-item > .details > .header-container > .header > .ratings,
.extensions-viewlet.narrow > .extensions .extension-list-item > .details > .header-container > .header > .install-count {
display: none;
}
.extensions-viewlet > .extensions .extension > .details > .description {
padding-right: 11px;
}
.extensions-viewlet > .extensions .extension > .details > .footer {
display: flex;
justify-content: flex-end;
padding-right: 7px;
height: 24px;
overflow: hidden;
}
.extensions-viewlet > .extensions .extension > .details > .footer > .author {
flex: 1;
font-size: 90%;
opacity: 0.9;
font-weight: 600;
}
.extensions-viewlet > .extensions .extension > .details > .footer > .sync-ignored {
font-size: 11px;
}
.extensions-viewlet > .extensions .extension > .details > .footer > .sync-ignored > .codicon {
font-size: 14px;
vertical-align: text-top;
}
.extensions-viewlet > .extensions .selected .extension > .details > .footer > .author,
.extensions-viewlet > .extensions .selected.focused .extension > .details > .footer > .author {
.extensions-viewlet > .extensions .selected .extension-list-item > .details > .footer > .author,
.extensions-viewlet > .extensions .selected.focused .extension-list-item > .details > .footer > .author {
opacity: 1;
}
.extensions-viewlet > .extensions .extension > .details > .footer > .monaco-action-bar > .actions-container {
flex-wrap: wrap-reverse;
}
.extensions-viewlet > .extensions .extension > .details > .footer > .monaco-action-bar > .actions-container .extension-action {
max-width: 150px;
}
.extensions-viewlet.narrow > .extensions .extension > .details > .footer > .monaco-action-bar > .actions-container .extension-action {
.extensions-viewlet.narrow > .extensions .extension-list-item > .details > .footer > .monaco-action-bar > .actions-container .extension-action {
max-width: 100px;
}
.extensions-viewlet > .extensions .extension > .details > .footer > .monaco-action-bar .action-label {
margin-top: 0.3em;
margin-left: 0.3em;
line-height: 14px;
}
.extensions-viewlet > .extensions .extension > .details > .footer > .monaco-action-bar .action-label:not(:empty) {
opacity: 0.9;
}
.vs .extensions-viewlet > .extensions .monaco-list-row.disabled > .bookmark,
.vs-dark .extensions-viewlet > .extensions .monaco-list-row.disabled > .bookmark,
.vs .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension > .icon-container > .icon,
.vs-dark .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension > .icon-container > .icon,
.vs .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension > .details > .header-container,
.vs-dark .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension > .details > .header-container,
.vs .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension > .details > .description,
.vs-dark .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension > .details > .description,
.vs .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension > .details > .footer > .author,
.vs-dark .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension > .details > .footer > .author {
.vs .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .icon-container > .icon,
.vs-dark .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .icon-container > .icon,
.vs .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .details > .header-container,
.vs-dark .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .details > .header-container,
.vs .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .details > .description,
.vs-dark .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .details > .description,
.vs .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .details > .footer > .author,
.vs-dark .extensions-viewlet > .extensions .monaco-list-row.disabled > .extension-list-item > .details > .footer > .author {
opacity: 0.5;
}
.extensions-viewlet > .extensions .extension .ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.extensions-badge.progress-badge > .badge-content {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSIxNCIgdmlld0JveD0iMiAyIDE0IDE0IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDIgMiAxNCAxNCI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTkgMTZjLTMuODYgMC03LTMuMTQtNy03czMuMTQtNyA3LTdjMy44NTkgMCA3IDMuMTQxIDcgN3MtMy4xNDEgNy03IDd6bTAtMTIuNmMtMy4wODggMC01LjYgMi41MTMtNS42IDUuNnMyLjUxMiA1LjYgNS42IDUuNiA1LjYtMi41MTIgNS42LTUuNi0yLjUxMi01LjYtNS42LTUuNnptMy44NiA3LjFsLTMuMTYtMS44OTZ2LTMuODA0aC0xLjR2NC41OTZsMy44NCAyLjMwNS43Mi0xLjIwMXoiLz48L3N2Zz4=");
background-position: center center;
......
......@@ -32,3 +32,24 @@
.extension-ratings .codicon-star-empty {
opacity: .4;
}
.extension-bookmark {
display: inline-block;
height: 20px;
width: 20px;
}
.extension-bookmark > .recommendation {
border-right: 20px solid transparent;
border-top: 20px solid;
box-sizing: border-box;
position: relative;
}
.extension-bookmark > .recommendation > .codicon {
position: absolute;
bottom: 9px;
left: 1px;
color: inherit;
font-size: 80%;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册