From 1ad3e3105c5ed576601490f6438e8af5c2af6ff2 Mon Sep 17 00:00:00 2001 From: purocean Date: Mon, 14 Jul 2025 13:51:16 +0800 Subject: [PATCH] feat: add extra CSS style setting with localization support --- src/renderer/others/setting-schema.ts | 10 ++++++++++ src/renderer/plugins/custom-styles.ts | 28 +++++++++++++++++++++++++++ src/renderer/types.ts | 1 + src/share/i18n/languages/en.ts | 1 + src/share/i18n/languages/ru.ts | 1 + src/share/i18n/languages/zh-CN.ts | 1 + src/share/i18n/languages/zh-TW.ts | 1 + 7 files changed, 43 insertions(+) diff --git a/src/renderer/others/setting-schema.ts b/src/renderer/others/setting-schema.ts index 295bd12e..c083503f 100644 --- a/src/renderer/others/setting-schema.ts +++ b/src/renderer/others/setting-schema.ts @@ -411,6 +411,16 @@ const schema: SettingSchema = ({ required: true, needReloadWindowWhenChanged: true, }, + 'render.extra-css-style': { + defaultValue: '.markdown-view .markdown-body a {\n /* color: red; */\n}', + title: 'T_setting-panel.schema.render.extra-css-style', + type: 'string', + group: 'render', + format: 'textarea', + options: { + inputAttributes: { placeholder: 'e.g., .markdown-view .markdown-body a { color: red; }', style: 'height: 8em' } + }, + }, shell: { defaultValue: '', title: 'T_setting-panel.schema.shell', diff --git a/src/renderer/plugins/custom-styles.ts b/src/renderer/plugins/custom-styles.ts index fa2b031a..c4456e7f 100644 --- a/src/renderer/plugins/custom-styles.ts +++ b/src/renderer/plugins/custom-styles.ts @@ -3,6 +3,15 @@ import type { Plugin } from '@fe/context' export default { name: 'custom-styles', register: (ctx) => { + let renderExtraStyle: HTMLStyleElement | null = null + async function updateRenderExtraStyle (style: string) { + if (!renderExtraStyle) { + renderExtraStyle = await ctx.view.addStyles(style) + } else { + renderExtraStyle.textContent = style + } + } + ctx.registerHook('STARTUP', () => { const head = document.getElementsByTagName('head')[0] const cssLink = document.createElement('link') @@ -47,6 +56,25 @@ export default { ctx.base.reloadMainWindow() } } + + if (changedKeys.includes('render.extra-css-style')) { + const extraStyle = ctx.setting.getSetting('render.extra-css-style', '') + updateRenderExtraStyle(extraStyle) + } + }) + + ctx.registerHook('SETTING_PANEL_AFTER_SHOW', ({ editor }) => { + const debouncedUpdate = ctx.lib.lodash.debounce(updateRenderExtraStyle, 300) + const input: HTMLTextAreaElement = editor.getEditor('root.render.extra-css-style').input + input.addEventListener('input', (e) => { + const value = (e.target as HTMLTextAreaElement).value + debouncedUpdate(value) + }) + + editor.watch('root.render.extra-css-style', () => { + const value = editor.getEditor('root.render.extra-css-style').getValue() + debouncedUpdate(value) + }) }) } } as Plugin diff --git a/src/renderer/types.ts b/src/renderer/types.ts index 66fb1cfd..8b260b6b 100644 --- a/src/renderer/types.ts +++ b/src/renderer/types.ts @@ -371,6 +371,7 @@ export interface BuildInSettings { 'render.multimd-rowspan': boolean, 'render.multimd-headerless': boolean, 'render.multimd-multibody': boolean, + 'render.extra-css-style': string, 'view.default-previewer-max-width': number, 'view.default-previewer-font-family': string, 'assets.path-type': 'relative' | 'absolute' | 'auto', diff --git a/src/share/i18n/languages/en.ts b/src/share/i18n/languages/en.ts index 1c5d0d77..71169e2f 100644 --- a/src/share/i18n/languages/en.ts +++ b/src/share/i18n/languages/en.ts @@ -433,6 +433,7 @@ const data = { 'multimd-rowspan': '[markdown-it-multimd-table]: Enable rowspan syntax', 'multimd-headerless': '[markdown-it-multimd-table]: Enable headerless syntax', 'multimd-multibody': '[markdown-it-multimd-table]: Enable multibody syntax', + 'extra-css-style': 'Custom CSS Style', }, 'view': { 'default-previewer-max-width': 'Previewer Max Width', diff --git a/src/share/i18n/languages/ru.ts b/src/share/i18n/languages/ru.ts index db701d97..61cbf340 100644 --- a/src/share/i18n/languages/ru.ts +++ b/src/share/i18n/languages/ru.ts @@ -434,6 +434,7 @@ const data: BaseLanguage = { 'multimd-rowspan': 'Включить синтаксис объединением рядов [multimd]:', 'multimd-headerless': 'Включить синтаксис без заголовков [multimd]:', 'multimd-multibody': 'Включить многокомпонентный синтаксис [multimd]:', + 'extra-css-style': 'Пользовательский CSS стиль', }, 'view': { 'default-previewer-max-width': 'Максимальная ширина окна предпросмотра', diff --git a/src/share/i18n/languages/zh-CN.ts b/src/share/i18n/languages/zh-CN.ts index 03f3a2d5..821ea08e 100644 --- a/src/share/i18n/languages/zh-CN.ts +++ b/src/share/i18n/languages/zh-CN.ts @@ -424,6 +424,7 @@ const data: BaseLanguage = { 'multimd-rowspan': '[markdown-it-multimd-table]: 启用 rowspan 语法', 'multimd-headerless': '[markdown-it-multimd-table]: 启用 headerless 语法', 'multimd-multibody': '[markdown-it-multimd-table]: 启用 multibody 语法', + 'extra-css-style': '自定义 CSS 样式', }, 'view': { 'default-previewer-max-width': '预览区最大宽度', diff --git a/src/share/i18n/languages/zh-TW.ts b/src/share/i18n/languages/zh-TW.ts index 76303371..e3e96c68 100644 --- a/src/share/i18n/languages/zh-TW.ts +++ b/src/share/i18n/languages/zh-TW.ts @@ -424,6 +424,7 @@ const data: BaseLanguage = { 'multimd-rowspan': '[markdown-it-multimd-table]: 啟用 rowspan 語法', 'multimd-headerless': '[markdown-it-multimd-table]: 啟用 headerless 語法', 'multimd-multibody': '[markdown-it-multimd-table]: 啟用 multibody 語法', + 'extra-css-style': '自訂 CSS 樣式', }, 'view': { 'default-previewer-max-width': '預覽區最大寬度',