From 96c84125056190fb69864272b56a741521459265 Mon Sep 17 00:00:00 2001 From: Ivan Posti Date: Thu, 9 Jul 2020 02:00:44 +0300 Subject: [PATCH 1/3] Make markdown preview use current IDE theme colors --- .../plugins/markdown/settings/darcula.css | 9 +- .../plugins/markdown/settings/default.css | 11 ++- .../ui/preview/MarkdownHtmlPanel.java | 7 +- .../ui/preview/PreviewStaticServer.java | 24 +++-- .../markdown/ui/preview/StyleOverrides.kt | 90 +++++++++++++++++++ .../javafx/MarkdownJavaFxHtmlPanel.java | 8 +- .../preview/jcef/MarkdownJCEFHtmlPanel.java | 8 +- 7 files changed, 141 insertions(+), 16 deletions(-) create mode 100644 plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/StyleOverrides.kt diff --git a/plugins/markdown/resource/org/intellij/plugins/markdown/settings/darcula.css b/plugins/markdown/resource/org/intellij/plugins/markdown/settings/darcula.css index 00eadb336f275..eac1cd019710e 100644 --- a/plugins/markdown/resource/org/intellij/plugins/markdown/settings/darcula.css +++ b/plugins/markdown/resource/org/intellij/plugins/markdown/settings/darcula.css @@ -650,7 +650,7 @@ span.user-del { } ::-webkit-scrollbar-thumb { -webkit-border-radius: 10px; - border: 2px solid #2c2c2c; + /*border: 2px solid #2c2c2c;*/ background-color: #404040; } ::-webkit-scrollbar-track { @@ -658,3 +658,10 @@ span.user-del { height: 12px; background-color: #2c2c2c; } + +::-webkit-scrollbar-track { + background-color: transparent; +} +::-webkit-scrollbar { + width: 7px; +} diff --git a/plugins/markdown/resource/org/intellij/plugins/markdown/settings/default.css b/plugins/markdown/resource/org/intellij/plugins/markdown/settings/default.css index fe4f37ea223bb..7f71cff238f7e 100644 --- a/plugins/markdown/resource/org/intellij/plugins/markdown/settings/default.css +++ b/plugins/markdown/resource/org/intellij/plugins/markdown/settings/default.css @@ -678,8 +678,7 @@ span.user-del { } ::-webkit-scrollbar-thumb { -webkit-border-radius: 10px; - border: 2px solid #f6f6f6; - + /*border: 2px solid #f6f6f6;*/ background-color: #959595; } ::-webkit-scrollbar-track { @@ -692,5 +691,11 @@ span.user-del { ::-webkit-scrollbar-track:horizontal { -webkit-box-shadow: 0 -1px 0px #ededed; +} -} \ No newline at end of file +::-webkit-scrollbar-track { + background-color: transparent; +} +::-webkit-scrollbar { + width: 7px; +} diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/MarkdownHtmlPanel.java b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/MarkdownHtmlPanel.java index b2e34235d15f2..c1d2a999d3d18 100644 --- a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/MarkdownHtmlPanel.java +++ b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/MarkdownHtmlPanel.java @@ -16,7 +16,12 @@ public interface MarkdownHtmlPanel extends Disposable { List SCRIPTS = ContainerUtil.immutableList("processLinks.js", "scrollToElement.js"); - List STYLES = ContainerUtil.immutableList("default.css", "darcula.css", PreviewStaticServer.INLINE_CSS_FILENAME); + List STYLES = ContainerUtil.immutableList( + "default.css", + "darcula.css", + PreviewStaticServer.INLINE_CSS_FILENAME, + PreviewStaticServer.OVERRIDES_CSS_FILENAME + ); @NotNull JComponent getComponent(); diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/PreviewStaticServer.java b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/PreviewStaticServer.java index 837d77f2bf7b7..afed0a23b1ec9 100644 --- a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/PreviewStaticServer.java +++ b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/PreviewStaticServer.java @@ -29,11 +29,14 @@ public class PreviewStaticServer extends HttpRequestHandler { public static final String INLINE_CSS_FILENAME = "inline.css"; + public static final String OVERRIDES_CSS_FILENAME = "overrides.css"; private static final Logger LOG = Logger.getInstance(PreviewStaticServer.class); private static final String PREFIX = "/4f800f8a-bbed-4dd8-b03c-00449c9f6698/"; private byte @Nullable [] myInlineStyleBytes = null; private long myInlineStyleTimestamp = 0; + private byte @Nullable [] myStyleOverridesBytes = null; + private long myStyleOverridesTimestamp = 0; public static PreviewStaticServer getInstance() { return HttpRequestHandler.Companion.getEP_NAME().findExtension(PreviewStaticServer.class); @@ -68,6 +71,11 @@ public void setInlineStyle(@Nullable String inlineStyle) { myInlineStyleTimestamp = System.currentTimeMillis(); } + public void setStyleOverrides(@Nullable String overrides) { + myStyleOverridesBytes = overrides == null ? null : overrides.getBytes(StandardCharsets.UTF_8); + myStyleOverridesTimestamp = System.currentTimeMillis(); + } + @Override public boolean isSupported(@NotNull FullHttpRequest request) { return super.isSupported(request) && request.uri().startsWith(PREFIX); @@ -99,7 +107,10 @@ public boolean process(@NotNull QueryStringDecoder urlDecoder, } else if ("styles".equals(contentType) && MarkdownHtmlPanel.STYLES.contains(fileName)) { if (INLINE_CSS_FILENAME.equals(fileName)) { - sendInlineStyle(request, context.channel()); + sendStyleFromMemory(myInlineStyleBytes, myInlineStyleTimestamp, request, context.channel()); + } + else if (OVERRIDES_CSS_FILENAME.equals(fileName)) { + sendStyleFromMemory(myStyleOverridesBytes, myStyleOverridesTimestamp, request, context.channel()); } else { sendResource(request, @@ -115,22 +126,21 @@ else if ("styles".equals(contentType) && MarkdownHtmlPanel.STYLES.contains(fileN return true; } - - private void sendInlineStyle(@NotNull HttpRequest request, @NotNull Channel channel) { - if (FileResponses.INSTANCE.checkCache(request, channel, myInlineStyleTimestamp)) { + private static void sendStyleFromMemory(@Nullable byte[] content, long timestamp, @NotNull HttpRequest request, @NotNull Channel channel) { + if (FileResponses.INSTANCE.checkCache(request, channel, timestamp)) { return; } - if (myInlineStyleBytes == null) { + if (content == null) { Responses.send(HttpResponseStatus.NOT_FOUND, channel, request); return; } FullHttpResponse response = - new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(myInlineStyleBytes)); + new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(content)); response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/css"); response.headers().set(HttpHeaderNames.CACHE_CONTROL, "private, must-revalidate"); - response.headers().set(HttpHeaderNames.LAST_MODIFIED, new Date(myInlineStyleTimestamp)); + response.headers().set(HttpHeaderNames.LAST_MODIFIED, new Date(timestamp)); Responses.send(response, channel, request); } diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/StyleOverrides.kt b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/StyleOverrides.kt new file mode 100644 index 0000000000000..3dd63611726d5 --- /dev/null +++ b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/StyleOverrides.kt @@ -0,0 +1,90 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.intellij.plugins.markdown.ui.preview + +import com.intellij.openapi.editor.colors.EditorColors +import com.intellij.openapi.editor.colors.EditorColorsManager +import com.intellij.util.ui.UIUtil +import java.awt.Color + +private fun Color.webRgba() = "rgba($red, $green, $blue, $alpha)" + +/** + * Simple linear contrast function. + * + * 0 < coefficient < 1 results in reduced contrast. + * coefficient > 1 results in increased contrast. + */ +private fun Color.contrast(coefficient: Double) = + Color( + (coefficient * (red - 128) + 128).toInt(), + (coefficient * (green - 128) + 128).toInt(), + (coefficient * (blue - 128) + 128).toInt(), + alpha + ) + +/** + * This method will generate stylesheet with colors, matching current IDE colors, + * for markdown elements. Generated rules will override base rules from the + * default.css and darcula.css, so the preview elements will have correct (almost) colors. + * + * @return String containing generated CSS rules. + */ +internal fun createStyleOverrides(): String { + val panelBackground = UIUtil.getPanelBackground() + EditorColorsManager.getInstance().globalScheme.run { + // For some reason background-color for ::-webkit-scrollbar-thumb + // doesn't work with [0..255] alpha values. Fortunately it works fine with [0..1] values. + // Default color from base stylesheets will be used, if the final value is null. + // (Generated rule will be invalid) + val scrollbarColor = getColor(EditorColors.SCROLLBAR_THUMB_COLOR)?.run { + "rgba($red, $blue, $green, ${alpha / 255.0})" + } + val contrastedForeground = defaultForeground.contrast(0.1) + val contrastedBackground = panelBackground.contrast(0.1) + val linkColor = getAttributes(EditorColors.REFERENCE_HYPERLINK_COLOR).foregroundColor + // language=CSS + return """ + body { + background-color: ${defaultBackground.webRgba()}; + color: ${defaultForeground.webRgba()}; + } + a { + color: ${linkColor.webRgba()}; + } + hr { + background-color: ${panelBackground.webRgba()}; + } + h6 { + color: ${contrastedForeground.webRgba()}; + } + pre { + background-color: ${panelBackground.webRgba()}; + } + pre > code { + color: ${defaultForeground.webRgba()}; + } + table tr { + color: ${defaultForeground.webRgba()}; + } + table th, table td, table tr { + background-color: ${defaultBackground.webRgba()}; + border-color: ${defaultBackground.contrast(0.85).webRgba()}; + } + table tr:nth-child(even) td { + background-color: ${defaultBackground.contrast(0.93).webRgba()}; + } + blockquote { + border-left-color: ${contrastedBackground.webRgba()}; + } + blockquote > p { + color: ${contrastedForeground.webRgba()}; + } + :checked + .radio-label { + border-color: ${panelBackground.webRgba()}; + } + ::-webkit-scrollbar-thumb { + background-color: $scrollbarColor; + } + """.trimIndent() + } +} diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/javafx/MarkdownJavaFxHtmlPanel.java b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/javafx/MarkdownJavaFxHtmlPanel.java index f60ca97712b1f..d7da90b0b700d 100644 --- a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/javafx/MarkdownJavaFxHtmlPanel.java +++ b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/javafx/MarkdownJavaFxHtmlPanel.java @@ -23,6 +23,7 @@ import org.intellij.plugins.markdown.settings.MarkdownApplicationSettings; import org.intellij.plugins.markdown.ui.preview.MarkdownHtmlPanel; import org.intellij.plugins.markdown.ui.preview.PreviewStaticServer; +import org.intellij.plugins.markdown.ui.preview.StyleOverridesKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -111,9 +112,12 @@ protected String prepareHtml(@NotNull String html) { @Override public void setCSS(@Nullable String inlineCss, String @NotNull ... fileUris) { PreviewStaticServer.getInstance().setInlineStyle(inlineCss); - myCssUris = inlineCss == null ? fileUris + PreviewStaticServer.getInstance().setStyleOverrides(StyleOverridesKt.createStyleOverrides()); + String[] baseStyles = + ArrayUtil.mergeArrays(fileUris, PreviewStaticServer.getStyleUrl(PreviewStaticServer.OVERRIDES_CSS_FILENAME)); + myCssUris = inlineCss == null ? baseStyles : ArrayUtil - .mergeArrays(fileUris, PreviewStaticServer.getStyleUrl(PreviewStaticServer.INLINE_CSS_FILENAME)); + .mergeArrays(baseStyles, PreviewStaticServer.getStyleUrl(PreviewStaticServer.INLINE_CSS_FILENAME)); myCSP = PreviewStaticServer.createCSP(ContainerUtil.map(SCRIPTS, s -> PreviewStaticServer.getScriptUrl(s)), ContainerUtil.concat( ContainerUtil.map(STYLES, s -> PreviewStaticServer.getStyleUrl(s)), diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/jcef/MarkdownJCEFHtmlPanel.java b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/jcef/MarkdownJCEFHtmlPanel.java index 4564de55af9df..b1b2361374c34 100644 --- a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/jcef/MarkdownJCEFHtmlPanel.java +++ b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/jcef/MarkdownJCEFHtmlPanel.java @@ -16,6 +16,7 @@ import org.intellij.plugins.markdown.ui.preview.MarkdownAccessor; import org.intellij.plugins.markdown.ui.preview.MarkdownHtmlPanel; import org.intellij.plugins.markdown.ui.preview.PreviewStaticServer; +import org.intellij.plugins.markdown.ui.preview.StyleOverridesKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -106,9 +107,12 @@ protected String prepareHtml(@NotNull String html) { @Override public void setCSS(@Nullable String inlineCss, String @NotNull ... fileUris) { PreviewStaticServer.getInstance().setInlineStyle(inlineCss); - myCssUris = inlineCss == null ? fileUris + PreviewStaticServer.getInstance().setStyleOverrides(StyleOverridesKt.createStyleOverrides()); + String[] baseStyles = + ArrayUtil.mergeArrays(fileUris, PreviewStaticServer.getStyleUrl(PreviewStaticServer.OVERRIDES_CSS_FILENAME)); + myCssUris = inlineCss == null ? baseStyles : ArrayUtil - .mergeArrays(fileUris, PreviewStaticServer.getStyleUrl(PreviewStaticServer.INLINE_CSS_FILENAME)); + .mergeArrays(baseStyles, PreviewStaticServer.getStyleUrl(PreviewStaticServer.INLINE_CSS_FILENAME)); myCSP = PreviewStaticServer.createCSP(ContainerUtil.map(SCRIPTS, s -> PreviewStaticServer.getScriptUrl(s)), ContainerUtil.concat( ContainerUtil.map(STYLES, s -> PreviewStaticServer.getStyleUrl(s)), From f918d64cd8979ac5c33f6ac0b0179753db0ff8da Mon Sep 17 00:00:00 2001 From: Ivan Posti Date: Sat, 11 Jul 2020 14:26:22 +0300 Subject: [PATCH 2/3] Fix incorrect code highlighting for some themes --- .../highlighter/MarkdownCodeFencePreviewHighlighter.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/extensions/highlighter/MarkdownCodeFencePreviewHighlighter.kt b/plugins/markdown/src/org/intellij/plugins/markdown/extensions/highlighter/MarkdownCodeFencePreviewHighlighter.kt index 31e69416eb290..cd179e29297e3 100644 --- a/plugins/markdown/src/org/intellij/plugins/markdown/extensions/highlighter/MarkdownCodeFencePreviewHighlighter.kt +++ b/plugins/markdown/src/org/intellij/plugins/markdown/extensions/highlighter/MarkdownCodeFencePreviewHighlighter.kt @@ -2,6 +2,7 @@ package org.intellij.plugins.markdown.extensions.highlighter import com.intellij.lang.Language +import com.intellij.openapi.editor.colors.EditorColorsManager import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory import com.intellij.testFramework.LightVirtualFile import org.intellij.markdown.html.entities.EntityConverter @@ -80,11 +81,14 @@ internal class MarkdownCodeFencePreviewHighlighter : MarkdownCodeFencePluginGene lexer.start(text) val html = StringBuilder(text.length) + val colorScheme = EditorColorsManager.getInstance().globalScheme while (lexer.tokenType != null) { val type = lexer.tokenType val highlights = highlighter.getTokenHighlights(type).lastOrNull() - val color = highlights?.defaultAttributes?.foregroundColor + val color = highlights?.let { + colorScheme.getAttributes(it)?.foregroundColor + } ?: highlights?.defaultAttributes?.foregroundColor val current = if (color != null) { //deprecated font tag is used since JavaFX HTML Viewer does not support span tag with style @@ -102,4 +106,4 @@ internal class MarkdownCodeFencePreviewHighlighter : MarkdownCodeFencePluginGene private fun Color.toHex(): String = String.format("#%02x%02x%02x", red, green, blue) private fun escape(html: String) = EntityConverter.replaceEntities(html, processEntities = true, processEscapes = true) -} \ No newline at end of file +} From 32d610dd53145f2e4f1e466008a45d86f2940f88 Mon Sep 17 00:00:00 2001 From: Ivan Posti Date: Sun, 12 Jul 2020 02:26:09 +0300 Subject: [PATCH 3/3] Drop explicit darcula support As a result, mark these methods as deprecated: - MarkdownLAFListener.reinit(boolean isDarcula) - MarkdownCssSettings.getDefaultCssSettings(boolean isDarcula) --- .../plugins/markdown/settings/darcula.css | 667 ------------------ .../settings/MarkdownApplicationSettings.java | 5 +- .../settings/MarkdownCssSettings.java | 21 +- .../settings/MarkdownLAFListener.java | 34 +- .../ui/preview/MarkdownHtmlPanel.java | 8 +- .../ui/preview/MarkdownPreviewFileEditor.java | 4 +- .../ui/preview/PreviewColorThemeStyles.kt | 96 +++ .../ui/preview/PreviewStaticServer.java | 16 +- .../markdown/ui/preview/StyleOverrides.kt | 90 --- .../javafx/MarkdownJavaFxHtmlPanel.java | 6 +- .../preview/jcef/MarkdownJCEFHtmlPanel.java | 6 +- 11 files changed, 141 insertions(+), 812 deletions(-) delete mode 100644 plugins/markdown/resource/org/intellij/plugins/markdown/settings/darcula.css create mode 100644 plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/PreviewColorThemeStyles.kt delete mode 100644 plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/StyleOverrides.kt diff --git a/plugins/markdown/resource/org/intellij/plugins/markdown/settings/darcula.css b/plugins/markdown/resource/org/intellij/plugins/markdown/settings/darcula.css deleted file mode 100644 index eac1cd019710e..0000000000000 --- a/plugins/markdown/resource/org/intellij/plugins/markdown/settings/darcula.css +++ /dev/null @@ -1,667 +0,0 @@ -/* -Adapted from https://github.com/sindresorhus/github-markdown-css - -The MIT License (MIT) - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -@font-face { - font-family: octicons-anchor; - src: url(data:font/woff;charset=utf-8;base64,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) format('woff'); -} - -body { - background-color: #3c3f41; - -webkit-text-size-adjust: 100%; - -fx-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; - text-size-adjust: 100%; - color: #cccccc; - font-family: Helvetica, Arial, freesans, sans-serif; - font-size: 16px; - line-height: 1.6; - word-wrap: break-word; -} - -a { - background-color: transparent; -} - -a:active, -a:hover { - outline: 0; -} - -strong { - font-weight: bold; -} - -h1 { - font-size: 2em; - margin: 0.67em 0; -} - -img { - border: 0; -} - -hr { - box-sizing: content-box; - height: 0; -} - -pre { - overflow: auto; -} - -code, -kbd, -pre { - font-family: monospace, monospace; - font-size: 1em; -} - -input { - color: inherit; - font: inherit; - margin: 0; -} - -html input[disabled] { - cursor: default; -} - -input { - line-height: normal; -} - -input[type="checkbox"] { - box-sizing: border-box; - padding: 0; -} - -table { - border-collapse: collapse; - border-spacing: 0; -} - -td, -th { - padding: 0; -} - -body * { - box-sizing: border-box; -} - -input { - font: 13px/1.4 Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; -} - -a { - color: #589df6; - text-decoration: none; -} - -a:hover, -a:active { - text-decoration: underline; -} - -hr { - height: 0; - margin: 15px 0; - overflow: hidden; - background: transparent; - border: 0; - border-bottom: 1px solid #2c2c2c; -} - -hr:before { - display: table; - content: ""; -} - -hr:after { - display: table; - clear: both; - content: ""; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - margin-top: 15px; - margin-bottom: 15px; - line-height: 1.1; -} - -h1 { - font-size: 30px; -} - -h2 { - font-size: 21px; -} - -h3 { - font-size: 16px; -} - -h4 { - font-size: 14px; -} - -h5 { - font-size: 12px; -} - -h6 { - font-size: 11px; -} - -blockquote { - margin: 0; -} - -ul, -ol { - padding: 0; - margin-top: 0; - margin-bottom: 0; -} - -ol ol, -ul ol { - list-style-type: lower-roman; -} - -ul ul ol, -ul ol ol, -ol ul ol, -ol ol ol { - list-style-type: lower-alpha; -} - -dd { - margin-left: 0; -} - -code { - font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; - font-size: 12px; -} - -pre { - margin-top: 0; - margin-bottom: 0; - font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; -} - -.octicon { - font: normal normal normal 16px/1 octicons-anchor; - display: inline-block; - text-decoration: none; - text-rendering: auto; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.octicon-link:before { - content: '\f05c'; -} - -.markdown-body > *:first-child { - margin-top: 0 !important; -} - -.markdown-body > *:last-child { - margin-bottom: 0 !important; -} - - -.anchor { - position: absolute; - top: 0; - left: 0; - display: block; - padding-right: 6px; - padding-left: 30px; - margin-left: -30px; -} - -.anchor:focus { - outline: none; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - position: relative; - margin-top: 1em; - margin-bottom: 16px; - font-weight: bold; - line-height: 1.4; -} - -h1 .octicon-link, -h2 .octicon-link, -h3 .octicon-link, -h4 .octicon-link, -h5 .octicon-link, -h6 .octicon-link { - display: none; - color: #bbbbbb; - vertical-align: middle; -} - -h1:hover .anchor, -h2:hover .anchor, -h3:hover .anchor, -h4:hover .anchor, -h5:hover .anchor, -h6:hover .anchor { - padding-left: 8px; - margin-left: -30px; - text-decoration: none; -} - -h1:hover .anchor .octicon-link, -h2:hover .anchor .octicon-link, -h3:hover .anchor .octicon-link, -h4:hover .anchor .octicon-link, -h5:hover .anchor .octicon-link, -h6:hover .anchor .octicon-link { - display: inline-block; -} - -h1 { - padding-bottom: 0.3em; - font-size: 2.25em; - line-height: 1.2; - border-bottom: 1px solid #2c2c2c; -} - -h1 .anchor { - line-height: 1; -} - -h2 { - padding-bottom: 0.3em; - font-size: 1.75em; - line-height: 1.225; - border-bottom: 1px solid #2c2c2c; -} - -h2 .anchor { - line-height: 1; -} - -h3 { - font-size: 1.5em; - line-height: 1.43; -} - -h3 .anchor { - line-height: 1.2; -} - -h4 { - font-size: 1.25em; -} - -h4 .anchor { - line-height: 1.2; -} - -h5 { - font-size: 1em; -} - -h5 .anchor { - line-height: 1.1; -} - -h6 { - font-size: 1em; - color: #777; -} - -h6 .anchor { - line-height: 1.1; -} - -p, -blockquote, -ul, -ol, -dl, -table, -pre { - margin-top: 0; - margin-bottom: 16px; -} - -hr { - height: 4px; - padding: 0; - margin: 16px 0; - background-color: #2c2c2c; - border: 0 none; -} - -ul, -ol { - padding-left: 2em; -} - -ul ul, -ul ol, -ol ol, -ol ul { - margin-top: 0; - margin-bottom: 0; -} - -li > p { - margin-top: 16px; -} - -dl { - padding: 0; -} - -dl dt { - padding: 0; - margin-top: 16px; - font-size: 1em; - font-style: italic; - font-weight: bold; -} - -dl dd { - padding: 0 16px; - margin-bottom: 16px; -} - -blockquote { - padding: 0 15px; - color: #a0a4a5; - border-left: 4px solid #626667; -} - -blockquote > :first-child { - margin-top: 0; -} - -blockquote > :last-child { - margin-bottom: 0; -} - -table { - display: block; - overflow: auto; - word-break: normal; - word-break: keep-all; -} - -table th { - font-weight: bold; -} - -table th, -table td { - padding: 6px 13px; - border: 1px solid #2c2c2c; -} - -table tr { - background-color: #2c2c2c; - border-top: 1px solid #2c2c2c; -} - -img { - max-width: 100%; - box-sizing: border-box; -} - -code { - padding: 0.2em 0; - margin: 0; - font-size: 85%; - color: #dddddd; - background-color: #333333; - border-radius: 3px; -} - -code:before, -code:after { - letter-spacing: -0.2em; - content: "\00a0"; -} - -pre > code { - padding: 0; - margin: 0; - font-size: 100%; - word-break: normal; - white-space: pre; - background: transparent; - border: 0; -} - -.highlight { - margin-bottom: 16px; -} - -.highlight pre, -pre { - padding: 16px; - overflow: auto; - font-size: 85%; - line-height: 1.45; - background-color: #2c2c2c; - border-radius: 3px; -} - -.highlight pre { - margin-bottom: 0; - word-break: normal; -} - -pre { - word-wrap: normal; -} - -pre code { - display: inline; - max-width: initial; - padding: 0; - margin: 0; - overflow: initial; - line-height: inherit; - word-wrap: normal; - background-color: transparent; - border: 0; -} - -pre code:before, -pre code:after { - content: normal; -} - -.pl-c { - color: #969896; -} - -.pl-c1, -.pl-s .pl-v { - color: #0086b3; -} - -.pl-e, -.pl-en { - color: #795da3; -} - -.pl-s .pl-s1, -.pl-smi { - color: #333; -} - -.pl-ent { - color: #63a35c; -} - -.pl-k { - color: #a71d5d; -} - -.pl-pds, -.pl-s, -.pl-s .pl-pse .pl-s1, -.pl-sr, -.pl-sr .pl-cce, -.pl-sr .pl-sra, -.pl-sr .pl-sre { - color: #183691; -} - -.pl-v { - color: #ed6a43; -} - -.pl-id { - color: #b52a1d; -} - -.pl-ii { - background-color: #b52a1d; - color: #f8f8f8; -} - -.pl-sr .pl-cce { - color: #63a35c; - font-weight: bold; -} - -.pl-ml { - color: #693a17; -} - -.pl-mh, -.pl-mh .pl-en, -.pl-ms { - color: #1d3e81; - font-weight: bold; -} - -.pl-mq { - color: #008080; -} - -.pl-mi { - color: #333; - font-style: italic; -} - -.pl-mb { - color: #333; - font-weight: bold; -} - -.pl-md { - background-color: #ffecec; - color: #bd2c00; -} - -.pl-mi1 { - background-color: #eaffea; - color: #55a532; -} - -.pl-mdr { - color: #795da3; - font-weight: bold; -} - -.pl-mo { - color: #1d3e81; -} - - - -.task-list-item { - list-style-type: none; -} - -.task-list-item + .task-list-item { - margin-top: 3px; -} - -.task-list-item input { - margin: 0 0.35em 0.25em -0.6em; - vertical-align: middle; -} - -:checked + .radio-label { - z-index: 1; - position: relative; - border-color: #4078c0; -} - -span.user-del { - text-decoration: line-through; -} - -::-webkit-scrollbar { - width: 12px; - height: 12px; - background-color: inherit; -} -::-webkit-scrollbar-thumb { - -webkit-border-radius: 10px; - /*border: 2px solid #2c2c2c;*/ - background-color: #404040; -} -::-webkit-scrollbar-track { - width: 12px; - height: 12px; - background-color: #2c2c2c; -} - -::-webkit-scrollbar-track { - background-color: transparent; -} -::-webkit-scrollbar { - width: 7px; -} diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/settings/MarkdownApplicationSettings.java b/plugins/markdown/src/org/intellij/plugins/markdown/settings/MarkdownApplicationSettings.java index cae46f394ed82..9a3cdaa4a38f4 100644 --- a/plugins/markdown/src/org/intellij/plugins/markdown/settings/MarkdownApplicationSettings.java +++ b/plugins/markdown/src/org/intellij/plugins/markdown/settings/MarkdownApplicationSettings.java @@ -29,7 +29,7 @@ public MarkdownApplicationSettings() { ApplicationManager.getApplication().getMessageBus().connect().subscribe(LafManagerListener.TOPIC, lafListener); // Let's init proper CSS scheme ApplicationManager.getApplication().invokeLater(() -> { - MarkdownLAFListener.reinit(StartupUiUtil.isUnderDarcula()); + MarkdownLAFListener.reinit(); }); } @@ -58,8 +58,7 @@ public void setMarkdownCssSettings(@NotNull MarkdownCssSettings settings) { @NotNull @Override public MarkdownCssSettings getMarkdownCssSettings() { - if (MarkdownCssSettings.DARCULA.getStylesheetUri().equals(myState.myCssSettings.getStylesheetUri()) - || MarkdownCssSettings.DEFAULT.getStylesheetUri().equals(myState.myCssSettings.getStylesheetUri())) { + if (MarkdownCssSettings.DEFAULT.getStylesheetUri().equals(myState.myCssSettings.getStylesheetUri())) { return new MarkdownCssSettings(false, "", myState.myCssSettings.isTextEnabled(), diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/settings/MarkdownCssSettings.java b/plugins/markdown/src/org/intellij/plugins/markdown/settings/MarkdownCssSettings.java index 1db8c1bf4a248..930988677c3e0 100644 --- a/plugins/markdown/src/org/intellij/plugins/markdown/settings/MarkdownCssSettings.java +++ b/plugins/markdown/src/org/intellij/plugins/markdown/settings/MarkdownCssSettings.java @@ -2,7 +2,6 @@ package org.intellij.plugins.markdown.settings; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.util.ui.StartupUiUtil; import com.intellij.util.xmlb.annotations.Attribute; import org.jetbrains.annotations.NotNull; @@ -10,8 +9,7 @@ import java.net.URL; public final class MarkdownCssSettings { - public static final MarkdownCssSettings DEFAULT = new MarkdownCssSettings(false); - public static final MarkdownCssSettings DARCULA = new MarkdownCssSettings(true); + public static final MarkdownCssSettings DEFAULT = new MarkdownCssSettings(); @SuppressWarnings("FieldMayBeFinal") @Attribute("UriEnabled") @@ -32,11 +30,7 @@ public final class MarkdownCssSettings { private String myStylesheetText; private MarkdownCssSettings() { - this(StartupUiUtil.isUnderDarcula()); - } - - private MarkdownCssSettings(boolean isDarcula) { - this(false, getPredefinedCssURI(isDarcula), false, ""); + this(false, getDefaultCssURI(), false, ""); } public MarkdownCssSettings(boolean uriEnabled, @NotNull String stylesheetUri, boolean textEnabled, @NotNull String stylesheetText) { @@ -79,16 +73,19 @@ public boolean equals(Object o) { return true; } + /** + * @deprecated use {@link DEFAULT} instead + */ @NotNull + @Deprecated public static MarkdownCssSettings getDefaultCssSettings(boolean isDarcula) { - return isDarcula ? DARCULA : DEFAULT; + return DEFAULT; } @NotNull - private static String getPredefinedCssURI(boolean isDarcula) { - final String fileName = isDarcula ? "darcula.css" : "default.css"; + private static String getDefaultCssURI() { try { - final URL resource = MarkdownCssSettings.class.getResource(fileName); + final URL resource = MarkdownCssSettings.class.getResource("default.css"); return resource != null ? resource.toURI().toString() : ""; } catch (URISyntaxException e) { diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/settings/MarkdownLAFListener.java b/plugins/markdown/src/org/intellij/plugins/markdown/settings/MarkdownLAFListener.java index 9760fb5d27379..6d3961d39c493 100644 --- a/plugins/markdown/src/org/intellij/plugins/markdown/settings/MarkdownLAFListener.java +++ b/plugins/markdown/src/org/intellij/plugins/markdown/settings/MarkdownLAFListener.java @@ -7,33 +7,38 @@ import com.intellij.openapi.util.text.StringUtil; import org.intellij.plugins.markdown.extensions.MarkdownCodeFencePluginGeneratingProvider; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; class MarkdownLAFListener implements LafManagerListener { @Override public void lookAndFeelChanged(@NotNull LafManager source) { - final UIManager.LookAndFeelInfo newLookAndFeel = source.getCurrentLookAndFeel(); - final boolean isNewLookAndFeelDarcula = isDarcula(newLookAndFeel); - - reinit(isNewLookAndFeelDarcula); + reinit(); } /** * Reinitialize plugin after change in look and feel. *

* For example, it would reinitialize preview and clear caches + * @deprecated use {@link #reinit()} instead */ + @Deprecated public static void reinit(boolean isDarcula) { + reinit(); + } + + /** + * Reinitialize plugin after change in look and feel. + *

+ * For example, it would reinitialize preview and clear caches + */ + public static void reinit() { MarkdownCodeFencePluginGeneratingProvider.Companion.notifyLAFChanged(); - updateCssSettingsForced(isDarcula); + updateCssSettingsForced(); } - private static void updateCssSettingsForced(boolean isDarcula) { + private static void updateCssSettingsForced() { final MarkdownCssSettings currentCssSettings = MarkdownApplicationSettings.getInstance().getMarkdownCssSettings(); final String stylesheetUri = StringUtil.isEmpty(currentCssSettings.getStylesheetUri()) - ? MarkdownCssSettings.getDefaultCssSettings(isDarcula).getStylesheetUri() + ? MarkdownCssSettings.DEFAULT.getStylesheetUri() : currentCssSettings.getStylesheetUri(); MarkdownApplicationSettings.getInstance().setMarkdownCssSettings(new MarkdownCssSettings( @@ -47,11 +52,4 @@ private static void updateCssSettingsForced(boolean isDarcula) { .syncPublisher(MarkdownApplicationSettings.SettingsChangedListener.TOPIC) .settingsChanged(MarkdownApplicationSettings.getInstance()); } - - public static boolean isDarcula(@Nullable UIManager.LookAndFeelInfo laf) { - if (laf == null) { - return false; - } - return laf.getName().contains("Darcula"); - } -} \ No newline at end of file +} diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/MarkdownHtmlPanel.java b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/MarkdownHtmlPanel.java index c1d2a999d3d18..c03669b7e5950 100644 --- a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/MarkdownHtmlPanel.java +++ b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/MarkdownHtmlPanel.java @@ -18,9 +18,8 @@ public interface MarkdownHtmlPanel extends Disposable { List STYLES = ContainerUtil.immutableList( "default.css", - "darcula.css", - PreviewStaticServer.INLINE_CSS_FILENAME, - PreviewStaticServer.OVERRIDES_CSS_FILENAME + PreviewStaticServer.COLOR_THEME_CSS_FILENAME, + PreviewStaticServer.INLINE_CSS_FILENAME ); @NotNull @@ -68,9 +67,6 @@ static String migrateUriToHttp(@NotNull String uri) { if (uri.equals(MarkdownCssSettings.DEFAULT.getStylesheetUri())) { return PreviewStaticServer.getStyleUrl("default.css"); } - else if (uri.equals(MarkdownCssSettings.DARCULA.getStylesheetUri())) { - return PreviewStaticServer.getStyleUrl("darcula.css"); - } else { return uri; } diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/MarkdownPreviewFileEditor.java b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/MarkdownPreviewFileEditor.java index 065822d902647..267a3776eaa84 100644 --- a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/MarkdownPreviewFileEditor.java +++ b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/MarkdownPreviewFileEditor.java @@ -378,13 +378,13 @@ private void updatePanelCssSettings(@NotNull MarkdownHtmlPanel panel, @NotNull M String styles = getCustomStyles(); if (styles != null) { - panel.setCSS(styles, MarkdownCssSettings.getDefaultCssSettings(StartupUiUtil.isUnderDarcula()).getStylesheetUri()); + panel.setCSS(styles, MarkdownCssSettings.DEFAULT.getStylesheetUri()); } else { String inlineCss = cssSettings.isTextEnabled() ? cssSettings.getStylesheetText() : null; String customCssURI = cssSettings.isUriEnabled() ? cssSettings.getStylesheetUri() - : MarkdownCssSettings.getDefaultCssSettings(StartupUiUtil.isUnderDarcula()).getStylesheetUri(); + : MarkdownCssSettings.DEFAULT.getStylesheetUri(); panel.setCSS(inlineCss, customCssURI); } diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/PreviewColorThemeStyles.kt b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/PreviewColorThemeStyles.kt new file mode 100644 index 0000000000000..6eed2f516f5ea --- /dev/null +++ b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/PreviewColorThemeStyles.kt @@ -0,0 +1,96 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.intellij.plugins.markdown.ui.preview + +import com.intellij.openapi.editor.colors.EditorColors +import com.intellij.openapi.editor.colors.EditorColorsManager +import com.intellij.util.ui.UIUtil +import java.awt.Color + +internal object PreviewColorThemeStyles { + /** + * This method will generate stylesheet with color rules for markdown elements, + * matching current IDE colors. Generated rules will override base rules from the + * default.css, so the preview elements will have (almost*) correct colors. + * + * *There will be no dedicated color for code blocks, if current IDE color theme defines same + * colors for UI panels and editor background (seems fine, though). + * + * @return String containing generated CSS rules. + */ + @JvmStatic + fun createStylesheet(): String { + val panelBackground = UIUtil.getPanelBackground() + with (EditorColorsManager.getInstance().globalScheme) { + // For some reason background-color for ::-webkit-scrollbar-thumb + // doesn't work with [0..255] alpha values. Fortunately it works fine with [0..1] values. + // Default color from base stylesheets will be used, if the final value is null. + // (Generated rule will be invalid) + val scrollbarColor = getColor(EditorColors.SCROLLBAR_THUMB_COLOR)?.run { + "rgba($red, $blue, $green, ${alpha / 255.0})" + } + val contrastedForeground = defaultForeground.contrast(0.1) + val contrastedBackground = panelBackground.contrast(0.1) + val linkColor = getAttributes(EditorColors.REFERENCE_HYPERLINK_COLOR).foregroundColor + // language=CSS + return """ + body { + background-color: ${defaultBackground.webRgba()}; + color: ${defaultForeground.webRgba()}; + } + a { + color: ${linkColor.webRgba()}; + } + hr { + background-color: ${panelBackground.webRgba()}; + } + h6 { + color: ${contrastedForeground.webRgba()}; + } + pre { + background-color: ${panelBackground.webRgba()}; + } + pre > code { + color: ${defaultForeground.webRgba()}; + } + table tr { + color: ${defaultForeground.webRgba()}; + } + table th, table td, table tr { + background-color: ${defaultBackground.webRgba()}; + border-color: ${defaultBackground.contrast(0.85).webRgba()}; + } + table tr:nth-child(even) td { + background-color: ${defaultBackground.contrast(0.93).webRgba()}; + } + blockquote { + border-left-color: ${contrastedBackground.webRgba()}; + } + blockquote > p { + color: ${contrastedForeground.webRgba()}; + } + :checked + .radio-label { + border-color: ${panelBackground.webRgba()}; + } + ::-webkit-scrollbar-thumb { + background-color: $scrollbarColor; + } + """.trimIndent() + } + } + + private fun Color.webRgba() = "rgba($red, $green, $blue, $alpha)" + + /** + * Simple linear contrast function. + * + * 0 < coefficient < 1 results in reduced contrast. + * coefficient > 1 results in increased contrast. + */ + private fun Color.contrast(coefficient: Double) = + Color( + (coefficient * (red - 128) + 128).toInt(), + (coefficient * (green - 128) + 128).toInt(), + (coefficient * (blue - 128) + 128).toInt(), + alpha + ) +} diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/PreviewStaticServer.java b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/PreviewStaticServer.java index afed0a23b1ec9..55110cdaefd71 100644 --- a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/PreviewStaticServer.java +++ b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/PreviewStaticServer.java @@ -29,14 +29,14 @@ public class PreviewStaticServer extends HttpRequestHandler { public static final String INLINE_CSS_FILENAME = "inline.css"; - public static final String OVERRIDES_CSS_FILENAME = "overrides.css"; + public static final String COLOR_THEME_CSS_FILENAME = "colors.css"; private static final Logger LOG = Logger.getInstance(PreviewStaticServer.class); private static final String PREFIX = "/4f800f8a-bbed-4dd8-b03c-00449c9f6698/"; private byte @Nullable [] myInlineStyleBytes = null; private long myInlineStyleTimestamp = 0; - private byte @Nullable [] myStyleOverridesBytes = null; - private long myStyleOverridesTimestamp = 0; + private byte @Nullable [] myColorThemeStylesBytes = null; + private long myColorThemeStylesTimestamp = 0; public static PreviewStaticServer getInstance() { return HttpRequestHandler.Companion.getEP_NAME().findExtension(PreviewStaticServer.class); @@ -71,9 +71,9 @@ public void setInlineStyle(@Nullable String inlineStyle) { myInlineStyleTimestamp = System.currentTimeMillis(); } - public void setStyleOverrides(@Nullable String overrides) { - myStyleOverridesBytes = overrides == null ? null : overrides.getBytes(StandardCharsets.UTF_8); - myStyleOverridesTimestamp = System.currentTimeMillis(); + public void setColorThemeStyles(@Nullable String overrides) { + myColorThemeStylesBytes = overrides == null ? null : overrides.getBytes(StandardCharsets.UTF_8); + myColorThemeStylesTimestamp = System.currentTimeMillis(); } @Override @@ -109,8 +109,8 @@ else if ("styles".equals(contentType) && MarkdownHtmlPanel.STYLES.contains(fileN if (INLINE_CSS_FILENAME.equals(fileName)) { sendStyleFromMemory(myInlineStyleBytes, myInlineStyleTimestamp, request, context.channel()); } - else if (OVERRIDES_CSS_FILENAME.equals(fileName)) { - sendStyleFromMemory(myStyleOverridesBytes, myStyleOverridesTimestamp, request, context.channel()); + else if (COLOR_THEME_CSS_FILENAME.equals(fileName)) { + sendStyleFromMemory(myColorThemeStylesBytes, myColorThemeStylesTimestamp, request, context.channel()); } else { sendResource(request, diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/StyleOverrides.kt b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/StyleOverrides.kt deleted file mode 100644 index 3dd63611726d5..0000000000000 --- a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/StyleOverrides.kt +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.intellij.plugins.markdown.ui.preview - -import com.intellij.openapi.editor.colors.EditorColors -import com.intellij.openapi.editor.colors.EditorColorsManager -import com.intellij.util.ui.UIUtil -import java.awt.Color - -private fun Color.webRgba() = "rgba($red, $green, $blue, $alpha)" - -/** - * Simple linear contrast function. - * - * 0 < coefficient < 1 results in reduced contrast. - * coefficient > 1 results in increased contrast. - */ -private fun Color.contrast(coefficient: Double) = - Color( - (coefficient * (red - 128) + 128).toInt(), - (coefficient * (green - 128) + 128).toInt(), - (coefficient * (blue - 128) + 128).toInt(), - alpha - ) - -/** - * This method will generate stylesheet with colors, matching current IDE colors, - * for markdown elements. Generated rules will override base rules from the - * default.css and darcula.css, so the preview elements will have correct (almost) colors. - * - * @return String containing generated CSS rules. - */ -internal fun createStyleOverrides(): String { - val panelBackground = UIUtil.getPanelBackground() - EditorColorsManager.getInstance().globalScheme.run { - // For some reason background-color for ::-webkit-scrollbar-thumb - // doesn't work with [0..255] alpha values. Fortunately it works fine with [0..1] values. - // Default color from base stylesheets will be used, if the final value is null. - // (Generated rule will be invalid) - val scrollbarColor = getColor(EditorColors.SCROLLBAR_THUMB_COLOR)?.run { - "rgba($red, $blue, $green, ${alpha / 255.0})" - } - val contrastedForeground = defaultForeground.contrast(0.1) - val contrastedBackground = panelBackground.contrast(0.1) - val linkColor = getAttributes(EditorColors.REFERENCE_HYPERLINK_COLOR).foregroundColor - // language=CSS - return """ - body { - background-color: ${defaultBackground.webRgba()}; - color: ${defaultForeground.webRgba()}; - } - a { - color: ${linkColor.webRgba()}; - } - hr { - background-color: ${panelBackground.webRgba()}; - } - h6 { - color: ${contrastedForeground.webRgba()}; - } - pre { - background-color: ${panelBackground.webRgba()}; - } - pre > code { - color: ${defaultForeground.webRgba()}; - } - table tr { - color: ${defaultForeground.webRgba()}; - } - table th, table td, table tr { - background-color: ${defaultBackground.webRgba()}; - border-color: ${defaultBackground.contrast(0.85).webRgba()}; - } - table tr:nth-child(even) td { - background-color: ${defaultBackground.contrast(0.93).webRgba()}; - } - blockquote { - border-left-color: ${contrastedBackground.webRgba()}; - } - blockquote > p { - color: ${contrastedForeground.webRgba()}; - } - :checked + .radio-label { - border-color: ${panelBackground.webRgba()}; - } - ::-webkit-scrollbar-thumb { - background-color: $scrollbarColor; - } - """.trimIndent() - } -} diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/javafx/MarkdownJavaFxHtmlPanel.java b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/javafx/MarkdownJavaFxHtmlPanel.java index d7da90b0b700d..d6bf9dc2f2561 100644 --- a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/javafx/MarkdownJavaFxHtmlPanel.java +++ b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/javafx/MarkdownJavaFxHtmlPanel.java @@ -22,8 +22,8 @@ import org.intellij.plugins.markdown.MarkdownBundle; import org.intellij.plugins.markdown.settings.MarkdownApplicationSettings; import org.intellij.plugins.markdown.ui.preview.MarkdownHtmlPanel; +import org.intellij.plugins.markdown.ui.preview.PreviewColorThemeStyles; import org.intellij.plugins.markdown.ui.preview.PreviewStaticServer; -import org.intellij.plugins.markdown.ui.preview.StyleOverridesKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -112,9 +112,9 @@ protected String prepareHtml(@NotNull String html) { @Override public void setCSS(@Nullable String inlineCss, String @NotNull ... fileUris) { PreviewStaticServer.getInstance().setInlineStyle(inlineCss); - PreviewStaticServer.getInstance().setStyleOverrides(StyleOverridesKt.createStyleOverrides()); + PreviewStaticServer.getInstance().setColorThemeStyles(PreviewColorThemeStyles.createStylesheet()); String[] baseStyles = - ArrayUtil.mergeArrays(fileUris, PreviewStaticServer.getStyleUrl(PreviewStaticServer.OVERRIDES_CSS_FILENAME)); + ArrayUtil.mergeArrays(fileUris, PreviewStaticServer.getStyleUrl(PreviewStaticServer.COLOR_THEME_CSS_FILENAME)); myCssUris = inlineCss == null ? baseStyles : ArrayUtil .mergeArrays(baseStyles, PreviewStaticServer.getStyleUrl(PreviewStaticServer.INLINE_CSS_FILENAME)); diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/jcef/MarkdownJCEFHtmlPanel.java b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/jcef/MarkdownJCEFHtmlPanel.java index b1b2361374c34..fa91cbb66dd0f 100644 --- a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/jcef/MarkdownJCEFHtmlPanel.java +++ b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/jcef/MarkdownJCEFHtmlPanel.java @@ -15,8 +15,8 @@ import org.intellij.markdown.html.HtmlGenerator; import org.intellij.plugins.markdown.ui.preview.MarkdownAccessor; import org.intellij.plugins.markdown.ui.preview.MarkdownHtmlPanel; +import org.intellij.plugins.markdown.ui.preview.PreviewColorThemeStyles; import org.intellij.plugins.markdown.ui.preview.PreviewStaticServer; -import org.intellij.plugins.markdown.ui.preview.StyleOverridesKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -107,9 +107,9 @@ protected String prepareHtml(@NotNull String html) { @Override public void setCSS(@Nullable String inlineCss, String @NotNull ... fileUris) { PreviewStaticServer.getInstance().setInlineStyle(inlineCss); - PreviewStaticServer.getInstance().setStyleOverrides(StyleOverridesKt.createStyleOverrides()); + PreviewStaticServer.getInstance().setColorThemeStyles(PreviewColorThemeStyles.createStylesheet()); String[] baseStyles = - ArrayUtil.mergeArrays(fileUris, PreviewStaticServer.getStyleUrl(PreviewStaticServer.OVERRIDES_CSS_FILENAME)); + ArrayUtil.mergeArrays(fileUris, PreviewStaticServer.getStyleUrl(PreviewStaticServer.COLOR_THEME_CSS_FILENAME)); myCssUris = inlineCss == null ? baseStyles : ArrayUtil .mergeArrays(baseStyles, PreviewStaticServer.getStyleUrl(PreviewStaticServer.INLINE_CSS_FILENAME));