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