diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js
index a3e7bb93c..c9d3d9636 100644
--- a/browser/components/MarkdownPreview.js
+++ b/browser/components/MarkdownPreview.js
@@ -144,10 +144,12 @@ export default class MarkdownPreview extends React.Component {
}
handleContextMenu (e) {
+ if (!this.props.onContextMenu) return
this.props.onContextMenu(e)
}
handleMouseDown (e) {
+ if (!this.props.onMouseDown) return
if (e.target != null) {
switch (e.target.tagName) {
case 'A':
@@ -159,6 +161,7 @@ export default class MarkdownPreview extends React.Component {
}
handleMouseUp (e) {
+ if (!this.props.onMouseUp) return
if (e.target != null && e.target.tagName === 'A') {
return null
}
diff --git a/browser/components/MarkdownSplitEditor.js b/browser/components/MarkdownSplitEditor.js
new file mode 100644
index 000000000..b77c0b6b9
--- /dev/null
+++ b/browser/components/MarkdownSplitEditor.js
@@ -0,0 +1,87 @@
+import React from 'react'
+import CodeEditor from 'browser/components/CodeEditor'
+import MarkdownPreview from 'browser/components/MarkdownPreview'
+import { findStorage } from 'browser/lib/findStorage'
+
+import styles from './MarkdownSplitEditor.styl'
+import CSSModules from 'browser/lib/CSSModules'
+
+class MarkdownSplitEditor extends React.Component {
+ constructor (props) {
+ super(props)
+ this.value = props.value
+ this.focus = () => this.refs.code.focus()
+ this.reload = () => this.refs.code.reload()
+ }
+
+ handleOnChange () {
+ this.value = this.refs.code.value
+ this.props.onChange()
+ }
+
+ handleCheckboxClick (e) {
+ e.preventDefault()
+ e.stopPropagation()
+ const idMatch = /checkbox-([0-9]+)/
+ const checkedMatch = /\[x\]/i
+ const uncheckedMatch = /\[ \]/
+ if (idMatch.test(e.target.getAttribute('id'))) {
+ const lineIndex = parseInt(e.target.getAttribute('id').match(idMatch)[1], 10) - 1
+ const lines = this.refs.code.value
+ .split('\n')
+
+ const targetLine = lines[lineIndex]
+
+ if (targetLine.match(checkedMatch)) {
+ lines[lineIndex] = targetLine.replace(checkedMatch, '[ ]')
+ }
+ if (targetLine.match(uncheckedMatch)) {
+ lines[lineIndex] = targetLine.replace(uncheckedMatch, '[x]')
+ }
+ this.refs.code.setValue(lines.join('\n'))
+ }
+ }
+
+ render () {
+ const { config, value, storageKey } = this.props
+ const storage = findStorage(storageKey)
+ const previewStyle = {}
+ if (this.props.ignorePreviewPointerEvents) previewStyle.pointerEvents = 'none'
+ return (
+
+
+ this.handleCheckboxClick(e)}
+ showCopyNotification={config.ui.showCopyNotification}
+ storagePath={storage.path}
+ />
+
+ )
+ }
+}
+
+export default CSSModules(MarkdownSplitEditor, styles)
diff --git a/browser/components/MarkdownSplitEditor.styl b/browser/components/MarkdownSplitEditor.styl
new file mode 100644
index 000000000..c9afd22fe
--- /dev/null
+++ b/browser/components/MarkdownSplitEditor.styl
@@ -0,0 +1,9 @@
+.root
+ width 100%
+ height 100%
+ font-size 30px
+ display flex
+ .codeEditor
+ width 50%
+ .preview
+ width 50%
diff --git a/browser/components/markdown.styl b/browser/components/markdown.styl
index 53e935745..0600d9abf 100644
--- a/browser/components/markdown.styl
+++ b/browser/components/markdown.styl
@@ -120,6 +120,7 @@ hr
margin 15px 0
h1, h2, h3, h4, h5, h6
font-weight bold
+ word-wrap break-word
h1
font-size 2.55em
padding-bottom 0.3em
@@ -157,6 +158,7 @@ p
line-height 1.6em
margin 0 0 1em
white-space pre-line
+ word-wrap break-word
img
max-width 100%
strong, b
@@ -338,4 +340,4 @@ body[data-theme="dark"]
body[data-theme="solarized-dark"]
color $ui-solarized-dark-text-color
border-color themeDarkBorder
- background-color $ui-solarized-dark-noteDetail-backgroundColor
\ No newline at end of file
+ background-color $ui-solarized-dark-noteDetail-backgroundColor
diff --git a/browser/main/Detail/MarkdownNoteDetail.js b/browser/main/Detail/MarkdownNoteDetail.js
index 25c993d02..8d3acea9e 100644
--- a/browser/main/Detail/MarkdownNoteDetail.js
+++ b/browser/main/Detail/MarkdownNoteDetail.js
@@ -3,6 +3,7 @@ import React from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './MarkdownNoteDetail.styl'
import MarkdownEditor from 'browser/components/MarkdownEditor'
+import MarkdownSplitEditor from 'browser/components/MarkdownSplitEditor'
import TodoListPercentage from 'browser/components/TodoListPercentage'
import StarButton from './StarButton'
import TagSelect from './TagSelect'
@@ -15,6 +16,7 @@ import StatusBar from '../StatusBar'
import _ from 'lodash'
import { findNoteTitle } from 'browser/lib/findNoteTitle'
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
+import ConfigManager from 'browser/main/lib/ConfigManager'
import TrashButton from './TrashButton'
import PermanentDeleteButton from './PermanentDeleteButton'
import InfoButton from './InfoButton'
@@ -39,7 +41,8 @@ class MarkdownNoteDetail extends React.Component {
content: ''
}, props.note),
isLockButtonShown: false,
- isLocked: false
+ isLocked: false,
+ editorType: props.config.editor.type
}
this.dispatchTimer = null
@@ -233,7 +236,7 @@ class MarkdownNoteDetail extends React.Component {
}
getToggleLockButton () {
- return this.state.isLocked ? '../resources/icon/icon-edit-lock.svg' : '../resources/icon/icon-edit.svg'
+ return this.state.isLocked ? '../resources/icon/icon-previewoff-on.svg' : '../resources/icon/icon-previewoff-off.svg'
}
handleDeleteKeyDown (e) {
@@ -262,9 +265,42 @@ class MarkdownNoteDetail extends React.Component {
ee.emit('print')
}
- render () {
- const { data, config, location } = this.props
+ handleSwitchMode (type) {
+ this.setState({ editorType: type }, () => {
+ const newConfig = Object.assign({}, this.props.config)
+ newConfig.editor.type = type
+ ConfigManager.set(newConfig)
+ })
+ }
+
+ renderEditor () {
+ const { config, ignorePreviewPointerEvents } = this.props
const { note } = this.state
+ if (this.state.editorType === 'EDITOR_PREVIEW') {
+ return this.handleChange(e)}
+ ignorePreviewPointerEvents={ignorePreviewPointerEvents}
+ />
+ } else {
+ return this.handleChange(e)}
+ ignorePreviewPointerEvents={ignorePreviewPointerEvents}
+ />
+ }
+ }
+
+ render () {
+ const { data, location } = this.props
+ const { note, editorType } = this.state
const storageKey = note.storage
const folderKey = note.folder
@@ -320,11 +356,11 @@ class MarkdownNoteDetail extends React.Component {
/>
-
-
+
this.handleSwitchMode('SPLIT')}>
+
-
-
+
this.handleSwitchMode('EDITOR_PREVIEW')}>
+
@@ -360,7 +396,7 @@ class MarkdownNoteDetail extends React.Component {
this.handleFullScreenButton(e)}
>
-
+
this.handleTrashButtonClick(e)} />
@@ -390,15 +426,7 @@ class MarkdownNoteDetail extends React.Component {
{location.pathname === '/trashed' ? trashTopBar : detailTopBar}
- this.handleChange(e)}
- ignorePreviewPointerEvents={this.props.ignorePreviewPointerEvents}
- />
+ {this.renderEditor()}
-
-
- icon-WYSIWYG-off
- Created with Sketch.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/resources/icon/icon-WYSIWYG-on.svg b/resources/icon/icon-WYSIWYG-on.svg
deleted file mode 100644
index b8ee94899..000000000
--- a/resources/icon/icon-WYSIWYG-on.svg
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
- icon-WYSIWYG-on
- Created with Sketch.
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/resources/icon/icon-edit.svg b/resources/icon/icon-edit.svg
index 3707c6fe2..cb7d92cc3 100644
--- a/resources/icon/icon-edit.svg
+++ b/resources/icon/icon-edit.svg
@@ -3,11 +3,22 @@
icon-edit
Created with Sketch.
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/resources/icon/icon-full.svg b/resources/icon/icon-full.svg
new file mode 100644
index 000000000..621ebacc7
--- /dev/null
+++ b/resources/icon/icon-full.svg
@@ -0,0 +1,15 @@
+
+
+
+ icon-full
+ Created with Sketch.
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/resources/icon/icon-mode-markdown-off.svg b/resources/icon/icon-mode-markdown-off.svg
new file mode 100644
index 000000000..7f6a02352
--- /dev/null
+++ b/resources/icon/icon-mode-markdown-off.svg
@@ -0,0 +1,23 @@
+
+
+
+ icon-mode-markdown-off
+ Created with Sketch.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/resources/icon/icon-mode-split-on.svg b/resources/icon/icon-mode-split-on.svg
new file mode 100644
index 000000000..338d2bd71
--- /dev/null
+++ b/resources/icon/icon-mode-split-on.svg
@@ -0,0 +1,27 @@
+
+
+
+ icon-mode-split-on
+ Created with Sketch.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/resources/icon/icon-previewoff-off.svg b/resources/icon/icon-previewoff-off.svg
new file mode 100644
index 000000000..b0e720e7c
--- /dev/null
+++ b/resources/icon/icon-previewoff-off.svg
@@ -0,0 +1,13 @@
+
+
+
+ icon-previewoff-off
+ Created with Sketch.
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/resources/icon/icon-previewoff-on.svg b/resources/icon/icon-previewoff-on.svg
new file mode 100644
index 000000000..8a6c5d7ed
--- /dev/null
+++ b/resources/icon/icon-previewoff-on.svg
@@ -0,0 +1,13 @@
+
+
+
+ icon-previewoff-on
+ Created with Sketch.
+
+
+
+
+
+
+
+
\ No newline at end of file