mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 17:19:48 +01:00
Apply editor foreground color changes to syntax theme. Fixes #25519
This commit is contained in:
@@ -19,13 +19,13 @@ import pfs = require('vs/base/node/pfs');
|
||||
import { Extensions, IColorRegistry, ColorIdentifier, editorBackground, editorForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { ThemeType } from 'vs/platform/theme/common/themeService';
|
||||
import { Registry } from 'vs/platform/platform';
|
||||
import { WorkbenchThemeService } from "vs/workbench/services/themes/electron-browser/workbenchThemeService";
|
||||
import { WorkbenchThemeService, IColorCustomizations } from "vs/workbench/services/themes/electron-browser/workbenchThemeService";
|
||||
|
||||
let colorRegistry = <IColorRegistry>Registry.as(Extensions.ColorContribution);
|
||||
|
||||
export class ColorThemeData implements IColorTheme {
|
||||
|
||||
constructor(private themeService: WorkbenchThemeService) {
|
||||
constructor() {
|
||||
}
|
||||
|
||||
id: string;
|
||||
@@ -38,20 +38,21 @@ export class ColorThemeData implements IColorTheme {
|
||||
path?: string;
|
||||
extensionData: ExtensionData;
|
||||
colorMap: IColorMap = {};
|
||||
customColorMap: IColorMap = {};
|
||||
|
||||
public getColor(colorId: ColorIdentifier, useDefault?: boolean): Color {
|
||||
let customColor = this.themeService.getCustomColor(colorId);
|
||||
if (customColor) {
|
||||
return customColor;
|
||||
let color = this.customColorMap[colorId];
|
||||
if (color) {
|
||||
return color;
|
||||
}
|
||||
let color = this.colorMap[colorId];
|
||||
color = this.colorMap[colorId];
|
||||
if (useDefault !== false && types.isUndefined(color)) {
|
||||
color = this.getDefault(colorId);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
private getDefault(colorId: ColorIdentifier): Color {
|
||||
public getDefault(colorId: ColorIdentifier): Color {
|
||||
return colorRegistry.resolveDefaultColor(colorId, this);
|
||||
}
|
||||
|
||||
@@ -64,6 +65,22 @@ export class ColorThemeData implements IColorTheme {
|
||||
return color === null ? defaultValue === null : color.equals(defaultValue);
|
||||
}
|
||||
|
||||
public setCustomColors(colors: IColorCustomizations) {
|
||||
this.customColorMap = {};
|
||||
for (let id in colors) {
|
||||
let colorVal = colors[id];
|
||||
if (typeof colorVal === 'string') {
|
||||
let color = Color.fromHex(colorVal, null);
|
||||
if (color) {
|
||||
this.customColorMap[id] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.tokenColors) {
|
||||
updateDefaultRuleSettings(this.tokenColors[0], this);
|
||||
}
|
||||
}
|
||||
|
||||
public ensureLoaded(themeService: WorkbenchThemeService): TPromise<void> {
|
||||
if (!this.isLoaded) {
|
||||
this.tokenColors = [];
|
||||
@@ -71,7 +88,7 @@ export class ColorThemeData implements IColorTheme {
|
||||
if (this.path) {
|
||||
return _loadColorThemeFromFile(this.path, this.tokenColors, this.colorMap).then(_ => {
|
||||
this.isLoaded = true;
|
||||
_completeTokenColors(this);
|
||||
_sanitizeTokenColors(this);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -119,10 +136,10 @@ export class ColorThemeData implements IColorTheme {
|
||||
}
|
||||
}
|
||||
|
||||
export function fromStorageData(themeService: WorkbenchThemeService, input: string): ColorThemeData {
|
||||
export function fromStorageData(input: string): ColorThemeData {
|
||||
try {
|
||||
let data = JSON.parse(input);
|
||||
let theme = new ColorThemeData(themeService);
|
||||
let theme = new ColorThemeData();
|
||||
for (let key in data) {
|
||||
if (key !== 'colorMap') {
|
||||
theme[key] = data[key];
|
||||
@@ -139,11 +156,11 @@ export function fromStorageData(themeService: WorkbenchThemeService, input: stri
|
||||
}
|
||||
}
|
||||
|
||||
export function fromExtensionTheme(themeService: WorkbenchThemeService, theme: IThemeExtensionPoint, normalizedAbsolutePath: string, extensionData: ExtensionData): ColorThemeData {
|
||||
export function fromExtensionTheme(theme: IThemeExtensionPoint, normalizedAbsolutePath: string, extensionData: ExtensionData): ColorThemeData {
|
||||
let baseTheme = theme['uiTheme'] || 'vs-dark';
|
||||
|
||||
let themeSelector = toCSSSelector(extensionData.extensionId + '-' + Paths.normalize(theme.path));
|
||||
let themeData = new ColorThemeData(themeService);
|
||||
let themeData = new ColorThemeData();
|
||||
themeData.id = `${baseTheme} ${themeSelector}`;
|
||||
themeData.label = theme.label || Paths.basename(theme.path);
|
||||
themeData.settingsId = theme.id || themeData.label;
|
||||
@@ -230,25 +247,31 @@ function _loadSyntaxTokensFromFile(themePath: string, resultRules: ITokenColoriz
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Make sure that the token colors contain the default fore and background
|
||||
* Place the default settings first and add add the token-info rules
|
||||
*/
|
||||
function _completeTokenColors(theme: ColorThemeData) {
|
||||
function _sanitizeTokenColors(theme: ColorThemeData) {
|
||||
let hasDefaultTokens = false;
|
||||
let updatedTokenColors: ITokenColorizationRule[] = [updateDefaultRuleSettings({ settings: {} }, theme)];
|
||||
theme.tokenColors.forEach(rule => {
|
||||
if (!rule.scope) {
|
||||
if (!rule.settings.background) {
|
||||
rule.settings.background = theme.getColor(editorBackground).toRGBAHex();
|
||||
if (rule.scope) {
|
||||
if (rule.scope === 'token.info-token') {
|
||||
hasDefaultTokens = true;
|
||||
}
|
||||
if (!rule.settings.foreground) {
|
||||
rule.settings.foreground = theme.getColor(editorForeground).toRGBAHex();
|
||||
}
|
||||
} else if (rule.scope === 'token.info-token') {
|
||||
hasDefaultTokens = true;
|
||||
updatedTokenColors.push(rule);
|
||||
}
|
||||
});
|
||||
if (!hasDefaultTokens) {
|
||||
theme.tokenColors.push(...defaultThemeColors[theme.type]);
|
||||
updatedTokenColors.push(...defaultThemeColors[theme.type]);
|
||||
}
|
||||
theme.tokenColors = updatedTokenColors;
|
||||
}
|
||||
|
||||
function updateDefaultRuleSettings(defaultRule: ITokenColorizationRule, theme: ColorThemeData): ITokenColorizationRule {
|
||||
let foreground = theme.getColor(editorForeground) || theme.getDefault(editorForeground);
|
||||
let background = theme.getColor(editorBackground) || theme.getDefault(editorBackground);
|
||||
defaultRule.settings.foreground = foreground.toRGBAHex();
|
||||
defaultRule.settings.background = background.toRGBAHex();
|
||||
return defaultRule;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { ColorThemeData, fromStorageData, fromExtensionTheme } from './colorThemeData';
|
||||
import { ITheme, Extensions as ThemingExtensions, IThemingRegistry } from 'vs/platform/theme/common/themeService';
|
||||
import { editorBackground, editorForeground, ColorIdentifier } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { editorBackground } from 'vs/platform/theme/common/colorRegistry';
|
||||
|
||||
import { $ } from 'vs/base/browser/builder';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
@@ -39,8 +39,6 @@ import pfs = require('vs/base/node/pfs');
|
||||
import colorThemeSchema = require('vs/workbench/services/themes/common/colorThemeSchema');
|
||||
import fileIconThemeSchema = require('vs/workbench/services/themes/common/fileIconThemeSchema');
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
|
||||
|
||||
// implementation
|
||||
|
||||
@@ -227,13 +225,15 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
|
||||
extensionData: null
|
||||
};
|
||||
|
||||
this.updateColorCustomizations(false);
|
||||
|
||||
let themeData = null;
|
||||
let persistedThemeData = this.storageService.get(PERSISTED_THEME_STORAGE_KEY);
|
||||
if (persistedThemeData) {
|
||||
themeData = fromStorageData(this, persistedThemeData);
|
||||
themeData = fromStorageData(persistedThemeData);
|
||||
}
|
||||
if (themeData !== null) {
|
||||
this.updateColorCustomizations(false);
|
||||
themeData.setCustomColors(this.colorCustomizations);
|
||||
this.updateDynamicCSSRules(themeData);
|
||||
this.applyTheme(themeData, null, true);
|
||||
} else {
|
||||
@@ -242,18 +242,14 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
|
||||
// a color theme document with good defaults until the theme is loaded
|
||||
let isLightTheme = (Array.prototype.indexOf.call(document.body.classList, 'vs') >= 0);
|
||||
|
||||
let initialTheme = new ColorThemeData(this);
|
||||
let initialTheme = new ColorThemeData();
|
||||
initialTheme.id = isLightTheme ? VS_LIGHT_THEME : VS_DARK_THEME;
|
||||
initialTheme.label = '';
|
||||
initialTheme.selector = isLightTheme ? VS_LIGHT_THEME : VS_DARK_THEME;
|
||||
initialTheme.settingsId = null;
|
||||
initialTheme.isLoaded = false;
|
||||
initialTheme.tokenColors = [{
|
||||
settings: {
|
||||
foreground: initialTheme.getColor(editorForeground).toRGBAHex(),
|
||||
background: initialTheme.getColor(editorBackground).toRGBAHex()
|
||||
}
|
||||
}];
|
||||
initialTheme.tokenColors = [{ settings: {} }];
|
||||
initialTheme.setCustomColors(this.colorCustomizations);
|
||||
this.currentColorTheme = initialTheme;
|
||||
}
|
||||
|
||||
@@ -413,6 +409,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
|
||||
this.currentColorTheme = themeData;
|
||||
return TPromise.as(themeData);
|
||||
}
|
||||
themeData.setCustomColors(this.colorCustomizations);
|
||||
this.updateDynamicCSSRules(themeData);
|
||||
return this.applyTheme(themeData, settingsTarget);
|
||||
}, error => {
|
||||
@@ -539,21 +536,16 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
|
||||
if (this.hasCustomizationChanged(newColorCustomizations, newColorIds)) {
|
||||
this.colorCustomizations = newColorCustomizations;
|
||||
this.numberOfColorCustomizations = newColorIds.length;
|
||||
if (notify) {
|
||||
this.updateDynamicCSSRules(this.currentColorTheme);
|
||||
this.onColorThemeChange.fire(this.currentColorTheme);
|
||||
if (this.currentColorTheme) {
|
||||
this.currentColorTheme.setCustomColors(newColorCustomizations);
|
||||
if (notify) {
|
||||
this.updateDynamicCSSRules(this.currentColorTheme);
|
||||
this.onColorThemeChange.fire(this.currentColorTheme);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getCustomColor(id: ColorIdentifier) {
|
||||
let color = this.colorCustomizations[id];
|
||||
if (typeof color === 'string') {
|
||||
return Color.fromHex(this.colorCustomizations[id], null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private onThemes(extensionFolderPath: string, extensionData: ExtensionData, themes: IThemeExtensionPoint[], collector: ExtensionMessageCollector): void {
|
||||
if (!Array.isArray(themes)) {
|
||||
collector.error(nls.localize(
|
||||
@@ -578,7 +570,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
|
||||
if (normalizedAbsolutePath.indexOf(Paths.normalize(extensionFolderPath)) !== 0) {
|
||||
collector.warn(nls.localize('invalid.path.1', "Expected `contributes.{0}.path` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.", themesExtPoint.name, normalizedAbsolutePath, extensionFolderPath));
|
||||
}
|
||||
let themeData = fromExtensionTheme(this, theme, normalizedAbsolutePath, extensionData);
|
||||
let themeData = fromExtensionTheme(theme, normalizedAbsolutePath, extensionData);
|
||||
this.extensionsColorThemes.push(themeData);
|
||||
|
||||
colorThemeSettingSchema.enum.push(themeData.settingsId);
|
||||
|
||||
Reference in New Issue
Block a user