"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); var PropTypes = require("prop-types"); var React = require("react"); var split_1 = require("./split"); var DiffMatchPatch = require("diff-match-patch"); var DiffComponent = /** @class */ (function (_super) { __extends(DiffComponent, _super); function DiffComponent(props) { var _this = _super.call(this, props) || this; _this.state = { value: _this.props.value }; _this.onChange = _this.onChange.bind(_this); _this.diff = _this.diff.bind(_this); return _this; } DiffComponent.prototype.componentDidUpdate = function () { var value = this.props.value; if (value !== this.state.value) { this.setState({ value: value }); } }; DiffComponent.prototype.onChange = function (value) { this.setState({ value: value }); if (this.props.onChange) { this.props.onChange(value); } }; DiffComponent.prototype.diff = function () { var dmp = new DiffMatchPatch(); var lhString = this.state.value[0]; var rhString = this.state.value[1]; if (lhString.length === 0 && rhString.length === 0) { return []; } var diff = dmp.diff_main(lhString, rhString); dmp.diff_cleanupSemantic(diff); var diffedLines = this.generateDiffedLines(diff); var codeEditorSettings = this.setCodeMarkers(diffedLines); return codeEditorSettings; }; DiffComponent.prototype.generateDiffedLines = function (diff) { var C = { DIFF_EQUAL: 0, DIFF_DELETE: -1, DIFF_INSERT: 1 }; var diffedLines = { left: [], right: [] }; var cursor = { left: 1, right: 1 }; diff.forEach(function (chunk) { var chunkType = chunk[0]; var text = chunk[1]; var lines = text.split("\n").length - 1; // diff-match-patch sometimes returns empty strings at random if (text.length === 0) { return; } var firstChar = text[0]; var lastChar = text[text.length - 1]; var linesToHighlight = 0; switch (chunkType) { case C.DIFF_EQUAL: cursor.left += lines; cursor.right += lines; break; case C.DIFF_DELETE: // If the deletion starts with a newline, push the cursor down to that line if (firstChar === "\n") { cursor.left++; lines--; } linesToHighlight = lines; // If the deletion does not include a newline, highlight the same line on the right if (linesToHighlight === 0) { diffedLines.right.push({ startLine: cursor.right, endLine: cursor.right }); } // If the last character is a newline, we don't want to highlight that line if (lastChar === "\n") { linesToHighlight -= 1; } diffedLines.left.push({ startLine: cursor.left, endLine: cursor.left + linesToHighlight }); cursor.left += lines; break; case C.DIFF_INSERT: // If the insertion starts with a newline, push the cursor down to that line if (firstChar === "\n") { cursor.right++; lines--; } linesToHighlight = lines; // If the insertion does not include a newline, highlight the same line on the left if (linesToHighlight === 0) { diffedLines.left.push({ startLine: cursor.left, endLine: cursor.left }); } // If the last character is a newline, we don't want to highlight that line if (lastChar === "\n") { linesToHighlight -= 1; } diffedLines.right.push({ startLine: cursor.right, endLine: cursor.right + linesToHighlight }); cursor.right += lines; break; default: throw new Error("Diff type was not defined."); } }); return diffedLines; }; // Receives a collection of line numbers and iterates through them to highlight appropriately // Returns an object that tells the render() method how to display the code editors DiffComponent.prototype.setCodeMarkers = function (diffedLines) { if (diffedLines === void 0) { diffedLines = { left: [], right: [] }; } var codeEditorSettings = []; var newMarkerSet = { left: [], right: [] }; for (var i = 0; i < diffedLines.left.length; i++) { var markerObj = { startRow: diffedLines.left[i].startLine - 1, endRow: diffedLines.left[i].endLine, type: "text", className: "codeMarker" }; newMarkerSet.left.push(markerObj); } for (var i = 0; i < diffedLines.right.length; i++) { var markerObj = { startRow: diffedLines.right[i].startLine - 1, endRow: diffedLines.right[i].endLine, type: "text", className: "codeMarker" }; newMarkerSet.right.push(markerObj); } codeEditorSettings[0] = newMarkerSet.left; codeEditorSettings[1] = newMarkerSet.right; return codeEditorSettings; }; DiffComponent.prototype.render = function () { var markers = this.diff(); return (React.createElement(split_1.default, { name: this.props.name, className: this.props.className, focus: this.props.focus, orientation: this.props.orientation, splits: this.props.splits, mode: this.props.mode, theme: this.props.theme, height: this.props.height, width: this.props.width, fontSize: this.props.fontSize, showGutter: this.props.showGutter, onChange: this.onChange, onPaste: this.props.onPaste, onLoad: this.props.onLoad, onScroll: this.props.onScroll, minLines: this.props.minLines, maxLines: this.props.maxLines, readOnly: this.props.readOnly, highlightActiveLine: this.props.highlightActiveLine, showPrintMargin: this.props.showPrintMargin, tabSize: this.props.tabSize, cursorStart: this.props.cursorStart, editorProps: this.props.editorProps, style: this.props.style, scrollMargin: this.props.scrollMargin, setOptions: this.props.setOptions, wrapEnabled: this.props.wrapEnabled, enableBasicAutocompletion: this.props.enableBasicAutocompletion, enableLiveAutocompletion: this.props.enableLiveAutocompletion, value: this.state.value, markers: markers })); }; DiffComponent.propTypes = { cursorStart: PropTypes.number, editorProps: PropTypes.object, enableBasicAutocompletion: PropTypes.bool, enableLiveAutocompletion: PropTypes.bool, focus: PropTypes.bool, fontSize: PropTypes.number, height: PropTypes.string, highlightActiveLine: PropTypes.bool, maxLines: PropTypes.number, minLines: PropTypes.number, mode: PropTypes.string, name: PropTypes.string, className: PropTypes.string, onLoad: PropTypes.func, onPaste: PropTypes.func, onScroll: PropTypes.func, onChange: PropTypes.func, orientation: PropTypes.string, readOnly: PropTypes.bool, scrollMargin: PropTypes.array, setOptions: PropTypes.object, showGutter: PropTypes.bool, showPrintMargin: PropTypes.bool, splits: PropTypes.number, style: PropTypes.object, tabSize: PropTypes.number, theme: PropTypes.string, value: PropTypes.array, width: PropTypes.string, wrapEnabled: PropTypes.bool }; DiffComponent.defaultProps = { cursorStart: 1, editorProps: {}, enableBasicAutocompletion: false, enableLiveAutocompletion: false, focus: false, fontSize: 12, height: "500px", highlightActiveLine: true, maxLines: null, minLines: null, mode: "", name: "ace-editor", onLoad: null, onScroll: null, onPaste: null, onChange: null, orientation: "beside", readOnly: false, scrollMargin: [0, 0, 0, 0], setOptions: {}, showGutter: true, showPrintMargin: true, splits: 2, style: {}, tabSize: 4, theme: "github", value: ["", ""], width: "500px", wrapEnabled: true }; return DiffComponent; }(React.Component)); exports.default = DiffComponent; //# sourceMappingURL=diff.js.map