@opensumi/ide-theme 2.21.13 → 2.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/lib/browser/icon-theme-data.js.map +1 -1
  2. package/lib/browser/icon-theme-store.js.map +1 -1
  3. package/lib/browser/icon.service.d.ts +3 -1
  4. package/lib/browser/icon.service.d.ts.map +1 -1
  5. package/lib/browser/icon.service.js +56 -24
  6. package/lib/browser/icon.service.js.map +1 -1
  7. package/lib/browser/index.js.map +1 -1
  8. package/lib/browser/semantic-tokens-registry.js.map +1 -1
  9. package/lib/browser/style.service.js.map +1 -1
  10. package/lib/browser/theme-data.js +7 -7
  11. package/lib/browser/theme-data.js.map +1 -1
  12. package/lib/browser/theme-store.js.map +1 -1
  13. package/lib/browser/theme.contribution.js +3 -3
  14. package/lib/browser/theme.contribution.js.map +1 -1
  15. package/lib/browser/workbench.theme.service.js +2 -2
  16. package/lib/browser/workbench.theme.service.js.map +1 -1
  17. package/lib/common/color-tokens/basic-color.d.ts +1 -1
  18. package/lib/common/color-tokens/basic-color.d.ts.map +1 -1
  19. package/lib/common/color-tokens/editor.d.ts +13 -0
  20. package/lib/common/color-tokens/editor.d.ts.map +1 -1
  21. package/lib/common/color-tokens/editor.js +35 -1
  22. package/lib/common/color-tokens/editor.js.map +1 -1
  23. package/lib/common/color.js +40 -40
  24. package/lib/common/color.js.map +1 -1
  25. package/lib/common/mocks/theme.service.js.map +1 -1
  26. package/lib/common/plistParser.js +40 -40
  27. package/lib/common/plistParser.js.map +1 -1
  28. package/lib/common/semantic-tokens-registry.d.ts +7 -7
  29. package/lib/common/semantic-tokens-registry.d.ts.map +1 -1
  30. package/lib/common/theme.service.d.ts +26 -6
  31. package/lib/common/theme.service.d.ts.map +1 -1
  32. package/lib/common/theme.service.js.map +1 -1
  33. package/package.json +11 -10
  34. package/src/browser/default-theme.ts +547 -0
  35. package/src/browser/icon-theme-data.ts +294 -0
  36. package/src/browser/icon-theme-store.ts +38 -0
  37. package/src/browser/icon.less +15 -0
  38. package/src/browser/icon.service.ts +457 -0
  39. package/src/browser/index.ts +45 -0
  40. package/src/browser/semantic-tokens-registry.ts +217 -0
  41. package/src/browser/style.service.ts +51 -0
  42. package/src/browser/theme-data.ts +719 -0
  43. package/src/browser/theme-store.ts +95 -0
  44. package/src/browser/theme.contribution.ts +343 -0
  45. package/src/browser/workbench.theme.service.ts +703 -0
  46. package/src/common/color-registry.ts +52 -0
  47. package/src/common/color-tokens/activity-bar.ts +122 -0
  48. package/src/common/color-tokens/badge.ts +31 -0
  49. package/src/common/color-tokens/base.ts +90 -0
  50. package/src/common/color-tokens/basic-color.ts +9 -0
  51. package/src/common/color-tokens/breadcrumb.ts +60 -0
  52. package/src/common/color-tokens/button.ts +69 -0
  53. package/src/common/color-tokens/charts.ts +68 -0
  54. package/src/common/color-tokens/checkbox.ts +23 -0
  55. package/src/common/color-tokens/custom/actionbar.ts +51 -0
  56. package/src/common/color-tokens/custom/activity-bar.ts +16 -0
  57. package/src/common/color-tokens/custom/badge.ts +30 -0
  58. package/src/common/color-tokens/custom/base.ts +111 -0
  59. package/src/common/color-tokens/custom/button.ts +359 -0
  60. package/src/common/color-tokens/custom/checkbox.ts +36 -0
  61. package/src/common/color-tokens/custom/decoration.ts +71 -0
  62. package/src/common/color-tokens/custom/editor.ts +27 -0
  63. package/src/common/color-tokens/custom/extension.ts +9 -0
  64. package/src/common/color-tokens/custom/icon.ts +30 -0
  65. package/src/common/color-tokens/custom/index.ts +26 -0
  66. package/src/common/color-tokens/custom/input.ts +48 -0
  67. package/src/common/color-tokens/custom/menu.ts +61 -0
  68. package/src/common/color-tokens/custom/modal.ts +57 -0
  69. package/src/common/color-tokens/custom/notification.ts +16 -0
  70. package/src/common/color-tokens/custom/panel.ts +112 -0
  71. package/src/common/color-tokens/custom/popover.ts +28 -0
  72. package/src/common/color-tokens/custom/select.ts +155 -0
  73. package/src/common/color-tokens/custom/settings.ts +32 -0
  74. package/src/common/color-tokens/custom/statusbar.ts +16 -0
  75. package/src/common/color-tokens/custom/tab.ts +31 -0
  76. package/src/common/color-tokens/custom/tooltip.ts +55 -0
  77. package/src/common/color-tokens/custom/tree.ts +106 -0
  78. package/src/common/color-tokens/debug.ts +103 -0
  79. package/src/common/color-tokens/debugToolbar.ts +134 -0
  80. package/src/common/color-tokens/dropdown.ts +27 -0
  81. package/src/common/color-tokens/editor.ts +945 -0
  82. package/src/common/color-tokens/index.ts +35 -0
  83. package/src/common/color-tokens/input.ts +105 -0
  84. package/src/common/color-tokens/list-tree.ts +205 -0
  85. package/src/common/color-tokens/menu-bar.ts +43 -0
  86. package/src/common/color-tokens/menu.ts +53 -0
  87. package/src/common/color-tokens/merge-conflict.ts +145 -0
  88. package/src/common/color-tokens/minimap.ts +99 -0
  89. package/src/common/color-tokens/notification.ts +169 -0
  90. package/src/common/color-tokens/panel.ts +177 -0
  91. package/src/common/color-tokens/pick-view.ts +96 -0
  92. package/src/common/color-tokens/picker.ts +15 -0
  93. package/src/common/color-tokens/progress-bar.ts +12 -0
  94. package/src/common/color-tokens/quick-input.ts +57 -0
  95. package/src/common/color-tokens/scrollbar.ts +42 -0
  96. package/src/common/color-tokens/settings.ts +126 -0
  97. package/src/common/color-tokens/sidebar.ts +121 -0
  98. package/src/common/color-tokens/snippet.ts +33 -0
  99. package/src/common/color-tokens/status-bar.ts +350 -0
  100. package/src/common/color-tokens/tab.ts +346 -0
  101. package/src/common/color-tokens/testing.ts +105 -0
  102. package/src/common/color-tokens/text.ts +41 -0
  103. package/src/common/color-tokens/title-bar.ts +62 -0
  104. package/src/common/color-tokens/toolbar.ts +28 -0
  105. package/src/common/color-tokens/welcome-page.ts +27 -0
  106. package/src/common/color.ts +647 -0
  107. package/src/common/default-themes.ts +273 -0
  108. package/src/common/event.ts +9 -0
  109. package/src/common/index.ts +8 -0
  110. package/src/common/mocks/theme.service.ts +55 -0
  111. package/src/common/plistParser.ts +525 -0
  112. package/src/common/semantic-tokens-registry.ts +439 -0
  113. package/src/common/style.ts +9 -0
  114. package/src/common/theme.service.ts +363 -0
  115. package/src/common/themeCompatibility.ts +95 -0
  116. package/src/common/utils.ts +195 -0
  117. package/src/index.ts +1 -0
@@ -0,0 +1,294 @@
1
+ import { Injectable, Autowired } from '@opensumi/di';
2
+ import { getDebugLogger, URI, parseWithComments, formatLocalize } from '@opensumi/ide-core-browser';
3
+ import { IFileServiceClient } from '@opensumi/ide-file-service';
4
+ import { StaticResourceService } from '@opensumi/ide-static-resource/lib/browser';
5
+
6
+ import { IIconTheme } from '../common';
7
+
8
+ @Injectable({ multiple: true })
9
+ export class IconThemeData implements IIconTheme {
10
+ hasFileIcons: boolean;
11
+ hasFolderIcons: boolean;
12
+ hidesExplorerArrows: boolean;
13
+ styleSheetContent: string;
14
+
15
+ @Autowired(IFileServiceClient)
16
+ private readonly fileServiceClient: IFileServiceClient;
17
+
18
+ @Autowired()
19
+ private readonly staticResourceService: StaticResourceService;
20
+
21
+ async load(location: URI) {
22
+ const ret = await this.fileServiceClient.readFile(location.toString());
23
+ let contentValue = {} as IconThemeDocument;
24
+ try {
25
+ contentValue = parseWithComments<IconThemeDocument>(ret.content.toString());
26
+ } catch (error) {
27
+ getDebugLogger().log(formatLocalize('error.cannotparseicontheme', location.codeUri.fsPath));
28
+ }
29
+
30
+ const result = processIconThemeDocument(location, contentValue, this.staticResourceService);
31
+ this.hasFileIcons = result.hasFileIcons;
32
+ this.hasFolderIcons = result.hasFolderIcons;
33
+ this.hidesExplorerArrows = result.hidesExplorerArrows;
34
+ this.styleSheetContent = result.content;
35
+ return result.content;
36
+ }
37
+ }
38
+
39
+ // tslint:disable: forin
40
+ interface IconDefinition {
41
+ iconPath: string;
42
+ fontColor: string;
43
+ fontCharacter: string;
44
+ fontSize: string;
45
+ fontId: string;
46
+ }
47
+
48
+ interface FontDefinition {
49
+ id: string;
50
+ weight: string;
51
+ style: string;
52
+ size: string;
53
+ src: { path: string; format: string }[];
54
+ }
55
+
56
+ // 图标名与图标定义的映射关系
57
+ interface IconsAssociation {
58
+ folder?: string;
59
+ file?: string;
60
+ folderExpanded?: string;
61
+ rootFolder?: string;
62
+ rootFolderExpanded?: string;
63
+ folderNames?: { [folderName: string]: string };
64
+ folderNamesExpanded?: { [folderName: string]: string };
65
+ fileExtensions?: { [extension: string]: string };
66
+ fileNames?: { [fileName: string]: string };
67
+ languageIds?: { [languageId: string]: string };
68
+ }
69
+
70
+ interface IconThemeDocument extends IconsAssociation {
71
+ iconDefinitions: { [key: string]: IconDefinition };
72
+ fonts: FontDefinition[];
73
+ light?: IconsAssociation;
74
+ highContrast?: IconsAssociation;
75
+ hidesExplorerArrows?: boolean;
76
+ }
77
+
78
+ /**
79
+ * 将图标配置信息转成 CSS
80
+ * @param iconThemeDocumentLocation
81
+ * @param iconThemeDocument
82
+ */
83
+ function processIconThemeDocument(
84
+ iconThemeDocumentLocation: URI,
85
+ iconThemeDocument: IconThemeDocument,
86
+ staticResourceService: StaticResourceService,
87
+ ): { content: string; hasFileIcons: boolean; hasFolderIcons: boolean; hidesExplorerArrows: boolean } {
88
+ const result = {
89
+ content: '',
90
+ hasFileIcons: false,
91
+ hasFolderIcons: false,
92
+ hidesExplorerArrows: !!iconThemeDocument.hidesExplorerArrows,
93
+ };
94
+
95
+ if (!iconThemeDocument.iconDefinitions) {
96
+ return result;
97
+ }
98
+ const selectorByDefinitionId: { [def: string]: string[] } = {};
99
+
100
+ function resolvePath(path: string) {
101
+ const targetPath = iconThemeDocumentLocation.path.dir.join(path.replace(/^\.\//, ''));
102
+ const targetLocation = iconThemeDocumentLocation.withPath(targetPath);
103
+ if (iconThemeDocumentLocation.scheme === 'https') {
104
+ return targetLocation.toString();
105
+ }
106
+ // file 协议的需要走 static-resource
107
+ return staticResourceService.resolveStaticResource(targetLocation);
108
+ }
109
+
110
+ /**
111
+ * 将图标关联关系转成css选择器数组,支持主题的light、hc传入
112
+ * @param associations
113
+ * @param baseThemeClassName
114
+ */
115
+ function collectSelectors(associations: IconsAssociation | undefined, baseThemeClassName?: string) {
116
+ // 将定义的图标名插入对应的选择器列表
117
+ function addSelector(selector: string, defId: string) {
118
+ if (defId) {
119
+ let list = selectorByDefinitionId[defId];
120
+ if (!list) {
121
+ list = selectorByDefinitionId[defId] = [];
122
+ }
123
+ list.push(selector);
124
+ }
125
+ }
126
+ if (associations) {
127
+ let qualifier = '.show-file-icons';
128
+ if (baseThemeClassName) {
129
+ qualifier = baseThemeClassName + ' ' + qualifier;
130
+ }
131
+
132
+ if (associations.folder) {
133
+ addSelector(`${qualifier} .folder-icon::before`, associations.folder);
134
+ result.hasFolderIcons = true;
135
+ }
136
+
137
+ if (associations.folderExpanded) {
138
+ addSelector(`${qualifier} .folder-icon.expanded::before`, associations.folderExpanded);
139
+ result.hasFolderIcons = true;
140
+ }
141
+
142
+ const rootFolder = associations.rootFolder || associations.folder;
143
+ const rootFolderExpanded = associations.rootFolderExpanded || associations.folderExpanded;
144
+
145
+ if (rootFolder) {
146
+ addSelector(`${qualifier} .rootfolder-icon::before`, rootFolder);
147
+ result.hasFolderIcons = true;
148
+ }
149
+
150
+ if (rootFolderExpanded) {
151
+ addSelector(`${qualifier} .rootfolder-icon.expanded::before`, rootFolderExpanded);
152
+ result.hasFolderIcons = true;
153
+ }
154
+
155
+ if (associations.file) {
156
+ addSelector(`${qualifier} .file-icon::before`, associations.file);
157
+ result.hasFileIcons = true;
158
+ }
159
+
160
+ const folderNames = associations.folderNames;
161
+ if (folderNames) {
162
+ // eslint-disable-next-line guard-for-in
163
+ for (const folderName in folderNames) {
164
+ addSelector(
165
+ `${qualifier} .${escapeCSS(folderName.toLowerCase())}-name-folder-icon.folder-icon::before`,
166
+ folderNames[folderName],
167
+ );
168
+ result.hasFolderIcons = true;
169
+ }
170
+ }
171
+ const folderNamesExpanded = associations.folderNamesExpanded;
172
+ if (folderNamesExpanded) {
173
+ // eslint-disable-next-line guard-for-in
174
+ for (const folderName in folderNamesExpanded) {
175
+ addSelector(
176
+ `${qualifier} .${escapeCSS(folderName.toLowerCase())}-name-folder-icon.folder-icon.expanded::before`,
177
+ folderNamesExpanded[folderName],
178
+ );
179
+ result.hasFolderIcons = true;
180
+ }
181
+ }
182
+
183
+ const languageIds = associations.languageIds;
184
+ if (languageIds) {
185
+ if (!languageIds.jsonc && languageIds.json) {
186
+ languageIds.jsonc = languageIds.json;
187
+ }
188
+ // eslint-disable-next-line guard-for-in
189
+ for (const languageId in languageIds) {
190
+ addSelector(
191
+ `${qualifier} .${escapeCSS(languageId)}-lang-file-icon.file-icon::before`,
192
+ languageIds[languageId],
193
+ );
194
+ result.hasFileIcons = true;
195
+ }
196
+ }
197
+ const fileExtensions = associations.fileExtensions;
198
+ if (fileExtensions) {
199
+ // eslint-disable-next-line guard-for-in
200
+ for (const fileExtension in fileExtensions) {
201
+ const selectors: string[] = [];
202
+ const segments = fileExtension.toLowerCase().split('.');
203
+ if (segments.length) {
204
+ for (let i = 0; i < segments.length; i++) {
205
+ selectors.push(`.${escapeCSS(segments.slice(i).join('.'))}-ext-file-icon`);
206
+ }
207
+ selectors.push('.ext-file-icon'); // extra segment to increase file-ext score
208
+ }
209
+ addSelector(`${qualifier} ${selectors.join('')}.file-icon::before`, fileExtensions[fileExtension]);
210
+ result.hasFileIcons = true;
211
+ }
212
+ }
213
+ const fileNames = associations.fileNames;
214
+ if (fileNames) {
215
+ // eslint-disable-next-line guard-for-in
216
+ for (let fileName in fileNames) {
217
+ const selectors: string[] = [];
218
+ fileName = fileName.toLowerCase();
219
+ selectors.push(`.${escapeCSS(fileName)}-name-file-icon`);
220
+ const segments = fileName.split('.');
221
+ if (segments.length) {
222
+ for (let i = 1; i < segments.length; i++) {
223
+ selectors.push(`.${escapeCSS(segments.slice(i).join('.'))}-ext-file-icon`);
224
+ }
225
+ selectors.push('.ext-file-icon'); // extra segment to increase file-ext score
226
+ }
227
+ addSelector(`${qualifier} ${selectors.join('')}.file-icon::before`, fileNames[fileName]);
228
+ result.hasFileIcons = true;
229
+ }
230
+ }
231
+ }
232
+ }
233
+ collectSelectors(iconThemeDocument);
234
+ collectSelectors(iconThemeDocument.light, '.vs');
235
+ collectSelectors(iconThemeDocument.highContrast, '.hc-black');
236
+ collectSelectors(iconThemeDocument.highContrast, '.hc-light');
237
+
238
+ if (!result.hasFileIcons && !result.hasFolderIcons) {
239
+ return result;
240
+ }
241
+
242
+ const cssRules: string[] = [];
243
+
244
+ const fonts = iconThemeDocument.fonts;
245
+ if (Array.isArray(fonts)) {
246
+ fonts.forEach((font) => {
247
+ const src = font.src.map((l) => `url('${resolvePath(l.path)}') format('${l.format}')`).join(', ');
248
+ cssRules.push(
249
+ `@font-face { src: ${src}; font-family: '${font.id}'; font-weight: ${font.weight}; font-style: ${font.style}; }`,
250
+ );
251
+ });
252
+ cssRules.push(
253
+ `.show-file-icons .file-icon::before, .show-file-icons .folder-icon::before, .show-file-icons .rootfolder-icon::before { font-family: '${
254
+ fonts[0].id
255
+ }'; font-size: ${fonts[0].size || '150%'}}`,
256
+ );
257
+ }
258
+
259
+ // eslint-disable-next-line guard-for-in
260
+ for (const defId in selectorByDefinitionId) {
261
+ const selectors = selectorByDefinitionId[defId];
262
+ const definition = iconThemeDocument.iconDefinitions[defId];
263
+ if (definition) {
264
+ if (definition.iconPath) {
265
+ cssRules.push(
266
+ `${selectors.join(', ')} { content: ' '; background-image: url("${resolvePath(definition.iconPath)}"); }`,
267
+ );
268
+ }
269
+ if (definition.fontCharacter || definition.fontColor) {
270
+ let body = '';
271
+ if (definition.fontColor) {
272
+ body += ` color: ${definition.fontColor};`;
273
+ }
274
+ if (definition.fontCharacter) {
275
+ body += ` content: '${definition.fontCharacter}';`;
276
+ }
277
+ if (definition.fontSize) {
278
+ body += ` font-size: ${definition.fontSize};`;
279
+ }
280
+ if (definition.fontId) {
281
+ body += ` font-family: ${definition.fontId};`;
282
+ }
283
+ cssRules.push(`${selectors.join(', ')} { ${body} }`);
284
+ }
285
+ }
286
+ }
287
+ result.content = cssRules.join('\n');
288
+ return result;
289
+ }
290
+
291
+ function escapeCSS(str: string) {
292
+ str = str.replace(/[\11\12\14\15\40]/g, '/'); // HTML class names can not contain certain whitespace characters, use / instead, which doesn't exist in file names.
293
+ return window.CSS.escape(str);
294
+ }
@@ -0,0 +1,38 @@
1
+ import { Injectable, Autowired, INJECTOR_TOKEN, Injector } from '@opensumi/di';
2
+ import { URI } from '@opensumi/ide-core-common';
3
+
4
+ import { IIconTheme, ThemeContribution, getThemeId } from '../common';
5
+
6
+ import { IconThemeData } from './icon-theme-data';
7
+
8
+ @Injectable()
9
+ export class IconThemeStore {
10
+ @Autowired(INJECTOR_TOKEN)
11
+ injector: Injector;
12
+
13
+ private iconThemeMap: Map<string, IIconTheme> = new Map();
14
+
15
+ async getIconTheme(contribution?: ThemeContribution, basePath?: URI): Promise<IIconTheme | undefined> {
16
+ if (!contribution || !basePath) {
17
+ return;
18
+ }
19
+ const id = getThemeId(contribution);
20
+ const cachedTheme = this.iconThemeMap.get(id);
21
+ if (cachedTheme) {
22
+ return cachedTheme;
23
+ }
24
+ const iconTheme = await this.initIconTheme(contribution, basePath);
25
+ this.iconThemeMap.set(id, iconTheme);
26
+ return iconTheme;
27
+ }
28
+
29
+ protected async initIconTheme(contribution: ThemeContribution, basePath: URI): Promise<IconThemeData> {
30
+ const contributedPath = contribution.path.replace(/^\.\//, '');
31
+ // http 的不作支持
32
+ const themeLocation = basePath.resolve(contributedPath);
33
+
34
+ const iconThemeData = this.injector.get(IconThemeData);
35
+ await iconThemeData.load(themeLocation);
36
+ return iconThemeData;
37
+ }
38
+ }
@@ -0,0 +1,15 @@
1
+ .kaitian-icon {
2
+ // 背景和 mask 模式,需要设置元素的默认宽高,否则不会显示
3
+ &.background-mode,
4
+ &.mask-mode {
5
+ width: 16px;
6
+ height: 16px;
7
+ line-height: 16px;
8
+ }
9
+ &.mask-mode {
10
+ // mask 模式下也需要指定大小
11
+ -webkit-mask-size: 16px;
12
+ // 默认颜色未当前前景色
13
+ background: currentColor;
14
+ }
15
+ }