From 77f9e601775f5bdae017664d2766e6e1f2f18afd Mon Sep 17 00:00:00 2001 From: Rokt33r Date: Sat, 5 Dec 2015 05:56:53 +0900 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=8B=95=E7=9A=84=E3=81=AB=E3=82=B9?= =?UTF-8?q?=E3=82=AF=E3=83=AD=E3=83=BC=E3=83=AB=E3=82=92=E5=90=88=E3=82=8F?= =?UTF-8?q?=E3=81=9B=E3=81=A6=E3=81=8F=E3=82=8C=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- browser/main/HomePage/ArticleDetail.js | 31 ++++++++++++++++++++++++-- lib/components/CodeEditor.js | 23 ++++++++++++++----- lib/markdown.js | 17 +++++++++++--- 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/browser/main/HomePage/ArticleDetail.js b/browser/main/HomePage/ArticleDetail.js index 4a4b7f0d..52e49f39 100644 --- a/browser/main/HomePage/ArticleDetail.js +++ b/browser/main/HomePage/ArticleDetail.js @@ -435,7 +435,34 @@ export default class ArticleDetail extends React.Component { handleTogglePreviewButtonClick (e) { if (this.state.article.mode === 'markdown') { - this.setState({previewMode: !this.state.previewMode}) + if (!this.state.previewMode) { + let cursorPosition = this.refs.code.getCursorPosition() + let firstVisibleRow = this.refs.code.getFirstVisibleRow() + this.setState({ + previewMode: true, + cursorPosition, + firstVisibleRow + }, function () { + let previewEl = ReactDOM.findDOMNode(this.refs.preview) + let anchors = previewEl.querySelectorAll('.lineAnchor') + for (let i = 0; i < anchors.length; i++) { + if (parseInt(anchors[i].dataset.key, 10) > cursorPosition.row || i === anchors.length - 1) { + var targetAnchor = anchors[i > 0 ? i - 1 : 0] + previewEl.scrollTop = targetAnchor.offsetTop - 100 + break + } + } + }) + } else { + this.setState({ + previewMode: false + }, function () { + console.log(this.state.cursorPosition) + this.refs.code.moveCursorTo(this.state.cursorPosition.row, this.state.cursorPosition.column) + this.refs.code.scrollToLine(this.state.firstVisibleRow) + this.refs.code.editor.focus() + }) + } } } @@ -524,7 +551,7 @@ export default class ArticleDetail extends React.Component { {this.state.previewMode - ? + ? : ( this.handleContentChange(e, value)} diff --git a/lib/components/CodeEditor.js b/lib/components/CodeEditor.js index d82ca3f2..e6941ed8 100644 --- a/lib/components/CodeEditor.js +++ b/lib/components/CodeEditor.js @@ -30,6 +30,7 @@ module.exports = React.createClass({ editor.renderer.setShowGutter(true) editor.setTheme('ace/theme/xcode') editor.clearSelection() + editor.moveCursorTo(0, 0) editor.setReadOnly(!!this.props.readOnly) @@ -50,16 +51,14 @@ module.exports = React.createClass({ this.props.onChange(e, value) } }.bind(this)) - - this.setState({editor: editor}) }, componentDidUpdate: function (prevProps) { - if (this.state.editor.getValue() !== this.props.code) { - this.state.editor.setValue(this.props.code) - this.state.editor.clearSelection() + if (this.editor.getValue() !== this.props.code) { + this.editor.setValue(this.props.code) + this.editor.clearSelection() } if (prevProps.mode !== this.props.mode) { - var session = this.state.editor.getSession() + var session = this.editor.getSession() let mode = _.findWhere(modes, {name: this.props.mode}) let syntaxMode = mode != null ? mode.mode @@ -67,6 +66,18 @@ module.exports = React.createClass({ session.setMode('ace/mode/' + syntaxMode) } }, + getFirstVisibleRow: function () { + return this.editor.getFirstVisibleRow() + }, + getCursorPosition: function () { + return this.editor.getCursorPosition() + }, + moveCursorTo: function (row, col) { + this.editor.moveCursorTo(row, col) + }, + scrollToLine: function (num) { + this.editor.scrollToLine(num, false, false) + }, render: function () { return (
diff --git a/lib/markdown.js b/lib/markdown.js index b27830ea..619b9655 100644 --- a/lib/markdown.js +++ b/lib/markdown.js @@ -8,20 +8,31 @@ var md = markdownit({ highlight: function (str, lang) { if (lang && hljs.getLanguage(lang)) { try { - return hljs.highlight(lang, str).value; + return hljs.highlight(lang, str).value } catch (__) {} } try { - return hljs.highlightAuto(str).value; + return hljs.highlightAuto(str).value } catch (__) {} - return ''; // use external default escaping + return '' } }) md.use(emoji) +let originalRenderToken = md.renderer.renderToken +md.renderer.renderToken = function renderToken (tokens, idx, options) { + let token = tokens[idx] + let result = originalRenderToken.call(md.renderer, tokens, idx, options) + if (token.map != null) { + return result + '' + } + return result +} + export default function markdown (content) { if (content == null) content = '' + return md.render(content.toString()) }