diff --git a/README.adoc b/README.adoc index 584973a..2c569cf 100644 --- a/README.adoc +++ b/README.adoc @@ -95,6 +95,9 @@ keep the cursor visible. * Cut/copy/paste of clipboard data, including conversion between rich text and HTML. +* Focus/blur support with appropriate styling for cursors (invisible) and +selections (gray). + * Cursor user identification via color and tag (TODO). * Figures and tables (TODO). diff --git a/src/components/Editor.js b/src/components/Editor.js index d73602a..4ef21c1 100644 --- a/src/components/Editor.js +++ b/src/components/Editor.js @@ -17,7 +17,8 @@ export default React.createClass({ minFontSize: T.number.isRequired, unitsPerEm: T.number.isRequired, width: T.number.isRequired, - margin: T.number.isRequired + margin: T.number.isRequired, + initialFocus: T.bool }, //mixins: [React.addons.PureRenderMixin], diff --git a/src/components/EditorContents.js b/src/components/EditorContents.js index 2cc185a..ee61d0f 100644 --- a/src/components/EditorContents.js +++ b/src/components/EditorContents.js @@ -34,11 +34,18 @@ export default React.createClass({ minFontSize: T.number.isRequired, unitsPerEm: T.number.isRequired, width: T.number.isRequired, - margin: T.number.isRequired + margin: T.number.isRequired, + initialFocus: T.bool }, mixins: [TextReplicaMixin], + getDefaultProps() { + return { + initialFocus: true + } + }, + getInitialState() { return EditorStore.getState() }, @@ -58,7 +65,6 @@ export default React.createClass({ componentDidMount() { this.clickCount = 0 EditorStore.listen(this.onStateChange) - this.refs.input.focus() }, componentDidUpdate() { @@ -115,7 +121,7 @@ export default React.createClass({ }, _doOnSingleClick(e) { - this.refs.input.focus() + EditorActions.focusInput() let coordinates = this._mouseEventToCoordinates(e) if(!coordinates) { @@ -169,12 +175,18 @@ export default React.createClass({ // DEBUGGING --------------------------------------------------------------------------------------------------------- + _dumpState() { + console.debug('Current state contents (NOTE: state.focus always false due to debug button click):') + console.dir(this.state) + EditorActions.focusInput() + }, + _dumpReplica() { let text = this.replica.getTextRange(BASE_CHAR) console.debug('Current replica text: [' + text.map(c => c.char).join('') + ']') console.debug('Current replica contents:') console.dir(text) - this.refs.input.focus() + EditorActions.focusInput() }, _dumpPosition() { @@ -183,7 +195,7 @@ export default React.createClass({ } else { console.debug('No active position') } - this.refs.input.focus() + EditorActions.focusInput() }, _dumpCurrentLine() { @@ -214,7 +226,7 @@ export default React.createClass({ console.debug('No lines') } }) - this.refs.input.focus() + EditorActions.focusInput() }, _dumpLines() { @@ -223,7 +235,7 @@ export default React.createClass({ } else { console.debug('No lines') } - this.refs.input.focus() + EditorActions.focusInput() }, _dumpSelection() { @@ -237,17 +249,17 @@ export default React.createClass({ } else { console.debug('No active selection') } - this.refs.input.focus() + EditorActions.focusInput() }, _forceFlow() { EditorActions.replicaUpdated() - this.refs.input.focus() + EditorActions.focusInput() }, _forceRender() { this.forceUpdate(() => console.debug('Render done.')) - this.refs.input.focus() + EditorActions.focusInput() }, _togglePositionEolStart() { @@ -257,7 +269,7 @@ export default React.createClass({ console.debug('Toggling positionEolStart from ' + previous + ' to ' + !previous) return { positionEolStart: !previous } }) - this.refs.input.focus() + EditorActions.focusInput() }, // RENDERING --------------------------------------------------------------------------------------------------------- @@ -283,9 +295,24 @@ export default React.createClass({ let selectionDiv = (leftX, widthX) => { let height = Math.round(lineHeight * 10) / 10 + let selectionStyle = { + top: 0, + left: leftX, + width: widthX, + height: height + } + + if(!this.state.focus) { + selectionStyle.borderTopColor = 'rgb(0, 0, 0)' + selectionStyle.borderBottomColor = 'rgb(0, 0, 0)' + selectionStyle.backgroundColor = 'rgb(0, 0, 0)' + selectionStyle.opacity = 0.15 + selectionStyle.color = 'black' + } + return (
+ style={selectionStyle}> ) } @@ -457,7 +484,7 @@ export default React.createClass({ let position = cursorPosition ? cursorPosition.top : 0 return ( -