UNPKG

feeles-ide

Version:

The hackable and serializable IDE to make learning material

209 lines (167 loc) 6.86 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _codemirror = _interopRequireDefault(require("codemirror")); var _deepEqual = _interopRequireDefault(require("deep-equal")); var _includes = _interopRequireDefault(require("lodash/includes")); var CodeMirrorComponent = /*#__PURE__*/ function (_PureComponent) { (0, _inherits2.default)(CodeMirrorComponent, _PureComponent); function CodeMirrorComponent() { var _getPrototypeOf2; var _this; (0, _classCallCheck2.default)(this, CodeMirrorComponent); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = (0, _possibleConstructorReturn2.default)(this, (_getPrototypeOf2 = (0, _getPrototypeOf3.default)(CodeMirrorComponent)).call.apply(_getPrototypeOf2, [this].concat(args))); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "state", { // File ごとに存在する CodeMirror.Doc インスタンスのキャッシュ docs: new Map() }); return _this; } (0, _createClass2.default)(CodeMirrorComponent, [{ key: "componentDidMount", value: function componentDidMount() { // initialize CodeMirror this.codeMirror = _codemirror.default.fromTextArea(this.ref, this.options); var id = this.props.id; var doc = this.codeMirror.getDoc(); doc.setValue(this.props.value); // set default value doc.clearHistory(); this.state.docs.set(id, doc); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { this.state.docs.clear(); this.codeMirror.toTextArea(); this.codeMirror = null; // GC?? } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps) { // タブ, value の更新 if (prevProps.id !== this.props.id) { // 次のタブ (or undefined) var doc = this.state.docs.get(this.props.id); if (!doc) { // 新しく開かれたタブ(キャッシュに存在しない) // copy をもとに新しい Doc を作り、 value を更新 doc = this.codeMirror.getDoc().copy(false); doc.setValue(this.props.value); // value の更新 doc.clearHistory(); this.state.docs.set(this.props.id, doc); } // 現在のタブと入れ替え this.codeMirror.swapDoc(doc); } else { // 同じタブ(ファイル) this.setValueIfDifferent(this.props.value); // value の更新 } // options の更新 var ignoreKeys = ['id', 'value']; var _arr = Object.entries(this.props); for (var _i = 0; _i < _arr.length; _i++) { var _arr$_i = (0, _slicedToArray2.default)(_arr[_i], 2), key = _arr$_i[0], nextValue = _arr$_i[1]; if ((0, _includes.default)(ignoreKeys, key)) continue; if (!(0, _deepEqual.default)(prevProps[key], this.props[key])) { // options の変更を CodeMirror に伝える this.codeMirror.setOption(key, nextValue); } } } }, { key: "getCodeMirror", value: function getCodeMirror() { return this.codeMirror; } }, { key: "setValueIfDifferent", value: function setValueIfDifferent(nextValue) { // 現在エディタに表示されている文章と比較し、違ったら setValue する var value = this.codeMirror.getValue(); if (value !== nextValue) { // スクロール位置を保持する var _this$codeMirror$getS = this.codeMirror.getScrollInfo(), left = _this$codeMirror$getS.left, top = _this$codeMirror$getS.top; this.codeMirror.setValue(value); this.codeMirror.scrollTo(left, top); } } }, { key: "render", value: function render() { var _this2 = this; return _react.default.createElement("textarea", { ref: function ref(_ref) { return _this2.ref = _ref; } }); } }, { key: "options", get: function get() { var gutters = []; if (this.props.lineNumbers) { gutters.push('CodeMirror-linenumbers'); } if (this.props.foldGutter) { gutters.push('CodeMirror-foldgutter'); } return (0, _objectSpread2.default)({}, this.props, { gutters: gutters }); } }]); return CodeMirrorComponent; }(_react.PureComponent); exports.default = CodeMirrorComponent; (0, _defineProperty2.default)(CodeMirrorComponent, "propTypes", { id: _propTypes.default.string.isRequired, // CodeMirror options value: _propTypes.default.string.isRequired, mode: _propTypes.default.string, lineNumbers: _propTypes.default.bool.isRequired, indentUnit: _propTypes.default.number.isRequired, indentWithTabs: _propTypes.default.bool.isRequired, matchBrackets: _propTypes.default.bool.isRequired, autoCloseBrackets: _propTypes.default.bool.isRequired, keyMap: _propTypes.default.string.isRequired, foldOptions: _propTypes.default.object, dragDrop: _propTypes.default.bool.isRequired, extraKeys: _propTypes.default.object.isRequired, readOnly: _propTypes.default.bool.isRequired, foldGutter: _propTypes.default.bool.isRequired }); (0, _defineProperty2.default)(CodeMirrorComponent, "defaultProps", { mode: null, lineNumbers: true, indentUnit: 4, indentWithTabs: true, matchBrackets: true, autoCloseBrackets: true, keyMap: 'default', dragDrop: false, extraKeys: {}, readOnly: false, foldGutter: false });