From 9a5653f1e3f47eae50738a5f7d90203fd8610a43 Mon Sep 17 00:00:00 2001 From: Dick Choi Date: Tue, 19 Jul 2016 02:38:23 +0900 Subject: [PATCH] preview on blur --- browser/components/CodeEditor.js | 23 ++++++++++--------- browser/components/MarkdownEditor.js | 32 ++++++++++++++++++++++++++- browser/components/MarkdownPreview.js | 19 +++++++++++++++- 3 files changed, 62 insertions(+), 12 deletions(-) diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index ea1d2db4..83bb8025 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -13,18 +13,19 @@ export default class CodeEditor extends React.Component { this.changeHandler = (e) => this.handleChange(e) this.blurHandler = (e) => { - if (e.relatedTarget === null) { - return + e.stopPropagation() + let el = e.relatedTarget + let isStillFocused = false + while (el != null) { + if (el === this.refs.root) { + isStillFocused = true + break + } + el = el.parentNode } + console.log(isStillFocused) - let isFocusingToSearch = e.relatedTarget.className && e.relatedTarget.className.split(' ').some((clss) => { - return clss === 'ace_search_field' || clss === 'ace_searchbtn' || clss === 'ace_replacebtn' || clss === 'ace_searchbtn_close' || clss === 'ace_text-input' - }) - if (isFocusingToSearch) { - return - } - - if (this.props.onBlur) this.props.onBlur(e) + if (!isStillFocused && this.props.onBlur != null) this.props.onBlur(e) } this.killedBuffer = '' @@ -230,6 +231,8 @@ export default class CodeEditor extends React.Component { ? 'CodeEditor' : `CodeEditor ${className}` } + ref='root' + tabIndex='-1' style={{ fontFamily: fontFamily.join(', ') }} diff --git a/browser/components/MarkdownEditor.js b/browser/components/MarkdownEditor.js index 1d82cece..f99f6f77 100644 --- a/browser/components/MarkdownEditor.js +++ b/browser/components/MarkdownEditor.js @@ -9,7 +9,7 @@ class MarkdownEditor extends React.Component { super(props) this.state = { - status: 'CODE' + status: 'PREVIEW' } } @@ -45,6 +45,32 @@ class MarkdownEditor extends React.Component { } } + handleBlur (e) { + let { config } = this.props + if (config.editor.switchPreview === 'BLUR') { + this.setState({ + status: 'PREVIEW' + }, () => { + this.refs.preview.focus() + }) + } + } + + handlePreviewMouseDown (e) { + this.previewMouseDownedAt = new Date() + } + + handlePreviewMouseUp (e) { + let { config } = this.props + if (config.editor.switchPreview === 'BLUR' && new Date() - this.previewMouseDownedAt < 150) { + this.setState({ + status: 'CODE' + }, () => { + this.refs.code.focus() + }) + } + } + focus () { if (this.state.status === 'PREVIEW') { this.setState({ @@ -77,6 +103,7 @@ class MarkdownEditor extends React.Component { : `MarkdownEditor ${className}` } onContextMenu={(e) => this.handleContextMenu(e)} + tabIndex='-1' > this.handleChange(e)} + onBlur={(e) => this.handleBlur(e)} /> this.handleContextMenu(e)} tabIndex='0' value={value} + onMouseUp={(e) => this.handlePreviewMouseUp(e)} + onMouseDown={(e) => this.handlePreviewMouseDown(e)} /> ) diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index 192e12e1..97108c3f 100644 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -7,6 +7,7 @@ const markdownStyle = require('!!css!stylus?sourceMap!./markdown.styl')[0][1] const { shell } = require('electron') const goExternal = function (e) { e.preventDefault() + e.stopPropagation() shell.openExternal(e.target.href) } @@ -24,20 +25,35 @@ export default class MarkdownPreview extends React.Component { super(props) this.contextMenuHandler = (e) => this.handleContextMenu(e) + this.mouseDownHandler = (e) => this.handleMouseDown(e) + this.mouseUpHandler = (e) => this.handleMouseUp(e) } handleContextMenu (e) { this.props.onContextMenu(e) } + handleMouseDown (e) { + if (this.props.onMouseDown != null) this.props.onMouseDown(e) + } + + handleMouseUp (e) { + if (this.props.onMouseUp != null) this.props.onMouseUp(e) + } + componentDidMount () { this.refs.root.setAttribute('sandbox', 'allow-same-origin') this.refs.root.contentWindow.document.body.addEventListener('contextmenu', this.contextMenuHandler) this.rewriteIframe() + + this.refs.root.contentWindow.document.addEventListener('mousedown', this.mouseDownHandler) + this.refs.root.contentWindow.document.addEventListener('mouseup', this.mouseUpHandler) } componentWillUnmount () { this.refs.root.contentWindow.document.body.removeEventListener('contextmenu', this.contextMenuHandler) + this.refs.root.contentWindow.document.removeEventListener('mousedown', this.mouseDownHandler) + this.refs.root.contentWindow.document.removeEventListener('mouseup', this.mouseUpHandler) } componentDidUpdate (prevProps) { @@ -55,6 +71,7 @@ export default class MarkdownPreview extends React.Component { el.removeEventListener('click', goExternal) }) + let { value, fontFamily, fontSize, codeBlockFontFamily, lineNumber, codeBlockTheme } = this.props fontFamily = _.isString(fontFamily) && fontFamily.trim().length > 0 ? [fontFamily].concat(defaultFontFamily) @@ -95,7 +112,7 @@ export default class MarkdownPreview extends React.Component { this.refs.root.contentWindow.document.body.innerHTML = markdown(value) Array.prototype.forEach.call(this.refs.root.contentWindow.document.querySelectorAll('a'), (el) => { - el.addEventListener('click', goExternal) + el.addEventListener('mousedown', goExternal) }) }