Detect light/dark theme programmatically in Visual Studio Code

和自甴很熟 提交于 2020-01-11 04:48:06

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!