diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index 952e026e..830cb48b 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -3,10 +3,35 @@ import ReactDOM from 'react-dom' import modes from '../lib/modes' import _ from 'lodash' -const remote = require('electron').remote +const electron = require('electron') +const remote = electron.remote +const ipc = electron.ipcRenderer + const ace = window.ace +function getConfig () { + return Object.assign({}, remote.getGlobal('config')) +} + +let config = getConfig() + export default class CodeEditor extends React.Component { + constructor (props) { + super(props) + + this.configApplyHandler = e => this.handleConfigApply(e) + this.changeHandler = e => this.handleChange(e) + + this.state = { + fontSize: config['editor-font-size'], + fontFamily: config['editor-font-family'], + indentType: config['editor-indent-type'], + indentSize: config['editor-indent-size'] + } + + this.silentChange = false + } + componentWillReceiveProps (nextProps) { if (nextProps.readOnly !== this.props.readOnly) { this.editor.setReadOnly(!!nextProps.readOnly) @@ -14,6 +39,7 @@ export default class CodeEditor extends React.Component { } componentDidMount () { + let { article } = this.props var el = ReactDOM.findDOMNode(this) var editor = this.editor = ace.edit(el) editor.$blockScrolling = Infinity @@ -21,6 +47,7 @@ export default class CodeEditor extends React.Component { editor.setTheme('ace/theme/xcode') editor.moveCursorTo(0, 0) editor.setReadOnly(!!this.props.readOnly) + editor.setFontSize(this.state.fontSize) editor.commands.addCommand({ name: 'Emacs cursor up', @@ -45,32 +72,38 @@ export default class CodeEditor extends React.Component { }) var session = editor.getSession() - let mode = _.findWhere(modes, {name: this.props.mode}) + let mode = _.findWhere(modes, {name: article.mode}) let syntaxMode = mode != null ? mode.mode : 'text' session.setMode('ace/mode/' + syntaxMode) - session.setUseSoftTabs(true) - session.setOption('useWorker', false) + session.setUseSoftTabs(this.state.indentType === 'space') + session.setTabSize(!isNaN(this.state.indentSize) ? parseInt(this.state.indentSize, 10) : 4) + session.setOption('useWorker', true) session.setUseWrapMode(true) - session.setValue(this.props.code) + session.setValue(this.props.article.content) - session.on('change', e => { - if (this.props.onChange != null) { - var value = editor.getValue() - this.props.onChange(e, value) - } - }) + session.on('change', this.changeHandler) + + ipc.on('config-apply', this.configApplyHandler) } - componentDidUpdate (prevProps) { + componentWillUnmount () { + ipc.removeListener('config-apply', this.configApplyHandler) + this.editor.getSession().removeListener('change', this.changeHandler) + } + + componentDidUpdate (prevProps, prevState) { var session = this.editor.getSession() - if (this.editor.getValue() !== this.props.code) { - session.setValue(this.props.code) + if (this.props.article.key !== prevProps.article.key) { + session.removeListener('change', this.changeHandler) + session.setValue(this.props.article.content) + session.getUndoManager().reset() + session.on('change', this.changeHandler) } - if (prevProps.mode !== this.props.mode) { - let mode = _.findWhere(modes, {name: this.props.mode}) + if (prevProps.article.mode !== this.props.article.mode) { + let mode = _.findWhere(modes, {name: this.props.article.mode}) let syntaxMode = mode != null ? mode.mode : 'text' @@ -78,6 +111,26 @@ export default class CodeEditor extends React.Component { } } + handleConfigApply () { + config = getConfig() + this.setState({ + fontSize: config['editor-font-size'], + fontFamily: config['editor-font-family'], + indentType: config['editor-indent-type'], + indentSize: config['editor-indent-size'] + }, function () { + var session = this.editor.getSession() + session.setUseSoftTabs(this.state.indentType === 'space') + session.setTabSize(!isNaN(this.state.indentSize) ? parseInt(this.state.indentSize, 10) : 4) + }) + } + handleChange (e) { + if (this.props.onChange) { + var value = this.editor.getValue() + this.props.onChange(value) + } + } + getFirstVisibleRow () { return this.editor.getFirstVisibleRow() } @@ -96,14 +149,23 @@ export default class CodeEditor extends React.Component { render () { return ( -
+ ) } } CodeEditor.propTypes = { - code: PropTypes.string, - mode: PropTypes.string, + article: PropTypes.shape({ + content: PropTypes.string, + mode: PropTypes.string, + key: PropTypes.string + }), className: PropTypes.string, onChange: PropTypes.func, onBlur: PropTypes.func, diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index 08f50b26..eddff52e 100644 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -2,11 +2,12 @@ import React, { PropTypes } from 'react' import markdown from '../lib/markdown' import ReactDOM from 'react-dom' import sanitizeHtml from '@rokt33r/sanitize-html' -import hljs from 'highlight.js' import _ from 'lodash' const electron = require('electron') const shell = electron.shell +const remote = electron.remote +const ipc = electron.ipcRenderer const katex = window.katex @@ -65,41 +66,43 @@ function math2Katex (display) { } } +function getConfig () { + return Object.assign({}, remote.getGlobal('config')) +} + +let config = getConfig() + export default class MarkdownPreview extends React.Component { + constructor (props) { + super(props) + + this.configApplyHandler = e => this.handleConfigApply(e) + + this.state = { + fontSize: config['preview-font-size'], + fontFamily: config['preview-font-family'] + } + } componentDidMount () { this.addListener() - // this.renderCode() this.renderMath() + ipc.on('config-apply', this.configApplyHandler) } componentDidUpdate () { this.addListener() - // this.renderCode() this.renderMath() } componentWillUnmount () { this.removeListener() + ipc.removeListener('config-apply', this.configApplyHandler) } componentWillUpdate () { this.removeListener() } - renderCode () { - let codes = ReactDOM.findDOMNode(this).querySelectorAll('code:not(.rendered)') - Array.prototype.forEach.call(codes, el => { - let matched = el.className.match(/language-(.+)/) - let lang = matched ? matched[1] : null - try { - let result = hljs.highlight(lang, el.innerHTML) - el.innerHTML = result.value - el.className += ' rendered' - } catch (e) { - } - }) - } - renderMath () { let inline = ReactDOM.findDOMNode(this).querySelectorAll('span.math') Array.prototype.forEach.call(inline, math2Katex(false)) @@ -157,6 +160,14 @@ export default class MarkdownPreview extends React.Component { } } + handleConfigApply () { + config = getConfig() + this.setState({ + fontSize: config['preview-font-size'], + fontFamily: config['preview-font-family'] + }) + } + render () { let isEmpty = this.props.content.trim().length === 0 let content = isEmpty @@ -174,6 +185,7 @@ export default class MarkdownPreview extends React.Component { onMouseMove={e => this.handleMouseMove(e)} onMouseUp={e => this.handleMouseUp(e)} dangerouslySetInnerHTML={{__html: ' ' + content}} + style={{fontSize: this.state.fontSize, fontFamily: this.state.fontFamily}} /> ) } diff --git a/browser/finder/FinderDetail.js b/browser/finder/FinderDetail.js index de815e27..5e4cfc3f 100644 --- a/browser/finder/FinderDetail.js +++ b/browser/finder/FinderDetail.js @@ -24,7 +24,7 @@ export default class FinderDetail extends React.Component {