mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-26 01:38:40 +01:00
galleryExtension.iconUrlFallback related to #10180
This commit is contained in:
@@ -33,6 +33,7 @@ export interface IGalleryExtensionAssets {
|
||||
readme: string;
|
||||
download: string;
|
||||
icon: string;
|
||||
iconFallback: string;
|
||||
license: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -181,11 +181,25 @@ function getAssetSource(files: IRawGalleryExtensionFile[], type: string): string
|
||||
|
||||
function toExtension(galleryExtension: IRawGalleryExtension, extensionsGalleryUrl: string, downloadHeaders: { [key: string]: string; }): IGalleryExtension {
|
||||
const [version] = galleryExtension.versions;
|
||||
|
||||
let iconFallback = getAssetSource(version.files, AssetType.Icon);
|
||||
let icon: string;
|
||||
|
||||
if (iconFallback) {
|
||||
const parsedUrl = url.parse(iconFallback, true);
|
||||
parsedUrl.search = undefined;
|
||||
parsedUrl.query['redirect'] = 'true';
|
||||
icon = url.format(parsedUrl);
|
||||
} else {
|
||||
iconFallback = icon = require.toUrl('./media/defaultIcon.png');
|
||||
}
|
||||
|
||||
const assets = {
|
||||
manifest: getAssetSource(version.files, AssetType.Manifest),
|
||||
readme: getAssetSource(version.files, AssetType.Details),
|
||||
download: `${ getAssetSource(version.files, AssetType.VSIX) }?install=true`,
|
||||
icon: getAssetSource(version.files, AssetType.Icon) || require.toUrl('./media/defaultIcon.png'),
|
||||
icon,
|
||||
iconFallback,
|
||||
license: getAssetSource(version.files, AssetType.License)
|
||||
};
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ import { marked } from 'vs/base/common/marked/marked';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { IDisposable, empty, dispose, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Builder } from 'vs/base/browser/builder';
|
||||
import { once } from 'vs/base/common/event';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { append, emmet as $, addClass, removeClass, finalHandler } from 'vs/base/browser/dom';
|
||||
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||
import { IViewlet } from 'vs/workbench/common/viewlet';
|
||||
@@ -48,7 +50,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
|
||||
static ID: string = 'workbench.editor.extension';
|
||||
|
||||
private icon: HTMLElement;
|
||||
private icon: HTMLImageElement;
|
||||
private name: HTMLAnchorElement;
|
||||
private license: HTMLAnchorElement;
|
||||
private publisher: HTMLAnchorElement;
|
||||
@@ -88,7 +90,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
const root = append(container, $('.extension-editor'));
|
||||
const header = append(root, $('.header'));
|
||||
|
||||
this.icon = append(header, $('.icon'));
|
||||
this.icon = append(header, $<HTMLImageElement>('img.icon'));
|
||||
|
||||
const details = append(header, $('.details'));
|
||||
const title = append(details, $('.title'));
|
||||
@@ -124,7 +126,10 @@ export class ExtensionEditor extends BaseEditor {
|
||||
const extension = input.extension;
|
||||
this.telemetryService.publicLog('extensionGallery:openExtension', extension.telemetryData);
|
||||
|
||||
this.icon.style.backgroundImage = `url("${ extension.iconUrl }")`;
|
||||
const onError = once(domEvent(this.icon, 'error'));
|
||||
onError(() => this.icon.src = extension.iconUrlFallback, null, this.transientDisposables);
|
||||
this.icon.src = extension.iconUrl;
|
||||
|
||||
this.name.textContent = extension.displayName;
|
||||
this.publisher.textContent = extension.publisherDisplayName;
|
||||
this.description.textContent = extension.description;
|
||||
|
||||
@@ -34,6 +34,7 @@ export interface IExtension {
|
||||
description: string;
|
||||
readmeUrl: string;
|
||||
iconUrl: string;
|
||||
iconUrlFallback: string;
|
||||
licenseUrl: string;
|
||||
installCount: number;
|
||||
rating: number;
|
||||
|
||||
@@ -12,6 +12,8 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
||||
import { IMessageService, Severity } from 'vs/platform/message/common/message';
|
||||
import { IDelegate } from 'vs/base/browser/ui/list/list';
|
||||
import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging';
|
||||
import { once } from 'vs/base/common/event';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { IExtension } from './extensions';
|
||||
import { CombinedInstallAction, UpdateAction, EnableAction } from './extensionsActions';
|
||||
import { Label, RatingsWidget, InstallWidget } from './extensionsWidgets';
|
||||
@@ -27,6 +29,7 @@ export interface ITemplateData {
|
||||
description: HTMLElement;
|
||||
extension: IExtension;
|
||||
disposables: IDisposable[];
|
||||
extensionDisposables: IDisposable[];
|
||||
}
|
||||
|
||||
export class Delegate implements IDelegate<IExtension> {
|
||||
@@ -74,6 +77,7 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
|
||||
|
||||
return {
|
||||
element, icon, name, installCount, ratings, author, description, disposables,
|
||||
extensionDisposables: [],
|
||||
set extension(extension: IExtension) {
|
||||
versionWidget.extension = extension;
|
||||
installCountWidget.extension = extension;
|
||||
@@ -87,6 +91,8 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
|
||||
|
||||
renderPlaceholder(index: number, data: ITemplateData): void {
|
||||
addClass(data.element, 'loading');
|
||||
|
||||
data.extensionDisposables = dispose(data.extensionDisposables);
|
||||
data.icon.src = '';
|
||||
data.name.textContent = '';
|
||||
data.author.textContent = '';
|
||||
@@ -98,6 +104,11 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
|
||||
|
||||
renderElement(extension: IExtension, index: number, data: ITemplateData): void {
|
||||
removeClass(data.element, 'loading');
|
||||
|
||||
data.extensionDisposables = dispose(data.extensionDisposables);
|
||||
|
||||
const onError = once(domEvent(data.icon, 'error'));
|
||||
onError(() => data.icon.src = extension.iconUrlFallback, null, data.extensionDisposables);
|
||||
data.icon.src = extension.iconUrl;
|
||||
|
||||
if (!data.icon.complete) {
|
||||
|
||||
@@ -86,11 +86,28 @@ class Extension implements IExtension {
|
||||
}
|
||||
|
||||
get iconUrl(): string {
|
||||
if (this.local && this.local.manifest.icon) {
|
||||
return URI.file(path.join(this.local.path, this.local.manifest.icon)).toString();
|
||||
}
|
||||
return this.localIconUrl || this.galleryIconUrl || this.defaultIconUrl;
|
||||
}
|
||||
|
||||
return this.gallery ? this.gallery.assets.icon : require.toUrl('./media/defaultIcon.png');
|
||||
get iconUrlFallback(): string {
|
||||
return this.localIconUrl || this.galleryIconUrlFallback || this.defaultIconUrl;
|
||||
}
|
||||
|
||||
private get localIconUrl(): string {
|
||||
return this.local && this.local.manifest.icon
|
||||
&& URI.file(path.join(this.local.path, this.local.manifest.icon)).toString();
|
||||
}
|
||||
|
||||
private get galleryIconUrl(): string {
|
||||
return this.gallery && this.gallery.assets.icon;
|
||||
}
|
||||
|
||||
private get galleryIconUrlFallback(): string {
|
||||
return this.gallery && this.gallery.assets.iconFallback;
|
||||
}
|
||||
|
||||
private get defaultIconUrl(): string {
|
||||
return require.toUrl('./media/defaultIcon.png');
|
||||
}
|
||||
|
||||
get licenseUrl(): string {
|
||||
|
||||
@@ -24,10 +24,7 @@
|
||||
.extension-editor > .header > .icon {
|
||||
height: 128px;
|
||||
width: 128px;
|
||||
min-width: 128px;
|
||||
background-size: 128px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.extension-editor > .header > .details {
|
||||
|
||||
Reference in New Issue
Block a user