提交 2319f162 编写于 作者: A Alex Dima

Allow for theme switching

上级 74b5f506
......@@ -4,40 +4,61 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import Event, { Emitter } from 'vs/base/common/event';
import { Theme } from 'vs/editor/common/modes/supports/tokenization';
import { Theme, IThemeRule } from 'vs/editor/common/modes/supports/tokenization';
import { IStandaloneColorService } from 'vs/editor/common/services/standaloneColorService';
import { vs } from 'vs/editor/common/standalone/themes';
import { vs, vs_dark, hc_black } from 'vs/editor/common/standalone/themes';
import * as dom from 'vs/base/browser/dom';
import { TokenizationRegistry } from 'vs/editor/common/modes';
export class StandaloneColorServiceImpl implements IStandaloneColorService {
_serviceBrand: any;
private _onThemeChanged: Emitter<void> = new Emitter<void>();
public onThemeChanged: Event<void> = this._onThemeChanged.event;
private _theme: Theme;
private _styleElement: HTMLStyleElement;
constructor() {
this._theme = Theme.createFromRawTheme(vs);
this._styleElement = dom.createStyleSheet();
this.setTheme('vs');
}
let colorMap = this._theme.getColorMap();
private static _generateCSS(colorMap: string[]): string {
let rules: string[] = [];
for (let i = 0, len = colorMap.length; i < len; i++) {
for (let i = 1, len = colorMap.length; i < len; i++) {
let color = colorMap[i];
rules[i] = `.mtk${i} { color: #${color}; }`;
}
rules.push('.mtki { font-style: italic; }');
rules.push('.mtkb { font-weight: bold; }');
rules.push('.mtku { text-decoration: underline; }');
this._styleElement.innerHTML = rules.join('\n');
return rules.join('\n');
}
public getTheme(): Theme {
return this._theme;
}
public setTheme(themeName: string): void {
let themeRules: IThemeRule[] = null;
switch (themeName) {
case 'vs':
themeRules = vs;
break;
case 'vs-dark':
themeRules = vs_dark;
break;
case 'hc-black':
themeRules = hc_black;
break;
default:
themeRules = [];
}
console.log(themeRules);
this._theme = Theme.createFromRawTheme(themeRules);
let colorMap = this._theme.getColorMap();
let cssRules = StandaloneColorServiceImpl._generateCSS(colorMap);
this._styleElement.innerHTML = cssRules;
TokenizationRegistry.setColorMap(colorMap);
}
}
......@@ -14,6 +14,7 @@ import { ViewLineToken } from 'vs/editor/common/core/viewLineToken';
import { LineParts } from 'vs/editor/common/core/lineParts';
import { LineTokens } from 'vs/editor/common/core/lineTokens';
import * as strings from 'vs/base/common/strings';
import { IStandaloneColorService } from 'vs/editor/common/services/standaloneColorService';
export interface IColorizerOptions {
tabSize?: number;
......@@ -26,7 +27,7 @@ export interface IColorizerElementOptions extends IColorizerOptions {
export class Colorizer {
public static colorizeElement(modeService: IModeService, domNode: HTMLElement, options: IColorizerElementOptions): TPromise<void> {
public static colorizeElement(standaloneColorService: IStandaloneColorService, modeService: IModeService, domNode: HTMLElement, options: IColorizerElementOptions): TPromise<void> {
options = options || {};
let theme = options.theme || 'vs';
let mimeType = options.mimeType || domNode.getAttribute('lang') || domNode.getAttribute('data-lang');
......@@ -34,6 +35,9 @@ export class Colorizer {
console.error('Mode not detected');
return;
}
standaloneColorService.setTheme(theme);
let text = domNode.firstChild.nodeValue;
domNode.className += 'monaco-editor ' + theme;
let render = (str: string) => {
......@@ -53,7 +57,7 @@ export class Colorizer {
return new TPromise<void>((c, e, p) => {
listener = TokenizationRegistry.onDidChange((e) => {
if (e.languageId === languageId) {
if (e.languageIds.indexOf(languageId) >= 0) {
stopListening();
c(void 0);
}
......
......@@ -11,7 +11,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { ICommandService, ICommandHandler } from 'vs/platform/commands/common/commands';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IActionDescriptor, ICodeEditorWidgetCreationOptions, IDiffEditorOptions, IModel, IModelChangedEvent, EventType } from 'vs/editor/common/editorCommon';
import { IEditorOptions, IActionDescriptor, ICodeEditorWidgetCreationOptions, IDiffEditorOptions, IModel, IModelChangedEvent, EventType } from 'vs/editor/common/editorCommon';
import { ICodeEditorService } from 'vs/editor/common/services/codeEditorService';
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
import { StandaloneKeybindingService } from 'vs/editor/browser/standalone/simpleServices';
......@@ -19,6 +19,7 @@ import { IEditorContextViewService } from 'vs/editor/browser/standalone/standalo
import { CodeEditor } from 'vs/editor/browser/codeEditor';
import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditorWidget';
import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser';
import { IStandaloneColorService } from 'vs/editor/common/services/standaloneColorService';
/**
* The options to create an editor.
......@@ -57,6 +58,7 @@ export interface IStandaloneDiffEditor extends IDiffEditor {
export class StandaloneEditor extends CodeEditor implements IStandaloneCodeEditor {
private _standaloneKeybindingService: StandaloneKeybindingService;
private _standaloneColorService: IStandaloneColorService;
private _contextViewService: IEditorContextViewService;
private _ownsModel: boolean;
private _toDispose2: IDisposable[];
......@@ -70,10 +72,12 @@ export class StandaloneEditor extends CodeEditor implements IStandaloneCodeEdito
@ICommandService commandService: ICommandService,
@IContextKeyService contextKeyService: IContextKeyService,
@IKeybindingService keybindingService: IKeybindingService,
@IContextViewService contextViewService: IContextViewService
@IContextViewService contextViewService: IContextViewService,
@IStandaloneColorService standaloneColorService: IStandaloneColorService
) {
options = options || {};
super(domElement, options, instantiationService, codeEditorService, commandService, contextKeyService);
this._standaloneColorService = standaloneColorService;
if (keybindingService instanceof StandaloneKeybindingService) {
this._standaloneKeybindingService = keybindingService;
......@@ -111,6 +115,15 @@ export class StandaloneEditor extends CodeEditor implements IStandaloneCodeEdito
this.dispose();
}
public updateOptions(newOptions: IEditorOptions): void {
let oldTheme = this._configuration.editor.viewInfo.theme;
super.updateOptions(newOptions);
let newTheme = this._configuration.editor.viewInfo.theme;
if (oldTheme !== newTheme) {
this._standaloneColorService.setTheme(newTheme);
}
}
public addCommand(keybinding: number, handler: ICommandHandler, context: string): string {
if (!this._standaloneKeybindingService) {
console.warn('Cannot add command because the editor is configured with an unrecognized KeybindingService');
......
......@@ -35,6 +35,7 @@ import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerServ
import { ITextModelResolverService } from 'vs/editor/common/services/resolverService';
import { IState, ITokenizationSupport, TokenizationRegistry } from 'vs/editor/common/modes';
import { NULL_STATE, nullTokenize } from 'vs/editor/common/modes/nullMode';
import { IStandaloneColorService } from 'vs/editor/common/services/standaloneColorService';
/**
* @internal
......@@ -92,7 +93,8 @@ export function create(domElement: HTMLElement, options?: IEditorConstructionOpt
services.get(ICommandService),
services.get(IContextKeyService),
services.get(IKeybindingService),
services.get(IContextViewService)
services.get(IContextViewService),
services.get(IStandaloneColorService)
);
});
}
......@@ -240,7 +242,7 @@ export function createWebWorker<T>(opts: IWebWorkerOptions): MonacoWebWorker<T>
* Colorize the contents of `domNode` using attribute `data-lang`.
*/
export function colorizeElement(domNode: HTMLElement, options: IColorizerElementOptions): TPromise<void> {
return Colorizer.colorizeElement(StaticServices.modeService.get(), domNode, options);
return Colorizer.colorizeElement(StaticServices.standaloneColorService.get(), StaticServices.modeService.get(), domNode, options);
}
/**
......
......@@ -95,7 +95,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke
this._languageIdentifier = languageIdentifier || NULL_LANGUAGE_IDENTIFIER;
this._tokenizationListener = TokenizationRegistry.onDidChange((e) => {
if (e.languageId !== this._languageIdentifier.sid) {
if (e.languageIds.indexOf(this._languageIdentifier.sid) === -1) {
return;
}
......
......@@ -826,7 +826,7 @@ export const LinkProviderRegistry = new LanguageFeatureRegistry<LinkProvider>();
* @internal
*/
export interface ITokenizationSupportChangedEvent {
languageId: string;
languageIds: string[];
}
/**
......@@ -850,20 +850,20 @@ export class TokenizationRegistryImpl {
* Fire a change event for a language.
* This is useful for languages that embed other languages.
*/
public fire(languageId: string): void {
this._onDidChange.fire({ languageId: languageId });
public fire(languageIds: string[]): void {
this._onDidChange.fire({ languageIds: languageIds });
}
public register(languageId: string, support: ITokenizationSupport): IDisposable {
this._map[languageId] = support;
this.fire(languageId);
this.fire([languageId]);
return {
dispose: () => {
if (this._map[languageId] !== support) {
return;
}
delete this._map[languageId];
this.fire(languageId);
this.fire([languageId]);
}
};
}
......@@ -872,6 +872,11 @@ export class TokenizationRegistryImpl {
return (this._map[languageId] || null);
}
public setColorMap(colorMap: string[]): void {
this._colorMap = colorMap;
this.fire(Object.keys(this._map));
}
public getColorMap(): string[] {
return this._colorMap;
}
......
......@@ -408,10 +408,17 @@ export class MonarchTokenizer implements modes.ITokenizationSupport {
if (emitting) {
return;
}
let isOneOfMyEmbeddedModes = this._embeddedModes[e.languageId];
let isOneOfMyEmbeddedModes = false;
for (let i = 0, len = e.languageIds.length; i < len; i++) {
let languageId = e.languageIds[i];
if (this._embeddedModes[languageId]) {
isOneOfMyEmbeddedModes = true;
break;
}
}
if (isOneOfMyEmbeddedModes) {
emitting = true;
modes.TokenizationRegistry.fire(this._modeId);
modes.TokenizationRegistry.fire([this._modeId]);
emitting = false;
}
});
......@@ -801,6 +808,9 @@ export class MonarchTokenizer implements modes.ITokenizationSupport {
let modeId = this._modeService.getModeId(mimetypeOrModeId);
// Fire mode loading event
this._modeService.getOrCreateMode(modeId);
let mode = this._modeService.getMode(modeId);
if (mode) {
// Re-emit tokenizationSupport change events from all modes that I ever embedded
......@@ -808,9 +818,6 @@ export class MonarchTokenizer implements modes.ITokenizationSupport {
return mode;
}
// Fire mode loading event
this._modeService.getOrCreateMode(modeId);
this._embeddedModes[modeId] = true;
return null;
......
......@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import Event from 'vs/base/common/event';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { Theme } from 'vs/editor/common/modes/supports/tokenization';
......@@ -13,7 +12,7 @@ export var IStandaloneColorService = createDecorator<IStandaloneColorService>('s
export interface IStandaloneColorService {
_serviceBrand: any;
onThemeChanged: Event<void>;
setTheme(themeName: string): void;
getTheme(): Theme;
}
......@@ -9,6 +9,7 @@ import { IThemeRule } from 'vs/editor/common/modes/supports/tokenization';
/* -------------------------------- Begin vs tokens -------------------------------- */
export const vs: IThemeRule[] = [
{ token: '', foreground: '000000' },
{ token: 'invalid', foreground: 'cd3131' },
{ token: 'emphasis', fontStyle: 'italic' },
{ token: 'strong', fontStyle: 'bold' },
......@@ -132,6 +133,7 @@ export const vs_dark: IThemeRule[] = [
/* -------------------------------- Begin hc-black tokens -------------------------------- */
export const hc_black: IThemeRule[] = [
{ token: '', foreground: 'FFFFFF' },
{ token: 'invalid', foreground: 'f44747' },
{ token: 'emphasis', fontStyle: 'italic' },
{ token: 'strong', fontStyle: 'bold' },
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册