From c6a9c9c57d73a5e84476d473a3b75f3efbdc1392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Vi=E1=BB=87t=20H=C6=B0ng?= Date: Tue, 5 Jun 2018 21:24:37 +0700 Subject: [PATCH 01/14] fixed disappear scrollbar --- browser/components/MarkdownPreview.js | 18 ++++++++++++++++++ browser/main/global.styl | 13 +++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index 89f71a9b..7b5facf2 100755 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -126,6 +126,21 @@ body p { ` } +const scrollBarStyle = ` +::-webkit-scrollbar-track { + border-radius: 10px; +} + +::-webkit-scrollbar { + width: 12px; +} + +::-webkit-scrollbar-thumb { + box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); + background-color: rgba(0, 0, 0, 0.3); +} +` + const { shell } = require('electron') const OSX = global.process.platform === 'darwin' @@ -298,6 +313,9 @@ export default class MarkdownPreview extends React.Component { + ` CSS_FILES.forEach((file) => { diff --git a/browser/main/global.styl b/browser/main/global.styl index 7025163f..c68df2b8 100644 --- a/browser/main/global.styl +++ b/browser/main/global.styl @@ -15,6 +15,16 @@ body font-weight 200 -webkit-font-smoothing antialiased +::-webkit-scrollbar-track + border-radius 10px + +::-webkit-scrollbar + width 12px + +::-webkit-scrollbar-thumb + box-shadow inset 0 0 6px rgba(0, 0, 0, 0.3) + background-color rgba(0, 0, 0, 0.3) + button, input, select, textarea font-family DEFAULT_FONTS @@ -85,7 +95,7 @@ modalBackColor = white absolute top left bottom right background-color modalBackColor z-index modalZIndex + 1 - + body[data-theme="dark"] .ModalBase @@ -140,4 +150,3 @@ body[data-theme="monokai"] background-color $ui-monokai-backgroundColor .sortableItemHelper color: $ui-monokai-text-color - From 31f1ebe801e9ffa5180934aff46fc68e654b9a4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Vi=E1=BB=87t=20H=C6=B0ng?= Date: Tue, 5 Jun 2018 21:31:50 +0700 Subject: [PATCH 02/14] removed unnecessary style --- browser/components/MarkdownPreview.js | 4 ---- browser/main/global.styl | 3 --- 2 files changed, 7 deletions(-) diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index 7b5facf2..0348996d 100755 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -127,10 +127,6 @@ body p { } const scrollBarStyle = ` -::-webkit-scrollbar-track { - border-radius: 10px; -} - ::-webkit-scrollbar { width: 12px; } diff --git a/browser/main/global.styl b/browser/main/global.styl index c68df2b8..9a967085 100644 --- a/browser/main/global.styl +++ b/browser/main/global.styl @@ -15,9 +15,6 @@ body font-weight 200 -webkit-font-smoothing antialiased -::-webkit-scrollbar-track - border-radius 10px - ::-webkit-scrollbar width 12px From 883b4c4c26a5602bed148c3d2d8a4e8e9d12229b Mon Sep 17 00:00:00 2001 From: Max Buranbaev Date: Tue, 3 Jul 2018 10:27:13 +0500 Subject: [PATCH 03/14] adding timeout on creating a note --- browser/main/modals/NewNoteModal.js | 86 +++++++++++++++++------------ 1 file changed, 52 insertions(+), 34 deletions(-) diff --git a/browser/main/modals/NewNoteModal.js b/browser/main/modals/NewNoteModal.js index 185004e7..59c6d80a 100644 --- a/browser/main/modals/NewNoteModal.js +++ b/browser/main/modals/NewNoteModal.js @@ -12,8 +12,7 @@ class NewNoteModal extends React.Component { constructor (props) { super(props) - this.state = { - } + this.state = {} } componentDidMount () { @@ -35,19 +34,20 @@ class NewNoteModal extends React.Component { title: '', content: '' }) - .then((note) => { + .then(note => { const noteHash = note.key dispatch({ type: 'UPDATE_NOTE', note: note }) + hashHistory.push({ pathname: location.pathname, - query: {key: noteHash} + query: { key: noteHash } }) ee.emit('list:jump', noteHash) ee.emit('detail:focus') - this.props.close() + setTimeout(this.props.close, 200) }) } @@ -69,13 +69,15 @@ class NewNoteModal extends React.Component { folder: folder, title: '', description: '', - snippets: [{ - name: '', - mode: 'text', - content: '' - }] + snippets: [ + { + name: '', + mode: 'text', + content: '' + } + ] }) - .then((note) => { + .then(note => { const noteHash = note.key dispatch({ type: 'UPDATE_NOTE', @@ -83,7 +85,7 @@ class NewNoteModal extends React.Component { }) hashHistory.push({ pathname: location.pathname, - query: {key: noteHash} + query: { key: noteHash } }) ee.emit('list:jump', noteHash) ee.emit('detail:focus') @@ -106,49 +108,65 @@ class NewNoteModal extends React.Component { render () { return ( -
this.handleKeyDown(e)} + onKeyDown={e => this.handleKeyDown(e)} >
{i18n.__('Make a note')}
- this.handleCloseButtonClick(e)} /> + this.handleCloseButtonClick(e)} + />
- -
-
{i18n.__('Tab to switch format')}
+
+ {i18n.__('Tab to switch format')} +
) } } -NewNoteModal.propTypes = { -} +NewNoteModal.propTypes = {} export default CSSModules(NewNoteModal, styles) From 3c8337cf544eb7c63e14bc809cddb1bfa05ed39a Mon Sep 17 00:00:00 2001 From: Max Buranbaev Date: Tue, 3 Jul 2018 10:29:22 +0500 Subject: [PATCH 04/14] adding timeout one creating a snippet --- browser/main/modals/NewNoteModal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/main/modals/NewNoteModal.js b/browser/main/modals/NewNoteModal.js index 59c6d80a..b748587c 100644 --- a/browser/main/modals/NewNoteModal.js +++ b/browser/main/modals/NewNoteModal.js @@ -89,7 +89,7 @@ class NewNoteModal extends React.Component { }) ee.emit('list:jump', noteHash) ee.emit('detail:focus') - this.props.close() + setTimeout(this.props.close, 200) }) } From 866a0e75347892e5860bcc5892902cf53e1854cb Mon Sep 17 00:00:00 2001 From: JianXu Date: Tue, 3 Jul 2018 15:10:08 +0800 Subject: [PATCH 05/14] Add mermaid support --- browser/components/MarkdownPreview.js | 5 + browser/components/render/MermaidRender.js | 28 ++ browser/lib/markdown.js | 3 + package.json | 1 + yarn.lock | 293 ++++++++++++++++++++- 5 files changed, 324 insertions(+), 6 deletions(-) create mode 100644 browser/components/render/MermaidRender.js diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index 124bd8c3..e148f576 100755 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -7,6 +7,7 @@ import 'codemirror-mode-elixir' import consts from 'browser/lib/consts' import Raphael from 'raphael' import flowchart from 'flowchart' +import mermaidRender from './render/MermaidRender' import SequenceDiagram from 'js-sequence-diagrams' import eventEmitter from 'browser/main/lib/eventEmitter' import htmlTextHelper from 'browser/lib/htmlTextHelper' @@ -496,6 +497,10 @@ export default class MarkdownPreview extends React.Component { el.innerHTML = 'Sequence diagram parse error: ' + e.message } }) + + _.forEach(this.refs.root.contentWindow.document.querySelectorAll('.mermaid'), (el) => { + mermaidRender(el, htmlTextHelper.decodeEntities(el.innerHTML)) + }) } focus () { diff --git a/browser/components/render/MermaidRender.js b/browser/components/render/MermaidRender.js new file mode 100644 index 00000000..e057cf34 --- /dev/null +++ b/browser/components/render/MermaidRender.js @@ -0,0 +1,28 @@ +import mermaidAPI from 'mermaid' + +function getRandomInt (min, max) { + return Math.floor(Math.random() * (max - min)) + min +} + +function getId () { + var pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' + var id = 'm-' + for (var i = 0; i < 7; i++) { + id += pool[getRandomInt(0, 16)] + } + return id +} + +function render (element, content) { + try { + mermaidAPI.render(getId(), content, (svgGraph) => { + element.innerHTML = svgGraph + }) + } catch (e) { + console.error(e) + element.className = 'mermaid-error' + element.innerHTML = 'mermaid diagram parse error: ' + e.message + } +} + +export default render diff --git a/browser/lib/markdown.js b/browser/lib/markdown.js index 4dafa4a3..48532538 100644 --- a/browser/lib/markdown.js +++ b/browser/lib/markdown.js @@ -40,6 +40,9 @@ class Markdown { if (langType === 'sequence') { return `
${str}
` } + if (langType === 'mermaid') { + return `
${str}
` + } return '
' +
           '' + fileName + '' +
           createGutter(str, firstLineNumber) +
diff --git a/package.json b/package.json
index a1d17e57..42839940 100644
--- a/package.json
+++ b/package.json
@@ -81,6 +81,7 @@
     "markdown-it-plantuml": "^1.1.0",
     "markdown-it-smartarrows": "^1.0.1",
     "mdurl": "^1.0.1",
+    "mermaid": "^8.0.0-rc.8",
     "moment": "^2.10.3",
     "mousetrap": "^1.6.1",
     "mousetrap-global-bind": "^1.1.0",
diff --git a/yarn.lock b/yarn.lock
index 42f51ab9..10d28022 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1806,6 +1806,10 @@ combined-stream@~0.0.4, combined-stream@~0.0.5:
   dependencies:
     delayed-stream "0.0.5"
 
+commander@2:
+  version "2.16.0"
+  resolved "http://registry.npm.taobao.org/commander/download/commander-2.16.0.tgz#f16390593996ceb4f3eeb020b31d78528f7f8a50"
+
 commander@2.3.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873"
@@ -2146,12 +2150,250 @@ currently-unhandled@^0.4.1:
   dependencies:
     array-find-index "^1.0.1"
 
+d3-array@1, d3-array@1.2.1, d3-array@^1.2.0:
+  version "1.2.1"
+  resolved "http://registry.npm.taobao.org/d3-array/download/d3-array-1.2.1.tgz#d1ca33de2f6ac31efadb8e050a021d7e2396d5dc"
+
+d3-axis@1.0.8:
+  version "1.0.8"
+  resolved "http://registry.npm.taobao.org/d3-axis/download/d3-axis-1.0.8.tgz#31a705a0b535e65759de14173a31933137f18efa"
+
+d3-brush@1.0.4:
+  version "1.0.4"
+  resolved "http://registry.npm.taobao.org/d3-brush/download/d3-brush-1.0.4.tgz#00c2f238019f24f6c0a194a26d41a1530ffe7bc4"
+  dependencies:
+    d3-dispatch "1"
+    d3-drag "1"
+    d3-interpolate "1"
+    d3-selection "1"
+    d3-transition "1"
+
+d3-chord@1.0.4:
+  version "1.0.4"
+  resolved "http://registry.npm.taobao.org/d3-chord/download/d3-chord-1.0.4.tgz#7dec4f0ba886f713fe111c45f763414f6f74ca2c"
+  dependencies:
+    d3-array "1"
+    d3-path "1"
+
+d3-collection@1, d3-collection@1.0.4:
+  version "1.0.4"
+  resolved "http://registry.npm.taobao.org/d3-collection/download/d3-collection-1.0.4.tgz#342dfd12837c90974f33f1cc0a785aea570dcdc2"
+
+d3-color@1:
+  version "1.2.0"
+  resolved "http://registry.npm.taobao.org/d3-color/download/d3-color-1.2.0.tgz#d1ea19db5859c86854586276ec892cf93148459a"
+
+d3-color@1.0.3:
+  version "1.0.3"
+  resolved "http://registry.npm.taobao.org/d3-color/download/d3-color-1.0.3.tgz#bc7643fca8e53a8347e2fbdaffa236796b58509b"
+
+d3-dispatch@1, d3-dispatch@1.0.3:
+  version "1.0.3"
+  resolved "http://registry.npm.taobao.org/d3-dispatch/download/d3-dispatch-1.0.3.tgz#46e1491eaa9b58c358fce5be4e8bed626e7871f8"
+
+d3-drag@1, d3-drag@1.2.1:
+  version "1.2.1"
+  resolved "http://registry.npm.taobao.org/d3-drag/download/d3-drag-1.2.1.tgz#df8dd4c502fb490fc7462046a8ad98a5c479282d"
+  dependencies:
+    d3-dispatch "1"
+    d3-selection "1"
+
+d3-dsv@1, d3-dsv@1.0.8:
+  version "1.0.8"
+  resolved "http://registry.npm.taobao.org/d3-dsv/download/d3-dsv-1.0.8.tgz#907e240d57b386618dc56468bacfe76bf19764ae"
+  dependencies:
+    commander "2"
+    iconv-lite "0.4"
+    rw "1"
+
+d3-ease@1, d3-ease@1.0.3:
+  version "1.0.3"
+  resolved "http://registry.npm.taobao.org/d3-ease/download/d3-ease-1.0.3.tgz#68bfbc349338a380c44d8acc4fbc3304aa2d8c0e"
+
+d3-force@1.1.0:
+  version "1.1.0"
+  resolved "http://registry.npm.taobao.org/d3-force/download/d3-force-1.1.0.tgz#cebf3c694f1078fcc3d4daf8e567b2fbd70d4ea3"
+  dependencies:
+    d3-collection "1"
+    d3-dispatch "1"
+    d3-quadtree "1"
+    d3-timer "1"
+
+d3-format@1:
+  version "1.3.0"
+  resolved "http://registry.npm.taobao.org/d3-format/download/d3-format-1.3.0.tgz#a3ac44269a2011cdb87c7b5693040c18cddfff11"
+
+d3-format@1.2.2:
+  version "1.2.2"
+  resolved "http://registry.npm.taobao.org/d3-format/download/d3-format-1.2.2.tgz#1a39c479c8a57fe5051b2e67a3bee27061a74e7a"
+
+d3-geo@1.9.1:
+  version "1.9.1"
+  resolved "http://registry.npm.taobao.org/d3-geo/download/d3-geo-1.9.1.tgz#157e3b0f917379d0f73bebfff3be537f49fa7356"
+  dependencies:
+    d3-array "1"
+
+d3-hierarchy@1.1.5:
+  version "1.1.5"
+  resolved "http://registry.npm.taobao.org/d3-hierarchy/download/d3-hierarchy-1.1.5.tgz#a1c845c42f84a206bcf1c01c01098ea4ddaa7a26"
+
+d3-interpolate@1:
+  version "1.2.0"
+  resolved "http://registry.npm.taobao.org/d3-interpolate/download/d3-interpolate-1.2.0.tgz#40d81bd8e959ff021c5ea7545bc79b8d22331c41"
+  dependencies:
+    d3-color "1"
+
+d3-interpolate@1.1.6:
+  version "1.1.6"
+  resolved "http://registry.npm.taobao.org/d3-interpolate/download/d3-interpolate-1.1.6.tgz#2cf395ae2381804df08aa1bf766b7f97b5f68fb6"
+  dependencies:
+    d3-color "1"
+
+d3-path@1, d3-path@1.0.5:
+  version "1.0.5"
+  resolved "http://registry.npm.taobao.org/d3-path/download/d3-path-1.0.5.tgz#241eb1849bd9e9e8021c0d0a799f8a0e8e441764"
+
+d3-polygon@1.0.3:
+  version "1.0.3"
+  resolved "http://registry.npm.taobao.org/d3-polygon/download/d3-polygon-1.0.3.tgz#16888e9026460933f2b179652ad378224d382c62"
+
+d3-quadtree@1, d3-quadtree@1.0.3:
+  version "1.0.3"
+  resolved "http://registry.npm.taobao.org/d3-quadtree/download/d3-quadtree-1.0.3.tgz#ac7987e3e23fe805a990f28e1b50d38fcb822438"
+
+d3-queue@3.0.7:
+  version "3.0.7"
+  resolved "http://registry.npm.taobao.org/d3-queue/download/d3-queue-3.0.7.tgz#c93a2e54b417c0959129d7d73f6cf7d4292e7618"
+
+d3-random@1.1.0:
+  version "1.1.0"
+  resolved "http://registry.npm.taobao.org/d3-random/download/d3-random-1.1.0.tgz#6642e506c6fa3a648595d2b2469788a8d12529d3"
+
+d3-request@1.0.6:
+  version "1.0.6"
+  resolved "http://registry.npm.taobao.org/d3-request/download/d3-request-1.0.6.tgz#a1044a9ef4ec28c824171c9379fae6d79474b19f"
+  dependencies:
+    d3-collection "1"
+    d3-dispatch "1"
+    d3-dsv "1"
+    xmlhttprequest "1"
+
+d3-scale@1.0.7:
+  version "1.0.7"
+  resolved "http://registry.npm.taobao.org/d3-scale/download/d3-scale-1.0.7.tgz#fa90324b3ea8a776422bd0472afab0b252a0945d"
+  dependencies:
+    d3-array "^1.2.0"
+    d3-collection "1"
+    d3-color "1"
+    d3-format "1"
+    d3-interpolate "1"
+    d3-time "1"
+    d3-time-format "2"
+
+d3-selection@1, d3-selection@1.3.0, d3-selection@^1.1.0:
+  version "1.3.0"
+  resolved "http://registry.npm.taobao.org/d3-selection/download/d3-selection-1.3.0.tgz#d53772382d3dc4f7507bfb28bcd2d6aed2a0ad6d"
+
+d3-shape@1.2.0:
+  version "1.2.0"
+  resolved "http://registry.npm.taobao.org/d3-shape/download/d3-shape-1.2.0.tgz#45d01538f064bafd05ea3d6d2cb748fd8c41f777"
+  dependencies:
+    d3-path "1"
+
+d3-time-format@2, d3-time-format@2.1.1:
+  version "2.1.1"
+  resolved "http://registry.npm.taobao.org/d3-time-format/download/d3-time-format-2.1.1.tgz#85b7cdfbc9ffca187f14d3c456ffda268081bb31"
+  dependencies:
+    d3-time "1"
+
+d3-time@1, d3-time@1.0.8:
+  version "1.0.8"
+  resolved "http://registry.npm.taobao.org/d3-time/download/d3-time-1.0.8.tgz#dbd2d6007bf416fe67a76d17947b784bffea1e84"
+
+d3-timer@1, d3-timer@1.0.7:
+  version "1.0.7"
+  resolved "http://registry.npm.taobao.org/d3-timer/download/d3-timer-1.0.7.tgz#df9650ca587f6c96607ff4e60cc38229e8dd8531"
+
+d3-transition@1, d3-transition@1.1.1:
+  version "1.1.1"
+  resolved "http://registry.npm.taobao.org/d3-transition/download/d3-transition-1.1.1.tgz#d8ef89c3b848735b060e54a39b32aaebaa421039"
+  dependencies:
+    d3-color "1"
+    d3-dispatch "1"
+    d3-ease "1"
+    d3-interpolate "1"
+    d3-selection "^1.1.0"
+    d3-timer "1"
+
+d3-voronoi@1.1.2:
+  version "1.1.2"
+  resolved "http://registry.npm.taobao.org/d3-voronoi/download/d3-voronoi-1.1.2.tgz#1687667e8f13a2d158c80c1480c5a29cb0d8973c"
+
+d3-zoom@1.7.1:
+  version "1.7.1"
+  resolved "http://registry.npm.taobao.org/d3-zoom/download/d3-zoom-1.7.1.tgz#02f43b3c3e2db54f364582d7e4a236ccc5506b63"
+  dependencies:
+    d3-dispatch "1"
+    d3-drag "1"
+    d3-interpolate "1"
+    d3-selection "1"
+    d3-transition "1"
+
+d3@^4.13.0:
+  version "4.13.0"
+  resolved "http://registry.npm.taobao.org/d3/download/d3-4.13.0.tgz#ab236ff8cf0cfc27a81e69bf2fb7518bc9b4f33d"
+  dependencies:
+    d3-array "1.2.1"
+    d3-axis "1.0.8"
+    d3-brush "1.0.4"
+    d3-chord "1.0.4"
+    d3-collection "1.0.4"
+    d3-color "1.0.3"
+    d3-dispatch "1.0.3"
+    d3-drag "1.2.1"
+    d3-dsv "1.0.8"
+    d3-ease "1.0.3"
+    d3-force "1.1.0"
+    d3-format "1.2.2"
+    d3-geo "1.9.1"
+    d3-hierarchy "1.1.5"
+    d3-interpolate "1.1.6"
+    d3-path "1.0.5"
+    d3-polygon "1.0.3"
+    d3-quadtree "1.0.3"
+    d3-queue "3.0.7"
+    d3-random "1.1.0"
+    d3-request "1.0.6"
+    d3-scale "1.0.7"
+    d3-selection "1.3.0"
+    d3-shape "1.2.0"
+    d3-time "1.0.8"
+    d3-time-format "2.1.1"
+    d3-timer "1.0.7"
+    d3-transition "1.1.1"
+    d3-voronoi "1.1.2"
+    d3-zoom "1.7.1"
+
 d@1:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f"
   dependencies:
     es5-ext "^0.10.9"
 
+dagre-d3-renderer@^0.5.8:
+  version "0.5.8"
+  resolved "http://registry.npm.taobao.org/dagre-d3-renderer/download/dagre-d3-renderer-0.5.8.tgz#aa071bb71d3c4d67426925906f3f6ddead49c1a3"
+  dependencies:
+    dagre-layout "^0.8.8"
+    lodash "^4.17.5"
+
+dagre-layout@^0.8.8:
+  version "0.8.8"
+  resolved "http://registry.npm.taobao.org/dagre-layout/download/dagre-layout-0.8.8.tgz#9b6792f24229f402441c14162c1049e3f261f6d9"
+  dependencies:
+    graphlibrary "^2.2.0"
+    lodash "^4.17.5"
+
 dashdash@^1.12.0:
   version "1.14.1"
   resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
@@ -3685,6 +3927,12 @@ graceful-fs@~1.2.0:
   version "1.2.3"
   resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364"
 
+graphlibrary@^2.2.0:
+  version "2.2.0"
+  resolved "http://registry.npm.taobao.org/graphlibrary/download/graphlibrary-2.2.0.tgz#017a14899775228dec4497a39babfdd6bf56eac6"
+  dependencies:
+    lodash "^4.17.5"
+
 growly@^1.3.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
@@ -3874,6 +4122,10 @@ hawk@~2.3.0:
     hoek "2.x.x"
     sntp "1.x.x"
 
+he@^1.1.1:
+  version "1.1.1"
+  resolved "http://registry.npm.taobao.org/he/download/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
+
 highlight.js@^9.3.0:
   version "9.12.0"
   resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e"
@@ -4037,16 +4289,16 @@ i18n-2@^0.7.2:
     debug "^3.1.0"
     sprintf "^0.1.5"
 
-iconv-lite@0.4.19:
-  version "0.4.19"
-  resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
-
-iconv-lite@^0.4.19, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
+iconv-lite@0.4, iconv-lite@^0.4.19, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
   version "0.4.23"
   resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63"
   dependencies:
     safer-buffer ">= 2.1.2 < 3"
 
+iconv-lite@0.4.19:
+  version "0.4.19"
+  resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
+
 iconv-lite@~0.2.11:
   version "0.2.11"
   resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.2.11.tgz#1ce60a3a57864a292d1321ff4609ca4bb965adc8"
@@ -5298,7 +5550,7 @@ lodash@^3.5.0:
   version "3.10.1"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
 
-lodash@^4.0.0, lodash@^4.0.1, lodash@^4.11.1, lodash@^4.12.0, lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.1, lodash@^4.6.1:
+lodash@^4.0.0, lodash@^4.0.1, lodash@^4.11.1, lodash@^4.12.0, lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.1, lodash@^4.6.1:
   version "4.17.10"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
 
@@ -5527,6 +5779,19 @@ merge@^1.1.3:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da"
 
+mermaid@^8.0.0-rc.8:
+  version "8.0.0-rc.8"
+  resolved "http://registry.npm.taobao.org/mermaid/download/mermaid-8.0.0-rc.8.tgz#74ed54d0d46e9ee71c4db2730b2d83d516a21e72"
+  dependencies:
+    d3 "^4.13.0"
+    dagre-d3-renderer "^0.5.8"
+    dagre-layout "^0.8.8"
+    graphlibrary "^2.2.0"
+    he "^1.1.1"
+    lodash "^4.17.5"
+    moment "^2.21.0"
+    scope-css "^1.0.5"
+
 methods@~1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
@@ -5700,6 +5965,10 @@ moment@^2.10.3:
   version "2.22.1"
   resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.1.tgz#529a2e9bf973f259c9643d237fda84de3a26e8ad"
 
+moment@^2.21.0:
+  version "2.22.2"
+  resolved "http://registry.npm.taobao.org/moment/download/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66"
+
 mousetrap-global-bind@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/mousetrap-global-bind/-/mousetrap-global-bind-1.1.0.tgz#cd7de9222bd0646fa2e010d54c84a74c26a88edd"
@@ -7345,6 +7614,10 @@ run-series@^1.1.1:
   version "1.1.8"
   resolved "https://registry.yarnpkg.com/run-series/-/run-series-1.1.8.tgz#2c4558f49221e01cd6371ff4e0a1e203e460fc36"
 
+rw@1:
+  version "1.3.3"
+  resolved "http://registry.npm.taobao.org/rw/download/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4"
+
 rx-lite@^3.1.2:
   version "3.1.2"
   resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
@@ -7422,6 +7695,10 @@ sax@>=0.6.0, sax@^1.2.1, sax@^1.2.4, sax@~1.2.1:
   version "1.2.4"
   resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
 
+scope-css@^1.0.5:
+  version "1.1.0"
+  resolved "http://registry.npm.taobao.org/scope-css/download/scope-css-1.1.0.tgz#74eff45461bc9d3f3b29ed575b798cd722fa1256"
+
 semver-diff@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36"
@@ -8822,6 +9099,10 @@ xmldom@0.1.x:
   version "0.1.27"
   resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9"
 
+xmlhttprequest@1:
+  version "1.8.0"
+  resolved "http://registry.npm.taobao.org/xmlhttprequest/download/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc"
+
 xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"

From 680eaa1d4ac448d2e8905983a47eafcfd11cf46d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=98=D0=B2=D0=B0?=
 =?UTF-8?q?=D0=BD=D0=BE=D0=B2?= 
Date: Wed, 4 Jul 2018 13:33:47 +0300
Subject: [PATCH 06/14] Filtering displayed notes in Detail component

---
 browser/main/Detail/index.js | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/browser/main/Detail/index.js b/browser/main/Detail/index.js
index 2c451085..3e6e450e 100644
--- a/browser/main/Detail/index.js
+++ b/browser/main/Detail/index.js
@@ -9,6 +9,7 @@ import ee from 'browser/main/lib/eventEmitter'
 import StatusBar from '../StatusBar'
 import i18n from 'browser/lib/i18n'
 import debounceRender from 'react-debounce-render'
+import searchFromNotes from 'browser/lib/search'
 
 const OSX = global.process.platform === 'darwin'
 
@@ -35,11 +36,38 @@ class Detail extends React.Component {
   }
 
   render () {
-    const { location, data, config } = this.props
+    const { location, data, params, config } = this.props
     let note = null
     if (location.query.key != null) {
       const noteKey = location.query.key
-      note = data.noteMap.get(noteKey)
+      let displayedNotes, noteKeys
+
+      if (location.pathname.match(/\/home/) || location.pathname.match(/alltags/)) {
+        displayedNotes = data.noteMap.map(note => note)
+      }
+      if (location.pathname.match(/\/starred/)) {
+        displayedNotes = data.starredSet.toJS().map(uniqueKey => data.noteMap.get(uniqueKey))
+      }
+      if (location.pathname.match(/\/searched/)) {
+        displayedNotes = searchFromNotes(
+          data.noteMap.map(note => note),
+          params.searchword
+        )
+      }
+      if (location.pathname.match(/\/trashed/)) {
+        displayedNotes = data.trashedSet.toJS().map(uniqueKey => data.noteMap.get(uniqueKey))
+      }
+      if (location.pathname.match(/\/tags/)) {
+        const listOfTags = params.tagname.split(' ')
+        displayedNotes = data.noteMap.map(note => note).filter(note =>
+          listOfTags.every(tag => note.tags.includes(tag))
+        )
+      }
+
+      noteKeys = displayedNotes.map(note => note.key)
+      if (noteKeys.includes(noteKey)) {
+        note = data.noteMap.get(noteKey)
+      }
     }
 
     if (note == null) {

From c69be5465576691d1c37914d2cbc87944dd6ccb6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=98=D0=B2=D0=B0?=
 =?UTF-8?q?=D0=BD=D0=BE=D0=B2?= 
Date: Wed, 4 Jul 2018 14:02:26 +0300
Subject: [PATCH 07/14] Fixing empty string searching

---
 browser/main/Detail/index.js | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/browser/main/Detail/index.js b/browser/main/Detail/index.js
index 3e6e450e..75a3f91a 100644
--- a/browser/main/Detail/index.js
+++ b/browser/main/Detail/index.js
@@ -40,7 +40,7 @@ class Detail extends React.Component {
     let note = null
     if (location.query.key != null) {
       const noteKey = location.query.key
-      let displayedNotes, noteKeys
+      let displayedNotes = []
 
       if (location.pathname.match(/\/home/) || location.pathname.match(/alltags/)) {
         displayedNotes = data.noteMap.map(note => note)
@@ -49,10 +49,10 @@ class Detail extends React.Component {
         displayedNotes = data.starredSet.toJS().map(uniqueKey => data.noteMap.get(uniqueKey))
       }
       if (location.pathname.match(/\/searched/)) {
-        displayedNotes = searchFromNotes(
-          data.noteMap.map(note => note),
-          params.searchword
-        )
+        const searchStr = params.searchword
+        const allNotes = data.noteMap.map(note => note)
+        displayedNotes = searchStr === undefined || searchStr === '' ? allNotes
+          : searchFromNotes(allNotes, searchStr)
       }
       if (location.pathname.match(/\/trashed/)) {
         displayedNotes = data.trashedSet.toJS().map(uniqueKey => data.noteMap.get(uniqueKey))
@@ -64,7 +64,7 @@ class Detail extends React.Component {
         )
       }
 
-      noteKeys = displayedNotes.map(note => note.key)
+      const noteKeys = displayedNotes.map(note => note.key)
       if (noteKeys.includes(noteKey)) {
         note = data.noteMap.get(noteKey)
       }

From 4a3602099a55bc6afe1f34269aa2cecbbf9986be Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=98=D0=B2=D0=B0?=
 =?UTF-8?q?=D0=BD=D0=BE=D0=B2?= 
Date: Wed, 4 Jul 2018 16:09:49 +0300
Subject: [PATCH 08/14] Difference home and searched notes from trashed units

---
 browser/main/Detail/index.js | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/browser/main/Detail/index.js b/browser/main/Detail/index.js
index 75a3f91a..90edf10e 100644
--- a/browser/main/Detail/index.js
+++ b/browser/main/Detail/index.js
@@ -38,30 +38,43 @@ class Detail extends React.Component {
   render () {
     const { location, data, params, config } = this.props
     let note = null
+
+    function differenceWithTrashed (notes) {
+      const trashedNotes = data.trashedSet.toJS().map(uniqueKey => data.noteMap.get(uniqueKey))
+      return _.differenceWith(notes, trashedNotes, (note, trashed) => note.key === trashed.key)
+    }
+
     if (location.query.key != null) {
       const noteKey = location.query.key
       let displayedNotes = []
 
       if (location.pathname.match(/\/home/) || location.pathname.match(/alltags/)) {
-        displayedNotes = data.noteMap.map(note => note)
+        const allNotes = data.noteMap.map(note => note)
+        displayedNotes = differenceWithTrashed(allNotes)
       }
+
       if (location.pathname.match(/\/starred/)) {
         displayedNotes = data.starredSet.toJS().map(uniqueKey => data.noteMap.get(uniqueKey))
       }
+
       if (location.pathname.match(/\/searched/)) {
         const searchStr = params.searchword
         const allNotes = data.noteMap.map(note => note)
-        displayedNotes = searchStr === undefined || searchStr === '' ? allNotes
+        const searchedNotes = searchStr === undefined || searchStr === '' ? allNotes
           : searchFromNotes(allNotes, searchStr)
+        displayedNotes = differenceWithTrashed(searchedNotes)
       }
+
       if (location.pathname.match(/\/trashed/)) {
         displayedNotes = data.trashedSet.toJS().map(uniqueKey => data.noteMap.get(uniqueKey))
       }
+
       if (location.pathname.match(/\/tags/)) {
         const listOfTags = params.tagname.split(' ')
-        displayedNotes = data.noteMap.map(note => note).filter(note =>
+        const searchedNotes = data.noteMap.map(note => note).filter(note =>
           listOfTags.every(tag => note.tags.includes(tag))
         )
+        displayedNotes = differenceWithTrashed(searchedNotes)
       }
 
       const noteKeys = displayedNotes.map(note => note.key)

From 806a5daa865a275452aa65e8b5f42c96029fd30c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=98=D0=B2=D0=B0?=
 =?UTF-8?q?=D0=BD=D0=BE=D0=B2?= 
Date: Thu, 5 Jul 2018 11:23:57 +0300
Subject: [PATCH 09/14] Processing all location's pathnames

---
 browser/main/Detail/index.js | 35 +++++++++++------------------------
 1 file changed, 11 insertions(+), 24 deletions(-)

diff --git a/browser/main/Detail/index.js b/browser/main/Detail/index.js
index 90edf10e..b6b6ef14 100644
--- a/browser/main/Detail/index.js
+++ b/browser/main/Detail/index.js
@@ -39,42 +39,29 @@ class Detail extends React.Component {
     const { location, data, params, config } = this.props
     let note = null
 
-    function differenceWithTrashed (notes) {
-      const trashedNotes = data.trashedSet.toJS().map(uniqueKey => data.noteMap.get(uniqueKey))
-      return _.differenceWith(notes, trashedNotes, (note, trashed) => note.key === trashed.key)
-    }
-
     if (location.query.key != null) {
       const noteKey = location.query.key
-      let displayedNotes = []
-
-      if (location.pathname.match(/\/home/) || location.pathname.match(/alltags/)) {
-        const allNotes = data.noteMap.map(note => note)
-        displayedNotes = differenceWithTrashed(allNotes)
-      }
-
-      if (location.pathname.match(/\/starred/)) {
-        displayedNotes = data.starredSet.toJS().map(uniqueKey => data.noteMap.get(uniqueKey))
-      }
+      const allNotes = data.noteMap.map(note => note)
+      const trashedNotes = data.trashedSet.toJS().map(uniqueKey => data.noteMap.get(uniqueKey))
+      let displayedNotes = allNotes
 
       if (location.pathname.match(/\/searched/)) {
         const searchStr = params.searchword
-        const allNotes = data.noteMap.map(note => note)
-        const searchedNotes = searchStr === undefined || searchStr === '' ? allNotes
+        displayedNotes = searchStr === undefined || searchStr === '' ? allNotes
           : searchFromNotes(allNotes, searchStr)
-        displayedNotes = differenceWithTrashed(searchedNotes)
-      }
-
-      if (location.pathname.match(/\/trashed/)) {
-        displayedNotes = data.trashedSet.toJS().map(uniqueKey => data.noteMap.get(uniqueKey))
       }
 
       if (location.pathname.match(/\/tags/)) {
         const listOfTags = params.tagname.split(' ')
-        const searchedNotes = data.noteMap.map(note => note).filter(note =>
+        displayedNotes = data.noteMap.map(note => note).filter(note =>
           listOfTags.every(tag => note.tags.includes(tag))
         )
-        displayedNotes = differenceWithTrashed(searchedNotes)
+      }
+
+      if (location.pathname.match(/\/trashed/)) {
+        displayedNotes = trashedNotes
+      } else {
+        displayedNotes = _.differenceWith(displayedNotes, trashedNotes, (note, trashed) => note.key === trashed.key)
       }
 
       const noteKeys = displayedNotes.map(note => note.key)

From dfcf6d2729ac3a010926a5a7661f1e738b927ca4 Mon Sep 17 00:00:00 2001
From: Kazz Yokomizo 
Date: Fri, 6 Jul 2018 15:37:10 +0900
Subject: [PATCH 10/14] Update readme

---
 readme.md | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/readme.md b/readme.md
index 6c68efaf..c6674902 100644
--- a/readme.md
+++ b/readme.md
@@ -1,4 +1,4 @@
-:mega: We've launched [Boostnote Bounty Program](http://bit.ly/2I5Tpik).
+:mega: The Boostnote team launches [IssueHunt](https://issuehunt.io/) for sustainable open-source ecosystem.
 
 ![Boostnote app screenshot](./resources/repository/top.png)
 
@@ -19,8 +19,10 @@ Thank you to all the people who already contributed to Boostnote!
 
 
 ## Supporting Boostnote
-Boostnote is an open source project. It's an independent project with its ongoing development made possible entirely thanks to the support by these awesome [backers](https://github.com/BoostIO/Boostnote/blob/master/Backers.md). If you'd like to join them, please consider:
-- [Become a backer or sponsor on Open Collective.](https://opencollective.com/boostnoteio)
+Boostnote is an open source project. It's an independent project with its ongoing development made possible entirely thanks to the support by these awesome backers. 
+
+Any issues on Boostnote can be funded by anyone and that money will be distributed to contributors and maintainers. If you'd like to join them, please consider:
+- [Become a backer on IssueHunt](https://issuehunt.io/repos/53266139).
 
 ## Community
 - [Facebook Group](https://www.facebook.com/groups/boostnote/)

From 7bfb094a40eae4661ca8ec516e08ec636791f12c Mon Sep 17 00:00:00 2001
From: Junyoung Choi 
Date: Fri, 6 Jul 2018 22:07:06 +0900
Subject: [PATCH 11/14] use lighter color for scroll bar

---
 browser/components/MarkdownPreview.js | 27 +++++++++++++++++++++++++--
 browser/main/global.styl              |  9 +++++++--
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js
index 0348996d..f2157882 100755
--- a/browser/components/MarkdownPreview.js
+++ b/browser/components/MarkdownPreview.js
@@ -132,7 +132,15 @@ const scrollBarStyle = `
 }
 
 ::-webkit-scrollbar-thumb {
-  box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
+  background-color: rgba(0, 0, 0, 0.15);
+}
+`
+const scrollBarDarkStyle = `
+::-webkit-scrollbar {
+  width: 12px;
+}
+
+::-webkit-scrollbar-thumb {
   background-color: rgba(0, 0, 0, 0.3);
 }
 `
@@ -301,6 +309,21 @@ export default class MarkdownPreview extends React.Component {
     }
   }
 
+  getScrollBarStyle () {
+    const {
+      theme
+    } = this.props
+
+    switch (theme) {
+      case 'dark':
+      case 'solarized-dark':
+      case 'monokai':
+        return scrollBarDarkStyle
+      default:
+        return scrollBarStyle
+    }
+  }
+
   componentDidMount () {
     this.refs.root.setAttribute('sandbox', 'allow-scripts')
     this.refs.root.contentWindow.document.body.addEventListener('contextmenu', this.contextMenuHandler)
@@ -310,7 +333,7 @@ export default class MarkdownPreview extends React.Component {
       
       
       
     `
 
diff --git a/browser/main/global.styl b/browser/main/global.styl
index 9a967085..8f3216ef 100644
--- a/browser/main/global.styl
+++ b/browser/main/global.styl
@@ -19,8 +19,7 @@ body
   width 12px
 
 ::-webkit-scrollbar-thumb
-  box-shadow inset 0 0 6px rgba(0, 0, 0, 0.3)
-  background-color rgba(0, 0, 0, 0.3)
+  background-color rgba(0, 0, 0, 0.15)
 
 button, input, select, textarea
   font-family DEFAULT_FONTS
@@ -95,6 +94,8 @@ modalBackColor = white
 
 
 body[data-theme="dark"]
+  ::-webkit-scrollbar-thumb
+    background-color rgba(0, 0, 0, 0.3)
   .ModalBase
     .modalBack
       background-color $ui-dark-backgroundColor
@@ -135,6 +136,8 @@ body[data-theme="dark"]
   z-index modalZIndex + 5
 
 body[data-theme="solarized-dark"]
+  ::-webkit-scrollbar-thumb
+    background-color rgba(0, 0, 0, 0.3)
   .ModalBase
     .modalBack
       background-color $ui-solarized-dark-backgroundColor
@@ -142,6 +145,8 @@ body[data-theme="solarized-dark"]
     color: $ui-solarized-dark-text-color
 
 body[data-theme="monokai"]
+  ::-webkit-scrollbar-thumb
+    background-color rgba(0, 0, 0, 0.3)
   .ModalBase
     .modalBack
       background-color $ui-monokai-backgroundColor

From 1d9b3ac2b56ce995f0b434789adf6e5ef13d9d0f Mon Sep 17 00:00:00 2001
From: Junyoung Choi 
Date: Sat, 7 Jul 2018 01:22:11 +0900
Subject: [PATCH 12/14] Add sanitization for code fence

---
 browser/components/MarkdownPreview.js    | 2 +-
 browser/lib/markdown-it-sanitize-html.js | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js
index c5abd57a..a5a9e9ee 100755
--- a/browser/components/MarkdownPreview.js
+++ b/browser/components/MarkdownPreview.js
@@ -449,7 +449,7 @@ export default class MarkdownPreview extends React.Component {
         value = value.replace(codeBlock, htmlTextHelper.encodeEntities(codeBlock))
       })
     }
-    let renderedHTML = this.markdown.render(value)
+    const renderedHTML = this.markdown.render(value)
     attachmentManagement.migrateAttachments(renderedHTML, storagePath, noteKey)
     this.refs.root.contentWindow.document.body.innerHTML = attachmentManagement.fixLocalURLS(renderedHTML, storagePath)
 
diff --git a/browser/lib/markdown-it-sanitize-html.js b/browser/lib/markdown-it-sanitize-html.js
index beec9566..6d1a44b6 100644
--- a/browser/lib/markdown-it-sanitize-html.js
+++ b/browser/lib/markdown-it-sanitize-html.js
@@ -10,6 +10,9 @@ module.exports = function sanitizePlugin (md, options) {
       if (state.tokens[tokenIdx].type === 'html_block') {
         state.tokens[tokenIdx].content = sanitizeHtml(state.tokens[tokenIdx].content, options)
       }
+      if (state.tokens[tokenIdx].type === 'fence') {
+        state.tokens[tokenIdx].content = state.tokens[tokenIdx].content.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"')
+      }
       if (state.tokens[tokenIdx].type === 'inline') {
         const inlineTokens = state.tokens[tokenIdx].children
         for (let childIdx = 0; childIdx < inlineTokens.length; childIdx++) {

From e18239048013682a6811b1b02c6b1e53f30ef877 Mon Sep 17 00:00:00 2001
From: JianXu 
Date: Sat, 7 Jul 2018 23:02:17 +0800
Subject: [PATCH 13/14] Replace shortcut for 'Next Note' and 'Previous Note'

---
 lib/main-menu.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/main-menu.js b/lib/main-menu.js
index 9345bd67..5a3f06d1 100644
--- a/lib/main-menu.js
+++ b/lib/main-menu.js
@@ -235,14 +235,14 @@ const view = {
     },
     {
       label: 'Next Note',
-      accelerator: 'Control+J',
+      accelerator: 'CommandOrControl+]',
       click () {
         mainWindow.webContents.send('list:next')
       }
     },
     {
       label: 'Previous Note',
-      accelerator: 'Control+K',
+      accelerator: 'CommandOrControl+[',
       click () {
         mainWindow.webContents.send('list:prior')
       }

From 933e38eca9b34ca1ece6186cddbea8e515589c33 Mon Sep 17 00:00:00 2001
From: Eric 
Date: Mon, 9 Jul 2018 18:37:54 -0500
Subject: [PATCH 14/14] improve bracket autoclosing

---
 browser/components/CodeEditor.js                      | 7 ++++++-
 browser/main/modals/PreferencesModal/SnippetEditor.js | 7 ++++++-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js
index a4d2278e..6fb6b0ec 100644
--- a/browser/components/CodeEditor.js
+++ b/browser/components/CodeEditor.js
@@ -113,7 +113,12 @@ export default class CodeEditor extends React.Component {
       dragDrop: false,
       foldGutter: true,
       gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
-      autoCloseBrackets: true,
+      autoCloseBrackets: {
+        pairs: '()[]{}\'\'""$$**``',
+        triples: '```"""\'\'\'',
+        explode: '[]{}``$$',
+        override: true
+      },
       extraKeys: {
         Tab: function (cm) {
           const cursor = cm.getCursor()
diff --git a/browser/main/modals/PreferencesModal/SnippetEditor.js b/browser/main/modals/PreferencesModal/SnippetEditor.js
index f0e93dec..4ce5dc34 100644
--- a/browser/main/modals/PreferencesModal/SnippetEditor.js
+++ b/browser/main/modals/PreferencesModal/SnippetEditor.js
@@ -27,7 +27,12 @@ class SnippetEditor extends React.Component {
       dragDrop: false,
       foldGutter: true,
       gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
-      autoCloseBrackets: true,
+      autoCloseBrackets: {
+        pairs: '()[]{}\'\'""$$**``',
+        triples: '```"""\'\'\'',
+        explode: '[]{}``$$',
+        override: true
+      },
       mode: 'null'
     })
     this.cm.setSize('100%', '100%')