Adopt custom hover for extension and runtime view (#206154)

adopt custom hover for extension and runtime view
This commit is contained in:
Benjamin Christopher Simmonds
2024-02-24 16:21:20 +01:00
committed by GitHub
parent d63202a538
commit 660264a263
3 changed files with 45 additions and 17 deletions
@@ -5,6 +5,8 @@
import { $, Dimension, addDisposableListener, append, clearNode } from 'vs/base/browser/dom';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { getDefaultHoverDelegate } from 'vs/base/browser/ui/hover/hoverDelegate';
import { setupCustomHover } from 'vs/base/browser/ui/iconLabel/iconLabelHover';
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels';
import { IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
@@ -364,13 +366,15 @@ export abstract class AbstractRuntimeExtensionsEditor extends EditorPane {
} else {
title = nls.localize('extensionActivating', "Extension is activating...");
}
data.activationTime.title = title;
data.elementDisposables.push(setupCustomHover(getDefaultHoverDelegate('mouse'), data.activationTime, title));
clearNode(data.msgContainer);
if (this._getUnresponsiveProfile(element.description.identifier)) {
const el = $('span', undefined, ...renderLabelWithIcons(` $(alert) Unresponsive`));
el.title = nls.localize('unresponsive.title', "Extension has caused the extension host to freeze.");
const extensionHostFreezTitle = nls.localize('unresponsive.title', "Extension has caused the extension host to freeze.");
data.elementDisposables.push(setupCustomHover(getDefaultHoverDelegate('mouse'), el, extensionHostFreezTitle));
data.msgContainer.appendChild(el);
}
@@ -416,7 +420,9 @@ export abstract class AbstractRuntimeExtensionsEditor extends EditorPane {
}
if (accessData?.current) {
const element = $('span', undefined, nls.localize('requests count', "{0} Requests: {1} (Session)", feature.label, accessData.current.count));
element.title = nls.localize('requests count title', "Last request was {0}. Overall Requests: {1}", fromNow(accessData.current.lastAccessed, true, true), accessData.totalCount);
const title = nls.localize('requests count title', "Last request was {0}. Overall Requests: {1}", fromNow(accessData.current.lastAccessed, true, true), accessData.totalCount);
data.elementDisposables.push(setupCustomHover(getDefaultHoverDelegate('mouse'), element, title));
data.msgContainer.appendChild(element);
}
}
@@ -5,6 +5,8 @@
import { $, Dimension, addDisposableListener, append, setParentFlowTo } from 'vs/base/browser/dom';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { getDefaultHoverDelegate } from 'vs/base/browser/ui/hover/hoverDelegate';
import { setupCustomHover } from 'vs/base/browser/ui/iconLabel/iconLabelHover';
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { CheckboxActionViewItem } from 'vs/base/browser/ui/toggle/toggle';
import { Action, IAction } from 'vs/base/common/actions';
@@ -188,7 +190,8 @@ class VersionWidget extends ExtensionWithDifferentGalleryVersionWidget {
private readonly element: HTMLElement;
constructor(container: HTMLElement) {
super();
this.element = append(container, $('code.version', { title: localize('extension version', "Extension Version") }));
this.element = append(container, $('code.version'));
this._register(setupCustomHover(getDefaultHoverDelegate('mouse'), this.element, localize('extension version', "Extension Version")));
this.render();
}
render(): void {
@@ -268,25 +271,30 @@ export class ExtensionEditor extends EditorPane {
const details = append(header, $('.details'));
const title = append(details, $('.title'));
const name = append(title, $('span.name.clickable', { title: localize('name', "Extension name"), role: 'heading', tabIndex: 0 }));
const name = append(title, $('span.name.clickable', { role: 'heading', tabIndex: 0 }));
this._register(setupCustomHover(getDefaultHoverDelegate('mouse'), name, localize('name', "Extension name")));
const versionWidget = new VersionWidget(title);
const preview = append(title, $('span.preview', { title: localize('preview', "Preview") }));
const preview = append(title, $('span.preview'));
this._register(setupCustomHover(getDefaultHoverDelegate('mouse'), preview, localize('preview', "Preview")));
preview.textContent = localize('preview', "Preview");
const builtin = append(title, $('span.builtin'));
builtin.textContent = localize('builtin', "Built-in");
const subtitle = append(details, $('.subtitle'));
const publisher = append(append(subtitle, $('.subtitle-entry')), $('.publisher.clickable', { title: localize('publisher', "Publisher"), tabIndex: 0 }));
const publisher = append(append(subtitle, $('.subtitle-entry')), $('.publisher.clickable', { tabIndex: 0 }));
this._register(setupCustomHover(getDefaultHoverDelegate('mouse'), publisher, localize('publisher', "Publisher")));
publisher.setAttribute('role', 'button');
const publisherDisplayName = append(publisher, $('.publisher-name'));
const verifiedPublisherWidget = this.instantiationService.createInstance(VerifiedPublisherWidget, append(publisher, $('.verified-publisher')), false);
const installCount = append(append(subtitle, $('.subtitle-entry')), $('span.install', { title: localize('install count', "Install count"), tabIndex: 0 }));
const installCount = append(append(subtitle, $('.subtitle-entry')), $('span.install', { tabIndex: 0 }));
this._register(setupCustomHover(getDefaultHoverDelegate('mouse'), installCount, localize('install count', "Install count")));
const installCountWidget = this.instantiationService.createInstance(InstallCountWidget, installCount, false);
const rating = append(append(subtitle, $('.subtitle-entry')), $('span.rating.clickable', { title: localize('rating', "Rating"), tabIndex: 0 }));
const rating = append(append(subtitle, $('.subtitle-entry')), $('span.rating.clickable', { tabIndex: 0 }));
this._register(setupCustomHover(getDefaultHoverDelegate('mouse'), rating, localize('rating', "Rating")));
rating.setAttribute('role', 'link'); // #132645
const ratingsWidget = this.instantiationService.createInstance(RatingsWidget, rating, false);
@@ -914,7 +922,9 @@ export class ExtensionEditor extends EditorPane {
append(extensionResourcesContainer, $('.additional-details-title', undefined, localize('resources', "Resources")));
const resourcesElement = append(extensionResourcesContainer, $('.resources'));
for (const [label, uri] of resources) {
this.transientDisposables.add(onClick(append(resourcesElement, $('a.resource', { title: uri.toString(), tabindex: '0' }, label)), () => this.openerService.open(uri)));
const resource = append(resourcesElement, $('a.resource', { tabindex: '0' }, label));
this.transientDisposables.add(onClick(resource, () => this.openerService.open(uri)));
this.transientDisposables.add(setupCustomHover(getDefaultHoverDelegate('mouse'), resource, uri.toString()));
}
}
}
@@ -31,7 +31,7 @@ import { URI } from 'vs/base/common/uri';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import Severity from 'vs/base/common/severity';
import { setupCustomHover } from 'vs/base/browser/ui/iconLabel/iconLabelHover';
import { ICustomHover, setupCustomHover } from 'vs/base/browser/ui/iconLabel/iconLabelHover';
import { Color } from 'vs/base/common/color';
import { renderMarkdown } from 'vs/base/browser/markdownRenderer';
import { IOpenerService } from 'vs/platform/opener/common/opener';
@@ -41,6 +41,7 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { defaultCountBadgeStyles } from 'vs/platform/theme/browser/defaultStyles';
import { getDefaultHoverDelegate } from 'vs/base/browser/ui/hover/hoverDelegate';
export abstract class ExtensionWidget extends Disposable implements IExtensionContainer {
private _extension: IExtension | null = null;
@@ -124,6 +125,8 @@ export class InstallCountWidget extends ExtensionWidget {
export class RatingsWidget extends ExtensionWidget {
private readonly containerHover: ICustomHover;
constructor(
private container: HTMLElement,
private small: boolean
@@ -135,12 +138,13 @@ export class RatingsWidget extends ExtensionWidget {
container.classList.add('small');
}
this.containerHover = this._register(setupCustomHover(getDefaultHoverDelegate('mouse'), container, ''));
this.render();
}
render(): void {
this.container.innerText = '';
this.container.title = '';
if (!this.extension) {
return;
@@ -159,7 +163,7 @@ export class RatingsWidget extends ExtensionWidget {
}
const rating = Math.round(this.extension.rating * 2) / 2;
this.container.title = localize('ratedLabel', "Average rating: {0} out of 5", rating);
this.containerHover.update(localize('ratedLabel', "Average rating: {0} out of 5", rating));
if (this.small) {
append(this.container, $('span' + ThemeIcon.asCSSSelector(starFullIcon)));
@@ -186,6 +190,7 @@ export class RatingsWidget extends ExtensionWidget {
export class VerifiedPublisherWidget extends ExtensionWidget {
private disposables = this._register(new DisposableStore());
private readonly containerHover: ICustomHover;
constructor(
private container: HTMLElement,
@@ -193,6 +198,7 @@ export class VerifiedPublisherWidget extends ExtensionWidget {
@IOpenerService private readonly openerService: IOpenerService,
) {
super();
this.containerHover = this._register(setupCustomHover(getDefaultHoverDelegate('mouse'), container, ''));
this.render();
}
@@ -209,7 +215,7 @@ export class VerifiedPublisherWidget extends ExtensionWidget {
if (!this.small) {
verifiedPublisher.tabIndex = 0;
verifiedPublisher.title = `Verified Domain: ${this.extension.publisherDomain.link}`;
this.containerHover.update(`Verified Domain: ${this.extension.publisherDomain.link}`);
verifiedPublisher.setAttribute('role', 'link');
append(verifiedPublisher, $('span.extension-verified-publisher-domain', undefined, publisherDomainLink.authority.startsWith('www.') ? publisherDomainLink.authority.substring(4) : publisherDomainLink.authority));
@@ -239,7 +245,8 @@ export class SponsorWidget extends ExtensionWidget {
return;
}
const sponsor = append(this.container, $('span.sponsor.clickable', { tabIndex: 0, title: this.extension?.publisherSponsorLink }));
const sponsor = append(this.container, $('span.sponsor.clickable', { tabIndex: 0 }));
this.disposables.add(setupCustomHover(getDefaultHoverDelegate('mouse'), sponsor, this.extension?.publisherSponsorLink.toString() ?? ''));
sponsor.setAttribute('role', 'link'); // #132645
const sponsorIconElement = renderIcon(sponsorIcon);
const label = $('span', undefined, localize('sponsor', "Sponsor"));
@@ -367,6 +374,7 @@ export class RemoteBadgeWidget extends ExtensionWidget {
class RemoteBadge extends Disposable {
readonly element: HTMLElement;
readonly elementHover: ICustomHover;
constructor(
private readonly tooltip: boolean,
@@ -376,6 +384,7 @@ class RemoteBadge extends Disposable {
) {
super();
this.element = $('div.extension-badge.extension-remote-badge');
this.elementHover = this._register(setupCustomHover(getDefaultHoverDelegate('mouse'), this.element, ''));
this.render();
}
@@ -397,7 +406,7 @@ class RemoteBadge extends Disposable {
if (this.tooltip) {
const updateTitle = () => {
if (this.element && this.extensionManagementServerService.remoteExtensionManagementServer) {
this.element.title = localize('remote extension title', "Extension in {0}", this.extensionManagementServerService.remoteExtensionManagementServer.label);
this.elementHover.update(localize('remote extension title', "Extension in {0}", this.extensionManagementServerService.remoteExtensionManagementServer.label));
}
};
this._register(this.labelService.onDidChangeFormatters(() => updateTitle()));
@@ -435,6 +444,8 @@ export class ExtensionPackCountWidget extends ExtensionWidget {
export class SyncIgnoredWidget extends ExtensionWidget {
private readonly disposables = this._register(new DisposableStore());
constructor(
private readonly container: HTMLElement,
@IConfigurationService private readonly configurationService: IConfigurationService,
@@ -448,11 +459,12 @@ export class SyncIgnoredWidget extends ExtensionWidget {
}
render(): void {
this.disposables.clear();
this.container.innerText = '';
if (this.extension && this.extension.state === ExtensionState.Installed && this.userDataSyncEnablementService.isEnabled() && this.extensionsWorkbenchService.isExtensionIgnoredToSync(this.extension)) {
const element = append(this.container, $('span.extension-sync-ignored' + ThemeIcon.asCSSSelector(syncIgnoredIcon)));
element.title = localize('syncingore.label', "This extension is ignored during sync.");
this.disposables.add(setupCustomHover(getDefaultHoverDelegate('mouse'), element, localize('syncingore.label', "This extension is ignored during sync.")));
element.classList.add(...ThemeIcon.asClassNameArray(syncIgnoredIcon));
}
}