77import URI from 'vs/base/common/uri' ;
88import Severity from 'vs/base/common/severity' ;
99import Event , { Emitter , debounceEvent , any } from 'vs/base/common/event' ;
10- import { IResourceDecorationsService , IResourceDecoration , IResourceDecorationChangeEvent , IDecorationsProvider } from './decorations' ;
10+ import { IResourceDecorationsService , IResourceDecoration , IResourceDecorationChangeEvent , IDecorationsProvider , IResourceDecorationData } from './decorations' ;
1111import { TernarySearchTree } from 'vs/base/common/map' ;
1212import { IDisposable , dispose } from 'vs/base/common/lifecycle' ;
1313import { isThenable } from 'vs/base/common/async' ;
@@ -17,6 +17,79 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
1717import { IdGenerator } from 'vs/base/common/idGenerator' ;
1818import { listActiveSelectionForeground , ColorIdentifier } from 'vs/platform/theme/common/colorRegistry' ;
1919
20+
21+ class DecorationColors {
22+
23+ private readonly _disposables : IDisposable [ ] ;
24+ private readonly _styleElement = createStyleSheet ( ) ;
25+ private readonly _classNames = new IdGenerator ( 'monaco-decoration-styles-' ) ;
26+ private readonly _classNames2ColorIds = new Map < string , [ string , string ] > ( ) ;
27+
28+ constructor (
29+ private _themeService : IThemeService ,
30+ ) {
31+ this . _disposables = [
32+ this . _themeService . onThemeChange ( this . _onThemeChange , this ) ,
33+ ] ;
34+ }
35+
36+ dispose ( ) : void {
37+ dispose ( this . _disposables ) ;
38+ this . _styleElement . innerHTML = '' ;
39+ }
40+
41+ makeResourceDecoration ( decoration : IResourceDecorationData ) : IResourceDecoration {
42+ if ( ! decoration ) {
43+ return undefined ;
44+ }
45+
46+ let { severity, letter, tooltip } = decoration ;
47+ let labelClassName , badgeClassName ;
48+
49+ let tuple = this . _classNames2ColorIds . get ( decoration . color ) ;
50+
51+ if ( tuple ) {
52+ // from cache
53+ labelClassName = tuple [ 0 ] ;
54+ badgeClassName = tuple [ 1 ] ;
55+ } else {
56+ // new css rules
57+ labelClassName = this . _classNames . nextId ( ) ;
58+ badgeClassName = this . _classNames . nextId ( ) ;
59+ this . _classNames2ColorIds . set ( decoration . color , [ labelClassName , badgeClassName ] ) ;
60+ this . _createCssRules ( labelClassName , badgeClassName , decoration . color ) ;
61+ }
62+
63+ return {
64+ _decoBrand : undefined ,
65+ severity,
66+ letter,
67+ tooltip,
68+ labelClassName,
69+ badgeClassName
70+ } ;
71+ }
72+
73+ private _onThemeChange ( ) : void {
74+ this . _classNames2ColorIds . forEach ( ( tuple , color ) => {
75+ const [ labelClassName , badgeClassName ] = tuple ;
76+ removeCSSRulesContainingSelector ( labelClassName , this . _styleElement ) ;
77+ removeCSSRulesContainingSelector ( badgeClassName , this . _styleElement ) ;
78+ this . _createCssRules ( labelClassName , badgeClassName , color ) ;
79+ } ) ;
80+ }
81+
82+ private _createCssRules ( labelClassName : string , badgeClassName : string , color : ColorIdentifier ) : void {
83+ const theme = this . _themeService . getTheme ( ) ;
84+ // label
85+ createCSSRule ( `.${ labelClassName } ` , `color: ${ theme . getColor ( color ) } ` , this . _styleElement ) ;
86+ createCSSRule ( `.selected .${ labelClassName } ` , `color: ${ theme . getColor ( listActiveSelectionForeground ) } ` , this . _styleElement ) ;
87+
88+ // badge
89+ createCSSRule ( `.${ badgeClassName } ` , `background-color: ${ theme . getColor ( color ) } ; color: ${ theme . getColor ( listActiveSelectionForeground ) } ;` , this . _styleElement ) ;
90+ }
91+ }
92+
2093class FileDecorationChangeEvent implements IResourceDecorationChangeEvent {
2194
2295 private readonly _data = TernarySearchTree . forPaths < boolean > ( ) ;
@@ -49,6 +122,7 @@ class DecorationProviderWrapper {
49122 private readonly _dispoable : IDisposable ;
50123
51124 constructor (
125+ private readonly _decorationStyles : DecorationColors ,
52126 private readonly _provider : IDecorationsProvider ,
53127 private readonly _emitter : Emitter < URI | URI [ ] >
54128 ) {
@@ -92,7 +166,7 @@ class DecorationProviderWrapper {
92166 const childTree = this . _data . findSuperstr ( key ) ;
93167 if ( childTree ) {
94168 childTree . forEach ( ( [ , value ] ) => {
95- if ( value && ! isThenable < void > ( value ) && ! value . leafOnly ) {
169+ if ( value && ! isThenable < void > ( value ) ) {
96170 callback ( value , true ) ;
97171 }
98172 } ) ;
@@ -102,88 +176,27 @@ class DecorationProviderWrapper {
102176
103177 private _fetchData ( uri : URI ) : IResourceDecoration {
104178
105- const decoOrThenable = this . _provider . provideDecorations ( uri ) ;
106- if ( ! isThenable ( decoOrThenable ) ) {
179+ const dataOrThenable = this . _provider . provideDecorations ( uri ) ;
180+ if ( ! isThenable ( dataOrThenable ) ) {
107181 // sync -> we have a result now
108- this . _data . set ( uri . toString ( ) , decoOrThenable || null ) ;
109- this . _emitter . fire ( uri ) ;
110- return decoOrThenable ;
182+ return this . _keepItem ( uri , dataOrThenable ) ;
111183
112184 } else {
113185 // async -> we have a result soon
114- const request = Promise . resolve ( decoOrThenable )
115- . then ( data => {
116- this . _data . set ( uri . toString ( ) , data || null ) ;
117- this . _emitter . fire ( uri ) ;
118- } )
186+ const request = Promise . resolve ( dataOrThenable )
187+ . then ( data => this . _keepItem ( uri , data ) )
119188 . catch ( _ => this . _data . delete ( uri . toString ( ) ) ) ;
120189
121190 this . _data . set ( uri . toString ( ) , request ) ;
122191 return undefined ;
123192 }
124193 }
125- }
126-
127- class DecorationColors {
128-
129- private readonly _disposables : IDisposable [ ] ;
130- private readonly _styleElement = createStyleSheet ( ) ;
131- private readonly _classNames = new IdGenerator ( 'monaco-decoration-styles-' ) ;
132- private readonly _classNames2ColorIds = new Map < string , [ string , string ] > ( ) ;
133-
134- constructor (
135- private _themeService : IThemeService ,
136- ) {
137- this . _disposables = [
138- this . _themeService . onThemeChange ( this . _onThemeChange , this ) ,
139- ] ;
140- }
141-
142- dispose ( ) : void {
143- dispose ( this . _disposables ) ;
144- this . _styleElement . innerHTML = '' ;
145- }
146-
147- ensureCssStyles ( decoration : IResourceDecoration ) : void {
148- if ( ! decoration || ! decoration . color ) {
149- return ;
150- }
151-
152- const tuple = this . _classNames2ColorIds . get ( decoration . color ) ;
153- if ( tuple ) {
154- // from cache
155- decoration . labelClasses = tuple [ 0 ] ;
156- decoration . badgeClassName = tuple [ 1 ] ;
157- return ;
158- }
159-
160- let labelClassName = this . _classNames . nextId ( ) ;
161- let badgeClassName = this . _classNames . nextId ( ) ;
162-
163- this . _classNames2ColorIds . set ( decoration . color , [ labelClassName , badgeClassName ] ) ;
164- decoration . labelClasses = labelClassName ;
165- decoration . badgeClassName = badgeClassName ;
166-
167- this . _createCssRules ( labelClassName , badgeClassName , decoration . color ) ;
168- }
169-
170- private _onThemeChange ( ) : void {
171- this . _classNames2ColorIds . forEach ( ( tuple , color ) => {
172- const [ labelClassName , badgeClassName ] = tuple ;
173- removeCSSRulesContainingSelector ( labelClassName , this . _styleElement ) ;
174- removeCSSRulesContainingSelector ( badgeClassName , this . _styleElement ) ;
175- this . _createCssRules ( labelClassName , badgeClassName , color ) ;
176- } ) ;
177- }
178194
179- private _createCssRules ( labelClassName : string , badgeClassName : string , color : ColorIdentifier ) : void {
180- const theme = this . _themeService . getTheme ( ) ;
181- // label
182- createCSSRule ( `.${ labelClassName } ` , `color: ${ theme . getColor ( color ) } ` , this . _styleElement ) ;
183- createCSSRule ( `.selected .${ labelClassName } ` , `color: ${ theme . getColor ( listActiveSelectionForeground ) } ` , this . _styleElement ) ;
184-
185- // badge
186- createCSSRule ( `.${ badgeClassName } ` , `background-color: ${ theme . getColor ( color ) } ; color: ${ theme . getColor ( listActiveSelectionForeground ) } ;` , this . _styleElement ) ;
195+ private _keepItem ( uri : URI , data : IResourceDecorationData ) : IResourceDecoration {
196+ let deco = data ? this . _decorationStyles . makeResourceDecoration ( data ) : null ;
197+ this . _data . set ( uri . toString ( ) , deco ) ;
198+ this . _emitter . fire ( uri ) ;
199+ return deco ;
187200 }
188201}
189202
@@ -216,7 +229,11 @@ export class FileDecorationsService implements IResourceDecorationsService {
216229
217230 registerDecortionsProvider ( provider : IDecorationsProvider ) : IDisposable {
218231
219- const wrapper = new DecorationProviderWrapper ( provider , this . _onDidChangeDecorationsDelayed ) ;
232+ const wrapper = new DecorationProviderWrapper (
233+ this . _decorationStyles ,
234+ provider ,
235+ this . _onDidChangeDecorationsDelayed
236+ ) ;
220237 const remove = this . _data . push ( wrapper ) ;
221238 return {
222239 dispose : ( ) => {
@@ -237,13 +254,13 @@ export class FileDecorationsService implements IResourceDecorationsService {
237254 if ( isChild && top === candidate ) {
238255 // only bubble up color
239256 top = {
257+ _decoBrand : undefined ,
240258 severity : top . severity ,
241- color : top . color
259+ labelClassName : top . labelClassName
242260 } ;
243261 }
244262 } ) ;
245263 }
246- this . _decorationStyles . ensureCssStyles ( top ) ;
247264 return top ;
248265 }
249266
0 commit comments