mirror of
https://github.com/coder/code-server.git
synced 2026-05-31 17:39:33 +00:00
Merge commit 'be3e8236086165e5e45a5a10783823874b3f3ebd' as 'lib/vscode'
This commit is contained in:
216
lib/vscode/src/vs/platform/theme/common/iconRegistry.ts
Normal file
216
lib/vscode/src/vs/platform/theme/common/iconRegistry.ts
Normal file
@@ -0,0 +1,216 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as platform from 'vs/platform/registry/common/platform';
|
||||
import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema';
|
||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { localize } from 'vs/nls';
|
||||
import { Extensions as JSONExtensions, IJSONContributionRegistry } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import * as Codicons from 'vs/base/common/codicons';
|
||||
|
||||
// ------ API types
|
||||
|
||||
|
||||
// color registry
|
||||
export const Extensions = {
|
||||
IconContribution: 'base.contributions.icons'
|
||||
};
|
||||
|
||||
export type IconDefaults = ThemeIcon | IconDefinition;
|
||||
|
||||
export interface IconDefinition {
|
||||
fontId?: string;
|
||||
character: string;
|
||||
}
|
||||
|
||||
export interface IconContribution {
|
||||
id: string;
|
||||
description: string;
|
||||
deprecationMessage?: string;
|
||||
defaults: IconDefaults;
|
||||
}
|
||||
|
||||
export interface IIconRegistry {
|
||||
|
||||
readonly onDidChangeSchema: Event<void>;
|
||||
|
||||
/**
|
||||
* Register a icon to the registry.
|
||||
* @param id The icon id
|
||||
* @param defaults The default values
|
||||
* @description the description
|
||||
*/
|
||||
registerIcon(id: string, defaults: IconDefaults, description: string): ThemeIcon;
|
||||
|
||||
/**
|
||||
* Register a icon to the registry.
|
||||
*/
|
||||
deregisterIcon(id: string): void;
|
||||
|
||||
/**
|
||||
* Get all icon contributions
|
||||
*/
|
||||
getIcons(): IconContribution[];
|
||||
|
||||
/**
|
||||
* Get the icon for the given id
|
||||
*/
|
||||
getIcon(id: string): IconContribution | undefined;
|
||||
|
||||
/**
|
||||
* JSON schema for an object to assign icon values to one of the color contributions.
|
||||
*/
|
||||
getIconSchema(): IJSONSchema;
|
||||
|
||||
/**
|
||||
* JSON schema to for a reference to a icon contribution.
|
||||
*/
|
||||
getIconReferenceSchema(): IJSONSchema;
|
||||
|
||||
}
|
||||
|
||||
class IconRegistry implements IIconRegistry {
|
||||
|
||||
private readonly _onDidChangeSchema = new Emitter<void>();
|
||||
readonly onDidChangeSchema: Event<void> = this._onDidChangeSchema.event;
|
||||
|
||||
private iconsById: { [key: string]: IconContribution };
|
||||
private iconSchema: IJSONSchema & { properties: IJSONSchemaMap } = {
|
||||
definitions: {
|
||||
icons: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
fontId: { type: 'string', description: localize('iconDefintion.fontId', 'The id of the font to use. If not set, the font that is defined first is used.') },
|
||||
fontCharacter: { type: 'string', description: localize('iconDefintion.fontCharacter', 'The font character associated with the icon definition.') }
|
||||
},
|
||||
additionalProperties: false,
|
||||
defaultSnippets: [{ body: { fontCharacter: '\\\\e030' } }]
|
||||
}
|
||||
},
|
||||
type: 'object',
|
||||
properties: {}
|
||||
};
|
||||
private iconReferenceSchema: IJSONSchema & { enum: string[], enumDescriptions: string[] } = { type: 'string', enum: [], enumDescriptions: [] };
|
||||
|
||||
constructor() {
|
||||
this.iconsById = {};
|
||||
}
|
||||
|
||||
public registerIcon(id: string, defaults: IconDefaults, description?: string, deprecationMessage?: string): ThemeIcon {
|
||||
if (!description) {
|
||||
description = localize('icon.defaultDescription', 'Icon with identifier \'{0}\'', id);
|
||||
}
|
||||
let iconContribution: IconContribution = { id, description, defaults, deprecationMessage };
|
||||
this.iconsById[id] = iconContribution;
|
||||
let propertySchema: IJSONSchema = { $ref: '#/definitions/icons' };
|
||||
if (deprecationMessage) {
|
||||
propertySchema.deprecationMessage = deprecationMessage;
|
||||
}
|
||||
propertySchema.markdownDescription = `${description}: $(${id})`;
|
||||
this.iconSchema.properties[id] = propertySchema;
|
||||
this.iconReferenceSchema.enum.push(id);
|
||||
this.iconReferenceSchema.enumDescriptions.push(description);
|
||||
|
||||
this._onDidChangeSchema.fire();
|
||||
return { id };
|
||||
}
|
||||
|
||||
|
||||
public deregisterIcon(id: string): void {
|
||||
delete this.iconsById[id];
|
||||
delete this.iconSchema.properties[id];
|
||||
const index = this.iconReferenceSchema.enum.indexOf(id);
|
||||
if (index !== -1) {
|
||||
this.iconReferenceSchema.enum.splice(index, 1);
|
||||
this.iconReferenceSchema.enumDescriptions.splice(index, 1);
|
||||
}
|
||||
this._onDidChangeSchema.fire();
|
||||
}
|
||||
|
||||
public getIcons(): IconContribution[] {
|
||||
return Object.keys(this.iconsById).map(id => this.iconsById[id]);
|
||||
}
|
||||
|
||||
public getIcon(id: string): IconContribution | undefined {
|
||||
return this.iconsById[id];
|
||||
}
|
||||
|
||||
public getIconSchema(): IJSONSchema {
|
||||
return this.iconSchema;
|
||||
}
|
||||
|
||||
public getIconReferenceSchema(): IJSONSchema {
|
||||
return this.iconReferenceSchema;
|
||||
}
|
||||
|
||||
public toString() {
|
||||
const sorter = (i1: IconContribution, i2: IconContribution) => {
|
||||
const isThemeIcon1 = ThemeIcon.isThemeIcon(i1.defaults);
|
||||
const isThemeIcon2 = ThemeIcon.isThemeIcon(i2.defaults);
|
||||
if (isThemeIcon1 !== isThemeIcon2) {
|
||||
return isThemeIcon1 ? -1 : 1;
|
||||
}
|
||||
return i1.id.localeCompare(i2.id);
|
||||
};
|
||||
const classNames = (i: IconContribution) => {
|
||||
while (ThemeIcon.isThemeIcon(i.defaults)) {
|
||||
i = this.iconsById[i.defaults.id];
|
||||
}
|
||||
return `codicon codicon-${i ? i.id : ''}`;
|
||||
};
|
||||
|
||||
let reference = [];
|
||||
let docCss = [];
|
||||
|
||||
const contributions = Object.keys(this.iconsById).map(key => this.iconsById[key]);
|
||||
|
||||
for (const i of contributions.sort(sorter)) {
|
||||
reference.push(`|<i class="${classNames(i)}"></i>|${i.id}|${ThemeIcon.isThemeIcon(i.defaults) ? i.defaults.id : ''}|`);
|
||||
|
||||
if (!ThemeIcon.isThemeIcon((i.defaults))) {
|
||||
docCss.push(`.codicon-${i.id}:before { content: "${i.defaults.character}" }`);
|
||||
}
|
||||
}
|
||||
return reference.join('\n') + '\n\n' + docCss.join('\n');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const iconRegistry = new IconRegistry();
|
||||
platform.Registry.add(Extensions.IconContribution, iconRegistry);
|
||||
|
||||
export function registerIcon(id: string, defaults: IconDefaults, description?: string, deprecationMessage?: string): ThemeIcon {
|
||||
return iconRegistry.registerIcon(id, defaults, description, deprecationMessage);
|
||||
}
|
||||
|
||||
export function getIconRegistry(): IIconRegistry {
|
||||
return iconRegistry;
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
for (const icon of Codicons.iconRegistry.all) {
|
||||
registerIcon(icon.id, icon.definition);
|
||||
}
|
||||
Codicons.iconRegistry.onDidRegister(icon => registerIcon(icon.id, icon.definition));
|
||||
}
|
||||
initialize();
|
||||
|
||||
|
||||
export const iconsSchemaId = 'vscode://schemas/icons';
|
||||
|
||||
let schemaRegistry = platform.Registry.as<IJSONContributionRegistry>(JSONExtensions.JSONContribution);
|
||||
schemaRegistry.registerSchema(iconsSchemaId, iconRegistry.getIconSchema());
|
||||
|
||||
const delayer = new RunOnceScheduler(() => schemaRegistry.notifySchemaChanged(iconsSchemaId), 200);
|
||||
iconRegistry.onDidChangeSchema(() => {
|
||||
if (!delayer.isScheduled()) {
|
||||
delayer.schedule();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//setTimeout(_ => console.log(iconRegistry.toString()), 5000);
|
||||
Reference in New Issue
Block a user