在 Visual Studio 代码中以编程方式检测 light/dark 主题
Detect light/dark theme programmatically in Visual Studio Code
我正在开发 Visual Studio 代码 extension that enables previewing mermaid 图表:
该扩展程序使用默认样式表,如果使用浅色主题,该样式表可以正常工作。但是,如果用户已将 Visual Studio 代码切换为使用深色主题,则样式表有一些与默认深色样式表不兼容的规则:
是否可以通过编程方式检测活动主题类型(例如 light/dark),以便我可以为每种情况提供不同的样式表?
我想使用美人鱼中捆绑的样式表,而不是在我的扩展中制作完全不同的样式表。
Visual Studio Code 1.3 添加了此功能:
When previewing html, we expose the style of the current theme via
class names of the body element. Those are vscode-light, vscode-dark,
and vscode-high-contrast.
使用 JavaScript 检查这些值之一允许自定义预览样式表以匹配编辑器中的活动主题。
由于回答了这个问题,HTML 预览功能已弃用,取而代之的是 Webview。这是文档的相关部分:Theming Webview content。
Vlad 的回答仍然有效,但我发现它不完整。
Webview 中自定义 html 内容的样式 sheet 确实需要考虑 document.body.class
,但除了在加载页面时读取属性值之外,您还需要处理事件,当用户在您的 Webview 已经加载后更改主题时。所以 Vald 的回答很有帮助,但我意识到我需要处理动态主题更改案例。通常会发生这种情况,当我在大屏幕上进行演示时,人们要求我切换主题以便清晰,然后我就被主题混乱且难以辨认的 Webview 困住了。
以下是有帮助的内容:
html 代码需要在完成加载时触发 onLoad()
javascript 函数,并且它应该采用默认主题(因此 HTML 是可测试的在 Webview 之外)。
<body onload="onLoad()" class="vscode-light">
然后javascript onLoad()
函数需要读取document.body.className
的初始值以及使用MutationObserver
订阅后续更改。
var theme = 'unknown';
function onLoad() {
postCommand('onload');
applyTheme(document.body.className);
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutationRecord) {
applyTheme(mutationRecord.target.className);
});
});
var target = document.body;
observer.observe(target, { attributes : true, attributeFilter : ['class'] });
}
function applyTheme(newTheme) {
var prefix = 'vscode-';
if (newTheme.startsWith(prefix)) {
// strip prefix
newTheme = newTheme.substr(prefix.length);
}
if (newTheme === 'high-contrast') {
newTheme = 'dark'; // the high-contrast theme seems to be an extreme case of the dark theme
}
if (theme === newTheme) return;
theme = newTheme;
console.log('Applying theme: ' + newTheme);
/* PUT YOUR CUSTOM CODE HERE */
}
在扩展中,您可以使用
vscode.window.activeColorTheme: ColorTheme
并且 ColorTheme.kind
类型具有以下属性:
Dark
HighContrast
Light
vscode.window
对象上还有一个 onDidChangeActiveColorTheme: Event<ColorTheme>
事件监听器。
我正在开发 Visual Studio 代码 extension that enables previewing mermaid 图表:
该扩展程序使用默认样式表,如果使用浅色主题,该样式表可以正常工作。但是,如果用户已将 Visual Studio 代码切换为使用深色主题,则样式表有一些与默认深色样式表不兼容的规则:
是否可以通过编程方式检测活动主题类型(例如 light/dark),以便我可以为每种情况提供不同的样式表?
我想使用美人鱼中捆绑的样式表,而不是在我的扩展中制作完全不同的样式表。
Visual Studio Code 1.3 添加了此功能:
When previewing html, we expose the style of the current theme via class names of the body element. Those are vscode-light, vscode-dark, and vscode-high-contrast.
使用 JavaScript 检查这些值之一允许自定义预览样式表以匹配编辑器中的活动主题。
由于回答了这个问题,HTML 预览功能已弃用,取而代之的是 Webview。这是文档的相关部分:Theming Webview content。 Vlad 的回答仍然有效,但我发现它不完整。
Webview 中自定义 html 内容的样式 sheet 确实需要考虑 document.body.class
,但除了在加载页面时读取属性值之外,您还需要处理事件,当用户在您的 Webview 已经加载后更改主题时。所以 Vald 的回答很有帮助,但我意识到我需要处理动态主题更改案例。通常会发生这种情况,当我在大屏幕上进行演示时,人们要求我切换主题以便清晰,然后我就被主题混乱且难以辨认的 Webview 困住了。
以下是有帮助的内容:
html 代码需要在完成加载时触发 onLoad()
javascript 函数,并且它应该采用默认主题(因此 HTML 是可测试的在 Webview 之外)。
<body onload="onLoad()" class="vscode-light">
然后javascript onLoad()
函数需要读取document.body.className
的初始值以及使用MutationObserver
订阅后续更改。
var theme = 'unknown';
function onLoad() {
postCommand('onload');
applyTheme(document.body.className);
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutationRecord) {
applyTheme(mutationRecord.target.className);
});
});
var target = document.body;
observer.observe(target, { attributes : true, attributeFilter : ['class'] });
}
function applyTheme(newTheme) {
var prefix = 'vscode-';
if (newTheme.startsWith(prefix)) {
// strip prefix
newTheme = newTheme.substr(prefix.length);
}
if (newTheme === 'high-contrast') {
newTheme = 'dark'; // the high-contrast theme seems to be an extreme case of the dark theme
}
if (theme === newTheme) return;
theme = newTheme;
console.log('Applying theme: ' + newTheme);
/* PUT YOUR CUSTOM CODE HERE */
}
在扩展中,您可以使用
vscode.window.activeColorTheme: ColorTheme
并且 ColorTheme.kind
类型具有以下属性:
Dark
HighContrast
Light
vscode.window
对象上还有一个 onDidChangeActiveColorTheme: Event<ColorTheme>
事件监听器。