@@ -14,31 +14,101 @@ import { IModelDecorationOptions, IModelDecorationOverviewRulerOptions, Overview
1414import { IResourceInput } from 'vs/platform/editor/common/editor' ;
1515import { ITheme , IThemeService , ThemeColor } from 'vs/platform/theme/common/themeService' ;
1616
17+ class RefCountedStyleSheet {
18+
19+ private readonly _parent : CodeEditorServiceImpl ;
20+ private readonly _editorId : string ;
21+ public readonly styleSheet : HTMLStyleElement ;
22+ private _refCount : number ;
23+
24+ constructor ( parent : CodeEditorServiceImpl , editorId : string , styleSheet : HTMLStyleElement ) {
25+ this . _parent = parent ;
26+ this . _editorId = editorId ;
27+ this . styleSheet = styleSheet ;
28+ this . _refCount = 0 ;
29+ }
30+
31+ public ref ( ) : void {
32+ this . _refCount ++ ;
33+ }
34+
35+ public unref ( ) : void {
36+ this . _refCount -- ;
37+ if ( this . _refCount === 0 ) {
38+ this . styleSheet . parentNode ?. removeChild ( this . styleSheet ) ;
39+ this . _parent . _removeEditorStyleSheets ( this . _editorId ) ;
40+ }
41+ }
42+ }
43+
44+ class GlobalStyleSheet {
45+ public readonly styleSheet : HTMLStyleElement ;
46+
47+ constructor ( styleSheet : HTMLStyleElement ) {
48+ this . styleSheet = styleSheet ;
49+ }
50+
51+ public ref ( ) : void {
52+ }
53+
54+ public unref ( ) : void {
55+ }
56+ }
57+
1758export abstract class CodeEditorServiceImpl extends AbstractCodeEditorService {
1859
19- private readonly _styleSheet : HTMLStyleElement ;
60+ private _globalStyleSheet : GlobalStyleSheet | null ;
2061 private readonly _decorationOptionProviders = new Map < string , IModelDecorationOptionsProvider > ( ) ;
62+ private readonly _editorStyleSheets = new Map < string , RefCountedStyleSheet > ( ) ;
2163 private readonly _themeService : IThemeService ;
2264
23- constructor ( @IThemeService themeService : IThemeService , styleSheet = dom . createStyleSheet ( ) ) {
65+ constructor ( @IThemeService themeService : IThemeService , styleSheet : HTMLStyleElement | null = null ) {
2466 super ( ) ;
25- this . _styleSheet = styleSheet ;
67+ this . _globalStyleSheet = styleSheet ? new GlobalStyleSheet ( styleSheet ) : null ;
2668 this . _themeService = themeService ;
2769 }
2870
29- public registerDecorationType ( key : string , options : IDecorationRenderOptions , parentTypeKey ?: string ) : void {
71+ private _getOrCreateGlobalStyleSheet ( ) : GlobalStyleSheet {
72+ if ( ! this . _globalStyleSheet ) {
73+ this . _globalStyleSheet = new GlobalStyleSheet ( dom . createStyleSheet ( ) ) ;
74+ }
75+ return this . _globalStyleSheet ;
76+ }
77+
78+ private _getOrCreateStyleSheet ( editor : ICodeEditor | undefined ) : GlobalStyleSheet | RefCountedStyleSheet {
79+ if ( ! editor ) {
80+ return this . _getOrCreateGlobalStyleSheet ( ) ;
81+ }
82+ const domNode = editor . getContainerDomNode ( ) ;
83+ if ( ! dom . isInShadowDOM ( domNode ) ) {
84+ return this . _getOrCreateGlobalStyleSheet ( ) ;
85+ }
86+ const editorId = editor . getId ( ) ;
87+ if ( ! this . _editorStyleSheets . has ( editorId ) ) {
88+ const refCountedStyleSheet = new RefCountedStyleSheet ( this , editorId , dom . createStyleSheet ( domNode ) ) ;
89+ this . _editorStyleSheets . set ( editorId , refCountedStyleSheet ) ;
90+ }
91+ return this . _editorStyleSheets . get ( editorId ) ! ;
92+ }
93+
94+ _removeEditorStyleSheets ( editorId : string ) : void {
95+ this . _editorStyleSheets . delete ( editorId ) ;
96+ }
97+
98+ public registerDecorationType ( key : string , options : IDecorationRenderOptions , parentTypeKey ?: string , editor ?: ICodeEditor ) : void {
3099 let provider = this . _decorationOptionProviders . get ( key ) ;
31100 if ( ! provider ) {
101+ const styleSheet = this . _getOrCreateStyleSheet ( editor ) ;
32102 const providerArgs : ProviderArguments = {
33- styleSheet : this . _styleSheet ,
103+ styleSheet : styleSheet . styleSheet ,
34104 key : key ,
35105 parentTypeKey : parentTypeKey ,
36106 options : options || Object . create ( null )
37107 } ;
38108 if ( ! parentTypeKey ) {
39- provider = new DecorationTypeOptionsProvider ( this . _themeService , providerArgs ) ;
109+ provider = new DecorationTypeOptionsProvider ( this . _themeService , styleSheet , providerArgs ) ;
40110 } else {
41- provider = new DecorationSubTypeOptionsProvider ( this . _themeService , providerArgs ) ;
111+ provider = new DecorationSubTypeOptionsProvider ( this . _themeService , styleSheet , providerArgs ) ;
42112 }
43113 this . _decorationOptionProviders . set ( key , provider ) ;
44114 }
@@ -76,13 +146,16 @@ interface IModelDecorationOptionsProvider extends IDisposable {
76146
77147class DecorationSubTypeOptionsProvider implements IModelDecorationOptionsProvider {
78148
149+ private readonly _styleSheet : GlobalStyleSheet | RefCountedStyleSheet ;
79150 public refCount : number ;
80151
81152 private readonly _parentTypeKey : string | undefined ;
82153 private _beforeContentRules : DecorationCSSRules | null ;
83154 private _afterContentRules : DecorationCSSRules | null ;
84155
85- constructor ( themeService : IThemeService , providerArgs : ProviderArguments ) {
156+ constructor ( themeService : IThemeService , styleSheet : GlobalStyleSheet | RefCountedStyleSheet , providerArgs : ProviderArguments ) {
157+ this . _styleSheet = styleSheet ;
158+ this . _styleSheet . ref ( ) ;
86159 this . _parentTypeKey = providerArgs . parentTypeKey ;
87160 this . refCount = 0 ;
88161
@@ -110,6 +183,7 @@ class DecorationSubTypeOptionsProvider implements IModelDecorationOptionsProvide
110183 this . _afterContentRules . dispose ( ) ;
111184 this . _afterContentRules = null ;
112185 }
186+ this . _styleSheet . unref ( ) ;
113187 }
114188}
115189
@@ -124,6 +198,7 @@ interface ProviderArguments {
124198class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
125199
126200 private readonly _disposables = new DisposableStore ( ) ;
201+ private readonly _styleSheet : GlobalStyleSheet | RefCountedStyleSheet ;
127202 public refCount : number ;
128203
129204 public className : string | undefined ;
@@ -136,7 +211,9 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
136211 public overviewRuler : IModelDecorationOverviewRulerOptions | undefined ;
137212 public stickiness : TrackedRangeStickiness | undefined ;
138213
139- constructor ( themeService : IThemeService , providerArgs : ProviderArguments ) {
214+ constructor ( themeService : IThemeService , styleSheet : GlobalStyleSheet | RefCountedStyleSheet , providerArgs : ProviderArguments ) {
215+ this . _styleSheet = styleSheet ;
216+ this . _styleSheet . ref ( ) ;
140217 this . refCount = 0 ;
141218
142219 const createCSSRules = ( type : ModelDecorationCSSRuleType ) => {
@@ -202,6 +279,7 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
202279
203280 public dispose ( ) : void {
204281 this . _disposables . dispose ( ) ;
282+ this . _styleSheet . unref ( ) ;
205283 }
206284}
207285
0 commit comments