split.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. "use strict";
  2. var __extends = (this && this.__extends) || (function () {
  3. var extendStatics = function (d, b) {
  4. extendStatics = Object.setPrototypeOf ||
  5. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  6. function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
  7. return extendStatics(d, b);
  8. };
  9. return function (d, b) {
  10. if (typeof b !== "function" && b !== null)
  11. throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
  12. extendStatics(d, b);
  13. function __() { this.constructor = d; }
  14. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  15. };
  16. })();
  17. var __assign = (this && this.__assign) || function () {
  18. __assign = Object.assign || function(t) {
  19. for (var s, i = 1, n = arguments.length; i < n; i++) {
  20. s = arguments[i];
  21. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
  22. t[p] = s[p];
  23. }
  24. return t;
  25. };
  26. return __assign.apply(this, arguments);
  27. };
  28. Object.defineProperty(exports, "__esModule", { value: true });
  29. var editorOptions_1 = require("./editorOptions");
  30. var ace = editorOptions_1.getAceInstance();
  31. var ace_builds_1 = require("ace-builds");
  32. var ext_split_1 = require("ace-builds/src-noconflict/ext-split");
  33. var PropTypes = require("prop-types");
  34. var React = require("react");
  35. var isEqual = require("lodash.isequal");
  36. var get = require("lodash.get");
  37. var SplitComponent = /** @class */ (function (_super) {
  38. __extends(SplitComponent, _super);
  39. function SplitComponent(props) {
  40. var _this = _super.call(this, props) || this;
  41. editorOptions_1.editorEvents.forEach(function (method) {
  42. _this[method] = _this[method].bind(_this);
  43. });
  44. _this.debounce = editorOptions_1.debounce;
  45. return _this;
  46. }
  47. SplitComponent.prototype.isInShadow = function (node) {
  48. var parent = node && node.parentNode;
  49. while (parent) {
  50. if (parent.toString() === "[object ShadowRoot]") {
  51. return true;
  52. }
  53. parent = parent.parentNode;
  54. }
  55. return false;
  56. };
  57. SplitComponent.prototype.componentDidMount = function () {
  58. var _this = this;
  59. var _a = this.props, className = _a.className, onBeforeLoad = _a.onBeforeLoad, mode = _a.mode, focus = _a.focus, theme = _a.theme, fontSize = _a.fontSize, value = _a.value, defaultValue = _a.defaultValue, cursorStart = _a.cursorStart, showGutter = _a.showGutter, wrapEnabled = _a.wrapEnabled, showPrintMargin = _a.showPrintMargin, _b = _a.scrollMargin, scrollMargin = _b === void 0 ? [0, 0, 0, 0] : _b, keyboardHandler = _a.keyboardHandler, onLoad = _a.onLoad, commands = _a.commands, annotations = _a.annotations, markers = _a.markers, splits = _a.splits;
  60. this.editor = ace.edit(this.refEditor);
  61. if (this.isInShadow(this.refEditor)) {
  62. this.editor.renderer.attachToShadowRoot();
  63. }
  64. this.editor.setTheme("ace/theme/" + theme);
  65. if (onBeforeLoad) {
  66. onBeforeLoad(ace);
  67. }
  68. var editorProps = Object.keys(this.props.editorProps);
  69. var split = new ext_split_1.Split(this.editor.container, "ace/theme/" + theme, splits);
  70. this.editor.env.split = split;
  71. this.splitEditor = split.getEditor(0);
  72. this.split = split;
  73. // in a split scenario we don't want a print margin for the entire application
  74. this.editor.setShowPrintMargin(false);
  75. this.editor.renderer.setShowGutter(false);
  76. // get a list of possible options to avoid 'misspelled option errors'
  77. var availableOptions = this.splitEditor.$options;
  78. if (this.props.debounceChangePeriod) {
  79. this.onChange = this.debounce(this.onChange, this.props.debounceChangePeriod);
  80. }
  81. split.forEach(function (editor, index) {
  82. for (var i = 0; i < editorProps.length; i++) {
  83. editor[editorProps[i]] = _this.props.editorProps[editorProps[i]];
  84. }
  85. var defaultValueForEditor = get(defaultValue, index);
  86. var valueForEditor = get(value, index, "");
  87. editor.session.setUndoManager(new ace.UndoManager());
  88. editor.setTheme("ace/theme/" + theme);
  89. editor.renderer.setScrollMargin(scrollMargin[0], scrollMargin[1], scrollMargin[2], scrollMargin[3]);
  90. editor.getSession().setMode("ace/mode/" + mode);
  91. editor.setFontSize(fontSize);
  92. editor.renderer.setShowGutter(showGutter);
  93. editor.getSession().setUseWrapMode(wrapEnabled);
  94. editor.setShowPrintMargin(showPrintMargin);
  95. editor.on("focus", _this.onFocus);
  96. editor.on("blur", _this.onBlur);
  97. editor.on("input", _this.onInput);
  98. editor.on("copy", _this.onCopy);
  99. editor.on("paste", _this.onPaste);
  100. editor.on("change", _this.onChange);
  101. editor
  102. .getSession()
  103. .selection.on("changeSelection", _this.onSelectionChange);
  104. editor.getSession().selection.on("changeCursor", _this.onCursorChange);
  105. editor.session.on("changeScrollTop", _this.onScroll);
  106. editor.setValue(defaultValueForEditor === undefined
  107. ? valueForEditor
  108. : defaultValueForEditor, cursorStart);
  109. var newAnnotations = get(annotations, index, []);
  110. var newMarkers = get(markers, index, []);
  111. editor.getSession().setAnnotations(newAnnotations);
  112. if (newMarkers && newMarkers.length > 0) {
  113. _this.handleMarkers(newMarkers, editor);
  114. }
  115. for (var i = 0; i < editorOptions_1.editorOptions.length; i++) {
  116. var option = editorOptions_1.editorOptions[i];
  117. if (availableOptions.hasOwnProperty(option)) {
  118. editor.setOption(option, _this.props[option]);
  119. }
  120. else if (_this.props[option]) {
  121. console.warn("ReaceAce: editor option " + option + " was activated but not found. Did you need to import a related tool or did you possibly mispell the option?");
  122. }
  123. }
  124. _this.handleOptions(_this.props, editor);
  125. if (Array.isArray(commands)) {
  126. commands.forEach(function (command) {
  127. if (typeof command.exec === "string") {
  128. editor.commands.bindKey(command.bindKey, command.exec);
  129. }
  130. else {
  131. editor.commands.addCommand(command);
  132. }
  133. });
  134. }
  135. if (keyboardHandler) {
  136. editor.setKeyboardHandler("ace/keyboard/" + keyboardHandler);
  137. }
  138. });
  139. if (className) {
  140. this.refEditor.className += " " + className;
  141. }
  142. if (focus) {
  143. this.splitEditor.focus();
  144. }
  145. var sp = this.editor.env.split;
  146. sp.setOrientation(this.props.orientation === "below" ? sp.BELOW : sp.BESIDE);
  147. sp.resize(true);
  148. if (onLoad) {
  149. onLoad(sp);
  150. }
  151. };
  152. SplitComponent.prototype.componentDidUpdate = function (prevProps) {
  153. var _this = this;
  154. var oldProps = prevProps;
  155. var nextProps = this.props;
  156. var split = this.editor.env.split;
  157. if (nextProps.splits !== oldProps.splits) {
  158. split.setSplits(nextProps.splits);
  159. }
  160. if (nextProps.orientation !== oldProps.orientation) {
  161. split.setOrientation(nextProps.orientation === "below" ? split.BELOW : split.BESIDE);
  162. }
  163. split.forEach(function (editor, index) {
  164. if (nextProps.mode !== oldProps.mode) {
  165. editor.getSession().setMode("ace/mode/" + nextProps.mode);
  166. }
  167. if (nextProps.keyboardHandler !== oldProps.keyboardHandler) {
  168. if (nextProps.keyboardHandler) {
  169. editor.setKeyboardHandler("ace/keyboard/" + nextProps.keyboardHandler);
  170. }
  171. else {
  172. editor.setKeyboardHandler(null);
  173. }
  174. }
  175. if (nextProps.fontSize !== oldProps.fontSize) {
  176. editor.setFontSize(nextProps.fontSize);
  177. }
  178. if (nextProps.wrapEnabled !== oldProps.wrapEnabled) {
  179. editor.getSession().setUseWrapMode(nextProps.wrapEnabled);
  180. }
  181. if (nextProps.showPrintMargin !== oldProps.showPrintMargin) {
  182. editor.setShowPrintMargin(nextProps.showPrintMargin);
  183. }
  184. if (nextProps.showGutter !== oldProps.showGutter) {
  185. editor.renderer.setShowGutter(nextProps.showGutter);
  186. }
  187. for (var i = 0; i < editorOptions_1.editorOptions.length; i++) {
  188. var option = editorOptions_1.editorOptions[i];
  189. if (nextProps[option] !== oldProps[option]) {
  190. editor.setOption(option, nextProps[option]);
  191. }
  192. }
  193. if (!isEqual(nextProps.setOptions, oldProps.setOptions)) {
  194. _this.handleOptions(nextProps, editor);
  195. }
  196. var nextValue = get(nextProps.value, index, "");
  197. if (editor.getValue() !== nextValue) {
  198. // editor.setValue is a synchronous function call, change event is emitted before setValue return.
  199. _this.silent = true;
  200. var pos = editor.session.selection.toJSON();
  201. editor.setValue(nextValue, nextProps.cursorStart);
  202. editor.session.selection.fromJSON(pos);
  203. _this.silent = false;
  204. }
  205. var newAnnotations = get(nextProps.annotations, index, []);
  206. var oldAnnotations = get(oldProps.annotations, index, []);
  207. if (!isEqual(newAnnotations, oldAnnotations)) {
  208. editor.getSession().setAnnotations(newAnnotations);
  209. }
  210. var newMarkers = get(nextProps.markers, index, []);
  211. var oldMarkers = get(oldProps.markers, index, []);
  212. if (!isEqual(newMarkers, oldMarkers) && Array.isArray(newMarkers)) {
  213. _this.handleMarkers(newMarkers, editor);
  214. }
  215. });
  216. if (nextProps.className !== oldProps.className) {
  217. var appliedClasses = this.refEditor.className;
  218. var appliedClassesArray_1 = appliedClasses.trim().split(" ");
  219. var oldClassesArray = oldProps.className.trim().split(" ");
  220. oldClassesArray.forEach(function (oldClass) {
  221. var index = appliedClassesArray_1.indexOf(oldClass);
  222. appliedClassesArray_1.splice(index, 1);
  223. });
  224. this.refEditor.className =
  225. " " + nextProps.className + " " + appliedClassesArray_1.join(" ");
  226. }
  227. if (nextProps.theme !== oldProps.theme) {
  228. split.setTheme("ace/theme/" + nextProps.theme);
  229. }
  230. if (nextProps.focus && !oldProps.focus) {
  231. this.splitEditor.focus();
  232. }
  233. if (nextProps.height !== this.props.height ||
  234. nextProps.width !== this.props.width) {
  235. this.editor.resize();
  236. }
  237. };
  238. SplitComponent.prototype.componentWillUnmount = function () {
  239. this.editor.destroy();
  240. this.editor = null;
  241. };
  242. SplitComponent.prototype.onChange = function (event) {
  243. if (this.props.onChange && !this.silent) {
  244. var value_1 = [];
  245. this.editor.env.split.forEach(function (editor) {
  246. value_1.push(editor.getValue());
  247. });
  248. this.props.onChange(value_1, event);
  249. }
  250. };
  251. SplitComponent.prototype.onSelectionChange = function (event) {
  252. if (this.props.onSelectionChange) {
  253. var value_2 = [];
  254. this.editor.env.split.forEach(function (editor) {
  255. value_2.push(editor.getSelection());
  256. });
  257. this.props.onSelectionChange(value_2, event);
  258. }
  259. };
  260. SplitComponent.prototype.onCursorChange = function (event) {
  261. if (this.props.onCursorChange) {
  262. var value_3 = [];
  263. this.editor.env.split.forEach(function (editor) {
  264. value_3.push(editor.getSelection());
  265. });
  266. this.props.onCursorChange(value_3, event);
  267. }
  268. };
  269. SplitComponent.prototype.onFocus = function (event) {
  270. if (this.props.onFocus) {
  271. this.props.onFocus(event);
  272. }
  273. };
  274. SplitComponent.prototype.onInput = function (event) {
  275. if (this.props.onInput) {
  276. this.props.onInput(event);
  277. }
  278. };
  279. SplitComponent.prototype.onBlur = function (event) {
  280. if (this.props.onBlur) {
  281. this.props.onBlur(event);
  282. }
  283. };
  284. SplitComponent.prototype.onCopy = function (text) {
  285. if (this.props.onCopy) {
  286. this.props.onCopy(text);
  287. }
  288. };
  289. SplitComponent.prototype.onPaste = function (text) {
  290. if (this.props.onPaste) {
  291. this.props.onPaste(text);
  292. }
  293. };
  294. SplitComponent.prototype.onScroll = function () {
  295. if (this.props.onScroll) {
  296. this.props.onScroll(this.editor);
  297. }
  298. };
  299. SplitComponent.prototype.handleOptions = function (props, editor) {
  300. var setOptions = Object.keys(props.setOptions);
  301. for (var y = 0; y < setOptions.length; y++) {
  302. editor.setOption(setOptions[y], props.setOptions[setOptions[y]]);
  303. }
  304. };
  305. SplitComponent.prototype.handleMarkers = function (markers, editor) {
  306. // remove foreground markers
  307. var currentMarkers = editor.getSession().getMarkers(true);
  308. for (var i in currentMarkers) {
  309. if (currentMarkers.hasOwnProperty(i)) {
  310. editor.getSession().removeMarker(currentMarkers[i].id);
  311. }
  312. }
  313. // remove background markers
  314. currentMarkers = editor.getSession().getMarkers(false);
  315. for (var i in currentMarkers) {
  316. if (currentMarkers.hasOwnProperty(i)) {
  317. editor.getSession().removeMarker(currentMarkers[i].id);
  318. }
  319. }
  320. // add new markers
  321. markers.forEach(function (_a) {
  322. var startRow = _a.startRow, startCol = _a.startCol, endRow = _a.endRow, endCol = _a.endCol, className = _a.className, type = _a.type, _b = _a.inFront, inFront = _b === void 0 ? false : _b;
  323. var range = new ace_builds_1.Range(startRow, startCol, endRow, endCol);
  324. editor
  325. .getSession()
  326. .addMarker(range, className, type, inFront);
  327. });
  328. };
  329. SplitComponent.prototype.updateRef = function (item) {
  330. this.refEditor = item;
  331. };
  332. SplitComponent.prototype.render = function () {
  333. var _a = this.props, name = _a.name, width = _a.width, height = _a.height, style = _a.style;
  334. var divStyle = __assign({ width: width, height: height }, style);
  335. return React.createElement("div", { ref: this.updateRef, id: name, style: divStyle });
  336. };
  337. SplitComponent.propTypes = {
  338. className: PropTypes.string,
  339. debounceChangePeriod: PropTypes.number,
  340. defaultValue: PropTypes.arrayOf(PropTypes.string),
  341. focus: PropTypes.bool,
  342. fontSize: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  343. height: PropTypes.string,
  344. mode: PropTypes.string,
  345. name: PropTypes.string,
  346. onBlur: PropTypes.func,
  347. onChange: PropTypes.func,
  348. onCopy: PropTypes.func,
  349. onFocus: PropTypes.func,
  350. onInput: PropTypes.func,
  351. onLoad: PropTypes.func,
  352. onPaste: PropTypes.func,
  353. onScroll: PropTypes.func,
  354. orientation: PropTypes.string,
  355. showGutter: PropTypes.bool,
  356. splits: PropTypes.number,
  357. theme: PropTypes.string,
  358. value: PropTypes.arrayOf(PropTypes.string),
  359. width: PropTypes.string,
  360. onSelectionChange: PropTypes.func,
  361. onCursorChange: PropTypes.func,
  362. onBeforeLoad: PropTypes.func,
  363. minLines: PropTypes.number,
  364. maxLines: PropTypes.number,
  365. readOnly: PropTypes.bool,
  366. highlightActiveLine: PropTypes.bool,
  367. tabSize: PropTypes.number,
  368. showPrintMargin: PropTypes.bool,
  369. cursorStart: PropTypes.number,
  370. editorProps: PropTypes.object,
  371. setOptions: PropTypes.object,
  372. style: PropTypes.object,
  373. scrollMargin: PropTypes.array,
  374. annotations: PropTypes.array,
  375. markers: PropTypes.array,
  376. keyboardHandler: PropTypes.string,
  377. wrapEnabled: PropTypes.bool,
  378. enableBasicAutocompletion: PropTypes.oneOfType([
  379. PropTypes.bool,
  380. PropTypes.array
  381. ]),
  382. enableLiveAutocompletion: PropTypes.oneOfType([
  383. PropTypes.bool,
  384. PropTypes.array
  385. ]),
  386. commands: PropTypes.array
  387. };
  388. SplitComponent.defaultProps = {
  389. name: "ace-editor",
  390. focus: false,
  391. orientation: "beside",
  392. splits: 2,
  393. mode: "",
  394. theme: "",
  395. height: "500px",
  396. width: "500px",
  397. value: [],
  398. fontSize: 12,
  399. showGutter: true,
  400. onChange: null,
  401. onPaste: null,
  402. onLoad: null,
  403. onScroll: null,
  404. minLines: null,
  405. maxLines: null,
  406. readOnly: false,
  407. highlightActiveLine: true,
  408. showPrintMargin: true,
  409. tabSize: 4,
  410. cursorStart: 1,
  411. editorProps: {},
  412. style: {},
  413. scrollMargin: [0, 0, 0, 0],
  414. setOptions: {},
  415. wrapEnabled: false,
  416. enableBasicAutocompletion: false,
  417. enableLiveAutocompletion: false
  418. };
  419. return SplitComponent;
  420. }(React.Component));
  421. exports.default = SplitComponent;
  422. //# sourceMappingURL=split.js.map