6f6a25a8ea4832f2df72984508b4da7708a061981322b08cd183c368e26db8b8eb7a044e67d9ffed71b91073583bac6b8ea9312a6328542ac67f2dddad9bbb 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. import { CSSIcon } from '../../../base/common/codicons.js';
  6. import { Emitter } from '../../../base/common/event.js';
  7. import { Disposable, toDisposable } from '../../../base/common/lifecycle.js';
  8. import { createDecorator } from '../../instantiation/common/instantiation.js';
  9. import * as platform from '../../registry/common/platform.js';
  10. import { ColorScheme } from './theme.js';
  11. export const IThemeService = createDecorator('themeService');
  12. export var ThemeColor;
  13. (function (ThemeColor) {
  14. function isThemeColor(obj) {
  15. return obj && typeof obj === 'object' && typeof obj.id === 'string';
  16. }
  17. ThemeColor.isThemeColor = isThemeColor;
  18. })(ThemeColor || (ThemeColor = {}));
  19. export function themeColorFromId(id) {
  20. return { id };
  21. }
  22. export var ThemeIcon;
  23. (function (ThemeIcon) {
  24. function isThemeIcon(obj) {
  25. return obj && typeof obj === 'object' && typeof obj.id === 'string' && (typeof obj.color === 'undefined' || ThemeColor.isThemeColor(obj.color));
  26. }
  27. ThemeIcon.isThemeIcon = isThemeIcon;
  28. const _regexFromString = new RegExp(`^\\$\\((${CSSIcon.iconNameExpression}(?:${CSSIcon.iconModifierExpression})?)\\)$`);
  29. function fromString(str) {
  30. const match = _regexFromString.exec(str);
  31. if (!match) {
  32. return undefined;
  33. }
  34. const [, name] = match;
  35. return { id: name };
  36. }
  37. ThemeIcon.fromString = fromString;
  38. function fromId(id) {
  39. return { id };
  40. }
  41. ThemeIcon.fromId = fromId;
  42. function modify(icon, modifier) {
  43. let id = icon.id;
  44. const tildeIndex = id.lastIndexOf('~');
  45. if (tildeIndex !== -1) {
  46. id = id.substring(0, tildeIndex);
  47. }
  48. if (modifier) {
  49. id = `${id}~${modifier}`;
  50. }
  51. return { id };
  52. }
  53. ThemeIcon.modify = modify;
  54. function getModifier(icon) {
  55. const tildeIndex = icon.id.lastIndexOf('~');
  56. if (tildeIndex !== -1) {
  57. return icon.id.substring(tildeIndex + 1);
  58. }
  59. return undefined;
  60. }
  61. ThemeIcon.getModifier = getModifier;
  62. function isEqual(ti1, ti2) {
  63. var _a, _b;
  64. return ti1.id === ti2.id && ((_a = ti1.color) === null || _a === void 0 ? void 0 : _a.id) === ((_b = ti2.color) === null || _b === void 0 ? void 0 : _b.id);
  65. }
  66. ThemeIcon.isEqual = isEqual;
  67. function asThemeIcon(codicon, color) {
  68. return { id: codicon.id, color: color ? themeColorFromId(color) : undefined };
  69. }
  70. ThemeIcon.asThemeIcon = asThemeIcon;
  71. ThemeIcon.asClassNameArray = CSSIcon.asClassNameArray;
  72. ThemeIcon.asClassName = CSSIcon.asClassName;
  73. ThemeIcon.asCSSSelector = CSSIcon.asCSSSelector;
  74. })(ThemeIcon || (ThemeIcon = {}));
  75. export function getThemeTypeSelector(type) {
  76. switch (type) {
  77. case ColorScheme.DARK: return 'vs-dark';
  78. case ColorScheme.HIGH_CONTRAST_DARK: return 'hc-black';
  79. case ColorScheme.HIGH_CONTRAST_LIGHT: return 'hc-light';
  80. default: return 'vs';
  81. }
  82. }
  83. // static theming participant
  84. export const Extensions = {
  85. ThemingContribution: 'base.contributions.theming'
  86. };
  87. class ThemingRegistry {
  88. constructor() {
  89. this.themingParticipants = [];
  90. this.themingParticipants = [];
  91. this.onThemingParticipantAddedEmitter = new Emitter();
  92. }
  93. onColorThemeChange(participant) {
  94. this.themingParticipants.push(participant);
  95. this.onThemingParticipantAddedEmitter.fire(participant);
  96. return toDisposable(() => {
  97. const idx = this.themingParticipants.indexOf(participant);
  98. this.themingParticipants.splice(idx, 1);
  99. });
  100. }
  101. getThemingParticipants() {
  102. return this.themingParticipants;
  103. }
  104. }
  105. const themingRegistry = new ThemingRegistry();
  106. platform.Registry.add(Extensions.ThemingContribution, themingRegistry);
  107. export function registerThemingParticipant(participant) {
  108. return themingRegistry.onColorThemeChange(participant);
  109. }
  110. /**
  111. * Utility base class for all themable components.
  112. */
  113. export class Themable extends Disposable {
  114. constructor(themeService) {
  115. super();
  116. this.themeService = themeService;
  117. this.theme = themeService.getColorTheme();
  118. // Hook up to theme changes
  119. this._register(this.themeService.onDidColorThemeChange(theme => this.onThemeChange(theme)));
  120. }
  121. onThemeChange(theme) {
  122. this.theme = theme;
  123. this.updateStyles();
  124. }
  125. updateStyles() {
  126. // Subclasses to override
  127. }
  128. }