问题
I'm developing a Visual Studio Code extension that enables previewing mermaid diagrams:
The extension uses a default stylesheet that works fine if using the light theme. However, if the user has switched Visual Studio Code to use the dark theme, the stylesheet has some rules that are not compatible with the default dark stylesheet:
Is is possible to detect programmatically the active theme type (e.g. light/dark) so that I could provide a different stylesheet for each case?
I would like to use the stylesheets bundled in mermaid and not craft completely different ones in my extension.
回答1:
Visual Studio Code 1.3 added this feature:
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.
Inspecting for one of these values using JavaScript allows customisation of the preview stylesheet to match the active theme in the editor.
回答2:
Since this question was answered, the HTML Preview feature was deprecated in favor of the Webview. Here is the relevant part of the documentation: Theming Webview content. Vlad's answer is still valid, but I found it incomplete.
The style sheet of the custom html content within your Webview indeed needs to be taking the document.body.class
into account, but besides just reading the attribute value when the page is loaded, you also need to handle the events, when the user changes the theme after your Webview has already been loaded. So Vald's answer was helpful, but I realized I need to handle the dynamic theme change case. It usually happens, when I am presenting on the big screen and people ask me to switch the theme for clarity and then I am stuck with the Webview that is theme-confused and illegible.
Here is what helped:
The html code needs to trigger a onLoad()
javascript function when it is done loading, and it should assume a default theme (so the HTML is testable outside of the Webview).
<body onload="onLoad()" class="vscode-light">
Then the javascript onLoad()
function needs to read the initial value of document.body.className
as well as subscribe to subsequent changes using the 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 */
}
来源:https://stackoverflow.com/questions/37257911/detect-light-dark-theme-programmatically-in-visual-studio-code