react-ace
Advanced tools
Comparing version 5.5.0 to 5.7.0
@@ -8,2 +8,8 @@ # Changelog | ||
## 5.7.0 | ||
* Adds debounce option for onChange event | ||
* Add support onCursorChange event | ||
* Adds editor as second argument to the onBlur | ||
## 5.5.0 | ||
@@ -10,0 +16,0 @@ |
@@ -64,2 +64,3 @@ # Ace Editor | ||
|tabSize| 4| Number| tabSize| | ||
|debounceChangePeriod| null| Number| A debounce delay period for the onChange event| | ||
|onLoad| | Function | called on editor load. The first argument is the instance of the editor | | ||
@@ -71,4 +72,5 @@ |onBeforeLoad| | Function | called before editor load. the first argument is an instance of `ace`| | ||
|onSelectionChange| | Function | triggered by editor `selectionChange` event, and passes a [Selection](https://ace.c9.io/#nav=api&api=selection) as it's first argument and the event as the second| | ||
|onCursorChange| | Function | triggered by editor `changeCursor` event, and passes a [Selection](https://ace.c9.io/#nav=api&api=selection) as it's first argument and the event as the second| | ||
|onFocus| | Function | triggered by editor `focus` event| | ||
|onBlur| | Function | triggered by editor `blur` event| | ||
|onBlur| | Function | triggered by editor `blur` event.It has two arguments event and editor| | ||
|onInput| | Function | triggered by editor `input` event| | ||
@@ -75,0 +77,0 @@ |onScroll| | Function | triggered by editor `scroll` event| |
@@ -68,2 +68,3 @@ # Split Editor | ||
|onSelectionChange| | Function | triggered by editor `selectionChange` event, and passes a [Selection](https://ace.c9.io/#nav=api&api=selection) as it's first argument and the event as the second| | ||
|onCursorChange| | Function | triggered by editor `changeCursor` event, and passes a [Selection](https://ace.c9.io/#nav=api&api=selection) as it's first argument and the event as the second| | ||
|onFocus| | Function | triggered by editor `focus` event| | ||
@@ -70,0 +71,0 @@ |onBlur| | Function | triggered by editor `blur` event| |
@@ -92,3 +92,5 @@ 'use strict'; | ||
} | ||
if (this.props.debounceChangePeriod) { | ||
this.onChange = this.debounce(this.onChange, this.props.debounceChangePeriod); | ||
} | ||
this.editor.renderer.setScrollMargin(scrollMargin[0], scrollMargin[1], scrollMargin[2], scrollMargin[3]); | ||
@@ -109,2 +111,3 @@ this.editor.getSession().setMode('ace/mode/' + mode); | ||
this.editor.getSession().selection.on('changeSelection', this.onSelectionChange); | ||
this.editor.getSession().selection.on('changeCursor', this.onCursorChange); | ||
if (onValidate) { | ||
@@ -163,2 +166,15 @@ this.editor.getSession().on('changeAnnotation', function () { | ||
}, { | ||
key: 'debounce', | ||
value: function debounce(fn, delay) { | ||
var timer = null; | ||
return function () { | ||
var context = this, | ||
args = arguments; | ||
clearTimeout(timer); | ||
timer = setTimeout(function () { | ||
fn.apply(context, args); | ||
}, delay); | ||
}; | ||
} | ||
}, { | ||
key: 'componentWillReceiveProps', | ||
@@ -275,2 +291,10 @@ value: function componentWillReceiveProps(nextProps) { | ||
}, { | ||
key: 'onCursorChange', | ||
value: function onCursorChange(event) { | ||
if (this.props.onCursorChange) { | ||
var value = this.editor.getSelection(); | ||
this.props.onCursorChange(value, event); | ||
} | ||
} | ||
}, { | ||
key: 'onInput', | ||
@@ -293,3 +317,3 @@ value: function onInput(event) { | ||
if (this.props.onBlur) { | ||
this.props.onBlur(event); | ||
this.props.onBlur(event, this.editor); | ||
} | ||
@@ -409,2 +433,3 @@ } | ||
onSelectionChange: _propTypes2.default.func, | ||
onCursorChange: _propTypes2.default.func, | ||
onBeforeLoad: _propTypes2.default.func, | ||
@@ -419,2 +444,3 @@ onValidate: _propTypes2.default.func, | ||
cursorStart: _propTypes2.default.number, | ||
debounceChangePeriod: _propTypes2.default.number, | ||
editorProps: _propTypes2.default.object, | ||
@@ -421,0 +447,0 @@ setOptions: _propTypes2.default.object, |
@@ -8,5 +8,5 @@ 'use strict'; | ||
var editorEvents = ['onChange', 'onFocus', 'onInput', 'onBlur', 'onCopy', 'onPaste', 'onSelectionChange', 'onScroll', 'handleOptions', 'updateRef']; | ||
var editorEvents = ['onChange', 'onFocus', 'onInput', 'onBlur', 'onCopy', 'onPaste', 'onSelectionChange', 'onCursorChange', 'onScroll', 'handleOptions', 'updateRef']; | ||
exports.editorOptions = editorOptions; | ||
exports.editorEvents = editorEvents; |
@@ -129,2 +129,3 @@ 'use strict'; | ||
editor.getSession().selection.on('changeSelection', _this2.onSelectionChange); | ||
editor.getSession().selection.on('changeCursor', _this2.onCursorChange); | ||
editor.session.on('changeScrollTop', _this2.onScroll); | ||
@@ -303,2 +304,13 @@ editor.setValue(defaultValueForEditor === undefined ? valueForEditor : defaultValueForEditor, cursorStart); | ||
}, { | ||
key: 'onCursorChange', | ||
value: function onCursorChange(event) { | ||
if (this.props.onCursorChange) { | ||
var value = []; | ||
this.editor.env.split.forEach(function (editor) { | ||
value.push(editor.getSelection()); | ||
}); | ||
this.props.onCursorChange(value, event); | ||
} | ||
} | ||
}, { | ||
key: 'onFocus', | ||
@@ -436,2 +448,3 @@ value: function onFocus(event) { | ||
onSelectionChange: _propTypes2.default.func, | ||
onCursorChange: _propTypes2.default.func, | ||
onBeforeLoad: _propTypes2.default.func, | ||
@@ -438,0 +451,0 @@ minLines: _propTypes2.default.number, |
{ | ||
"name": "react-ace", | ||
"version": "5.5.0", | ||
"version": "5.7.0", | ||
"description": "A react component for Ace Editor", | ||
@@ -49,9 +49,9 @@ "main": "lib/index.js", | ||
"enzyme-adapter-react-16": "^1.0.1", | ||
"eslint": "4.10.0", | ||
"eslint": "4.11.0", | ||
"eslint-plugin-import": "^2.2.0", | ||
"eslint-plugin-jsx-a11y": "^6.0.0", | ||
"eslint-plugin-react": "7.4.0", | ||
"eslint-plugin-react": "7.5.0", | ||
"jsdom": "^11.0.0", | ||
"mocha": "4.0.1", | ||
"nyc": "11.2.1", | ||
"nyc": "11.3.0", | ||
"react": "^16.0.0", | ||
@@ -61,5 +61,5 @@ "react-dom": "^16.0.0", | ||
"rimraf": "2.6.2", | ||
"sinon": "4.0.2", | ||
"sinon": "4.1.2", | ||
"webpack": "3.8.1", | ||
"webpack-dev-server": "2.9.3" | ||
"webpack-dev-server": "2.9.4" | ||
}, | ||
@@ -66,0 +66,0 @@ "keywords": [ |
@@ -50,3 +50,5 @@ import ace from 'brace' | ||
} | ||
if (this.props.debounceChangePeriod) { | ||
this.onChange = this.debounce(this.onChange, this.props.debounceChangePeriod); | ||
} | ||
this.editor.renderer.setScrollMargin(scrollMargin[0], scrollMargin[1], scrollMargin[2], scrollMargin[3]) | ||
@@ -67,2 +69,3 @@ this.editor.getSession().setMode(`ace/mode/${mode}`); | ||
this.editor.getSession().selection.on('changeSelection', this.onSelectionChange); | ||
this.editor.getSession().selection.on('changeCursor', this.onCursorChange); | ||
if (onValidate) { | ||
@@ -122,2 +125,13 @@ this.editor.getSession().on('changeAnnotation', () => { | ||
debounce(fn, delay) { | ||
var timer = null; | ||
return function () { | ||
var context = this, args = arguments; | ||
clearTimeout(timer); | ||
timer = setTimeout(function () { | ||
fn.apply(context, args); | ||
}, delay); | ||
}; | ||
} | ||
componentWillReceiveProps(nextProps) { | ||
@@ -225,2 +239,8 @@ const oldProps = this.props; | ||
} | ||
onCursorChange(event) { | ||
if(this.props.onCursorChange) { | ||
const value = this.editor.getSelection(); | ||
this.props.onCursorChange(value, event) | ||
} | ||
} | ||
onInput(event) { | ||
@@ -239,3 +259,3 @@ if (this.props.onInput) { | ||
if (this.props.onBlur) { | ||
this.props.onBlur(event); | ||
this.props.onBlur(event,this.editor); | ||
} | ||
@@ -332,2 +352,3 @@ } | ||
onSelectionChange: PropTypes.func, | ||
onCursorChange: PropTypes.func, | ||
onBeforeLoad: PropTypes.func, | ||
@@ -342,2 +363,3 @@ onValidate: PropTypes.func, | ||
cursorStart: PropTypes.number, | ||
debounceChangePeriod: PropTypes.number, | ||
editorProps: PropTypes.object, | ||
@@ -344,0 +366,0 @@ setOptions: PropTypes.object, |
@@ -20,2 +20,3 @@ const editorOptions = [ | ||
'onSelectionChange', | ||
'onCursorChange', | ||
'onScroll', | ||
@@ -22,0 +23,0 @@ 'handleOptions', |
@@ -82,2 +82,3 @@ import ace from 'brace' | ||
editor.getSession().selection.on('changeSelection', this.onSelectionChange); | ||
editor.getSession().selection.on('changeCursor', this.onCursorChange); | ||
editor.session.on('changeScrollTop', this.onScroll); | ||
@@ -251,3 +252,11 @@ editor.setValue(defaultValueForEditor === undefined ? valueForEditor : defaultValueForEditor, cursorStart); | ||
} | ||
onCursorChange(event) { | ||
if(this.props.onCursorChange) { | ||
let value = [] | ||
this.editor.env.split.forEach((editor) => { | ||
value.push(editor.getSelection()) | ||
}) | ||
this.props.onCursorChange(value, event) | ||
} | ||
} | ||
onFocus(event) { | ||
@@ -361,2 +370,3 @@ if (this.props.onFocus) { | ||
onSelectionChange: PropTypes.func, | ||
onCursorChange: PropTypes.func, | ||
onBeforeLoad: PropTypes.func, | ||
@@ -363,0 +373,0 @@ minLines: PropTypes.number, |
@@ -240,2 +240,75 @@ import { expect } from 'chai'; | ||
//inspired from https://github.com/goodtimeaj/debounce-function/blob/master/test/unit/debounce-function.js | ||
describe('Debounce function', () => { | ||
it('function arg should be called when after timeout', (done) => { | ||
const wrapper = mount(<AceEditor/>, mountOptions); | ||
var flag = false; | ||
var func = wrapper.instance().debounce(function() { | ||
flag = true | ||
}, 100); | ||
func(); | ||
expect(flag).to.be.false; | ||
setTimeout(function() { | ||
expect(flag).to.be.true; | ||
done(); | ||
}, 150); | ||
}); | ||
it('timer should be reset on successive call', (done) => { | ||
const wrapper = mount(<AceEditor/>, mountOptions); | ||
var flag = false; | ||
var func = wrapper.instance().debounce(function() { | ||
flag = true | ||
}, 100); | ||
func(); | ||
expect(flag).to.be.false; | ||
setTimeout(function() { | ||
expect(flag).to.be.false; | ||
func(); | ||
}, 50); | ||
setTimeout(function() { | ||
expect(flag).to.be.false; | ||
}, 120); | ||
setTimeout(function() { | ||
expect(flag).to.be.true; | ||
done(); | ||
}, 160); | ||
}); | ||
it('function should be called only once per period', (done) => { | ||
const wrapper = mount(<AceEditor/>, mountOptions); | ||
var flag1 = false; | ||
var flag2 = false; | ||
var func = wrapper.instance().debounce(function() { | ||
if (flag1) { | ||
flag2 = true; | ||
} | ||
flag1 = true | ||
}, 100); | ||
func(); | ||
expect(flag1).to.be.false; | ||
expect(flag2).to.be.false; | ||
setTimeout(function() { | ||
expect(flag1).to.be.false; | ||
expect(flag2).to.be.false; | ||
func(); | ||
setTimeout(function() { | ||
expect(flag1).to.be.true; | ||
expect(flag2).to.be.false; | ||
func(); | ||
setTimeout(function() { | ||
expect(flag1).to.be.true; | ||
expect(flag2).to.be.false; | ||
done(); | ||
}, 90); | ||
}, 110); | ||
}, 50); | ||
}); | ||
}); | ||
describe('Events', () => { | ||
@@ -259,2 +332,35 @@ | ||
it('should limit call to onChange (debounce)', (done) => { | ||
const period = 100; | ||
const onChangeCallback = sinon.spy(); | ||
const wrapper = mount(<AceEditor onChange={onChangeCallback} debounceChangePeriod={period}/>, mountOptions); | ||
// Check is not previously called | ||
expect(onChangeCallback.callCount).to.equal(0); | ||
// Trigger the change event | ||
const expectText = 'React Ace Test'; | ||
const expectText2 = 'React Ace Test2'; | ||
wrapper.instance().editor.setValue(expectText, 1); | ||
wrapper.instance().editor.setValue(expectText2, 1); | ||
expect(onChangeCallback.callCount).to.equal(0); | ||
setTimeout(function(){ | ||
expect(onChangeCallback.callCount).to.equal(1); | ||
expect(onChangeCallback.getCall(0).args[0]).to.equal(expectText2); | ||
expect(onChangeCallback.getCall(0).args[1].action).to.eq('insert'); | ||
onChangeCallback.reset(); | ||
wrapper.instance().editor.setValue(expectText2, 1); | ||
wrapper.instance().editor.setValue(expectText, 1); | ||
expect(onChangeCallback.callCount).to.equal(0); | ||
setTimeout(function(){ | ||
expect(onChangeCallback.callCount).to.equal(1); | ||
expect(onChangeCallback.getCall(0).args[0]).to.equal(expectText); | ||
expect(onChangeCallback.getCall(0).args[1].action).to.eq('insert'); | ||
done(); | ||
},100); | ||
},100); | ||
}); | ||
it('should call the onCopy method', () => { | ||
@@ -323,2 +429,21 @@ const onCopyCallback = sinon.spy(); | ||
it('should call the onCursorChange method callback', (done) => { | ||
let onCursorChange = function(){} | ||
const value =` | ||
function main(value) { | ||
console.log('hi james') | ||
return value; | ||
} | ||
` | ||
const wrapper = mount(<AceEditor value={value} />, mountOptions); | ||
onCursorChange = function (selection) { | ||
expect(selection.getCursor()).to.deep.equal({ row: 0, column: 0 }) | ||
done() | ||
} | ||
wrapper.setProps({onCursorChange}) | ||
expect(wrapper.instance().editor.getSession().selection.getCursor()).to.deep.equal({row: 5, column: 6}) | ||
wrapper.instance().editor.getSession().selection.moveCursorTo(0, 0) | ||
}); | ||
it('should call the onBlur method callback', () => { | ||
@@ -325,0 +450,0 @@ const onBlurCallback = sinon.spy(); |
@@ -228,2 +228,16 @@ import { expect } from 'chai'; | ||
it('should call the onCursorChange method callback', () => { | ||
const onCursorChangeCallback = sinon.spy(); | ||
const wrapper = mount(<SplitEditor value="a" onCursorChange={onCursorChangeCallback}/>, mountOptions) | ||
// The changeCursor event is called when the initial value is set | ||
expect(onCursorChangeCallback.callCount).to.equal(1); | ||
// Trigger the changeCursor event | ||
wrapper.instance().splitEditor.getSession().selection.moveCursorTo(0, 0); | ||
expect(onCursorChangeCallback.callCount).to.equal(2); | ||
}); | ||
it('should call the onBlur method callback', () => { | ||
@@ -230,0 +244,0 @@ const onBlurCallback = sinon.spy(); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
2043875
37890