425 lines
15 KiB
JavaScript
425 lines
15 KiB
JavaScript
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _brace = require('brace');
|
|
|
|
var _brace2 = _interopRequireDefault(_brace);
|
|
|
|
var _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _propTypes = require('prop-types');
|
|
|
|
var _propTypes2 = _interopRequireDefault(_propTypes);
|
|
|
|
var _lodash = require('lodash.isequal');
|
|
|
|
var _lodash2 = _interopRequireDefault(_lodash);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var _ace$acequire = _brace2.default.acequire('ace/range'),
|
|
Range = _ace$acequire.Range;
|
|
|
|
var editorOptions = ['minLines', 'maxLines', 'readOnly', 'highlightActiveLine', 'tabSize', 'enableBasicAutocompletion', 'enableLiveAutocompletion', 'enableSnippets'];
|
|
|
|
var ReactAce = function (_Component) {
|
|
_inherits(ReactAce, _Component);
|
|
|
|
function ReactAce(props) {
|
|
_classCallCheck(this, ReactAce);
|
|
|
|
var _this = _possibleConstructorReturn(this, (ReactAce.__proto__ || Object.getPrototypeOf(ReactAce)).call(this, props));
|
|
|
|
['onChange', 'onFocus', 'onBlur', 'onCopy', 'onPaste', 'onSelectionChange', 'onScroll', 'handleOptions', 'updateRef'].forEach(function (method) {
|
|
_this[method] = _this[method].bind(_this);
|
|
});
|
|
return _this;
|
|
}
|
|
|
|
_createClass(ReactAce, [{
|
|
key: 'componentDidMount',
|
|
value: function componentDidMount() {
|
|
var _this2 = this;
|
|
|
|
var _props = this.props,
|
|
className = _props.className,
|
|
onBeforeLoad = _props.onBeforeLoad,
|
|
mode = _props.mode,
|
|
focus = _props.focus,
|
|
theme = _props.theme,
|
|
fontSize = _props.fontSize,
|
|
value = _props.value,
|
|
defaultValue = _props.defaultValue,
|
|
cursorStart = _props.cursorStart,
|
|
showGutter = _props.showGutter,
|
|
wrapEnabled = _props.wrapEnabled,
|
|
showPrintMargin = _props.showPrintMargin,
|
|
_props$scrollMargin = _props.scrollMargin,
|
|
scrollMargin = _props$scrollMargin === undefined ? [0, 0, 0, 0] : _props$scrollMargin,
|
|
keyboardHandler = _props.keyboardHandler,
|
|
onLoad = _props.onLoad,
|
|
commands = _props.commands,
|
|
annotations = _props.annotations,
|
|
markers = _props.markers;
|
|
|
|
|
|
this.editor = _brace2.default.edit(this.refEditor);
|
|
|
|
if (onBeforeLoad) {
|
|
onBeforeLoad(_brace2.default);
|
|
}
|
|
|
|
var editorProps = Object.keys(this.props.editorProps);
|
|
for (var i = 0; i < editorProps.length; i++) {
|
|
this.editor[editorProps[i]] = this.props.editorProps[editorProps[i]];
|
|
}
|
|
|
|
this.editor.renderer.setScrollMargin(scrollMargin[0], scrollMargin[1], scrollMargin[2], scrollMargin[3]);
|
|
this.editor.getSession().setMode('ace/mode/' + mode);
|
|
this.editor.setTheme('ace/theme/' + theme);
|
|
this.editor.setFontSize(fontSize);
|
|
this.editor.setValue(defaultValue === undefined ? value : defaultValue, cursorStart);
|
|
this.editor.renderer.setShowGutter(showGutter);
|
|
this.editor.getSession().setUseWrapMode(wrapEnabled);
|
|
this.editor.setShowPrintMargin(showPrintMargin);
|
|
this.editor.on('focus', this.onFocus);
|
|
this.editor.on('blur', this.onBlur);
|
|
this.editor.on('copy', this.onCopy);
|
|
this.editor.on('paste', this.onPaste);
|
|
this.editor.on('change', this.onChange);
|
|
this.editor.getSession().selection.on('changeSelection', this.onSelectionChange);
|
|
this.editor.session.on('changeScrollTop', this.onScroll);
|
|
this.handleOptions(this.props);
|
|
this.editor.getSession().setAnnotations(annotations || []);
|
|
if (markers && markers.length > 0) {
|
|
this.handleMarkers(markers);
|
|
}
|
|
|
|
// get a list of possible options to avoid 'misspelled option errors'
|
|
var availableOptions = this.editor.$options;
|
|
for (var _i = 0; _i < editorOptions.length; _i++) {
|
|
var option = editorOptions[_i];
|
|
if (availableOptions.hasOwnProperty(option)) {
|
|
this.editor.setOption(option, this.props[option]);
|
|
}
|
|
}
|
|
|
|
if (Array.isArray(commands)) {
|
|
commands.forEach(function (command) {
|
|
_this2.editor.commands.addCommand(command);
|
|
});
|
|
}
|
|
|
|
if (keyboardHandler) {
|
|
this.editor.setKeyboardHandler('ace/keyboard/' + keyboardHandler);
|
|
}
|
|
|
|
if (className) {
|
|
this.refEditor.className += ' ' + className;
|
|
}
|
|
|
|
if (focus) {
|
|
this.editor.focus();
|
|
}
|
|
|
|
if (onLoad) {
|
|
onLoad(this.editor);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'componentWillReceiveProps',
|
|
value: function componentWillReceiveProps(nextProps) {
|
|
var oldProps = this.props;
|
|
|
|
for (var i = 0; i < editorOptions.length; i++) {
|
|
var option = editorOptions[i];
|
|
if (nextProps[option] !== oldProps[option]) {
|
|
this.editor.setOption(option, nextProps[option]);
|
|
}
|
|
}
|
|
|
|
if (nextProps.className !== oldProps.className) {
|
|
var appliedClasses = this.refEditor.className;
|
|
var appliedClassesArray = appliedClasses.trim().split(' ');
|
|
var oldClassesArray = oldProps.className.trim().split(' ');
|
|
oldClassesArray.forEach(function (oldClass) {
|
|
var index = appliedClassesArray.indexOf(oldClass);
|
|
appliedClassesArray.splice(index, 1);
|
|
});
|
|
this.refEditor.className = ' ' + nextProps.className + ' ' + appliedClassesArray.join(' ');
|
|
}
|
|
|
|
if (nextProps.mode !== oldProps.mode) {
|
|
this.editor.getSession().setMode('ace/mode/' + nextProps.mode);
|
|
}
|
|
if (nextProps.theme !== oldProps.theme) {
|
|
this.editor.setTheme('ace/theme/' + nextProps.theme);
|
|
}
|
|
if (nextProps.keyboardHandler !== oldProps.keyboardHandler) {
|
|
if (nextProps.keyboardHandler) {
|
|
this.editor.setKeyboardHandler('ace/keyboard/' + nextProps.keyboardHandler);
|
|
} else {
|
|
this.editor.setKeyboardHandler(null);
|
|
}
|
|
}
|
|
if (nextProps.fontSize !== oldProps.fontSize) {
|
|
this.editor.setFontSize(nextProps.fontSize);
|
|
}
|
|
if (nextProps.wrapEnabled !== oldProps.wrapEnabled) {
|
|
this.editor.getSession().setUseWrapMode(nextProps.wrapEnabled);
|
|
}
|
|
if (nextProps.showPrintMargin !== oldProps.showPrintMargin) {
|
|
this.editor.setShowPrintMargin(nextProps.showPrintMargin);
|
|
}
|
|
if (nextProps.showGutter !== oldProps.showGutter) {
|
|
this.editor.renderer.setShowGutter(nextProps.showGutter);
|
|
}
|
|
if (!(0, _lodash2.default)(nextProps.setOptions, oldProps.setOptions)) {
|
|
this.handleOptions(nextProps);
|
|
}
|
|
if (!(0, _lodash2.default)(nextProps.annotations, oldProps.annotations)) {
|
|
this.editor.getSession().setAnnotations(nextProps.annotations || []);
|
|
}
|
|
if (!(0, _lodash2.default)(nextProps.markers, oldProps.markers) && nextProps.markers && nextProps.markers.length > 0) {
|
|
this.handleMarkers(nextProps.markers);
|
|
}
|
|
|
|
// this doesn't look like it works at all....
|
|
if (!(0, _lodash2.default)(nextProps.scrollMargin, oldProps.scrollMargin)) {
|
|
this.handleScrollMargins(nextProps.scrollMargin);
|
|
}
|
|
if (this.editor && this.editor.getValue() !== nextProps.value) {
|
|
// editor.setValue is a synchronous function call, change event is emitted before setValue return.
|
|
this.silent = true;
|
|
var pos = this.editor.session.selection.toJSON();
|
|
this.editor.setValue(nextProps.value, nextProps.cursorStart);
|
|
this.editor.session.selection.fromJSON(pos);
|
|
this.silent = false;
|
|
}
|
|
|
|
if (nextProps.focus && !oldProps.focus) {
|
|
this.editor.focus();
|
|
}
|
|
if (nextProps.height !== this.props.height || nextProps.width !== this.props.width) {
|
|
this.editor.resize();
|
|
}
|
|
}
|
|
}, {
|
|
key: 'handleScrollMargins',
|
|
value: function handleScrollMargins() {
|
|
var margins = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [0, 0, 0, 0];
|
|
|
|
this.editor.renderer.setScrollMargins(margins[0], margins[1], margins[2], margins[3]);
|
|
}
|
|
}, {
|
|
key: 'componentWillUnmount',
|
|
value: function componentWillUnmount() {
|
|
this.editor.destroy();
|
|
this.editor = null;
|
|
}
|
|
}, {
|
|
key: 'onChange',
|
|
value: function onChange(event) {
|
|
if (this.props.onChange && !this.silent) {
|
|
var value = this.editor.getValue();
|
|
this.props.onChange(value, event);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'onSelectionChange',
|
|
value: function onSelectionChange(event) {
|
|
if (this.props.onSelectionChange) {
|
|
var value = this.editor.getSelection();
|
|
this.props.onSelectionChange(value, event);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'onFocus',
|
|
value: function onFocus() {
|
|
if (this.props.onFocus) {
|
|
this.props.onFocus();
|
|
}
|
|
}
|
|
}, {
|
|
key: 'onBlur',
|
|
value: function onBlur() {
|
|
if (this.props.onBlur) {
|
|
this.props.onBlur();
|
|
}
|
|
}
|
|
}, {
|
|
key: 'onCopy',
|
|
value: function onCopy(text) {
|
|
if (this.props.onCopy) {
|
|
this.props.onCopy(text);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'onPaste',
|
|
value: function onPaste(text) {
|
|
if (this.props.onPaste) {
|
|
this.props.onPaste(text);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'onScroll',
|
|
value: function onScroll() {
|
|
if (this.props.onScroll) {
|
|
this.props.onScroll(this.editor);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'handleOptions',
|
|
value: function handleOptions(props) {
|
|
var setOptions = Object.keys(props.setOptions);
|
|
for (var y = 0; y < setOptions.length; y++) {
|
|
this.editor.setOption(setOptions[y], props.setOptions[setOptions[y]]);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'handleMarkers',
|
|
value: function handleMarkers(markers) {
|
|
var _this3 = this;
|
|
|
|
// remove foreground markers
|
|
var currentMarkers = this.editor.getSession().getMarkers(true);
|
|
for (var i in currentMarkers) {
|
|
if (currentMarkers.hasOwnProperty(i)) {
|
|
this.editor.getSession().removeMarker(currentMarkers[i].id);
|
|
}
|
|
}
|
|
// remove background markers
|
|
currentMarkers = this.editor.getSession().getMarkers(false);
|
|
for (var _i2 in currentMarkers) {
|
|
if (currentMarkers.hasOwnProperty(_i2)) {
|
|
this.editor.getSession().removeMarker(currentMarkers[_i2].id);
|
|
}
|
|
}
|
|
// add new markers
|
|
markers.forEach(function (_ref) {
|
|
var startRow = _ref.startRow,
|
|
startCol = _ref.startCol,
|
|
endRow = _ref.endRow,
|
|
endCol = _ref.endCol,
|
|
className = _ref.className,
|
|
type = _ref.type,
|
|
_ref$inFront = _ref.inFront,
|
|
inFront = _ref$inFront === undefined ? false : _ref$inFront;
|
|
|
|
var range = new Range(startRow, startCol, endRow, endCol);
|
|
_this3.editor.getSession().addMarker(range, className, type, inFront);
|
|
});
|
|
}
|
|
}, {
|
|
key: 'updateRef',
|
|
value: function updateRef(item) {
|
|
this.refEditor = item;
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
var _props2 = this.props,
|
|
name = _props2.name,
|
|
width = _props2.width,
|
|
height = _props2.height,
|
|
style = _props2.style;
|
|
|
|
var divStyle = _extends({ width: width, height: height }, style);
|
|
return _react2.default.createElement('div', { ref: this.updateRef,
|
|
id: name,
|
|
style: divStyle
|
|
});
|
|
}
|
|
}]);
|
|
|
|
return ReactAce;
|
|
}(_react.Component);
|
|
|
|
exports.default = ReactAce;
|
|
|
|
|
|
ReactAce.propTypes = {
|
|
mode: _propTypes2.default.string,
|
|
focus: _propTypes2.default.bool,
|
|
theme: _propTypes2.default.string,
|
|
name: _propTypes2.default.string,
|
|
className: _propTypes2.default.string,
|
|
height: _propTypes2.default.string,
|
|
width: _propTypes2.default.string,
|
|
fontSize: _propTypes2.default.oneOfType([_propTypes2.default.number, _propTypes2.default.string]),
|
|
showGutter: _propTypes2.default.bool,
|
|
onChange: _propTypes2.default.func,
|
|
onCopy: _propTypes2.default.func,
|
|
onPaste: _propTypes2.default.func,
|
|
onFocus: _propTypes2.default.func,
|
|
onBlur: _propTypes2.default.func,
|
|
onScroll: _propTypes2.default.func,
|
|
value: _propTypes2.default.string,
|
|
defaultValue: _propTypes2.default.string,
|
|
onLoad: _propTypes2.default.func,
|
|
onSelectionChange: _propTypes2.default.func,
|
|
onBeforeLoad: _propTypes2.default.func,
|
|
minLines: _propTypes2.default.number,
|
|
maxLines: _propTypes2.default.number,
|
|
readOnly: _propTypes2.default.bool,
|
|
highlightActiveLine: _propTypes2.default.bool,
|
|
tabSize: _propTypes2.default.number,
|
|
showPrintMargin: _propTypes2.default.bool,
|
|
cursorStart: _propTypes2.default.number,
|
|
editorProps: _propTypes2.default.object,
|
|
setOptions: _propTypes2.default.object,
|
|
style: _propTypes2.default.object,
|
|
scrollMargin: _propTypes2.default.array,
|
|
annotations: _propTypes2.default.array,
|
|
markers: _propTypes2.default.array,
|
|
keyboardHandler: _propTypes2.default.string,
|
|
wrapEnabled: _propTypes2.default.bool,
|
|
enableBasicAutocompletion: _propTypes2.default.oneOfType([_propTypes2.default.bool, _propTypes2.default.array]),
|
|
enableLiveAutocompletion: _propTypes2.default.oneOfType([_propTypes2.default.bool, _propTypes2.default.array]),
|
|
commands: _propTypes2.default.array
|
|
};
|
|
|
|
ReactAce.defaultProps = {
|
|
name: 'brace-editor',
|
|
focus: false,
|
|
mode: '',
|
|
theme: '',
|
|
height: '500px',
|
|
width: '500px',
|
|
value: '',
|
|
fontSize: 12,
|
|
showGutter: true,
|
|
onChange: null,
|
|
onPaste: null,
|
|
onLoad: null,
|
|
onScroll: null,
|
|
minLines: null,
|
|
maxLines: null,
|
|
readOnly: false,
|
|
highlightActiveLine: true,
|
|
showPrintMargin: true,
|
|
tabSize: 4,
|
|
cursorStart: 1,
|
|
editorProps: {},
|
|
style: {},
|
|
scrollMargin: [0, 0, 0, 0],
|
|
setOptions: {},
|
|
wrapEnabled: false,
|
|
enableBasicAutocompletion: false,
|
|
enableLiveAutocompletion: false
|
|
}; |