From e1cfec6e3e489a0a78b9da3357e2bf6e792338c9 Mon Sep 17 00:00:00 2001 From: Ran Luo Date: Sun, 24 Mar 2019 05:09:00 +0800 Subject: [PATCH] opti: rewrite TOC and remove hard code theme (#778) * opti: prevent the duplicated header text error * scroll error in toc * delay the change event when init muya, so that the change event listener can handle change event. * opti: style * almost finished need last check * style in table * clear up some unused codes * clear up theme hard code * add no search data picture and new Folder new File * move search and replace to top of editor * add: no data image when there is no TOC * update structure * little bug fix * update styles * update un_draw icons * update style of editor * add animation when make open folder collapse. * remove theme props in editor component, deprecated lightColor and darkColor * add Ulysses Light * theme: graphite * update Ulysses blockquote * update emoji style * update titleBar height * change theme color * Support macOs dark mode * update style of tooltip in editor * update styles * fix: TOC auto expand all * patch added --- package.json | 5 +- src/main/app.js | 42 +- src/main/config.js | 2 +- src/main/menus/theme.js | 23 +- src/muya/lib/assets/styles/index.css | 156 ++--- src/muya/lib/config/index.js | 1 - src/muya/lib/contentState/index.js | 2 + src/muya/lib/contentState/tocCtrl.js | 24 + src/muya/lib/index.js | 31 +- .../render/renderBlock/renderLeafBlock.js | 6 +- src/muya/lib/ui/baseFloat/index.css | 15 +- src/muya/lib/ui/baseFloat/index.js | 11 - src/muya/lib/ui/codePicker/index.css | 18 +- src/muya/lib/ui/emojiPicker/index.css | 26 +- src/muya/lib/ui/formatPicker/index.css | 17 +- src/muya/lib/ui/quickInsert/index.css | 47 +- src/muya/lib/ui/tablePicker/index.css | 36 +- src/muya/lib/ui/tooltip/index.css | 12 +- src/muya/lib/ui/tooltip/index.js | 2 +- src/muya/lib/utils/dirtyToc.js | 39 -- src/muya/themes/dark.css | 633 ------------------ src/muya/themes/light.css | 106 ++- src/renderer/app.vue | 65 +- src/renderer/assets/icons/undraw_content.svg | 1 + src/renderer/assets/icons/undraw_empty.svg | 1 + src/renderer/assets/icons/undraw_folder.svg | 1 + .../assets/icons/undraw_toc_empty.svg | 1 + src/renderer/assets/styles/index.css | 101 ++- src/renderer/components/about/index.vue | 24 +- src/renderer/components/aidou/aidou.vue | 45 +- src/renderer/components/aidou/loading.vue | 6 +- src/renderer/components/bottomBar.vue | 36 - .../components/editorWithTabs/editor.vue | 92 ++- .../components/editorWithTabs/index.vue | 12 +- .../components/editorWithTabs/sourceCode.vue | 40 +- .../components/editorWithTabs/tabs.vue | 31 +- src/renderer/components/font.vue | 3 +- src/renderer/components/import/index.vue | 15 +- src/renderer/components/recent/index.vue | 49 +- src/renderer/components/rename.vue | 35 +- src/renderer/components/search.vue | 78 +-- src/renderer/components/sideBar/file.vue | 23 +- src/renderer/components/sideBar/folder.vue | 16 +- src/renderer/components/sideBar/index.vue | 40 +- src/renderer/components/sideBar/listFile.vue | 44 +- .../components/sideBar/openedFile.vue | 15 +- src/renderer/components/sideBar/search.vue | 47 +- src/renderer/components/sideBar/toc.vue | 88 ++- src/renderer/components/sideBar/tree.vue | 83 ++- src/renderer/components/titleBar.vue | 97 ++- src/renderer/components/tweet/index.vue | 51 +- src/renderer/components/uploadImage/index.vue | 22 +- src/renderer/config.js | 4 +- src/renderer/main.js | 16 +- src/renderer/store/editor.js | 23 +- src/renderer/util/day.js | 9 + src/renderer/util/listToTree.js | 30 + src/renderer/util/theme.js | 46 +- src/renderer/util/themeColor.js | 392 +++++++++++ yarn.lock | 10 +- 60 files changed, 1368 insertions(+), 1578 deletions(-) create mode 100644 src/muya/lib/contentState/tocCtrl.js delete mode 100644 src/muya/lib/utils/dirtyToc.js delete mode 100755 src/muya/themes/dark.css create mode 100644 src/renderer/assets/icons/undraw_content.svg create mode 100644 src/renderer/assets/icons/undraw_empty.svg create mode 100644 src/renderer/assets/icons/undraw_folder.svg create mode 100644 src/renderer/assets/icons/undraw_toc_empty.svg delete mode 100644 src/renderer/components/bottomBar.vue create mode 100644 src/renderer/util/day.js create mode 100644 src/renderer/util/listToTree.js create mode 100644 src/renderer/util/themeColor.js diff --git a/package.json b/package.json index fb6afdc9..e20c0846 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,8 @@ ] }, "mac": { - "icon": "resources/icons/icon.icns" + "icon": "resources/icons/icon.icns", + "darkModeSupport": true }, "win": { "icon": "resources/icons/icon.ico", @@ -143,7 +144,7 @@ "chokidar": "^2.1.2", "codemirror": "^5.44.0", "command-exists": "^1.2.8", - "diacritics-map": "^0.1.0", + "dayjs": "^1.8.10", "dompurify": "^1.0.10", "electron-is-accelerator": "^0.1.2", "element-resize-detector": "^1.2.0", diff --git a/src/main/app.js b/src/main/app.js index f85b335b..fed5c070 100644 --- a/src/main/app.js +++ b/src/main/app.js @@ -1,10 +1,12 @@ import path from 'path' -import { app } from 'electron' +import { app, systemPreferences } from 'electron' import appWindow from './window' import { isOsx } from './config' import { dockMenu } from './menus' -import { isDirectory, isMarkdownFile } from './utils' +import { isDirectory, isMarkdownFile, getMenuItemById } from './utils' import { watchers } from './utils/imagePathAutoComplement' +import { selectTheme } from './actions/theme' +import preference from './preference' class App { constructor () { @@ -22,12 +24,12 @@ class App { app.commandLine.appendSwitch('remote-debugging-port', '8315') } - app.on('open-file', this.openFile.bind(this)) + app.on('open-file', this.openFile) - app.on('ready', this.ready.bind(this)) + app.on('ready', this.ready) app.on('window-all-closed', () => { - app.removeListener('open-file', this.openFile.bind(this)) + app.removeListener('open-file', this.openFile) // close all the image path watcher for (const watcher of watchers.values()) { watcher.close() @@ -63,7 +65,7 @@ class App { }) } - ready () { + ready = () => { if (!isOsx && process.argv.length >= 2) { for (const arg of process.argv) { if (arg.startsWith('--')) { @@ -79,6 +81,32 @@ class App { // Set dock on macOS if (process.platform === 'darwin') { app.dock.setMenu(dockMenu) + + // listen for system theme change and change Mark Text own `dark` and `light`, + // In macOS 10.14 Mojave, + // Apple introduced a new system-wide dark mode for all macOS computers. + systemPreferences.subscribeNotification( + 'AppleInterfaceThemeChangedNotification', + () => { + const { theme } = preference.getAll() + let setedTheme = null + if (systemPreferences.isDarkMode() && theme !== 'dark') { + selectTheme('dark') + setedTheme = 'dark' + } + if (!systemPreferences.isDarkMode() && theme === 'dark') { + selectTheme('light') + setedTheme = 'light' + } + if (setedTheme) { + const themeMenu = getMenuItemById('themeMenu') + const menuItem = themeMenu.submenu.items.filter(item => (item.id === setedTheme))[0] + if (menuItem) { + menuItem.checked = true + } + } + } + ) } if (this.openFilesCache.length) { @@ -89,7 +117,7 @@ class App { } } - openFile (event, path) { + openFile = (event, path) => { const { openFilesCache } = this event.preventDefault() if (app.isReady()) { diff --git a/src/main/config.js b/src/main/config.js index 5e440397..daa177b8 100644 --- a/src/main/config.js +++ b/src/main/config.js @@ -15,7 +15,7 @@ export const defaultWinOptions = { useContentSize: true, show: false, frame: false, - titleBarStyle: 'hidden' + titleBarStyle: 'hiddenInset' } export const EXTENSIONS = [ diff --git a/src/main/menus/theme.js b/src/main/menus/theme.js index fc748c9a..c0b20841 100644 --- a/src/main/menus/theme.js +++ b/src/main/menus/theme.js @@ -5,19 +5,38 @@ const { theme } = userPreference.getAll() export default { label: 'Theme', + id: 'themeMenu', submenu: [{ - label: 'Dark', + label: 'Mateial Dark', type: 'radio', + id: 'dark', checked: theme === 'dark', click (menuItem, browserWindow) { actions.selectTheme('dark') } }, { - label: 'Light', + label: 'Cadmium Light', type: 'radio', + id: 'light', checked: theme === 'light', click (menuItem, browserWindow) { actions.selectTheme('light') } + }, { + label: 'Ulysses Light', + type: 'radio', + id: 'ulysses', + checked: theme === 'ulysses', + click (menuItem, browserWindow) { + actions.selectTheme('ulysses') + } + }, { + label: 'Graphite Light', + type: 'radio', + id: 'graphite', + checked: theme === 'graphite', + click (menuItem, browserWindow) { + actions.selectTheme('graphite') + } }] } diff --git a/src/muya/lib/assets/styles/index.css b/src/muya/lib/assets/styles/index.css index aec17107..a9d6f7a9 100644 --- a/src/muya/lib/assets/styles/index.css +++ b/src/muya/lib/assets/styles/index.css @@ -1,22 +1,3 @@ -/* Common CSS use by both light and dark themes */ -:root { - --brandColor: #5b3cc4; - --successColor: rgb(23, 201, 100); - --warningColor: rgb(255, 130, 0); - --dangerColor: rgb(242, 19, 93); - --activeColor: #409eff; - --infoColor: #909399; - --primaryColor: #303133; - --regularColor: #606266; - --secondaryColor: #909399; - --placeholerColor: #C0C4CC; - --baseBorder: #DCDFE6; - --lightBorder: #E4E7ED; - --lighterBorder: #EBEEF5; - --extraLightBorder: #F2F6FC; - --editorAreaWidth: 700px; -} - html { -webkit-font-smoothing: antialiased; } @@ -54,14 +35,14 @@ pre { top: 0; left: -25px; font-size: 14px; - color: var(--secondaryColor); + color: var(--iconColor); font-weight: 400; font-style: italic; } div.ag-show-quick-insert-hint p.ag-paragraph.ag-active > span.ag-line:first-of-type:empty::after { content: 'Type @ to insert'; - color: var(--placeholerColor); + color: var(--editorColor10); } .ag-paragraph:empty::after, @@ -81,7 +62,7 @@ div.ag-show-quick-insert-hint p.ag-paragraph.ag-active > span.ag-line:first-of-t .ag-reference-marker { font-size: .9em; - color: var(--secondaryColor); + color: var(--editorColor10); } .ag-reference-title { @@ -94,19 +75,14 @@ div.ag-show-quick-insert-hint p.ag-paragraph.ag-active > span.ag-line:first-of-t margin: 0 5px; } -/* .ag-soft-line-break::after { - content: '↓'; - opacity: .5; -} */ - .ag-hard-line-break::after { content: '↩'; opacity: .5; } *:not(.ag-hide)::selection, .ag-selection { - background: var(--baseBorder); - color: var(--primaryColor); + background: var(--selectionColor); + color: var(--editorColor); } .ag-hide::selection { @@ -149,19 +125,18 @@ div.ag-function-html.ag-active .ag-html-preview { animation-name: highlight; animation-duration: .25s; display: inline-block; - background: rgb(249, 226, 153); - color: var(--primaryColor); + background: var(--highlightColor); } span.ag-html-tag { - color: var(--secondaryColor); + color: var(--editorColor50); font-weight: 200; font-family: monospace; } span.ag-math { position: relative; - color: rebeccapurple; + color: var(--editorColor); font-family: monospace; display: inline-block; vertical-align: bottom; @@ -179,7 +154,7 @@ span.ag-math { div.ag-empty { text-align: center; - color: var(--regularColor); + color: var(--editorColor50); font-size: 14px; font-style: italic; font-family: monospace; @@ -187,7 +162,7 @@ div.ag-empty { div.ag-math-error, span.ag-math > .ag-math-render.ag-math-error { - color: var(--warningColor); + color: var(--deleteColor); font-size: 14px; font-style: italic; font-family: monospace; @@ -268,11 +243,10 @@ figure { display: flex; width: 20px; height: 20px; - padding: 2px; margin-right: 3px; cursor: pointer; border-radius: 3px; - color: var(--regularColor); + color: var(--iconColor); } .ag-tool-bar ul li[data-label=delete] { @@ -281,23 +255,18 @@ figure { } .ag-tool-bar ul li[data-label=delete] { - color: var(--dangerColor); + color: var(--deleteColor); right: 0; } .ag-tool-bar ul li.active svg { - fill: #409eff; + fill: var(--themeColor); } .ag-tool-bar ul li svg { width: 100%; height: 100%; will-change: transform; - transition: transform .2s ease-in-out; -} - -.ag-tool-bar ul li:hover svg { - transform: scale(1.1); } figure.ag-active .ag-tool-bar { @@ -313,7 +282,7 @@ figure.ag-active[data-role=HTML]::before { top: 0; left: -45px; font-size: 12px; - color: var(--secondaryColor); + color: var(--editorColor50); font-weight: 400; font-style: italic; } @@ -345,66 +314,56 @@ li.ag-task-list-item { li.ag-task-list-item > input[type=checkbox] { position: absolute; cursor: pointer; - width: 16px; - height: 16px; - margin: 4px 0px 0px; - top: 0; + width: 10px; + height: 10px; + top: 5px; left: -22px; transform-origin: center; - transform: rotate(-90deg); transition: all .2s ease; } -li.ag-task-list-item > input.ag-checkbox-checked { - transform: rotate(0); -} - li.ag-task-list-item > input.ag-checkbox-checked ~ * { - color: var(--regularColor); + color: var(--editorColor50); } li.ag-task-list-item > input.ag-checkbox-checked ~ p { text-decoration: line-through; - color: var(--secondaryColor); + color: var(--editorColor50); } li.ag-task-list-item > input[type=checkbox]::before { content: ''; - width: 16px; - height: 16px; + width: 14px; + height: 14px; box-sizing: border-box; display: inline-block; - border: 2px solid var(--infoColor); - border-radius: 2px; - background-color: #fff; + border: 1px solid var(--iconColor); + border-radius: 50%; + background-color: var(--editorBgColor); position: absolute; - top: 0; - left: 0; + top: -2px; + left: -2px; transition: all .2s ease; } -li.ag-task-list-item > input.ag-checkbox-checked::before { - border: transparent; - background-color: var(--activeColor); -} - li.ag-task-list-item > input::after { content: ''; - transform: rotate(-45deg) scale(0); - width: 9px; - height: 5px; - border: 2px solid #fff; + transform: rotate(-28deg) skew(0, -25deg) scale(0); + width: 8px; + height: 4px; + border: 1px solid var(--iconColor); border-top: none; border-right: none; position: absolute; display: inline-block; - top: 3px; - left: 3px; + top: 0px; + left: 2px; + transform-origin: bottom; transition: all .2s ease; } li.ag-task-list-item > input.ag-checkbox-checked::after { - transform: rotate(-45deg) scale(1); + transform: rotate(-28deg) skew(0, -25deg) scale(1); } /* li p .ag-hide:first-child { @@ -419,8 +378,8 @@ p:not(.ag-active)[data-role="hr"] { p:not(.ag-active)[data-role="hr"]::before { content: ''; width: 100%; - height: 5px; - background: gainsboro; + height: 2px; + background: var(--editorColor10); position: absolute; top: 50%; transform: translateY(-50%); @@ -433,7 +392,7 @@ p:not(.ag-active)[data-role="hr"] * { pre.ag-multiple-math, pre.ag-front-matter { position: relative; - background: #f6f8fa; + background: var(--selectionColor); padding: .5rem; border: 5px; font-size: 14px; @@ -445,17 +404,17 @@ pre.ag-front-matter { pre.ag-front-matter span.ag-code-line:first-of-type:empty::after { content: 'Input YAML Front Matter...'; - color: var(--placeholerColor); + color: var(--editorColor10); } pre[data-role$='code'] span.ag-language-input:empty::after { content: 'Input Language...'; - color: var(--placeholerColor); + color: var(--editorColor10); } pre.ag-multiple-math span.ag-code-line:first-of-type:empty::after { content: 'Input Mathematical Formula...'; - color: var(--placeholerColor); + color: var(--editorColor10); } figure, @@ -545,7 +504,7 @@ pre.ag-active.ag-indent-code::before, pre.ag-active.ag-indent-code::after, pre.ag-active.ag-multiple-math::before, pre.ag-active.ag-multiple-math::after { - color: var(--regularColor); + color: var(--editorColor30); font-family: monospace; position: absolute; font-weight: 600; @@ -574,11 +533,6 @@ pre.ag-active.ag-indent-code::after { bottom: -23px; } -span.ag-multiple-math-line { - color: purple; - font-family: monospace; -} - figure.ag-container-block div.ag-container-preview { width: 100%; text-align: center; @@ -593,8 +547,8 @@ figure.ag-active.ag-container-block > div.ag-container-preview { z-index: 10000; transform: translateX(-50%); padding: .5rem; - background: #fff; - border: 1px solid var(--lightBorder); + background: var(--floatBgColor); + border: 1px solid var(--floatBorderColor); border-radius: 4px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1); } @@ -614,7 +568,7 @@ hr { span.ag-emoji-marked-text { position: relative; - color: var(--regularColor); + color: var(--themeColor); text-decoration: none; } @@ -632,14 +586,14 @@ span.ag-emoji-marked-text { .ag-emoji-marked-text::before { position: absolute; content: attr(data-emoji); - color: #000; + color: var(--editorColor); top: -6px; left: -1.1em; - font-size: 1.5em; + font-size: 1em; } .ag-hide.ag-emoji-marked-text::before { - top: -19px; + top: -15px; } .ag-html-escape { @@ -653,7 +607,7 @@ span.ag-emoji-marked-text { top: -2px; left: -1rem; width: 1rem; - color: var(--secondaryColor); + color: var(--editorColor30); height: 100%; display: flex; justify-content: space-around; @@ -670,14 +624,14 @@ span.ag-emoji-marked-text { font-size: 14px; font-family: monospace; font-weight: 600; - color: var(--activeColor); + color: var(--themeColor); background: transparent; border: none; z-index: 10; } .ag-language-input::placeholder { - color: var(--placeholerColor); + color: var(--editorColor10); } pre.ag-active .ag-language-input { @@ -685,14 +639,14 @@ pre.ag-active .ag-language-input { } .ag-language { - color: var(--activeColor); + color: var(--themeColor); font-weight: 600; text-decoration: none; font-family: monospace; } span.ag-image-marked-text, span.ag-link-in-bracket, span.ag-link-in-bracket .ag-backlash { - color: var(--regularColor); + color: var(--editorColor50); font-size: 16px; text-decoration: none; font-family: monospace; @@ -703,7 +657,7 @@ span.ag-image-marked-text, span.ag-link-in-bracket, span.ag-link-in-bracket .ag- color: rgb(51, 51, 51); } span.ag-warn.ag-emoji-marked-text { - color: var(--warningColor); + color: var(--deleteColor); text-decoration: none; } @@ -735,12 +689,12 @@ span.ag-warn.ag-emoji-marked-text { } span[data-role="link"], a[data-role="link"], span[data-role="link"] .ag-backlash { - color: #0366d6; + color: var(--themeColor); text-decoration: none; } span.ag-reference-link { - color: var(--warningColor); + color: var(--deleteColor); } .ag-focus-mode p.ag-paragraph, diff --git a/src/muya/lib/config/index.js b/src/muya/lib/config/index.js index 5a84fb42..8f3b2865 100644 --- a/src/muya/lib/config/index.js +++ b/src/muya/lib/config/index.js @@ -218,7 +218,6 @@ export const EXPORT_DOMPURIFY_CONFIG = { export const MUYA_DEFAULT_OPTION = { focusMode: false, - theme: 'light', markdown: '', preferLooseListItem: true, autoPairBracket: true, diff --git a/src/muya/lib/contentState/index.js b/src/muya/lib/contentState/index.js index 32d68165..1bc0e517 100644 --- a/src/muya/lib/contentState/index.js +++ b/src/muya/lib/contentState/index.js @@ -22,6 +22,7 @@ import imagePathCtrl from './imagePathCtrl' import htmlBlockCtrl from './htmlBlock' import clickCtrl from './clickCtrl' import inputCtrl from './inputCtrl' +import tocCtrl from './tocCtrl' import importMarkdown from '../utils/importMarkdown' const prototypes = [ @@ -44,6 +45,7 @@ const prototypes = [ htmlBlockCtrl, clickCtrl, inputCtrl, + tocCtrl, importMarkdown ] diff --git a/src/muya/lib/contentState/tocCtrl.js b/src/muya/lib/contentState/tocCtrl.js new file mode 100644 index 00000000..798ee4c0 --- /dev/null +++ b/src/muya/lib/contentState/tocCtrl.js @@ -0,0 +1,24 @@ +const tocCtrl = ContentState => { + ContentState.prototype.getTOC = function () { + const { blocks } = this + const toc = [] + + for (const block of blocks) { + if (/^h\d$/.test(block.type)) { + const { headingStyle, text, key, type } = block + const content = headingStyle === 'setext' ? text.trim() : text.replace(/^ *#{1,6} {1,}/, '').trim() + const lvl = +type.substring(1) + const slug = key + toc.push({ + content, + lvl, + slug + }) + } + } + + return toc + } +} + +export default tocCtrl diff --git a/src/muya/lib/index.js b/src/muya/lib/index.js index a41a3d90..21f1e463 100644 --- a/src/muya/lib/index.js +++ b/src/muya/lib/index.js @@ -18,9 +18,8 @@ class Muya { } constructor (container, options) { this.options = Object.assign({}, MUYA_DEFAULT_OPTION, options) - const { focusMode, theme, markdown } = this.options + const { focusMode, markdown } = this.options this.focusMode = focusMode - this.theme = theme this.markdown = markdown this.container = getContainer(container, this.options) this.eventCenter = new EventCenter() @@ -42,7 +41,7 @@ class Muya { init () { const { container, contentState, eventCenter } = this contentState.stateRender.setContainer(container.children[0]) - eventCenter.subscribe('stateChange', this.dispatchChange.bind(this)) + eventCenter.subscribe('stateChange', this.dispatchChange) eventCenter.attachDOMEvent(container, 'contextmenu', event => { event.preventDefault() event.stopPropagation() @@ -61,19 +60,19 @@ class Muya { eventCenter.dispatch('contextmenu', event, sectionChanges) }) contentState.listenForPathChange() - const { theme, focusMode, markdown } = this - this.setTheme(theme) + const { focusMode, markdown } = this this.setMarkdown(markdown) this.setFocusMode(focusMode) } - dispatchChange () { + dispatchChange = () => { const { eventCenter } = this const markdown = this.markdown = this.getMarkdown() const wordCount = this.getWordCount(markdown) const cursor = this.getCursor() const history = this.getHistory() - eventCenter.dispatch('change', { markdown, wordCount, cursor, history }) + const toc = this.getTOC() + eventCenter.dispatch('change', { markdown, wordCount, cursor, history, toc }) } getMarkdown () { @@ -85,6 +84,10 @@ class Muya { return this.contentState.getHistory() } + getTOC () { + return this.contentState.getTOC() + } + setHistory (history) { return this.contentState.setHistory(history) } @@ -119,7 +122,9 @@ class Muya { this.contentState.importMarkdown(newMarkdown) this.contentState.importCursor(cursor) this.contentState.render(isRenderCursor) - this.dispatchChange() + setTimeout(() => { + this.dispatchChange() + }, 0) } createTable (tableChecker) { @@ -140,16 +145,6 @@ class Muya { this.focusMode = bool } - setTheme (name) { - if (!name) return - const { eventCenter } = this - this.theme = name - // Render cursor and refresh code block - this.contentState.render(true) - // notice the ui components to change theme - eventCenter.dispatch('theme-change', name) - } - setFont ({ fontSize, lineHeight }) { if (fontSize) this.contentState.fontSize = parseInt(fontSize, 10) if (lineHeight) this.contentState.lineHeight = lineHeight diff --git a/src/muya/lib/parser/render/renderBlock/renderLeafBlock.js b/src/muya/lib/parser/render/renderBlock/renderLeafBlock.js index e4893fe2..7b159c61 100644 --- a/src/muya/lib/parser/render/renderBlock/renderLeafBlock.js +++ b/src/muya/lib/parser/render/renderBlock/renderLeafBlock.js @@ -1,8 +1,7 @@ import katex from 'katex' import mermaid from 'mermaid' import prism, { loadedCache } from '../../../prism/' -import { slugify } from '../../../utils/dirtyToc' -import { CLASS_OR_ID, DEVICE_MEMORY, isInElectron, PREVIEW_DOMPURIFY_CONFIG, HAS_TEXT_BLOCK_REG } from '../../../config' +import { CLASS_OR_ID, DEVICE_MEMORY, PREVIEW_DOMPURIFY_CONFIG, HAS_TEXT_BLOCK_REG } from '../../../config' import { tokenizer } from '../../parse' import { snakeToCamel, sanitize, escapeHtml, getLongUniqueId, getImageInfo } from '../../../utils' import { h, htmlToVNode } from '../snabbdom' @@ -199,8 +198,7 @@ export default function renderLeafBlock (block, cursor, activeBlocks, matches, u // TODO: This should be the best place to create and update the TOC. // Cache `block.key` and title and update only if necessary. Object.assign(data.dataset, { - head: type, - id: isInElectron ? slugify(text.replace(/^#+\s(.*)/, (_, p1) => p1)) : '' + head: type }) selector += `.${headingStyle}` } diff --git a/src/muya/lib/ui/baseFloat/index.css b/src/muya/lib/ui/baseFloat/index.css index 461a2de9..39a33eeb 100644 --- a/src/muya/lib/ui/baseFloat/index.css +++ b/src/muya/lib/ui/baseFloat/index.css @@ -7,9 +7,9 @@ top: -1000px; right: -1000px; border-radius: 8px; - box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.1); - border: 1px solid rgba(0, 0, 0, 0.1); - background-color: #ffffff; + box-shadow: 0 4px 8px 0 var(--floatBorderColor); + border: 1px solid var(--floatBorderColor); + background-color: var(--floatBgColor); transition: opacity .25s ease-in-out; transform-origin: top; box-sizing: border-box; @@ -17,11 +17,6 @@ overflow: hidden; } -.ag-float-wrapper.dark { - background: var(--primaryColor); - border-color: var(--primaryColor); -} - .ag-float-container::-webkit-scrollbar:vertical { width: 0px; } @@ -40,10 +35,6 @@ transform: rotate(45deg); } -.dark[x-placement] .ag-popper-arrow { - border-color: var(--primaryColor); -} - [x-placement="bottom-start"] > .ag-popper-arrow { border-right: none; border-bottom: none; diff --git a/src/muya/lib/ui/baseFloat/index.js b/src/muya/lib/ui/baseFloat/index.js index a7d9b1c6..6c90fd9a 100644 --- a/src/muya/lib/ui/baseFloat/index.js +++ b/src/muya/lib/ui/baseFloat/index.js @@ -88,16 +88,6 @@ class BaseFloat { } } - const themeChange = theme => { - const { container, floatBox } = this - ;[container, floatBox].forEach(ele => { - if (!ele.classList.contains(theme)) { - ele.classList.remove(theme === 'dark' ? 'light' : 'dark') - ele.classList.add(theme) - } - }) - } - eventCenter.attachDOMEvent(document, 'click', this.hide.bind(this)) eventCenter.attachDOMEvent(floatBox, 'click', event => { event.stopPropagation() @@ -105,7 +95,6 @@ class BaseFloat { }) eventCenter.attachDOMEvent(container, 'keydown', keydownHandler) eventCenter.attachDOMEvent(container, 'scroll', scrollHandler) - eventCenter.subscribe('theme-change', themeChange) } hide () { diff --git a/src/muya/lib/ui/codePicker/index.css b/src/muya/lib/ui/codePicker/index.css index ea2fe42b..f5d21c5f 100644 --- a/src/muya/lib/ui/codePicker/index.css +++ b/src/muya/lib/ui/codePicker/index.css @@ -20,11 +20,14 @@ .ag-list-picker:hover .active { background: transparent; - color: #606266; } + +.ag-list-picker .item .language { + color: var(--editorColor); +} + .ag-list-picker .active, .ag-list-picker .item:hover { - background-color: #ecf5ff; - color: var(--activeColor); + background-color: var(--floatHoverColor); } .ag-list-picker .item .icon-wrapper { @@ -48,13 +51,4 @@ font-size: 14px; line-height: 35px; margin-left: 10px; -} - -.ag-list-picker.dark:hover .active { - background: transparent; - color: currentColor; -} -.ag-list-picker.dark .active, .ag-list-picker.dark .item:hover { - background-color: rgb(71, 72, 66); - color: var(--activeColor); } \ No newline at end of file diff --git a/src/muya/lib/ui/emojiPicker/index.css b/src/muya/lib/ui/emojiPicker/index.css index 87c972a5..a02b9f36 100644 --- a/src/muya/lib/ui/emojiPicker/index.css +++ b/src/muya/lib/ui/emojiPicker/index.css @@ -6,7 +6,7 @@ } .ag-emoji-picker .title { - color: rgba(55, 53, 47, 0.6); + color: var(--editorColor); line-height: 120%; font-size: 11px; padding: 10px 14px 12px 14px; @@ -16,7 +16,7 @@ font-weight: 600; position: sticky; top: 0; - background: #fff; + background: var(--floatBgColor); z-index: 1001; } @@ -44,8 +44,7 @@ } .ag-emoji-picker .active, .ag-emoji-picker .item:hover { - background-color: #ecf5ff; - border: 1px solid var(--activeColor); + background-color: var(--floatHoverColor); } .ag-emoji-picker section .emoji-wrapper .item span { @@ -58,23 +57,4 @@ transition: transform .2s ease-in; transform-origin: center; } - -.ag-emoji-picker .active span, .ag-emoji-picker .item:hover span { - transform: scale(1.1); - } - - .ag-emoji-picker.dark .title { - background: var(--primaryColor); - color: var(--placeholerColor); -} - -.ag-emoji-picker.dark:hover .active { - background: transparent; - border-color: transparent; -} - -.ag-emoji-picker.dark .active, .ag-emoji-picker.dark .item:hover { - background-color: rgb(72, 71, 66); - border: 1px solid var(--primaryColor); - } \ No newline at end of file diff --git a/src/muya/lib/ui/formatPicker/index.css b/src/muya/lib/ui/formatPicker/index.css index 7fac248c..fdb7e22a 100644 --- a/src/muya/lib/ui/formatPicker/index.css +++ b/src/muya/lib/ui/formatPicker/index.css @@ -26,7 +26,7 @@ } .ag-format-picker li.item:hover { - background: rgb(243, 243, 243); + background: var(--floatHoverColor); } .ag-format-picker li.item:last-of-type { @@ -38,29 +38,20 @@ width: 2px; position: absolute; height: 18px; - background: #eee; + background: var(--editorColor10); left: -4px; top: 6px; } .ag-format-picker li.item svg { - fill: #666; + fill: var(--iconColor); } .ag-format-picker li.item.active svg { - fill: var(--activeColor); + fill: var(--themeColor); } .ag-format-picker li.item .icon-wrapper { width: 16px; height: 16px; -} - -/* dark theme */ -.ag-format-picker.dark li.item:hover { - background: rgb(60, 60, 60); -} - -.ag-format-picker.dark li.item:last-of-type:before { - background: rgb(71, 71, 71); } \ No newline at end of file diff --git a/src/muya/lib/ui/quickInsert/index.css b/src/muya/lib/ui/quickInsert/index.css index 126597d9..740d70ef 100644 --- a/src/muya/lib/ui/quickInsert/index.css +++ b/src/muya/lib/ui/quickInsert/index.css @@ -6,7 +6,7 @@ } .ag-quick-insert .title { - color: rgba(0, 0, 0, .6); + color: var(--editorColor); line-height: 120%; font-size: 14px; padding: 10px 14px 10px 14px; @@ -15,7 +15,7 @@ letter-spacing: 1px; position: sticky; top: 0; - background: #fff; + background: var(--floatBgColor); z-index: 1001; } @@ -32,20 +32,21 @@ } .ag-quick-insert .active, .ag-quick-insert div.item:hover { - background-color: rgba(0, 0, 0, .04); + background-color: var(--floatHoverColor); } .ag-quick-insert .no-result { margin-top: 20px; padding: 0 20px; font-size: 14px; - color: #999; + text-align: center; + color: var(--themeColor); } .ag-quick-insert .icon-container { width: 40px; height: 40px; - border: 1px solid rgb(0, 0, 0, .1); + border: 1px solid var(--floatBorderColor); display: flex; justify-content: space-around; align-items: center; @@ -57,7 +58,7 @@ width: 20px; height: 20px; opacity: .6; - fill: rgba(0, 0, 0, .6); + fill: var(--iconColor); } .ag-quick-insert .description { @@ -70,49 +71,21 @@ margin-right: 20px; flex-shrink: 1; text-align: right; - color: rgba(0, 0, 0, .3); + color: var(--editorColor50); font-size: 14px; letter-spacing: 1px; } .ag-quick-insert .big-title { font-size: 14px; - color: rgba(0, 0, 0, .6); + color: var(--editorColor); } .ag-quick-insert .sub-title { font-size: 12px; - color: rgba(0, 0, 0, .4); + color: var(--editorColor50); } .ag-quick-insert .hide { display: none; } - -.ag-quick-insert.dark .title { - background: var(--primaryColor); - color: var(--placeholerColor); -} - -.ag-quick-insert.dark .big-title { - color: var(--lightBorder); -} - -.ag-quick-insert.dark .sub-title { - color: rgba(255, 255, 255, .6); -} - -.ag-quick-insert.dark .active, -.ag-quick-insert.dark div.item:hover { - background-color: rgb(71, 72, 66); -} - -.ag-quick-insert.dark .icon-container > svg { - fill: rgba(255, 255, 255, .5); -} - -.ag-quick-insert.dark .short-cut { - color: rgba(255, 255, 255, .5); -} - - diff --git a/src/muya/lib/ui/tablePicker/index.css b/src/muya/lib/ui/tablePicker/index.css index aedadc6e..571bcc97 100644 --- a/src/muya/lib/ui/tablePicker/index.css +++ b/src/muya/lib/ui/tablePicker/index.css @@ -19,46 +19,54 @@ box-sizing: border-box; margin-right: 1px; margin-bottom: 1px; - border: 1px solid #ccc; + border: 1px solid var(--editorColor10); cursor: pointer; } .ag-table-picker-header span { - background: #ddd; + background: var(--editorColor10); } .ag-table-picker-cell.current { - background: darkgray; + background: var(--editorColor30); } .ag-table-picker-header .current { - background: #666; + background: var(--editorColor50); } .ag-table-picker-cell.selected { - background: #ecf5ff; + background: var(--selectionColor); } .ag-table-picker-header .selected { - background: #ecf5ff; + background: var(--selectionColor); } .ag-table-picker-cell:last-of-type { margin-right: 0; } .ag-table-picker .footer { - padding-top: 5px; - border-top: 1px solid #ccc; + padding: 10px 0 0 0; + border-top: 1px solid var(--floatBorderColor); text-align: center; + display: flex; + justify-content: space-around; } .ag-table-picker .footer input { + color: var(--editorColor); + background: var(--floatBorderColor); + outline: none; + border-radius: 3px; text-align: center; border: none; + box-sizing: border-box; padding: 0; - height: 16px; - width: 16px; + height: 20px; + width: 30px; + border: none; } .ag-table-picker .footer button { outline: none; cursor: pointer; - border-radius: 2px; - line-height: 12px; + border-radius: 3px; + line-height: 20px; border: none; - height: 16px; - background: #409eff; + height: 20px; + background: var(--themeColor); color: #fff; } diff --git a/src/muya/lib/ui/tooltip/index.css b/src/muya/lib/ui/tooltip/index.css index f7690273..9b008ba8 100644 --- a/src/muya/lib/ui/tooltip/index.css +++ b/src/muya/lib/ui/tooltip/index.css @@ -4,8 +4,11 @@ font-size: 12px; padding: 5px 7px; border-radius: 3px; - background: rgb(50, 50, 50); - color: rgb(255, 255, 255); + background: var(--floatBgColor); + color: var(--editorColor); + box-shadow: 0 4px 8px 0 var(--floatBorderColor); + border: 1px solid var(--floatBorderColor); + box-sizing: border-box; z-index: 1000; opacity: 0; } @@ -16,10 +19,13 @@ } .ag-tooltip:after { - top: 0; + top: -2px; left: 50%; content: ''; background: inherit; + border: 1px solid var(--floatBorderColor); + border-right: none; + border-bottom: none; width: 8px; height: 8px; position: absolute; diff --git a/src/muya/lib/ui/tooltip/index.js b/src/muya/lib/ui/tooltip/index.js index 6a225f2a..a106a05f 100644 --- a/src/muya/lib/ui/tooltip/index.js +++ b/src/muya/lib/ui/tooltip/index.js @@ -6,7 +6,7 @@ const position = (source, ele) => { Object.assign(ele.style, { top: `${top + height + 10}px`, - left: `${right - ele.offsetWidth / 2 - 3}px` + left: `${right - ele.offsetWidth / 2 - 5}px` }) } diff --git a/src/muya/lib/utils/dirtyToc.js b/src/muya/lib/utils/dirtyToc.js deleted file mode 100644 index 58e4ae73..00000000 --- a/src/muya/lib/utils/dirtyToc.js +++ /dev/null @@ -1,39 +0,0 @@ -import { Lexer } from '../parser/marked' -import diacritics from 'diacritics-map' - -export const getTocFromMarkdown = markdown => { - const tokens = new Lexer({ disableInline: true }).lex(markdown) - const toc = [] - let token = null - while ((token = tokens.shift())) { - switch (token.type) { - case 'heading': { - const { depth, text } = token - toc.push({ - content: text, - lvl: depth, - slug: slugify(text) - }) - break - } - } - } - return toc -} - -export const slugify = str => { - str = str.replace(/^\s+|\s+$/g, '').toLowerCase() - - // replace accents - str = str.replace(/[À-ž]/g, c => { - return diacritics[c] || c - }) - - return str - .replace(/[^a-z0-9 -]/g, '') // remove invalid chars - .replace(/\t/g, '--') // collapse tabs and replace by -- - .replace(/\s+/g, '-') // collapse whitespace and replace by - - .replace(/^-+/, '') // trim - from start of text - .replace(/-+$/, '') // trim - from end of text - .replace(/-+/g, '-') // collapse dashes -} diff --git a/src/muya/themes/dark.css b/src/muya/themes/dark.css deleted file mode 100755 index 566561ce..00000000 --- a/src/muya/themes/dark.css +++ /dev/null @@ -1,633 +0,0 @@ -/* - * Open Sans - * https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i&subset=latin-ext - */ - @font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 300; - src: local('Open Sans Light'), local('OpenSans-Light'), - url('./fonts/open-sans-v15-latin_latin-ext-300.woff') format('woff'); -} -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 300; - src: local('Open Sans Light Italic'), local('OpenSans-LightItalic'), - url('./fonts/open-sans-v15-latin_latin-ext-300italic.woff') format('woff'); -} -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans Regular'), local('OpenSans-Regular'), - url('./fonts/open-sans-v15-latin_latin-ext-regular.woff') format('woff'); -} -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 400; - src: local('Open Sans Italic'), local('OpenSans-Italic'), - url('./fonts/open-sans-v15-latin_latin-ext-italic.woff') format('woff'); -} -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 600; - src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'), - url('./fonts/open-sans-v15-latin_latin-ext-600.woff') format('woff'); -} -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 600; - src: local('Open Sans SemiBold Italic'), local('OpenSans-SemiBoldItalic'), - url('./fonts/open-sans-v15-latin_latin-ext-600italic.woff') format('woff'); -} -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), - url('./fonts/open-sans-v15-latin_latin-ext-700.woff') format('woff'); -} -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 700; - src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'), - url('./fonts/open-sans-v15-latin_latin-ext-700italic.woff') format('woff'); -} - -/* - * DejaVu Sans Mono - */ -@font-face { - font-family: "DejaVu Sans Mono"; - src: local('DejaVu Sans Mono'), url('./fonts/DejaVuSansMono.ttf'); -} -@font-face { - font-family: "DejaVu Sans Mono"; - font-weight: bold; - src: url('./fonts/DejaVuSansMono-Bold.ttf'); -} -@font-face { - font-family: "DejaVu Sans Mono"; - font-style: oblique; - font-weight: bold; - src: url('./fonts/DejaVuSansMono-BoldOblique.ttf'); -} -@font-face { - font-family: "DejaVu Sans Mono"; - font-style: italic; - font-weight: bold; - src: url('./fonts/DejaVuSansMono-BoldOblique.ttf'); -} -@font-face { - font-family: "DejaVu Sans Mono"; - font-style: italic; - src: url('./fonts/DejaVuSansMono-Oblique.ttf'); -} -@font-face { - font-family: "DejaVu Sans Mono"; - font-style: oblique; - src: url('./fonts/DejaVuSansMono-Oblique.ttf'); -} - -html, body { - font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 16px; - color: rgb(217, 217, 217); - line-height: 1.6; - background: rgb(45, 45, 45); -} - -span code, -td code, -th code, -code, -code[class*="language-"], -.CodeMirror, -pre.ag-paragraph { - font-family: "DejaVu Sans Mono", "Source Code Pro", "Droid Sans Mono", Consolas, monospace; - font-size: 14px; -} - -::-webkit-scrollbar { - background: rgb(43, 43, 43); -} -::-webkit-scrollbar:vertical { - width: 12px; -} -::-webkit-scrollbar-thumb { - background: rgb(55, 55, 55); -} -::-webkit-scrollbar-thumb:hover { - background: #3F3F3F; -} - -#ag-editor-id { - max-width: var(--editorAreaWidth); - margin: 0 auto; - padding: 20px 50px 40px 50px; - padding-top: 20px; - padding-bottom: 100px; -} - -#ag-editor-id, [contenteditable] { - outline: none; - caret-color: #efefef; -} - -.ag-float-box { - background: #303133; - border: 1px solid #303133; -} -.ag-float-item { - color: #909399; -} - -.ag-float-item-active { - background: #606266; - color: #C0C4CC; -} - -.ag-table-picker { - background: #606266; - border: 1px solid #606266; -} - -[x-placement] > .ag-popper-arrow { - border: 1px solid #606266; - border-right: none; - border-bottom: none; -} - -figure.ag-active.ag-container-block > div.ag-container-preview { - background: rgb(50, 50, 50); - border: 1px solid rgb(43, 43, 43); -} - -.ag-gray { - color: #909399; - text-decoration: none; -} - -.el-dialog { - background: rgb(43, 43, 43); -} - -.v-modal { - backdrop-filter: blur(5px); - background: rgba(0, 0, 0, .9); -} - -body > *:first-child { - margin-top: 0 !important; -} - -body>*:last-child { - margin-bottom: 0 !important; -} - -a { - color: #4183C4; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - position: relative; - margin-top: 1rem; - margin-bottom: 1rem; - font-weight: bold; - line-height: 1.4; - cursor: text; -} - -h1:hover a.anchor, -h2:hover a.anchor, -h3:hover a.anchor, -h4:hover a.anchor, -h5:hover a.anchor, -h6:hover a.anchor { - /*background: url("../../images/modules/styleguide/para.png") no-repeat 10px center;*/ - text-decoration: none; -} - -h1 tt, -h1 code { - font-size: inherit; -} - -h2 tt, -h2 code { - font-size: inherit; -} - -h3 tt, -h3 code { - font-size: inherit; -} - -h4 tt, -h4 code { - font-size: inherit; -} - -h5 tt, -h5 code { - font-size: inherit; -} - -h6 tt, -h6 code { - font-size: inherit; -} - -h1 { - padding-bottom: .3em; - font-size: 2.25em; - line-height: 1.2; - border-bottom: 1px solid #eee; -} - -h2 { - padding-bottom: .3em; - font-size: 1.75em; - line-height: 1.225; - border-bottom: 1px solid #eee; -} - -h3 { - font-size: 1.5em; - line-height: 1.43; -} - -h4 { - font-size: 1.25em; -} - -h5 { - font-size: 1em; -} - -h6 { - font-size: 1em; - color: #777; -} - -p, -blockquote, -ul, -ol, -dl, -table { - margin: 0.5em 0; -} - -li>ol, -li>ul { - margin: 0 0; -} - -hr { - height: 4px; - padding: 0; - margin: 16px 0; - background-color: #545454; - border: 0 none; - overflow: hidden; - box-sizing: content-box; -} - -p:not(.ag-active)[data-role="hr"]::before { - background-color: #545454; -} - -body>h2:first-child { - margin-top: 0; - padding-top: 0; -} - -body>h1:first-child { - margin-top: 0; - padding-top: 0; -} - -body>h1:first-child+h2 { - margin-top: 0; - padding-top: 0; -} - -body>h3:first-child, -body>h4:first-child, -body>h5:first-child, -body>h6:first-child { - margin-top: 0; - padding-top: 0; -} - -a:first-child h1, -a:first-child h2, -a:first-child h3, -a:first-child h4, -a:first-child h5, -a:first-child h6 { - margin-top: 0; - padding-top: 0; -} - -h1 p, -h2 p, -h3 p, -h4 p, -h5 p, -h6 p { - margin-top: 0; -} - -li p.first { - display: inline-block; -} - -li.ag-tight-list-item > p { - padding: 0; - margin: 0; -} - -ul, -ol { - padding-left: 30px; -} - -ul:first-child, -ol:first-child { - margin-top: 0; -} - -ul:last-child, -ol:last-child { - margin-bottom: 0; -} - -blockquote { - border-left: 4px solid #606266; - padding: 0 15px; - color: #999999; -} - -blockquote blockquote { - padding-right: 0; -} - -table { - padding: 0; - word-break: initial; -} - -table tr { - margin: 0; - padding: 0; -} - -table thead tr, -table tr:nth-child(2n) { - background-color: #303133; -} - -table tr th { - font-weight: bold; - border: 2px solid #606266; - text-align: left; - margin: 0; - padding: 6px 13px; -} - -table tr td { - border: 1px solid #606266; - text-align: left; - margin: 0; - padding: 6px 13px; -} - -table tr th:first-child, -table tr td:first-child { - margin-top: 0; -} - -table tr th:last-child, -table tr td:last-child { - margin-bottom: 0; -} - -/* custom add */ -span.ag-line code, -th code, -td code { - border: none; - padding: 2px 4px; - border-radius: 3px; - font-size: 90%; - color: #efefef; - background-color: #606266; - border-radius: 4px; - /*font-family: Menlo, Monaco, Consolas, "Courier New", monospace;*/ -} - -@media print { - html { - font-size: 13px; - } - table, - pre { - page-break-inside: avoid; - } - pre { - word-wrap: break-word; - } -} - -.ag-hide.ag-math > .ag-math-render { - color: #efefef; -} - -blockquote .ag-hide.ag-math > .ag-math-render { - color: #999999; -} - -.ag-gray.ag-math > .ag-math-render { - color: #333333; - background: #f6f8fa; - box-shadow: 0 2px 12px 0 rgba(255, 255, 255, 0.3); -} -.ag-gray.ag-math > .ag-math-render::before { - border-bottom-color: #f6f8fa; -} - -#ag-editor-id pre.ag-html-block { - padding: 0 .5rem; - margin-top: 0; -} - -#ag-editor-id pre.ag-front-matter { - background: transparent; - border-bottom: 1px dashed #efefef; -} - -#ag-editor-id pre.ag-multiple-math { - background: transparent; - border: 1px solid #909399; -} - -#ag-editor-id span.ag-math-text, -#ag-editor-id pre.ag-multiple-math span.ag-multiple-math-line { - color: lightsalmon; -} - -#ag-editor-id div.ag-math-preview { - background: #303133; - border-color: #333; -} - -#ag-editor-id pre.ag-html-block { - font-size: 90%; - line-height: 1.6; - background: var(--primaryColor); - color: #777777; -} - -.ag-color-dark { - color: #c6c6c6; -} - -/** - * okaidia theme for JavaScript, CSS and HTML - * Loosely based on Monokai textmate theme by http://www.monokai.nl/ - * @author ocodia - */ - -code[class*="language-"], -pre.ag-paragraph { - color: #f8f8f2; - /*font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;*/ - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - word-wrap: normal; - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; - overflow: visible; - } - - /* Code blocks */ - pre.ag-paragraph { - padding: 1em; - margin: 1em 0; - border-radius: 0.3em; - } - - :not(pre) > code[class*="language-"], - pre.ag-paragraph { - background: #272822; - } - - /* Inline code */ - :not(pre) > code[class*="language-"] { - padding: .1em; - border-radius: .3em; - white-space: normal; - } - - .token.comment, - .token.prolog, - .token.doctype, - .token.cdata { - color: slategray; - } - - .token.punctuation { - color: #f8f8f2; - } - - .namespace { - opacity: .7; - } - - .token.property, - .token.tag, - .token.constant, - .token.symbol { - color: #f92672; - } - - .token.boolean, - .token.number { - color: #ae81ff; - } - - .token.selector, - .token.attr-name, - .token.string, - .token.char, - .token.builtin { - color: #a6e22e; - } - - .token.inserted { - color: #22863a; - background: #f0fff4; -} - -.token.deleted { - color: #b31d28; - background: #ffeef0; -} - - .token.operator, - .token.entity, - .token.url, - .language-css .token.string, - .style .token.string, - .token.variable { - color: #f8f8f2; - } - - .token.atrule, - .token.attr-value, - .token.function, - .token.class-name { - color: #e6db74; - } - - .token.keyword { - color: #66d9ef; - } - - .token.regex, - .token.important { - color: #fd971f; - } - - .token.important, - .token.bold { - font-weight: bold; - } - .token.italic { - font-style: italic; - } - - .token.entity { - cursor: help; - } - diff --git a/src/muya/themes/light.css b/src/muya/themes/light.css index 0c456dc3..8fea493c 100644 --- a/src/muya/themes/light.css +++ b/src/muya/themes/light.css @@ -99,7 +99,6 @@ html, body { font-size: 16px; color: #303133; line-height: 1.6; - background: rgb(252, 252, 252); } span code, @@ -113,19 +112,6 @@ pre.ag-paragraph { font-size: 14px; } -::-webkit-scrollbar { - background: rgb(252, 252, 252); -} -::-webkit-scrollbar:vertical { - width: 12px; -} -::-webkit-scrollbar-thumb { - background: #EBEEF5; -} -::-webkit-scrollbar-thumb:hover { - background: #E1E4EA; -} - #ag-editor-id { max-width: var(--editorAreaWidth); margin: 0 auto; @@ -136,17 +122,16 @@ pre.ag-paragraph { #ag-editor-id, [contenteditable] { outline: none; - caret-color: #000000; } .ag-gray { - color: #C0C4CC; + color: var(--editorColor30); text-decoration: none; } .v-modal { backdrop-filter: blur(5px); - background: rgba(230, 230, 230, .9); + background: var(--floatBorderColor); } body>*:first-child { @@ -158,7 +143,7 @@ body>*:last-child { } a { - color: #4183C4; + color: var(--themeColor); } h1, @@ -216,35 +201,27 @@ h6 code { } h1 { - padding-bottom: .3em; - font-size: 2.25em; - line-height: 1.2; - border-bottom: 1px solid #eee; + font-size: 40px; } h2 { - padding-bottom: .3em; - font-size: 1.75em; - line-height: 1.225; - border-bottom: 1px solid #eee; + font-size: 32px; } h3 { - font-size: 1.5em; - line-height: 1.43; + font-size: 28px; } h4 { - font-size: 1.25em; + font-size: 24px; } h5 { - font-size: 1em; + font-size: 20px; } h6 { - font-size: 1em; - color: #777; + font-size: 16px; } p, @@ -271,10 +248,6 @@ hr { box-sizing: content-box; } -p:not(.ag-active)[data-role="hr"]::before { - background: gainsboro; -} - body>h2:first-child { margin-top: 0; padding-top: 0; @@ -317,6 +290,14 @@ h6 p { margin-top: 0; } +li.ag-paragraph { + color: var(--themeColor); +} + +li > * { + color: var(--editorColor); +} + li p.first { display: inline-block; } @@ -342,9 +323,20 @@ ol:last-child { } blockquote { - border-left: 4px solid #dddddd; - padding: 0 15px; - color: #777777; + position: relative; + padding: 0 30px; + color: var(--editorColor50); +} + +blockquote::before { + content: ''; + display: block; + height: 100%; + width: 2px; + position: absolute; + left: 13px; + top: 0; + background: var(--themeColor); } blockquote blockquote { @@ -363,19 +355,19 @@ table tr { table thead tr, table tr:nth-child(2n) { - background-color: #fafafa; + background-color: var(--codeBlockBgColor); } table tr th { font-weight: bold; - border: 1px solid #ebeef5; + border: 1px solid var(--editorColor10); text-align: left; margin: 0; padding: 6px 13px; } table tr td { - border: 1px solid #ebeef5; + border: 1px solid var(--editorColor10); text-align: left; margin: 0; padding: 6px 13px; @@ -394,7 +386,7 @@ table tr td:last-child { span code, td code, th code { - background-color: rgba(27, 31, 35, 0.05); + background-color: var(--codeBlockBgColor); border-radius: 3px; padding: 0; /*font-family: Menlo, Monaco, Consolas, "Courier New", monospace;*/ @@ -402,7 +394,7 @@ th code { font-size: 85%; margin: 0; padding: 0.2em 0.4em; - color: #24292e; + color: var(--editorColor); } :not(pre) > code[class*="language-"], @@ -411,10 +403,10 @@ pre[class*="language-"] { overflow: visible; font-size: 90%; line-height: 1.6; - background: #f6f8fa; + background: var(--codeBlockBgColor); border: 0; border-radius: 3px; - color: #777777; + color: var(--editorColor50); } @media print { @@ -431,20 +423,20 @@ pre[class*="language-"] { } .ag-hide.ag-math > .ag-math-render { - color: #333333; + color: var(--editorColor); } blockquote .ag-hide.ag-math > .ag-math-render { - color: #777777; + color: var(--editorColor50); } .ag-gray.ag-math > .ag-math-render { - color: #f6f8fa; - background: #333333; - box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.3); + color: var(--editorColor); + background: var(--floatBgColor); + box-shadow: 0 4px 8px 0 var(--floatBorderColor); } .ag-gray.ag-math > .ag-math-render::before { - border-bottom-color: #333333; + border-bottom-color: var(--floatBgColor); } #ag-editor-id pre.ag-html-block { @@ -454,15 +446,7 @@ blockquote .ag-hide.ag-math > .ag-math-render { } #ag-editor-id pre.ag-active.ag-html-block { - background: #f6f8fa; -} - -p:not(.ag-active)[data-role="hr"]::before { - background: gainsboro; -} - -.fg-color-dark { - color: #303133; + background: var(--codeBlockBgColor); } /* prismjs default theme */ diff --git a/src/renderer/app.vue b/src/renderer/app.vue index 1162e6bb..6f053ab1 100644 --- a/src/renderer/app.vue +++ b/src/renderer/app.vue @@ -2,18 +2,17 @@
- +
- + @@ -22,34 +21,28 @@ :markdown="markdown" :filename="filename" :cursor="cursor" - :theme="theme" :source-code="sourceCode" :show-tab-bar="showTabBar" :text-direction="textDirection" > + + + + + + +
- - - - - - - -
- - \ No newline at end of file diff --git a/src/renderer/components/editorWithTabs/editor.vue b/src/renderer/components/editorWithTabs/editor.vue index 6f0b9e5c..b5366da7 100644 --- a/src/renderer/components/editorWithTabs/editor.vue +++ b/src/renderer/components/editorWithTabs/editor.vue @@ -1,8 +1,8 @@ @@ -71,23 +68,24 @@ import ImagePathPicker from 'muya/lib/ui/imagePicker' import FormatPicker from 'muya/lib/ui/formatPicker' import bus from '../../bus' + import Search from '../search.vue' import { animatedScrollTo } from '../../util' import { showContextMenu } from '../../contextMenu/editor' import Printer from '@/services/printService' import { DEFAULT_EDITOR_FONT_FAMILY } from '@/config' - import { addThemeStyle } from '@/util/theme' + + import 'muya/themes/light.css' const STANDAR_Y = 320 export default { + components: { + Search + }, props: { filename: { type: String }, - theme: { - type: String, - required: true - }, markdown: String, cursor: Object, textDirection: { @@ -138,13 +136,6 @@ focus: function (value) { this.editor.setFocusMode(value) }, - theme: function (value, oldValue) { - const { editor } = this - if (value !== oldValue && editor) { - editor.setTheme(value) - addThemeStyle(value) - } - }, fontSize: function (value, oldValue) { const { editor } = this if (value !== oldValue && editor) { @@ -175,7 +166,6 @@ this.printer = new Printer() const ele = this.$refs.editor const { - theme, focus: focusMode, markdown, preferLooseListItem, @@ -196,7 +186,6 @@ Muya.use(ImagePathPicker) Muya.use(FormatPicker) const { container } = this.editor = new Muya(ele, { - theme, focusMode, markdown, preferLooseListItem, @@ -212,9 +201,6 @@ this.scrollToCursor() } - // the default theme is light write in the store - addThemeStyle(theme) - // listen for bus events. bus.$on('file-loaded', this.setMarkdownToEditor) bus.$on('undo', this.handleUndo) @@ -336,7 +322,7 @@ }, scrollToHeader (slug) { - return this.scrollToElement(`[data-id="${slug}"]`) + return this.scrollToElement(`#${slug}`) }, scrollToElement (selector) { @@ -445,7 +431,6 @@ this.editor.copy(name) } }, - beforeDestroy () { bus.$off('file-loaded', this.setMarkdownToEditor) bus.$off('undo', this.handleUndo) @@ -479,6 +464,31 @@ height: 100%; position: relative; flex: 1; + color: var(--editorColor); + & .ag-dialog-table { + & .el-button { + width: 70px; + } + & .el-button:focus, + & .el-button:hover { + color: var(--themeColor); + border-color: var(--highlightColor); + background-color: var(--selectionColor); + } + & .el-button--primary { + color: #fff; + background: var(--themeColor); + border-color: var(--highlightColor); + + } + & .el-input-number.is-controls-right .el-input__inner { + background: var(--itemBgColor); + color: var(--editorColor); + } + & .el-input-number.is-controls-right .el-input__inner:focus { + border-color: var(--themeColor); + } + } } .editor-wrapper.source { position: absolute; @@ -496,26 +506,4 @@ padding-top: calc(50vh - 136px); padding-bottom: calc(50vh - 54px); } - /* for dark theme */ - .dark.editor-wrapper, - .dark.editor-wrapper #ag-editor-id { - background: var(--darkBgColor); - } - - - diff --git a/src/renderer/components/editorWithTabs/index.vue b/src/renderer/components/editorWithTabs/index.vue index ca20aea6..9582c6af 100644 --- a/src/renderer/components/editorWithTabs/index.vue +++ b/src/renderer/components/editorWithTabs/index.vue @@ -5,7 +5,6 @@
.editor-with-tabs { + width: 100%; + height: 100%; + padding-top: var(--titleBarHeight); flex: 1; display: flex; flex-direction: column; - height: calc(100vh - var(--titleBarHeight)); + overflow: hidden; + background: var(--editorBgColor); & > .container { flex: 1; overflow: hidden; diff --git a/src/renderer/components/editorWithTabs/sourceCode.vue b/src/renderer/components/editorWithTabs/sourceCode.vue index 6dd127be..8067fadb 100644 --- a/src/renderer/components/editorWithTabs/sourceCode.vue +++ b/src/renderer/components/editorWithTabs/sourceCode.vue @@ -1,7 +1,6 @@