react-ace
Version:
A react component for Ace Editor
245 lines • 10.2 kB
JavaScript
"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