Skip to content

Commit dfdae1b

Browse files
authored
Merge pull request JedWatson#79 from skidding/preserve-scroll-position
Add option to preserve scroll position between updates
2 parents 732f5d5 + ea0b1e5 commit dfdae1b

File tree

3 files changed

+28
-3
lines changed

3 files changed

+28
-3
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ You can interact with the CodeMirror instance using a `ref` and the `getCodeMirr
6969

7070
* `autoSave` `Boolean` automatically persist changes to underlying textarea (default false)
7171
* `value` `String` the editor value
72+
* `preserveScrollPosition` `Boolean=false` Preserve previous scroll position after updating value
7273
* `options` `Object (newValue)` options passed to the CodeMirror instance
7374
* `onChange` `Function (newValue)` called when a change is made
7475
* `onFocusChange` `Function (focused)` called when the editor is focused or loses focus

lib/Codemirror.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@ var CodeMirror = React.createClass({
1818
onScroll: React.PropTypes.func,
1919
options: React.PropTypes.object,
2020
path: React.PropTypes.string,
21-
value: React.PropTypes.string
21+
value: React.PropTypes.string,
22+
preserveScrollPosition: React.PropTypes.bool
23+
},
24+
getDefaultProps: function getDefaultProps() {
25+
return {
26+
preserveScrollPosition: false
27+
};
2228
},
2329
getCodeMirrorInstance: function getCodeMirrorInstance() {
2430
return this.props.codeMirrorInstance || require('codemirror');
@@ -49,7 +55,13 @@ var CodeMirror = React.createClass({
4955
},
5056
componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
5157
if (this.codeMirror && nextProps.value !== undefined && this.codeMirror.getValue() !== nextProps.value) {
52-
this.codeMirror.setValue(nextProps.value);
58+
if (this.props.preserveScrollPosition) {
59+
var prevScrollPosition = this.codeMirror.getScrollInfo();
60+
this.codeMirror.setValue(nextProps.value);
61+
this.codeMirror.scrollTo(prevScrollPosition.left, prevScrollPosition.top);
62+
} else {
63+
this.codeMirror.setValue(nextProps.value);
64+
}
5365
}
5466
if (typeof nextProps.options === 'object') {
5567
for (var optionName in nextProps.options) {

src/Codemirror.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ const CodeMirror = React.createClass({
1515
options: React.PropTypes.object,
1616
path: React.PropTypes.string,
1717
value: React.PropTypes.string,
18+
preserveScrollPosition: React.PropTypes.bool,
19+
},
20+
getDefaultProps () {
21+
return {
22+
preserveScrollPosition: false,
23+
};
1824
},
1925
getCodeMirrorInstance () {
2026
return this.props.codeMirrorInstance || require('codemirror');
@@ -45,7 +51,13 @@ const CodeMirror = React.createClass({
4551
},
4652
componentWillReceiveProps: function (nextProps) {
4753
if (this.codeMirror && nextProps.value !== undefined && this.codeMirror.getValue() !== nextProps.value) {
48-
this.codeMirror.setValue(nextProps.value);
54+
if (this.props.preserveScrollPosition) {
55+
var prevScrollPosition = this.codeMirror.getScrollInfo();
56+
this.codeMirror.setValue(nextProps.value);
57+
this.codeMirror.scrollTo(prevScrollPosition.left, prevScrollPosition.top);
58+
} else {
59+
this.codeMirror.setValue(nextProps.value);
60+
}
4961
}
5062
if (typeof nextProps.options === 'object') {
5163
for (let optionName in nextProps.options) {

0 commit comments

Comments
 (0)