Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
fc877755
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
fc877755
编写于
12月 10, 2019
作者:
M
Marvin Heilemann
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Rolled back changes to better see my changes (thanks to wrong configured prettier)
上级
256f2e09
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
94 addition
and
346 deletion
+94
-346
src/vs/workbench/services/themes/browser/workbenchThemeService.ts
...orkbench/services/themes/browser/workbenchThemeService.ts
+88
-314
src/vs/workbench/services/themes/common/workbenchThemeService.ts
...workbench/services/themes/common/workbenchThemeService.ts
+6
-32
未找到文件。
src/vs/workbench/services/themes/browser/workbenchThemeService.ts
浏览文件 @
fc877755
...
...
@@ -6,41 +6,13 @@
import
*
as
nls
from
'
vs/nls
'
;
import
*
as
types
from
'
vs/base/common/types
'
;
import
{
IExtensionService
}
from
'
vs/workbench/services/extensions/common/extensions
'
;
import
{
IWorkbenchThemeService
,
IColorTheme
,
ITokenColorCustomizations
,
IFileIconTheme
,
ExtensionData
,
VS_LIGHT_THEME
,
VS_DARK_THEME
,
VS_HC_THEME
,
COLOR_THEME_SETTING
,
ICON_THEME_SETTING
,
CUSTOM_WORKBENCH_COLORS_SETTING
,
CUSTOM_EDITOR_COLORS_SETTING
,
DETECT_HC_SETTING
,
HC_THEME_ID
,
IColorCustomizations
,
CUSTOM_EDITOR_TOKENSTYLES_SETTING
,
IExperimentalTokenStyleCustomizations
,
COLOR_THEME_DARK_SETTING
,
COLOR_THEME_LIGHT_SETTING
,
DETECT_AS_SETTING
,
ColorScheme
,
WINDOW_MATCH_PREFERS_COLOR_SCHEME
}
from
'
vs/workbench/services/themes/common/workbenchThemeService
'
;
import
{
IWorkbenchThemeService
,
IColorTheme
,
ITokenColorCustomizations
,
IFileIconTheme
,
ExtensionData
,
VS_LIGHT_THEME
,
VS_DARK_THEME
,
VS_HC_THEME
,
COLOR_THEME_SETTING
,
ICON_THEME_SETTING
,
CUSTOM_WORKBENCH_COLORS_SETTING
,
CUSTOM_EDITOR_COLORS_SETTING
,
DETECT_HC_SETTING
,
HC_THEME_ID
,
IColorCustomizations
,
CUSTOM_EDITOR_TOKENSTYLES_SETTING
,
IExperimentalTokenStyleCustomizations
}
from
'
vs/workbench/services/themes/common/workbenchThemeService
'
;
import
{
IStorageService
,
StorageScope
}
from
'
vs/platform/storage/common/storage
'
;
import
{
ITelemetryService
}
from
'
vs/platform/telemetry/common/telemetry
'
;
import
{
Registry
}
from
'
vs/platform/registry/common/platform
'
;
import
*
as
errors
from
'
vs/base/common/errors
'
;
import
{
IConfigurationService
,
ConfigurationTarget
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
IConfigurationRegistry
,
Extensions
as
ConfigurationExtensions
,
IConfigurationPropertySchema
,
IConfigurationNode
}
from
'
vs/platform/configuration/common/configurationRegistry
'
;
import
{
IConfigurationRegistry
,
Extensions
as
ConfigurationExtensions
,
IConfigurationPropertySchema
,
IConfigurationNode
}
from
'
vs/platform/configuration/common/configurationRegistry
'
;
import
{
ColorThemeData
}
from
'
vs/workbench/services/themes/common/colorThemeData
'
;
import
{
ITheme
,
Extensions
as
ThemingExtensions
,
IThemingRegistry
}
from
'
vs/platform/theme/common/themeService
'
;
import
{
Event
,
Emitter
}
from
'
vs/base/common/event
'
;
...
...
@@ -55,11 +27,7 @@ import { IFileService, FileChangeType } from 'vs/platform/files/common/files';
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
*
as
resources
from
'
vs/base/common/resources
'
;
import
{
IJSONSchema
}
from
'
vs/base/common/jsonSchema
'
;
import
{
textmateColorsSchemaId
,
registerColorThemeSchemas
,
textmateColorSettingsSchemaId
}
from
'
vs/workbench/services/themes/common/colorThemeSchema
'
;
import
{
textmateColorsSchemaId
,
registerColorThemeSchemas
,
textmateColorSettingsSchemaId
}
from
'
vs/workbench/services/themes/common/colorThemeSchema
'
;
import
{
workbenchColorsSchemaId
}
from
'
vs/platform/theme/common/colorRegistry
'
;
import
{
tokenStylingSchemaId
}
from
'
vs/platform/theme/common/tokenClassificationRegistry
'
;
import
{
registerSingleton
}
from
'
vs/platform/instantiation/common/extensions
'
;
...
...
@@ -71,9 +39,6 @@ import { IExtensionResourceLoaderService } from 'vs/workbench/services/extension
const
DEFAULT_THEME_ID
=
'
vs-dark vscode-theme-defaults-themes-dark_plus-json
'
;
const
DEFAULT_THEME_SETTING_VALUE
=
'
Default Dark+
'
;
const
DEFAULT_THEME_DARK_SETTING_VALUE
=
'
Default Dark+
'
;
const
DEFAULT_THEME_LIGHT_SETTING_VALUE
=
'
Default Light+
'
;
const
DEFAULT_THEME_AUTO_SWITCH_SETTING_VALUE
=
true
;
const
PERSISTED_THEME_STORAGE_KEY
=
'
colorThemeData
'
;
const
PERSISTED_ICON_THEME_STORAGE_KEY
=
'
iconThemeData
'
;
...
...
@@ -93,16 +58,11 @@ const themingRegistry = Registry.as<IThemingRegistry>(ThemingExtensions.ThemingC
function
validateThemeId
(
theme
:
string
):
string
{
// migrations
switch
(
theme
)
{
case
VS_LIGHT_THEME
:
return
`vs
${
defaultThemeExtensionId
}
-themes-light_vs-json`
;
case
VS_DARK_THEME
:
return
`vs-dark
${
defaultThemeExtensionId
}
-themes-dark_vs-json`
;
case
VS_HC_THEME
:
return
`hc-black
${
defaultThemeExtensionId
}
-themes-hc_black-json`
;
case
`vs
${
oldDefaultThemeExtensionId
}
-themes-light_plus-tmTheme`
:
return
`vs
${
defaultThemeExtensionId
}
-themes-light_plus-json`
;
case
`vs-dark
${
oldDefaultThemeExtensionId
}
-themes-dark_plus-tmTheme`
:
return
`vs-dark
${
defaultThemeExtensionId
}
-themes-dark_plus-json`
;
case
VS_LIGHT_THEME
:
return
`vs
${
defaultThemeExtensionId
}
-themes-light_vs-json`
;
case
VS_DARK_THEME
:
return
`vs-dark
${
defaultThemeExtensionId
}
-themes-dark_vs-json`
;
case
VS_HC_THEME
:
return
`hc-black
${
defaultThemeExtensionId
}
-themes-hc_black-json`
;
case
`vs
${
oldDefaultThemeExtensionId
}
-themes-light_plus-tmTheme`
:
return
`vs
${
defaultThemeExtensionId
}
-themes-light_plus-json`
;
case
`vs-dark
${
oldDefaultThemeExtensionId
}
-themes-dark_plus-tmTheme`
:
return
`vs-dark
${
defaultThemeExtensionId
}
-themes-dark_plus-json`
;
}
return
theme
;
}
...
...
@@ -111,8 +71,6 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
_serviceBrand
:
undefined
;
private
colorThemeStore
:
ColorThemeStore
;
private
autoSwitchColorTheme
=
DEFAULT_THEME_AUTO_SWITCH_SETTING_VALUE
;
private
autoSwitchColorThemeListener
:
MediaQueryList
|
undefined
=
undefined
;
private
currentColorTheme
:
ColorThemeData
;
private
container
:
HTMLElement
;
private
readonly
onColorThemeChange
:
Emitter
<
IColorTheme
>
;
...
...
@@ -136,9 +94,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
}
private
get
tokenStylesCustomizations
():
IExperimentalTokenStyleCustomizations
{
return
(
this
.
configurationService
.
getValue
<
IExperimentalTokenStyleCustomizations
>
(
CUSTOM_EDITOR_TOKENSTYLES_SETTING
)
||
{}
);
return
this
.
configurationService
.
getValue
<
IExperimentalTokenStyleCustomizations
>
(
CUSTOM_EDITOR_TOKENSTYLES_SETTING
)
||
{};
}
constructor
(
...
...
@@ -151,13 +107,13 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
@
IExtensionResourceLoaderService
private
readonly
extensionResourceLoaderService
:
IExtensionResourceLoaderService
,
@
IWorkbenchLayoutService
readonly
layoutService
:
IWorkbenchLayoutService
)
{
this
.
container
=
layoutService
.
getWorkbenchContainer
();
this
.
colorThemeStore
=
new
ColorThemeStore
(
extensionService
);
this
.
onFileIconThemeChange
=
new
Emitter
<
IFileIconTheme
>
();
this
.
iconThemeStore
=
new
FileIconThemeStore
(
extensionService
);
this
.
onColorThemeChange
=
new
Emitter
<
IColorTheme
>
({
leakWarningThreshold
:
400
});
this
.
onPreferColorSchemeChange
=
this
.
onPreferColorSchemeChange
.
bind
(
this
);
this
.
currentColorTheme
=
ColorThemeData
.
createUnloadedTheme
(
''
);
this
.
currentIconTheme
=
FileIconThemeData
.
createUnloadedTheme
(
''
);
...
...
@@ -190,12 +146,9 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
}
}
this
.
initialize
()
.
then
(
undefined
,
errors
.
onUnexpectedError
)
.
then
(
_
=>
{
this
.
installConfigurationListener
();
this
.
installColorThemeSwitch
();
});
this
.
initialize
().
then
(
undefined
,
errors
.
onUnexpectedError
).
then
(
_
=>
{
this
.
installConfigurationListener
();
});
let
prevColorId
:
string
|
undefined
=
undefined
;
...
...
@@ -224,10 +177,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
tokenColorCustomizationSchema
.
allOf
!
[
1
]
=
themeSpecificTokenColors
;
experimentalTokenStylingCustomizationSchema
.
allOf
!
[
1
]
=
themeSpecificTokenStyling
;
configurationRegistry
.
notifyConfigurationSchemaUpdated
(
themeSettingsConfiguration
,
tokenColorCustomizationConfiguration
);
configurationRegistry
.
notifyConfigurationSchemaUpdated
(
themeSettingsConfiguration
,
tokenColorCustomizationConfiguration
);
if
(
this
.
currentColorTheme
.
isLoaded
)
{
const
themeData
=
await
this
.
colorThemeStore
.
findThemeData
(
this
.
currentColorTheme
.
id
);
...
...
@@ -236,11 +186,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
prevColorId
=
this
.
currentColorTheme
.
id
;
this
.
setColorTheme
(
DEFAULT_THEME_ID
,
'
auto
'
);
}
else
{
if
(
this
.
currentColorTheme
.
id
===
DEFAULT_THEME_ID
&&
!
types
.
isUndefined
(
prevColorId
)
&&
(
await
this
.
colorThemeStore
.
findThemeData
(
prevColorId
))
)
{
if
(
this
.
currentColorTheme
.
id
===
DEFAULT_THEME_ID
&&
!
types
.
isUndefined
(
prevColorId
)
&&
await
this
.
colorThemeStore
.
findThemeData
(
prevColorId
))
{
// restore color
this
.
setColorTheme
(
prevColorId
,
'
auto
'
);
prevColorId
=
undefined
;
...
...
@@ -254,10 +200,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
let
prevFileIconId
:
string
|
undefined
=
undefined
;
this
.
iconThemeStore
.
onDidChange
(
async
event
=>
{
iconThemeSettingSchema
.
enum
=
[
null
,
...
event
.
themes
.
map
(
t
=>
t
.
settingsId
)];
iconThemeSettingSchema
.
enumDescriptions
=
[
iconThemeSettingSchema
.
enumDescriptions
!
[
0
],
...
event
.
themes
.
map
(
t
=>
t
.
description
||
''
)
];
iconThemeSettingSchema
.
enumDescriptions
=
[
iconThemeSettingSchema
.
enumDescriptions
!
[
0
],
...
event
.
themes
.
map
(
t
=>
t
.
description
||
''
)];
configurationRegistry
.
notifyConfigurationSchemaUpdated
(
themeSettingsConfiguration
);
if
(
this
.
currentIconTheme
.
isLoaded
)
{
...
...
@@ -268,11 +211,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
this
.
setFileIconTheme
(
DEFAULT_ICON_THEME_ID
,
'
auto
'
);
}
else
{
// restore color
if
(
this
.
currentIconTheme
.
id
===
DEFAULT_ICON_THEME_ID
&&
!
types
.
isUndefined
(
prevFileIconId
)
&&
(
await
this
.
iconThemeStore
.
findThemeData
(
prevFileIconId
))
)
{
if
(
this
.
currentIconTheme
.
id
===
DEFAULT_ICON_THEME_ID
&&
!
types
.
isUndefined
(
prevFileIconId
)
&&
await
this
.
iconThemeStore
.
findThemeData
(
prevFileIconId
))
{
this
.
setFileIconTheme
(
prevFileIconId
,
'
auto
'
);
prevFileIconId
=
undefined
;
}
else
{
...
...
@@ -283,18 +222,10 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
});
this
.
fileService
.
onFileChanges
(
async
e
=>
{
if
(
this
.
watchedColorThemeLocation
&&
this
.
currentColorTheme
&&
e
.
contains
(
this
.
watchedColorThemeLocation
,
FileChangeType
.
UPDATED
)
)
{
if
(
this
.
watchedColorThemeLocation
&&
this
.
currentColorTheme
&&
e
.
contains
(
this
.
watchedColorThemeLocation
,
FileChangeType
.
UPDATED
))
{
this
.
reloadCurrentColorTheme
();
}
if
(
this
.
watchedIconThemeLocation
&&
this
.
currentIconTheme
&&
e
.
contains
(
this
.
watchedIconThemeLocation
,
FileChangeType
.
UPDATED
)
)
{
if
(
this
.
watchedIconThemeLocation
&&
this
.
currentIconTheme
&&
e
.
contains
(
this
.
watchedIconThemeLocation
,
FileChangeType
.
UPDATED
))
{
this
.
reloadCurrentFileIconTheme
();
}
});
...
...
@@ -317,20 +248,17 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
}
private
initialize
():
Promise
<
[
IColorTheme
|
null
,
IFileIconTheme
|
null
]
>
{
let
colorThemeSetting
=
this
.
configurationService
.
getValue
<
string
>
(
COLOR_THEME_SETTING
);
let
iconThemeSetting
=
this
.
configurationService
.
getValue
<
string
|
null
>
(
ICON_THEME_SETTING
);
let
detectThemeAutoSwitch
=
this
.
configurationService
.
getValue
<
boolean
>
(
DETECT_AS_SETTING
);
this
.
autoSwitchColorTheme
=
detectThemeAutoSwitch
;
if
(
detectThemeAutoSwitch
)
{
colorThemeSetting
=
this
.
getPreferredTheme
();
}
let
detectHCThemeSetting
=
this
.
configurationService
.
getValue
<
boolean
>
(
DETECT_HC_SETTING
);
let
colorThemeSetting
:
string
;
if
(
this
.
environmentService
.
configuration
.
highContrast
&&
detectHCThemeSetting
)
{
colorThemeSetting
=
HC_THEME_ID
;
}
else
{
colorThemeSetting
=
this
.
configurationService
.
getValue
<
string
>
(
COLOR_THEME_SETTING
);
}
let
iconThemeSetting
=
this
.
configurationService
.
getValue
<
string
|
null
>
(
ICON_THEME_SETTING
);
const
extDevLocs
=
this
.
environmentService
.
extensionDevelopmentLocationURI
;
let
uri
:
URI
|
undefined
;
if
(
extDevLocs
&&
extDevLocs
.
length
>
0
)
{
...
...
@@ -339,7 +267,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
}
return
Promise
.
all
([
this
.
getColorThemeData
(
colorThemeSetting
).
then
(
theme
=>
{
this
.
colorThemeStore
.
findThemeDataBySettingsId
(
colorThemeSetting
,
DEFAULT_THEME_ID
).
then
(
theme
=>
{
return
this
.
colorThemeStore
.
findThemeDataByParentLocation
(
uri
).
then
(
devThemes
=>
{
if
(
devThemes
.
length
)
{
return
this
.
setColorTheme
(
devThemes
[
0
].
id
,
ConfigurationTarget
.
MEMORY
);
...
...
@@ -356,76 +284,20 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
return
this
.
setFileIconTheme
(
theme
?
theme
.
id
:
DEFAULT_ICON_THEME_ID
,
undefined
);
}
});
})
})
,
]);
}
private
installColorThemeSwitch
()
{
console
.
log
(
'
INSTALL
'
);
this
.
autoSwitchColorThemeListener
=
window
.
matchMedia
(
WINDOW_MATCH_PREFERS_COLOR_SCHEME
);
this
.
autoSwitchColorThemeListener
.
addListener
(
this
.
onPreferColorSchemeChange
);
console
.
log
(
'
INSTALLED
'
);
}
private
deinstallColorThemeSwitch
()
{
console
.
log
(
'
DEINSTALL
'
);
if
(
this
.
autoSwitchColorThemeListener
)
{
this
.
autoSwitchColorThemeListener
.
removeListener
(
this
.
onPreferColorSchemeChange
);
this
.
configurationService
.
updateValue
(
DETECT_AS_SETTING
,
false
);
console
.
log
(
'
DEINSTALLED
'
);
}
}
private
onPreferColorSchemeChange
<
MediaQueryList
>
({
matches
}:
MediaQueryListEvent
)
{
console
.
log
(
'
onPreferColorSchemeChange
'
,
matches
);
let
themeName
=
this
.
configurationService
.
getValue
<
string
>
(
COLOR_THEME_LIGHT_SETTING
);
if
(
matches
)
{
// prefers dark mode
themeName
=
this
.
configurationService
.
getValue
<
string
>
(
COLOR_THEME_DARK_SETTING
);
}
this
.
setTheme
(
themeName
);
}
private
getPreferredTheme
():
string
{
let
colorThemeSetting
=
this
.
configurationService
.
getValue
<
string
>
(
COLOR_THEME_LIGHT_SETTING
);
const
darkMode
=
this
.
getPreferredColorScheme
()
===
ColorScheme
.
DARK
;
if
(
darkMode
)
{
colorThemeSetting
=
this
.
configurationService
.
getValue
<
string
>
(
COLOR_THEME_DARK_SETTING
);
}
return
colorThemeSetting
;
}
private
setTheme
(
themeName
:
string
)
{
this
.
getColorThemeData
(
themeName
).
then
(
theme
=>
{
if
(
theme
)
{
this
.
setColorTheme
(
theme
.
id
,
undefined
);
this
.
configurationService
.
updateValue
(
COLOR_THEME_SETTING
,
themeName
);
}
});
}
private
installConfigurationListener
()
{
this
.
configurationService
.
onDidChangeConfiguration
(
e
=>
{
if
(
e
.
affectsConfiguration
(
COLOR_THEME_SETTING
))
{
let
colorThemeSetting
=
this
.
configurationService
.
getValue
<
string
>
(
COLOR_THEME_SETTING
);
if
(
colorThemeSetting
!==
this
.
currentColorTheme
.
settingsId
)
{
this
.
setTheme
(
colorThemeSetting
);
this
.
deinstallColorThemeSwitch
();
}
}
if
(
e
.
affectsConfiguration
(
DETECT_AS_SETTING
))
{
let
autoSwitchColorTheme
=
this
.
configurationService
.
getValue
<
boolean
>
(
DETECT_AS_SETTING
);
console
.
log
(
autoSwitchColorTheme
);
if
(
this
.
autoSwitchColorTheme
!==
autoSwitchColorTheme
)
{
this
.
autoSwitchColorTheme
=
autoSwitchColorTheme
;
console
.
log
(
'
HAS CHANGED
'
);
if
(
autoSwitchColorTheme
)
{
this
.
installColorThemeSwitch
();
let
themeName
=
this
.
getPreferredTheme
();
this
.
setTheme
(
themeName
);
}
else
{
this
.
deinstallColorThemeSwitch
();
}
this
.
colorThemeStore
.
findThemeDataBySettingsId
(
colorThemeSetting
,
undefined
).
then
(
theme
=>
{
if
(
theme
)
{
this
.
setColorTheme
(
theme
.
id
,
undefined
);
}
});
}
}
if
(
e
.
affectsConfiguration
(
ICON_THEME_SETTING
))
{
...
...
@@ -466,33 +338,11 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
return
this
.
colorThemeStore
.
getColorThemes
();
}
public
getColorThemeData
(
colorThemeSetting
:
string
):
Promise
<
IColorTheme
>
{
return
new
Promise
(
resolve
=>
{
this
.
colorThemeStore
.
findThemeDataBySettingsId
(
colorThemeSetting
,
DEFAULT_THEME_ID
).
then
(
theme
=>
{
resolve
(
theme
);
});
});
}
public
getPreferredColorScheme
():
ColorScheme
{
const
noPreference
=
window
.
matchMedia
(
`(prefers-color-scheme:
${
ColorScheme
.
NO_PREFERENCE
}
)`
).
matches
;
const
prefersDark
=
window
.
matchMedia
(
`(prefers-color-scheme:
${
ColorScheme
.
DARK
}
)`
).
matches
;
if
(
noPreference
)
{
return
ColorScheme
.
NO_PREFERENCE
;
}
else
if
(
prefersDark
)
{
return
ColorScheme
.
DARK
;
}
return
ColorScheme
.
LIGHT
;
}
public
getTheme
():
ITheme
{
return
this
.
getColorTheme
();
}
public
setColorTheme
(
themeId
:
string
|
undefined
,
settingsTarget
:
ConfigurationTarget
|
undefined
|
'
auto
'
):
Promise
<
IColorTheme
|
null
>
{
public
setColorTheme
(
themeId
:
string
|
undefined
,
settingsTarget
:
ConfigurationTarget
|
undefined
|
'
auto
'
):
Promise
<
IColorTheme
|
null
>
{
if
(
!
themeId
)
{
return
Promise
.
resolve
(
null
);
}
...
...
@@ -507,40 +357,24 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
return
null
;
}
const
themeData
=
data
;
return
themeData
.
ensureLoaded
(
this
.
extensionResourceLoaderService
).
then
(
_
=>
{
if
(
themeId
===
this
.
currentColorTheme
.
id
&&
!
this
.
currentColorTheme
.
isLoaded
&&
this
.
currentColorTheme
.
hasEqualData
(
themeData
)
)
{
this
.
currentColorTheme
.
clearCaches
();
// the loaded theme is identical to the perisisted theme. Don't need to send an event.
this
.
currentColorTheme
=
themeData
;
themeData
.
setCustomColors
(
this
.
colorCustomizations
);
themeData
.
setCustomTokenColors
(
this
.
tokenColorCustomizations
);
themeData
.
setCustomTokenStyleRules
(
this
.
tokenStylesCustomizations
);
return
Promise
.
resolve
(
themeData
);
}
return
themeData
.
ensureLoaded
(
this
.
extensionResourceLoaderService
).
then
(
_
=>
{
if
(
themeId
===
this
.
currentColorTheme
.
id
&&
!
this
.
currentColorTheme
.
isLoaded
&&
this
.
currentColorTheme
.
hasEqualData
(
themeData
))
{
this
.
currentColorTheme
.
clearCaches
();
// the loaded theme is identical to the perisisted theme. Don't need to send an event.
this
.
currentColorTheme
=
themeData
;
themeData
.
setCustomColors
(
this
.
colorCustomizations
);
themeData
.
setCustomTokenColors
(
this
.
tokenColorCustomizations
);
themeData
.
setCustomTokenStyleRules
(
this
.
tokenStylesCustomizations
);
this
.
updateDynamicCSSRules
(
themeData
);
return
this
.
applyTheme
(
themeData
,
settingsTarget
);
},
error
=>
{
return
Promise
.
reject
(
new
Error
(
nls
.
localize
(
'
error.cannotloadtheme
'
,
'
Unable to load {0}: {1}
'
,
themeData
.
location
!
.
toString
(),
error
.
message
)
)
);
return
Promise
.
resolve
(
themeData
);
}
);
themeData
.
setCustomColors
(
this
.
colorCustomizations
);
themeData
.
setCustomTokenColors
(
this
.
tokenColorCustomizations
);
themeData
.
setCustomTokenStyleRules
(
this
.
tokenStylesCustomizations
);
this
.
updateDynamicCSSRules
(
themeData
);
return
this
.
applyTheme
(
themeData
,
settingsTarget
);
},
error
=>
{
return
Promise
.
reject
(
new
Error
(
nls
.
localize
(
'
error.cannotloadtheme
'
,
"
Unable to load {0}: {1}
"
,
themeData
.
location
!
.
toString
(),
error
.
message
)));
});
});
}
...
...
@@ -556,7 +390,11 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
public
restoreColorTheme
()
{
let
colorThemeSetting
=
this
.
configurationService
.
getValue
<
string
>
(
COLOR_THEME_SETTING
);
if
(
colorThemeSetting
!==
this
.
currentColorTheme
.
settingsId
)
{
this
.
setTheme
(
colorThemeSetting
);
this
.
colorThemeStore
.
findThemeDataBySettingsId
(
colorThemeSetting
,
undefined
).
then
(
theme
=>
{
if
(
theme
)
{
this
.
setColorTheme
(
theme
.
id
,
undefined
);
}
});
}
}
...
...
@@ -573,11 +411,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
_applyRules
([...
cssRules
].
join
(
'
\n
'
),
colorThemeRulesClassName
);
}
private
applyTheme
(
newTheme
:
ColorThemeData
,
settingsTarget
:
ConfigurationTarget
|
undefined
|
'
auto
'
,
silent
=
false
):
Promise
<
IColorTheme
|
null
>
{
private
applyTheme
(
newTheme
:
ColorThemeData
,
settingsTarget
:
ConfigurationTarget
|
undefined
|
'
auto
'
,
silent
=
false
):
Promise
<
IColorTheme
|
null
>
{
if
(
this
.
currentColorTheme
.
id
)
{
removeClasses
(
this
.
container
,
this
.
currentColorTheme
.
id
);
}
else
{
...
...
@@ -588,9 +422,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
this
.
currentColorTheme
.
clearCaches
();
this
.
currentColorTheme
=
newTheme
;
if
(
!
this
.
themingParticipantChangeListener
)
{
this
.
themingParticipantChangeListener
=
themingRegistry
.
onThemingParticipantAdded
(
_
=>
this
.
updateDynamicCSSRules
(
this
.
currentColorTheme
)
);
this
.
themingParticipantChangeListener
=
themingRegistry
.
onThemingParticipantAdded
(
_
=>
this
.
updateDynamicCSSRules
(
this
.
currentColorTheme
));
}
if
(
this
.
fileService
&&
!
resources
.
isEqual
(
newTheme
.
location
,
this
.
watchedColorThemeLocation
))
{
...
...
@@ -621,9 +453,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
private
writeColorThemeConfiguration
(
settingsTarget
:
ConfigurationTarget
|
undefined
|
'
auto
'
):
Promise
<
IColorTheme
>
{
if
(
!
types
.
isUndefinedOrNull
(
settingsTarget
))
{
return
this
.
writeConfiguration
(
COLOR_THEME_SETTING
,
this
.
currentColorTheme
.
settingsId
,
settingsTarget
).
then
(
_
=>
this
.
currentColorTheme
);
return
this
.
writeConfiguration
(
COLOR_THEME_SETTING
,
this
.
currentColorTheme
.
settingsId
,
settingsTarget
).
then
(
_
=>
this
.
currentColorTheme
);
}
return
Promise
.
resolve
(
this
.
currentColorTheme
);
}
...
...
@@ -634,11 +464,11 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
let
key
=
themeType
+
themeData
.
extensionId
;
if
(
!
this
.
themeExtensionsActivated
.
get
(
key
))
{
type
ActivatePluginClassification
=
{
id
:
{
classification
:
'
PublicNonPersonalData
'
;
purpose
:
'
FeatureInsight
'
};
name
:
{
classification
:
'
PublicNonPersonalData
'
;
purpose
:
'
FeatureInsight
'
};
isBuiltin
:
{
classification
:
'
SystemMetaData
'
;
purpose
:
'
FeatureInsight
'
;
isMeasurement
:
true
};
publisherDisplayName
:
{
classification
:
'
SystemMetaData
'
;
purpose
:
'
FeatureInsight
'
};
themeId
:
{
classification
:
'
PublicNonPersonalData
'
;
purpose
:
'
FeatureInsight
'
};
id
:
{
classification
:
'
PublicNonPersonalData
'
,
purpose
:
'
FeatureInsight
'
};
name
:
{
classification
:
'
PublicNonPersonalData
'
,
purpose
:
'
FeatureInsight
'
};
isBuiltin
:
{
classification
:
'
SystemMetaData
'
,
purpose
:
'
FeatureInsight
'
,
isMeasurement
:
true
};
publisherDisplayName
:
{
classification
:
'
SystemMetaData
'
,
purpose
:
'
FeatureInsight
'
};
themeId
:
{
classification
:
'
PublicNonPersonalData
'
,
purpose
:
'
FeatureInsight
'
};
};
type
ActivatePluginEvent
=
{
id
:
string
;
...
...
@@ -671,10 +501,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
return
this
.
currentIconTheme
;
}
public
setFileIconTheme
(
iconTheme
:
string
|
undefined
,
settingsTarget
:
ConfigurationTarget
|
undefined
|
'
auto
'
):
Promise
<
IFileIconTheme
>
{
public
setFileIconTheme
(
iconTheme
:
string
|
undefined
,
settingsTarget
:
ConfigurationTarget
|
undefined
|
'
auto
'
):
Promise
<
IFileIconTheme
>
{
iconTheme
=
iconTheme
||
''
;
if
(
iconTheme
===
this
.
currentIconTheme
.
id
&&
this
.
currentIconTheme
.
isLoaded
)
{
return
this
.
writeFileIconConfiguration
(
settingsTarget
);
...
...
@@ -730,10 +557,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
dispose
(
this
.
watchedIconThemeDisposable
);
this
.
watchedIconThemeLocation
=
undefined
;
if
(
iconThemeData
.
location
&&
(
iconThemeData
.
watch
||
!!
this
.
environmentService
.
extensionDevelopmentLocationURI
)
)
{
if
(
iconThemeData
.
location
&&
(
iconThemeData
.
watch
||
!!
this
.
environmentService
.
extensionDevelopmentLocationURI
))
{
this
.
watchedIconThemeLocation
=
iconThemeData
.
location
;
this
.
watchedIconThemeDisposable
=
this
.
fileService
.
watch
(
iconThemeData
.
location
);
}
...
...
@@ -743,15 +567,12 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
this
.
sendTelemetry
(
iconThemeData
.
id
,
iconThemeData
.
extensionData
,
'
fileIcon
'
);
}
this
.
onFileIconThemeChange
.
fire
(
this
.
currentIconTheme
);
}
private
writeFileIconConfiguration
(
settingsTarget
:
ConfigurationTarget
|
undefined
|
'
auto
'
):
Promise
<
IFileIconTheme
>
{
private
writeFileIconConfiguration
(
settingsTarget
:
ConfigurationTarget
|
undefined
|
'
auto
'
):
Promise
<
IFileIconTheme
>
{
if
(
!
types
.
isUndefinedOrNull
(
settingsTarget
))
{
return
this
.
writeConfiguration
(
ICON_THEME_SETTING
,
this
.
currentIconTheme
.
settingsId
,
settingsTarget
).
then
(
_
=>
this
.
currentIconTheme
);
return
this
.
writeConfiguration
(
ICON_THEME_SETTING
,
this
.
currentIconTheme
.
settingsId
,
settingsTarget
).
then
(
_
=>
this
.
currentIconTheme
);
}
return
Promise
.
resolve
(
this
.
currentIconTheme
);
}
...
...
@@ -777,10 +598,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
}
value
=
undefined
;
// remove configuration from user settings
}
}
else
if
(
settingsTarget
===
ConfigurationTarget
.
WORKSPACE
||
settingsTarget
===
ConfigurationTarget
.
WORKSPACE_FOLDER
)
{
}
else
if
(
settingsTarget
===
ConfigurationTarget
.
WORKSPACE
||
settingsTarget
===
ConfigurationTarget
.
WORKSPACE_FOLDER
)
{
if
(
value
===
settings
.
value
)
{
return
Promise
.
resolve
(
undefined
);
// nothing to do
}
...
...
@@ -799,10 +617,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
}
}
function
_applyIconTheme
(
data
:
FileIconThemeData
,
onApply
:
(
theme
:
FileIconThemeData
)
=>
Promise
<
IFileIconTheme
>
):
Promise
<
IFileIconTheme
>
{
function
_applyIconTheme
(
data
:
FileIconThemeData
,
onApply
:
(
theme
:
FileIconThemeData
)
=>
Promise
<
IFileIconTheme
>
):
Promise
<
IFileIconTheme
>
{
_applyRules
(
data
.
styleSheetContent
!
,
iconThemeRulesClassName
);
return
onApply
(
data
);
}
...
...
@@ -828,49 +643,30 @@ const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationE
const
colorThemeSettingSchema
:
IConfigurationPropertySchema
=
{
type
:
'
string
'
,
description
:
nls
.
localize
(
'
colorTheme
'
,
'
Specifies the color theme used in the workbench.
'
),
description
:
nls
.
localize
(
'
colorTheme
'
,
"
Specifies the color theme used in the workbench.
"
),
default
:
DEFAULT_THEME_SETTING_VALUE
,
errorMessage
:
nls
.
localize
(
'
colorThemeError
'
,
'
Theme is unknown or not installed.
'
)
};
const
colorThemeDarkSettingSchema
:
IConfigurationPropertySchema
=
{
type
:
'
string
'
,
description
:
nls
.
localize
(
'
colorThemeDark
'
,
'
Specifies the color theme used for a dark OS appearance.
'
),
default
:
DEFAULT_THEME_DARK_SETTING_VALUE
,
errorMessage
:
nls
.
localize
(
'
colorThemeError
'
,
'
Theme is unknown or not installed.
'
)
};
const
colorThemeLightSettingSchema
:
IConfigurationPropertySchema
=
{
type
:
'
string
'
,
description
:
nls
.
localize
(
'
colorThemeLight
'
,
'
Specifies the color theme used for a light OS appearance.
'
),
default
:
DEFAULT_THEME_LIGHT_SETTING_VALUE
,
errorMessage
:
nls
.
localize
(
'
colorThemeError
'
,
'
Theme is unknown or not installed.
'
)
};
const
colorThemeAutoSwitchSettingSchema
:
IConfigurationPropertySchema
=
{
type
:
'
boolean
'
,
description
:
nls
.
localize
(
'
colorThemeAutoSwitch
'
,
'
Changes the color theme based on the OS appearance.
'
),
default
:
DEFAULT_THEME_AUTO_SWITCH_SETTING_VALUE
enum
:
[],
enumDescriptions
:
[],
errorMessage
:
nls
.
localize
(
'
colorThemeError
'
,
"
Theme is unknown or not installed.
"
),
};
const
iconThemeSettingSchema
:
IConfigurationPropertySchema
=
{
type
:
[
'
string
'
,
'
null
'
],
default
:
DEFAULT_ICON_THEME_SETTING_VALUE
,
description
:
nls
.
localize
(
'
iconTheme
'
,
"
Specifies the icon theme used in the workbench or 'null' to not show any file icons.
"
),
description
:
nls
.
localize
(
'
iconTheme
'
,
"
Specifies the icon theme used in the workbench or 'null' to not show any file icons.
"
),
enum
:
[
null
],
enumDescriptions
:
[
nls
.
localize
(
'
noIconThemeDesc
'
,
'
No file icons
'
)],
errorMessage
:
nls
.
localize
(
'
iconThemeError
'
,
'
File icon theme is unknown or not installed.
'
)
errorMessage
:
nls
.
localize
(
'
iconThemeError
'
,
"
File icon theme is unknown or not installed.
"
)
};
const
colorCustomizationsSchema
:
IConfigurationPropertySchema
=
{
type
:
'
object
'
,
description
:
nls
.
localize
(
'
workbenchColors
'
,
'
Overrides colors from the currently selected color theme.
'
),
description
:
nls
.
localize
(
'
workbenchColors
'
,
"
Overrides colors from the currently selected color theme.
"
),
allOf
:
[{
$ref
:
workbenchColorsSchemaId
}],
default
:
{},
defaultSnippets
:
[
{
body
:
{}
defaultSnippets
:
[{
body
:
{
}
]
}
]
};
const
themeSettingsConfiguration
:
IConfigurationNode
=
{
...
...
@@ -879,9 +675,6 @@ const themeSettingsConfiguration: IConfigurationNode = {
type
:
'
object
'
,
properties
:
{
[
COLOR_THEME_SETTING
]:
colorThemeSettingSchema
,
[
COLOR_THEME_DARK_SETTING
]:
colorThemeDarkSettingSchema
,
[
COLOR_THEME_LIGHT_SETTING
]:
colorThemeLightSettingSchema
,
[
DETECT_AS_SETTING
]:
colorThemeAutoSwitchSettingSchema
,
[
ICON_THEME_SETTING
]:
iconThemeSettingSchema
,
[
CUSTOM_WORKBENCH_COLORS_SETTING
]:
colorCustomizationsSchema
}
...
...
@@ -906,45 +699,26 @@ function tokenGroupSettings(description: string): IJSONSchema {
const
tokenColorSchema
:
IJSONSchema
=
{
properties
:
{
comments
:
tokenGroupSettings
(
nls
.
localize
(
'
editorColors.comments
'
,
'
Sets the colors and styles for comments
'
)),
strings
:
tokenGroupSettings
(
nls
.
localize
(
'
editorColors.strings
'
,
'
Sets the colors and styles for strings literals.
'
)
),
keywords
:
tokenGroupSettings
(
nls
.
localize
(
'
editorColors.keywords
'
,
'
Sets the colors and styles for keywords.
'
)),
numbers
:
tokenGroupSettings
(
nls
.
localize
(
'
editorColors.numbers
'
,
'
Sets the colors and styles for number literals.
'
)
),
types
:
tokenGroupSettings
(
nls
.
localize
(
'
editorColors.types
'
,
'
Sets the colors and styles for type declarations and references.
'
)
),
functions
:
tokenGroupSettings
(
nls
.
localize
(
'
editorColors.functions
'
,
'
Sets the colors and styles for functions declarations and references.
'
)
),
variables
:
tokenGroupSettings
(
nls
.
localize
(
'
editorColors.variables
'
,
'
Sets the colors and styles for variables declarations and references.
'
)
),
comments
:
tokenGroupSettings
(
nls
.
localize
(
'
editorColors.comments
'
,
"
Sets the colors and styles for comments
"
)),
strings
:
tokenGroupSettings
(
nls
.
localize
(
'
editorColors.strings
'
,
"
Sets the colors and styles for strings literals.
"
)),
keywords
:
tokenGroupSettings
(
nls
.
localize
(
'
editorColors.keywords
'
,
"
Sets the colors and styles for keywords.
"
)),
numbers
:
tokenGroupSettings
(
nls
.
localize
(
'
editorColors.numbers
'
,
"
Sets the colors and styles for number literals.
"
)),
types
:
tokenGroupSettings
(
nls
.
localize
(
'
editorColors.types
'
,
"
Sets the colors and styles for type declarations and references.
"
)),
functions
:
tokenGroupSettings
(
nls
.
localize
(
'
editorColors.functions
'
,
"
Sets the colors and styles for functions declarations and references.
"
)),
variables
:
tokenGroupSettings
(
nls
.
localize
(
'
editorColors.variables
'
,
"
Sets the colors and styles for variables declarations and references.
"
)),
textMateRules
:
{
description
:
nls
.
localize
(
'
editorColors.textMateRules
'
,
'
Sets colors and styles using textmate theming rules (advanced).
'
),
description
:
nls
.
localize
(
'
editorColors.textMateRules
'
,
'
Sets colors and styles using textmate theming rules (advanced).
'
),
$ref
:
textmateColorsSchemaId
}
}
};
const
tokenColorCustomizationSchema
:
IConfigurationPropertySchema
=
{
description
:
nls
.
localize
(
'
editorColors
'
,
'
Overrides editor colors and font style from the currently selected color theme.
'
),
description
:
nls
.
localize
(
'
editorColors
'
,
"
Overrides editor colors and font style from the currently selected color theme.
"
),
default
:
{},
allOf
:
[
tokenColorSchema
]
};
const
experimentalTokenStylingCustomizationSchema
:
IConfigurationPropertySchema
=
{
description
:
nls
.
localize
(
'
editorColorsTokenStyles
'
,
'
Overrides token color and styles from the currently selected color theme.
'
),
description
:
nls
.
localize
(
'
editorColorsTokenStyles
'
,
"
Overrides token color and styles from the currently selected color theme.
"
),
default
:
{},
allOf
:
[{
$ref
:
tokenStylingSchemaId
}]
};
...
...
@@ -959,4 +733,4 @@ const tokenColorCustomizationConfiguration: IConfigurationNode = {
};
configurationRegistry
.
registerConfiguration
(
tokenColorCustomizationConfiguration
);
registerSingleton
(
IWorkbenchThemeService
,
WorkbenchThemeService
);
registerSingleton
(
IWorkbenchThemeService
,
WorkbenchThemeService
);
\ No newline at end of file
src/vs/workbench/services/themes/common/workbenchThemeService.ts
浏览文件 @
fc877755
...
...
@@ -18,22 +18,12 @@ export const VS_HC_THEME = 'hc-black';
export
const
HC_THEME_ID
=
'
Default High Contrast
'
;
export
const
COLOR_THEME_SETTING
=
'
workbench.colorTheme
'
;
export
const
COLOR_THEME_DARK_SETTING
=
'
workbench.colorThemeDark
'
;
export
const
COLOR_THEME_LIGHT_SETTING
=
'
workbench.colorThemeLight
'
;
export
const
DETECT_AS_SETTING
=
'
workbench.colorThemeAutoSwitch
'
;
export
const
WINDOW_MATCH_PREFERS_COLOR_SCHEME
=
'
(prefers-color-scheme: dark)
'
;
export
const
DETECT_HC_SETTING
=
'
window.autoDetectHighContrast
'
;
export
const
ICON_THEME_SETTING
=
'
workbench.iconTheme
'
;
export
const
CUSTOM_WORKBENCH_COLORS_SETTING
=
'
workbench.colorCustomizations
'
;
export
const
CUSTOM_EDITOR_COLORS_SETTING
=
'
editor.tokenColorCustomizations
'
;
export
const
CUSTOM_EDITOR_TOKENSTYLES_SETTING
=
'
editor.tokenColorCustomizationsExperimental
'
;
export
enum
ColorScheme
{
LIGHT
=
'
light
'
,
DARK
=
'
dark
'
,
NO_PREFERENCE
=
'
no-preference
'
}
export
interface
IColorTheme
extends
ITheme
{
readonly
id
:
string
;
readonly
label
:
string
;
...
...
@@ -63,20 +53,13 @@ export interface IFileIconTheme extends IIconTheme {
export
interface
IWorkbenchThemeService
extends
IThemeService
{
_serviceBrand
:
undefined
;
setColorTheme
(
themeId
:
string
|
undefined
,
settingsTarget
:
ConfigurationTarget
|
undefined
):
Promise
<
IColorTheme
|
null
>
;
setColorTheme
(
themeId
:
string
|
undefined
,
settingsTarget
:
ConfigurationTarget
|
undefined
):
Promise
<
IColorTheme
|
null
>
;
getColorTheme
():
IColorTheme
;
getColorThemes
():
Promise
<
IColorTheme
[]
>
;
getColorThemeData
(
colorThemeSetting
:
string
):
Promise
<
IColorTheme
|
null
>
;
onDidColorThemeChange
:
Event
<
IColorTheme
>
;
restoreColorTheme
():
void
;
setFileIconTheme
(
iconThemeId
:
string
|
undefined
,
settingsTarget
:
ConfigurationTarget
|
undefined
):
Promise
<
IFileIconTheme
>
;
setFileIconTheme
(
iconThemeId
:
string
|
undefined
,
settingsTarget
:
ConfigurationTarget
|
undefined
):
Promise
<
IFileIconTheme
>
;
getFileIconTheme
():
IFileIconTheme
;
getFileIconThemes
():
Promise
<
IFileIconTheme
[]
>
;
onDidFileIconThemeChange
:
Event
<
IFileIconTheme
>
;
...
...
@@ -87,12 +70,7 @@ export interface IColorCustomizations {
}
export
interface
ITokenColorCustomizations
{
[
groupIdOrThemeSettingsId
:
string
]:
|
string
|
ITokenColorizationSetting
|
ITokenColorCustomizations
|
undefined
|
ITextMateThemingRule
[];
[
groupIdOrThemeSettingsId
:
string
]:
string
|
ITokenColorizationSetting
|
ITokenColorCustomizations
|
undefined
|
ITextMateThemingRule
[];
comments
?:
string
|
ITokenColorizationSetting
;
strings
?:
string
|
ITokenColorizationSetting
;
numbers
?:
string
|
ITokenColorizationSetting
;
...
...
@@ -104,11 +82,7 @@ export interface ITokenColorCustomizations {
}
export
interface
IExperimentalTokenStyleCustomizations
{
[
styleRuleOrThemeSettingsId
:
string
]:
|
string
|
ITokenColorizationSetting
|
IExperimentalTokenStyleCustomizations
|
undefined
;
[
styleRuleOrThemeSettingsId
:
string
]:
string
|
ITokenColorizationSetting
|
IExperimentalTokenStyleCustomizations
|
undefined
;
}
export
interface
ITextMateThemingRule
{
...
...
@@ -120,7 +94,7 @@ export interface ITextMateThemingRule {
export
interface
ITokenColorizationSetting
{
foreground
?:
string
;
background
?:
string
;
fontStyle
?:
string
/* [italic|underline|bold] */
;
fontStyle
?:
string
;
/* [italic|underline|bold] */
}
export
interface
ExtensionData
{
...
...
@@ -137,4 +111,4 @@ export interface IThemeExtensionPoint {
path
:
string
;
uiTheme
?:
typeof
VS_LIGHT_THEME
|
typeof
VS_DARK_THEME
|
typeof
VS_HC_THEME
;
_watch
:
boolean
;
// unsupported options to watch location
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录