forgeplus-react/node_modules/react-codemirror/lib/Codemirror.js

136 lines
4.4 KiB
JavaScript
Raw Normal View History

2023-07-29 21:19:10 +08:00
'use strict';
var React = require('react');
var ReactDOM = require('react-dom');
var PropTypes = require('prop-types');
var className = require('classnames');
var debounce = require('lodash.debounce');
var isEqual = require('lodash.isequal');
var createReactClass = require('create-react-class');
function normalizeLineEndings(str) {
if (!str) return str;
return str.replace(/\r\n|\r/g, '\n');
}
var CodeMirror = createReactClass({
propTypes: {
autoFocus: PropTypes.bool,
className: PropTypes.any,
codeMirrorInstance: PropTypes.func,
defaultValue: PropTypes.string,
name: PropTypes.string,
onChange: PropTypes.func,
onCursorActivity: PropTypes.func,
onFocusChange: PropTypes.func,
onScroll: PropTypes.func,
options: PropTypes.object,
path: PropTypes.string,
value: PropTypes.string,
preserveScrollPosition: PropTypes.bool
},
getDefaultProps: function getDefaultProps() {
return {
preserveScrollPosition: false
};
},
getCodeMirrorInstance: function getCodeMirrorInstance() {
return this.props.codeMirrorInstance || require('codemirror');
},
getInitialState: function getInitialState() {
return {
isFocused: false
};
},
componentWillMount: function componentWillMount() {
this.componentWillReceiveProps = debounce(this.componentWillReceiveProps, 0);
if (this.props.path) {
console.error('Warning: react-codemirror: the `path` prop has been changed to `name`');
}
},
componentDidMount: function componentDidMount() {
var codeMirrorInstance = this.getCodeMirrorInstance();
this.codeMirror = codeMirrorInstance.fromTextArea(this.textareaNode, this.props.options);
this.codeMirror.on('change', this.codemirrorValueChanged);
this.codeMirror.on('cursorActivity', this.cursorActivity);
this.codeMirror.on('focus', this.focusChanged.bind(this, true));
this.codeMirror.on('blur', this.focusChanged.bind(this, false));
this.codeMirror.on('scroll', this.scrollChanged);
this.codeMirror.setValue(this.props.defaultValue || this.props.value || '');
},
componentWillUnmount: function componentWillUnmount() {
// is there a lighter-weight way to remove the cm instance?
if (this.codeMirror) {
this.codeMirror.toTextArea();
}
},
componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
if (this.codeMirror && nextProps.value !== undefined && nextProps.value !== this.props.value && normalizeLineEndings(this.codeMirror.getValue()) !== normalizeLineEndings(nextProps.value)) {
if (this.props.preserveScrollPosition) {
var prevScrollPosition = this.codeMirror.getScrollInfo();
this.codeMirror.setValue(nextProps.value);
this.codeMirror.scrollTo(prevScrollPosition.left, prevScrollPosition.top);
} else {
this.codeMirror.setValue(nextProps.value);
}
}
if (typeof nextProps.options === 'object') {
for (var optionName in nextProps.options) {
if (nextProps.options.hasOwnProperty(optionName)) {
this.setOptionIfChanged(optionName, nextProps.options[optionName]);
}
}
}
},
setOptionIfChanged: function setOptionIfChanged(optionName, newValue) {
var oldValue = this.codeMirror.getOption(optionName);
if (!isEqual(oldValue, newValue)) {
this.codeMirror.setOption(optionName, newValue);
}
},
getCodeMirror: function getCodeMirror() {
return this.codeMirror;
},
focus: function focus() {
if (this.codeMirror) {
this.codeMirror.focus();
}
},
focusChanged: function focusChanged(focused) {
this.setState({
isFocused: focused
});
this.props.onFocusChange && this.props.onFocusChange(focused);
},
cursorActivity: function cursorActivity(cm) {
this.props.onCursorActivity && this.props.onCursorActivity(cm);
},
scrollChanged: function scrollChanged(cm) {
this.props.onScroll && this.props.onScroll(cm.getScrollInfo());
},
codemirrorValueChanged: function codemirrorValueChanged(doc, change) {
if (this.props.onChange && change.origin !== 'setValue') {
this.props.onChange(doc.getValue(), change);
}
},
render: function render() {
var _this = this;
var editorClassName = className('ReactCodeMirror', this.state.isFocused ? 'ReactCodeMirror--focused' : null, this.props.className);
return React.createElement(
'div',
{ className: editorClassName },
React.createElement('textarea', {
ref: function (ref) {
return _this.textareaNode = ref;
},
name: this.props.name || this.props.path,
defaultValue: this.props.value,
autoComplete: 'off',
autoFocus: this.props.autoFocus
})
);
}
});
module.exports = CodeMirror;