diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index b848c775..9d9e5f2b 100644 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -3,7 +3,23 @@ import markdown from 'browser/lib/markdown' import _ from 'lodash' import CodeMirror from 'codemirror' import consts from 'browser/lib/consts' +import Raphael from 'raphael' +import flowchart from 'flowchart' +function decodeHTMLEntities (text) { + var entities = [ + ['apos', '\''], + ['amp', '&'], + ['lt', '<'], + ['gt', '>'] + ] + + for (var i = 0, max = entities.length; i < max; ++i) { + text = text.replace(new RegExp('&' + entities[i][0] + ';', 'g'), entities[i][1]) + } + + return text +} const { remote } = require('electron') const { app } = remote const path = require('path') @@ -64,14 +80,15 @@ export default class MarkdownPreview extends React.Component { e.preventDefault() e.stopPropagation() - let href = e.target.getAttribute('href') + let anchor = e.target.closest('a') + let href = anchor.getAttribute('href') if (_.isString(href) && href.match(/^#/)) { let targetElement = this.refs.root.contentWindow.document.getElementById(href.substring(1, href.length)) if (targetElement != null) { this.getWindow().scrollTo(0, targetElement.offsetTop) } } else { - shell.openExternal(e.target.href) + shell.openExternal(href) } } @@ -182,18 +199,40 @@ export default class MarkdownPreview extends React.Component { ? codeBlockTheme : 'default' - Array.prototype.forEach.call(this.refs.root.contentWindow.document.querySelectorAll('.code code'), (el) => { - let syntax = CodeMirror.findModeByName(el.className) - if (syntax == null) syntax = CodeMirror.findModeByName('Plain Text') - CodeMirror.requireMode(syntax.mode, () => { - let content = el.innerHTML - el.innerHTML = '' - el.parentNode.className += ` cm-s-${codeBlockTheme} CodeMirror` - CodeMirror.runMode(content, syntax.mime, el, { - tabSize: indentSize + Array.prototype.forEach + .call(this.refs.root.contentWindow.document.querySelectorAll('.code code'), (el) => { + let syntax = CodeMirror.findModeByName(el.className) + if (syntax == null) syntax = CodeMirror.findModeByName('Plain Text') + CodeMirror.requireMode(syntax.mode, () => { + let content = el.innerHTML + el.innerHTML = '' + el.parentNode.className += ` cm-s-${codeBlockTheme} CodeMirror` + CodeMirror.runMode(content, syntax.mime, el, { + tabSize: indentSize + }) }) }) - }) + let opts = {} + if (this.props.theme === 'dark') { + opts['font-color'] = '#DDD' + opts['line-color'] = '#DDD' + opts['element-color'] = '#DDD' + opts['fill'] = '#3A404C' + } + Array.prototype.forEach + .call(this.refs.root.contentWindow.document.querySelectorAll('.flowchart'), (el) => { + Raphael.setWindow(this.getWindow()) + try { + let diagram = flowchart.parse(decodeHTMLEntities(el.innerHTML)) + el.innerHTML = '' + diagram.drawSVG(el, opts) + Array.prototype.forEach.call(el.querySelectorAll('a'), (el) => { + el.addEventListener('click', this.anchorClickHandler) + }) + } catch (e) { + console.error(e) + } + }) } focus () { diff --git a/browser/components/markdown.styl b/browser/components/markdown.styl index f8ee6345..d572e29b 100644 --- a/browser/components/markdown.styl +++ b/browser/components/markdown.styl @@ -202,6 +202,9 @@ pre margin 0 0 1em display flex line-height 1.4em + &.flowchart + display flex + justify-content center &.CodeMirror height initial &>code @@ -279,7 +282,7 @@ body[data-theme="dark"] code border-color darken(themeDarkBorder, 10%) - background-color lighten(themeDarkPreview, 5%) + background-color lighten(themeDarkPreview, 10%) pre border-color lighten(#21252B, 20%) diff --git a/browser/lib/markdown.js b/browser/lib/markdown.js index 6985b2a2..6af8f0b0 100644 --- a/browser/lib/markdown.js +++ b/browser/lib/markdown.js @@ -20,6 +20,9 @@ var md = markdownit({ html: true, xhtmlOut: true, highlight: function (str, lang) { + if (lang === 'flowchart') { + return `
${str}
` + } return '
' +
     createGutter(str) +
     '' +
diff --git a/lib/finder.html b/lib/finder.html
index 1b7f12ea..c454fc18 100644
--- a/lib/finder.html
+++ b/lib/finder.html
@@ -33,6 +33,9 @@
   
   
 
+  
+  
+
   
   
   
diff --git a/lib/main.html b/lib/main.html
index 5cb40371..c1acfcb8 100644
--- a/lib/main.html
+++ b/lib/main.html
@@ -61,6 +61,9 @@
 
   
 
+  
+  
+
   
   
   
diff --git a/oh-my-cdn.json b/oh-my-cdn.json
index 128a503f..4607a299 100644
--- a/oh-my-cdn.json
+++ b/oh-my-cdn.json
@@ -6,6 +6,8 @@
     "redux": "https://cdnjs.cloudflare.com/ajax/libs/redux/3.5.2/redux.js",
     "react-redux": "https://unpkg.com/react-redux@4.4.5/dist/react-redux.min.js",
     "katex": "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.js",
-    "katex-style": "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.css"
+    "katex-style": "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.css",
+    "raphael": "https://raw.githubusercontent.com/DmitryBaranovskiy/raphael/master/raphael.js",
+    "flowchart": "https://cdnjs.cloudflare.com/ajax/libs/flowchart/1.6.3/flowchart.js"
   }
 }
diff --git a/webpack-skeleton.js b/webpack-skeleton.js
index 96c7c6fc..5399ce73 100644
--- a/webpack-skeleton.js
+++ b/webpack-skeleton.js
@@ -47,7 +47,9 @@ var config = {
       'react-dom': 'var ReactDOM',
       'react-redux': 'var ReactRedux',
       'codemirror': 'var CodeMirror',
-      'redux': 'var Redux'
+      'redux': 'var Redux',
+      'raphael': 'var Raphael',
+      'flowchart': 'var flowchart'
     }
   ]
 }