diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index 6ad294ed..8b06cd72 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -835,6 +835,9 @@ export default class CodeEditor extends React.Component { ch: 1 } this.editor.setCursor(cursor) + const top = this.editor.charCoords({line: num, ch: 0}, 'local').top + const middleHeight = this.editor.getScrollerElement().offsetHeight / 2 + this.editor.scrollTo(null, top - middleHeight - 5) } focus () { diff --git a/browser/components/MarkdownEditor.js b/browser/components/MarkdownEditor.js index 466be3fa..593f7d99 100644 --- a/browser/components/MarkdownEditor.js +++ b/browser/components/MarkdownEditor.js @@ -32,6 +32,7 @@ class MarkdownEditor extends React.Component { componentDidMount () { this.value = this.refs.code.value eventEmitter.on('editor:lock', this.lockEditorCode) + eventEmitter.on('editor:focus', this.focusEditor.bind(this)) } componentDidUpdate () { @@ -47,6 +48,15 @@ class MarkdownEditor extends React.Component { componentWillUnmount () { this.cancelQueue() eventEmitter.off('editor:lock', this.lockEditorCode) + eventEmitter.off('editor:focus', this.focusEditor.bind(this)) + } + + focusEditor () { + this.setState({ + status: 'CODE' + }, () => { + this.refs.code.focus() + }) } queueRendering (value) { diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index 743b59a6..fcde3c1e 100755 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -192,6 +192,19 @@ const defaultCodeBlockFontFamily = [ 'source-code-pro', 'monospace' ] + +// return the line number of the line that used to generate the specified element +// return -1 if the line is not found +function getSourceLineNumberByElement (element) { + let isHasLineNumber = element.dataset.line !== undefined + let parent = element + while (!isHasLineNumber && parent.parentElement !== null) { + parent = parent.parentElement + isHasLineNumber = parent.dataset.line !== undefined + } + return parent.dataset.line !== undefined ? parseInt(parent.dataset.line) : -1 +} + export default class MarkdownPreview extends React.Component { constructor (props) { super(props) @@ -272,6 +285,22 @@ export default class MarkdownPreview extends React.Component { if (config.editor.switchPreview === 'RIGHTCLICK' && e.buttons === 2 && config.editor.type === 'SPLIT') { eventEmitter.emit('topbar:togglemodebutton', 'CODE') } + if (e.ctrlKey) { + if (config.editor.type === 'SPLIT') { + const clickElement = e.target + const lineNumber = getSourceLineNumberByElement(clickElement) + if (lineNumber !== -1) { + eventEmitter.emit('line:jump', lineNumber) + } + } else { + const clickElement = e.target + const lineNumber = getSourceLineNumberByElement(clickElement) + if (lineNumber !== -1) { + eventEmitter.emit('editor:focus') + eventEmitter.emit('line:jump', lineNumber) + } + } + } if (e.target != null) { switch (e.target.tagName) { case 'A':