Permalink
Browse files

add insert mode, maintain cursor position

  • Loading branch information...
1 parent 2ead738 commit 3f466c35d74d5cb271406a722ffade1b037fa699 @xadn committed Jul 18, 2014
Showing with 2,423 additions and 149 deletions.
  1. +2,377 −143 build/index.js
  2. +2 −1 package.json
  3. +44 −5 src/editor.js
View
Oops, something went wrong.
View
@@ -14,6 +14,7 @@
"react": "^0.10.0",
"reactify": "^0.13.1",
"browserify": "^4.2.0",
- "watchify": "^0.10.2"
+ "watchify": "^0.10.2",
+ "diff-match-patch": "^1.0.0"
}
}
View
@@ -1,6 +1,10 @@
/** @jsx React.DOM */
var React = require('react');
var EditorBackground = require('./editor_background');
+var DiffMatchPatch = require('diff-match-patch');
+var dmp = new DiffMatchPatch();
+
+var INVALID_CHARS = /\r|\n/g;
// 38 * 18 = 634
function defaultHtml(length) {
@@ -9,11 +13,34 @@ function defaultHtml(length) {
return html;
}
-function prepareText(text, length) {
- // return text.slice(0, length);
+function replaceWithSpaces(text) {
+ return defaultHtml(text.length);
+}
+
+function rest(text, skip) {
+ return text.slice(skip, text.length);
+}
+
+function diffToText(diff, index, array) {
+ var prevDiff = [].concat(array[index - 1]);
+ var prevOp = prevDiff[0];
+ var prevText = prevDiff[1] || '';
+ var op = diff[0];
+ var text = diff[1];
+
+ if (op === DiffMatchPatch.DIFF_DELETE) {
+ return replaceWithSpaces(text);
+ }
+ if (prevOp === DiffMatchPatch.DIFF_INSERT) {
+ return rest(text, prevText.length);
+ }
return text;
}
+function extract(diffs) {
+ return diffs.map(diffToText).join('');
+}
+
var Editor = React.createClass({
getInitialState: function() {
return {text: defaultHtml(this.maxLength())};
@@ -32,9 +59,16 @@ var Editor = React.createClass({
},
handleChange: function(e) {
- var target = e.target;
+ var target = e.target,
+ nextText = target.value,
+ prevText = this.state.text;
+
+ nextText = nextText.replace(INVALID_CHARS, '');
+
+ var diffs = dmp.diff_main(prevText, nextText);
+
this.setState({
- text: prepareText(target.value, this.maxLength()),
+ text: extract(diffs).slice(0, this.maxLength()),
selectionStart: target.selectionStart
});
},
@@ -50,9 +84,14 @@ var Editor = React.createClass({
return (
<div className='editor' style={style}>
<EditorBackground className='editor-content' charWidth={this.props.charWidth} charHeight={this.props.charHeight} widthInChars={this.props.widthInChars} heightInChars={this.props.heightInChars} />
- <textarea ref='ef' className='editor-content' value={this.state.text} onChange={this.handleChange} />
+ <textarea ref='ef' className='editor-content' value={this.state.text} onChange={this.handleChange} spellCheck={false} />
</div>
);
+ },
+
+ componentDidUpdate: function() {
+ this.refs.ef.getDOMNode().selectionStart = this.state.selectionStart;
+ this.refs.ef.getDOMNode().selectionEnd = this.state.selectionStart;
}
});

0 comments on commit 3f466c3

Please sign in to comment.