@@ -14,12 +14,13 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
1414import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems' ;
1515import { IAction } from 'vs/base/common/actions' ;
1616
17- const codeSettingRegex = / ^ < s p a n c o d e s e t t i n g = " ( [ ^ \s " \: ] + ) (?: : ( [ ^ \s " ] + ) ) ? " > / ;
17+ const codeSettingRegex = / ^ < s p a n ( c o d e s e t t i n g | c o d e f e a t u r e ) = " ( [ ^ \s " \: ] + ) (?: : ( [ ^ \s " ] + ) ) ? " > / ;
1818
1919export class SimpleSettingRenderer {
2020 private _defaultSettings : DefaultSettings ;
2121 private _updatedSettings = new Map < string , any > ( ) ; // setting ID to user's original setting value
2222 private _encounteredSettings = new Map < string , ISetting > ( ) ; // setting ID to setting
23+ private _featuredSettings = new Map < string , any > ( ) ; // setting ID to feature value
2324
2425 constructor (
2526 @IConfigurationService private readonly _configurationService : IConfigurationService ,
@@ -29,12 +30,20 @@ export class SimpleSettingRenderer {
2930 this . _defaultSettings = new DefaultSettings ( [ ] , ConfigurationTarget . USER ) ;
3031 }
3132
33+ get featuredSettingStates ( ) : Map < string , boolean > {
34+ const result = new Map < string , boolean > ( ) ;
35+ for ( const [ settingId , value ] of this . _featuredSettings ) {
36+ result . set ( settingId , this . _configurationService . getValue ( settingId ) === value ) ;
37+ }
38+ return result ;
39+ }
40+
3241 getHtmlRenderer ( ) : ( html : string ) => string {
3342 return ( html ) : string => {
3443 const match = codeSettingRegex . exec ( html ) ;
35- if ( match && match . length === 3 ) {
36- const settingId = match [ 1 ] ;
37- const rendered = this . render ( settingId , match [ 2 ] ) ;
44+ if ( match && match . length === 4 ) {
45+ const settingId = match [ 2 ] ;
46+ const rendered = this . render ( settingId , match [ 3 ] , match [ 1 ] === 'codefeature' ) ;
3847 if ( rendered ) {
3948 html = html . replace ( codeSettingRegex , rendered ) ;
4049 }
@@ -47,6 +56,10 @@ export class SimpleSettingRenderer {
4756 return `${ Schemas . codeSetting } ://${ settingId } ${ value ? `/${ value } ` : '' } ` ;
4857 }
4958
59+ featureToUriString ( settingId : string , value ?: any ) : string {
60+ return `${ Schemas . codeFeature } ://${ settingId } ${ value ? `/${ value } ` : '' } ` ;
61+ }
62+
5063 private settingsGroups : ISettingsGroup [ ] | undefined = undefined ;
5164 private getSetting ( settingId : string ) : ISetting | undefined {
5265 if ( ! this . settingsGroups ) {
@@ -69,7 +82,7 @@ export class SimpleSettingRenderer {
6982 }
7083
7184 parseValue ( settingId : string , value : string ) : any {
72- if ( value === 'undefined' ) {
85+ if ( value === 'undefined' || value === '' ) {
7386 return undefined ;
7487 }
7588 const setting = this . getSetting ( settingId ) ;
@@ -88,13 +101,16 @@ export class SimpleSettingRenderer {
88101 }
89102 }
90103
91- private render ( settingId : string , newValue : string ) : string | undefined {
104+ private render ( settingId : string , newValue : string , asFeature : boolean ) : string | undefined {
92105 const setting = this . getSetting ( settingId ) ;
93106 if ( ! setting ) {
94107 return '' ;
95108 }
96-
97- return this . renderSetting ( setting , newValue ) ;
109+ if ( asFeature ) {
110+ return this . renderFeature ( setting , newValue ) ;
111+ } else {
112+ return this . renderSetting ( setting , newValue ) ;
113+ }
98114 }
99115
100116 private viewInSettingsMessage ( settingId : string , alreadyDisplayed : boolean ) {
@@ -149,7 +165,16 @@ export class SimpleSettingRenderer {
149165 private renderSetting ( setting : ISetting , newValue : string | undefined ) : string | undefined {
150166 const href = this . settingToUriString ( setting . key , newValue ) ;
151167 const title = nls . localize ( 'changeSettingTitle' , "Try feature" ) ;
152- return `<span><a href="${ href } " class="codesetting" title="${ title } " aria-rol="button"><svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path d="M9.1 4.4L8.6 2H7.4l-.5 2.4-.7.3-2-1.3-.9.8 1.3 2-.2.7-2.4.5v1.2l2.4.5.3.8-1.3 2 .8.8 2-1.3.8.3.4 2.3h1.2l.5-2.4.8-.3 2 1.3.8-.8-1.3-2 .3-.8 2.3-.4V7.4l-2.4-.5-.3-.8 1.3-2-.8-.8-2 1.3-.7-.2zM9.4 1l.5 2.4L12 2.1l2 2-1.4 2.1 2.4.4v2.8l-2.4.5L14 12l-2 2-2.1-1.4-.5 2.4H6.6l-.5-2.4L4 13.9l-2-2 1.4-2.1L1 9.4V6.6l2.4-.5L2.1 4l2-2 2.1 1.4.4-2.4h2.8zm.6 7c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zM8 9c.6 0 1-.4 1-1s-.4-1-1-1-1 .4-1 1 .4 1 1 1z"/></svg></a>` ;
168+ return `<span><a href="${ href } " class="codesetting" title="${ title } " aria-role="button"><svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path d="M9.1 4.4L8.6 2H7.4l-.5 2.4-.7.3-2-1.3-.9.8 1.3 2-.2.7-2.4.5v1.2l2.4.5.3.8-1.3 2 .8.8 2-1.3.8.3.4 2.3h1.2l.5-2.4.8-.3 2 1.3.8-.8-1.3-2 .3-.8 2.3-.4V7.4l-2.4-.5-.3-.8 1.3-2-.8-.8-2 1.3-.7-.2zM9.4 1l.5 2.4L12 2.1l2 2-1.4 2.1 2.4.4v2.8l-2.4.5L14 12l-2 2-2.1-1.4-.5 2.4H6.6l-.5-2.4L4 13.9l-2-2 1.4-2.1L1 9.4V6.6l2.4-.5L2.1 4l2-2 2.1 1.4.4-2.4h2.8zm.6 7c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zM8 9c.6 0 1-.4 1-1s-.4-1-1-1-1 .4-1 1 .4 1 1 1z"/></svg></a>` ;
169+ }
170+
171+ private renderFeature ( setting : ISetting , newValue : string ) : string | undefined {
172+ const href = this . featureToUriString ( setting . key , newValue ) ;
173+ const parsedValue = this . parseValue ( setting . key , newValue ) ;
174+ const isChecked = this . _configurationService . getValue ( setting . key ) === parsedValue ;
175+ this . _featuredSettings . set ( setting . key , parsedValue ) ;
176+ const title = nls . localize ( 'changeFeatureTitle' , "Toggle feature with setting {0}" , setting . key ) ;
177+ return `<span><div class="codefeature-container"><input id="${ setting . key } " class="hiddenCheck" type="checkbox" ${ isChecked ? 'checked' : '' } ><span class="codefeature"><a href="${ href } " class="toggle" title="${ title } " role="checkbox" aria-checked="${ isChecked ? 'true' : 'false' } "></a></span><span class="title"></span></div>` ;
153178 }
154179
155180 private getSettingMessage ( setting : ISetting , newValue : boolean | string | number ) : string | undefined {
@@ -185,7 +210,7 @@ export class SimpleSettingRenderer {
185210 const newSettingValue = this . parseValue ( uri . authority , uri . path . substring ( 1 ) ) ;
186211 const currentSettingValue = this . _configurationService . inspect ( settingId ) . userValue ;
187212
188- if ( newSettingValue && newSettingValue === currentSettingValue && this . _updatedSettings . has ( settingId ) ) {
213+ if ( ( newSettingValue !== undefined ) && newSettingValue === currentSettingValue && this . _updatedSettings . has ( settingId ) ) {
189214 const restoreMessage = this . restorePreviousSettingMessage ( settingId ) ;
190215 actions . push ( {
191216 class : undefined ,
@@ -197,7 +222,7 @@ export class SimpleSettingRenderer {
197222 return this . restoreSetting ( settingId ) ;
198223 }
199224 } ) ;
200- } else if ( newSettingValue ) {
225+ } else if ( newSettingValue !== undefined ) {
201226 const setting = this . getSetting ( settingId ) ;
202227 const trySettingMessage = setting ? this . getSettingMessage ( setting , newSettingValue ) : undefined ;
203228
@@ -230,7 +255,7 @@ export class SimpleSettingRenderer {
230255 return actions ;
231256 }
232257
233- async updateSetting ( uri : URI , x : number , y : number ) {
258+ private showContextMenu ( uri : URI , x : number , y : number ) {
234259 const actions = this . getActions ( uri ) ;
235260 if ( ! actions ) {
236261 return ;
@@ -244,4 +269,27 @@ export class SimpleSettingRenderer {
244269 } ,
245270 } ) ;
246271 }
272+
273+ private async setFeatureState ( uri : URI ) {
274+ const settingId = uri . authority ;
275+ const newSettingValue = this . parseValue ( uri . authority , uri . path . substring ( 1 ) ) ;
276+ let valueToSetSetting : any ;
277+ if ( this . _updatedSettings . has ( settingId ) ) {
278+ valueToSetSetting = this . _updatedSettings . get ( settingId ) ;
279+ this . _updatedSettings . delete ( settingId ) ;
280+ } else if ( newSettingValue !== this . _configurationService . getValue ( settingId ) ) {
281+ valueToSetSetting = newSettingValue ;
282+ } else {
283+ valueToSetSetting = undefined ;
284+ }
285+ await this . _configurationService . updateValue ( settingId , valueToSetSetting , ConfigurationTarget . USER ) ;
286+ }
287+
288+ async updateSetting ( uri : URI , x : number , y : number ) {
289+ if ( uri . scheme === Schemas . codeSetting ) {
290+ return this . showContextMenu ( uri , x , y ) ;
291+ } else if ( uri . scheme === Schemas . codeFeature ) {
292+ return this . setFeatureState ( uri ) ;
293+ }
294+ }
247295}
0 commit comments