From 6012fc929ed11939918afec7fdb236dfd68279b7 Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Fri, 15 Feb 2019 22:42:56 +0100 Subject: [PATCH 1/3] add Nord theme to CodeMirror --- browser/components/MarkdownPreview.js | 31 ++++++------- browser/lib/consts.js | 44 +++++++++++++++---- browser/main/lib/ConfigManager.js | 27 ++++-------- browser/main/modals/PreferencesModal/UiTab.js | 11 +++-- extra_scripts/codemirror/theme/nord.css | 25 +++++++++++ 5 files changed, 91 insertions(+), 47 deletions(-) create mode 100644 extra_scripts/codemirror/theme/nord.css diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index ff5e85e1..d6be4765 100755 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -670,14 +670,14 @@ export default class MarkdownPreview extends React.Component { ) } - GetCodeThemeLink (theme) { - theme = consts.THEMES.some(_theme => _theme === theme) && - theme !== 'default' - ? theme - : 'elegant' - return theme.startsWith('solarized') - ? `${appPath}/node_modules/codemirror/theme/solarized.css` - : `${appPath}/node_modules/codemirror/theme/${theme}.css` + GetCodeThemeLink (name) { + const theme = consts.THEMES.find(theme => theme.name === name) + + if (theme) { + return `${appPath}/${theme.path}` + } else { + return `${appPath}/node_modules/codemirror/theme/elegant.css` + } } rewriteIframe () { @@ -735,9 +735,9 @@ export default class MarkdownPreview extends React.Component { } ) - codeBlockTheme = consts.THEMES.some(_theme => _theme === codeBlockTheme) - ? codeBlockTheme - : 'default' + codeBlockTheme = consts.THEMES.find(theme => theme.name === codeBlockTheme) + + const codeBlockThemeClassName = codeBlockTheme ? codeBlockTheme.className : 'cm-s-default' _.forEach( this.refs.root.contentWindow.document.querySelectorAll('.code code'), @@ -760,14 +760,11 @@ export default class MarkdownPreview extends React.Component { }) } } + el.parentNode.appendChild(copyIcon) el.innerHTML = '' - if (codeBlockTheme.indexOf('solarized') === 0) { - const [refThema, color] = codeBlockTheme.split(' ') - el.parentNode.className += ` cm-s-${refThema} cm-s-${color}` - } else { - el.parentNode.className += ` cm-s-${codeBlockTheme}` - } + el.parentNode.className += ` ${codeBlockThemeClassName}` + CodeMirror.runMode(content, syntax.mime, el, { tabSize: indentSize }) diff --git a/browser/lib/consts.js b/browser/lib/consts.js index 84b962eb..8cd3409a 100644 --- a/browser/lib/consts.js +++ b/browser/lib/consts.js @@ -3,14 +3,40 @@ const fs = require('sander') const { remote } = require('electron') const { app } = remote -const themePath = process.env.NODE_ENV === 'production' - ? path.join(app.getAppPath(), './node_modules/codemirror/theme') - : require('path').resolve('./node_modules/codemirror/theme') -const themes = fs.readdirSync(themePath) - .map((themePath) => { - return themePath.substring(0, themePath.lastIndexOf('.')) - }) -themes.splice(themes.indexOf('solarized'), 1, 'solarized dark', 'solarized light') +const isProduction = process.env.NODE_ENV === 'production' +const paths = [ + isProduction ? path.join(app.getAppPath(), './node_modules/codemirror/theme') : path.resolve('./node_modules/codemirror/theme'), + isProduction ? path.join(app.getAppPath(), './extra_scripts/codemirror/theme') : path.resolve('./extra_scripts/codemirror/theme') +] + +const themes = paths + .map(directory => fs.readdirSync(directory).map(file => { + const name = file.substring(0, file.lastIndexOf('.')) + + return { + name, + path: path.join(directory.split(/\//g).slice(-3).join('/'), file), + className: `cm-s-${name}` + } + })) + .reduce((accumulator, value) => accumulator.concat(value), []) + .sort((a, b) => a.name.localeCompare(b.name)) + +themes.splice(themes.findIndex(({ name }) => name === 'solarized'), 1, { + name: 'solarized dark', + path: 'node_modules/codemirror/theme/solarized.css', + className: `cm-s-solarized cm-s-dark` +}, { + name: 'solarized light', + path: 'node_modules/codemirror/theme/solarized.css', + className: `cm-s-solarized cm-s-light` +}) + +themes.splice(0, 0, { + name: 'default', + path: '/node_modules/codemirror/theme/elegant.css', + className: `cm-s-default` +}) const snippetFile = process.env.NODE_ENV !== 'test' ? path.join(app.getPath('userData'), 'snippets.json') @@ -35,7 +61,7 @@ const consts = { 'Dodger Blue', 'Violet Eggplant' ], - THEMES: ['default'].concat(themes), + THEMES: themes, SNIPPET_FILE: snippetFile, DEFAULT_EDITOR_FONT_FAMILY: [ 'Monaco', diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js index 05f3d822..f20b3d88 100644 --- a/browser/main/lib/ConfigManager.js +++ b/browser/main/lib/ConfigManager.js @@ -132,16 +132,12 @@ function get () { document.head.appendChild(editorTheme) } - config.editor.theme = consts.THEMES.some((theme) => theme === config.editor.theme) - ? config.editor.theme - : 'default' + const theme = consts.THEMES.find(theme => theme.name === config.editor.theme) - if (config.editor.theme !== 'default') { - if (config.editor.theme.startsWith('solarized')) { - editorTheme.setAttribute('href', '../node_modules/codemirror/theme/solarized.css') - } else { - editorTheme.setAttribute('href', '../node_modules/codemirror/theme/' + config.editor.theme + '.css') - } + if (theme) { + editorTheme.setAttribute('href', `../${theme.path}`) + } else { + config.editor.theme = 'default' } } @@ -177,16 +173,11 @@ function set (updates) { editorTheme.setAttribute('rel', 'stylesheet') document.head.appendChild(editorTheme) } - const newTheme = consts.THEMES.some((theme) => theme === newConfig.editor.theme) - ? newConfig.editor.theme - : 'default' - if (newTheme !== 'default') { - if (newTheme.startsWith('solarized')) { - editorTheme.setAttribute('href', '../node_modules/codemirror/theme/solarized.css') - } else { - editorTheme.setAttribute('href', '../node_modules/codemirror/theme/' + newTheme + '.css') - } + const newTheme = consts.THEMES.find(theme => theme.name === newConfig.editor.theme) + + if (newTheme) { + editorTheme.setAttribute('href', `../${newTheme.path}`) } ipcRenderer.send('config-renew', { diff --git a/browser/main/modals/PreferencesModal/UiTab.js b/browser/main/modals/PreferencesModal/UiTab.js index 316b7f9d..994ca3d3 100644 --- a/browser/main/modals/PreferencesModal/UiTab.js +++ b/browser/main/modals/PreferencesModal/UiTab.js @@ -128,8 +128,13 @@ class UiTab extends React.Component { const newCodemirrorTheme = this.refs.editorTheme.value if (newCodemirrorTheme !== codemirrorTheme) { - checkHighLight.setAttribute('href', `../node_modules/codemirror/theme/${newCodemirrorTheme.split(' ')[0]}.css`) + const theme = consts.THEMES.find(theme => theme.name === newCodemirrorTheme) + + if (theme) { + checkHighLight.setAttribute('href', `../${theme.path}`) + } } + this.setState({ config: newConfig, codemirrorTheme: newCodemirrorTheme }, () => { const {ui, editor, preview} = this.props.config this.currentConfig = {ui, editor, preview} @@ -355,7 +360,7 @@ class UiTab extends React.Component { > { themes.map((theme) => { - return () + return () }) } @@ -670,7 +675,7 @@ class UiTab extends React.Component { > { themes.map((theme) => { - return () + return () }) } diff --git a/extra_scripts/codemirror/theme/nord.css b/extra_scripts/codemirror/theme/nord.css new file mode 100644 index 00000000..3c0461de --- /dev/null +++ b/extra_scripts/codemirror/theme/nord.css @@ -0,0 +1,25 @@ +/* Theme: nord */ + +.cm-s-nord.CodeMirror { color: #d8dee9; } +.cm-s-nord.CodeMirror { background: #2e3440; } +.cm-s-nord .CodeMirror-cursor { color: #d8dee9; } +.cm-s-nord .CodeMirror-activeline-background { background: #434c5e52 !important; } +.cm-s-nord .CodeMirror-selected { background: undefined; } +.cm-s-nord .cm-comment { color: #4c566a; } +.cm-s-nord .cm-string { color: #a3be8c; } +.cm-s-nord .cm-string-2 { color: #8fbcbb; } +.cm-s-nord .cm-property { color: #8fbcbb; } +.cm-s-nord .cm-qualifier { color: #8fbcbb; } +.cm-s-nord .cm-tag { color: #81a1c1; } +.cm-s-nord .cm-attribute { color: #8fbcbb; } +.cm-s-nord .cm-number { color: #b48ead; } +.cm-s-nord .cm-keyword { color: #81a1c1; } +.cm-s-nord .cm-operator { color: #81a1c1; } +.cm-s-nord .cm-error { background: #bf616a; color: #d8dee9; } +.cm-s-nord .cm-invalidchar { background: #bf616a; color: #d8dee9; } +.cm-s-nord .cm-variable { color: #d8dee9; } +.cm-s-nord .cm-variable-2 { color: #8fbcbb; } +.cm-s-nord .CodeMirror-gutters { + background: #3b4252; + color: #d8dee9; +} \ No newline at end of file From ba913b77e7d78c83e75dfb3cc46d3fbf6612dd33 Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Sun, 5 May 2019 03:25:29 +0200 Subject: [PATCH 2/3] use constants and fix cursor color --- browser/lib/consts.js | 13 ++++++++----- extra_scripts/codemirror/theme/nord.css | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/browser/lib/consts.js b/browser/lib/consts.js index 8cd3409a..9c993055 100644 --- a/browser/lib/consts.js +++ b/browser/lib/consts.js @@ -3,10 +3,13 @@ const fs = require('sander') const { remote } = require('electron') const { app } = remote +const CODEMIRROR_THEME_PATH = 'node_modules/codemirror/theme' +const CODEMIRROR_EXTRA_THEME_PATH = 'extra_scripts/codemirror/theme' + const isProduction = process.env.NODE_ENV === 'production' const paths = [ - isProduction ? path.join(app.getAppPath(), './node_modules/codemirror/theme') : path.resolve('./node_modules/codemirror/theme'), - isProduction ? path.join(app.getAppPath(), './extra_scripts/codemirror/theme') : path.resolve('./extra_scripts/codemirror/theme') + isProduction ? path.join(app.getAppPath(), CODEMIRROR_THEME_PATH) : path.resolve(CODEMIRROR_THEME_PATH), + isProduction ? path.join(app.getAppPath(), CODEMIRROR_EXTRA_THEME_PATH) : path.resolve(CODEMIRROR_EXTRA_THEME_PATH) ] const themes = paths @@ -24,17 +27,17 @@ const themes = paths themes.splice(themes.findIndex(({ name }) => name === 'solarized'), 1, { name: 'solarized dark', - path: 'node_modules/codemirror/theme/solarized.css', + path: `${CODEMIRROR_THEME_PATH}/solarized.css`, className: `cm-s-solarized cm-s-dark` }, { name: 'solarized light', - path: 'node_modules/codemirror/theme/solarized.css', + path: `${CODEMIRROR_THEME_PATH}/solarized.css`, className: `cm-s-solarized cm-s-light` }) themes.splice(0, 0, { name: 'default', - path: '/node_modules/codemirror/theme/elegant.css', + path: `${CODEMIRROR_THEME_PATH}/elegant.css`, className: `cm-s-default` }) diff --git a/extra_scripts/codemirror/theme/nord.css b/extra_scripts/codemirror/theme/nord.css index 3c0461de..c6b52e8a 100644 --- a/extra_scripts/codemirror/theme/nord.css +++ b/extra_scripts/codemirror/theme/nord.css @@ -2,7 +2,7 @@ .cm-s-nord.CodeMirror { color: #d8dee9; } .cm-s-nord.CodeMirror { background: #2e3440; } -.cm-s-nord .CodeMirror-cursor { color: #d8dee9; } +.cm-s-nord .CodeMirror-cursor { color: #d8dee9; border-color: #d8dee9; } .cm-s-nord .CodeMirror-activeline-background { background: #434c5e52 !important; } .cm-s-nord .CodeMirror-selected { background: undefined; } .cm-s-nord .cm-comment { color: #4c566a; } From 8cd24a5734159abf4e4c742b1ae17e896628c723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Vi=E1=BB=87t=20H=C6=B0ng?= Date: Thu, 2 May 2019 11:58:18 +1200 Subject: [PATCH 3/3] fixed open empty link 2 --- browser/components/MarkdownPreview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index d6be4765..55b36243 100755 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -255,7 +255,7 @@ export default class MarkdownPreview extends React.Component { return } // No contextMenu was passed to us -> execute our own link-opener - if (event.target.tagName.toLowerCase() === 'a') { + if (event.target.tagName.toLowerCase() === 'a' && event.target.getAttribute('href')) { const href = event.target.href const isLocalFile = href.startsWith('file:') if (isLocalFile) {