123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- // http://json-diff.com/
- let JsonDiff = (function () {
- function JsonInputView(el, initialText) {
- this.el = el;
- let codemirror = this.codemirror = CodeMirror.fromTextArea(this.el, {
- lineNumbers: true,
- mode: {
- name: "javascript",
- json: true
- },
- matchBrackets: true,
- theme: 'tomorrow-night'
- });
- if (initialText) {
- codemirror.setValue(initialText);
- }
- let self = this;
- codemirror.on('inputRead', function (cm, e) {
- if (e.origin === 'paste') {
- autoFormat();
- }
- triggerChange();
- });
- codemirror.on('keyup', triggerChange);
- codemirror.on('change', triggerChange);
- codemirror.on('clear', function () {
- console.log(arguments);
- });
- let oldValue = '';
- function triggerChange() {
- let text = codemirror.getValue();
- if (text !== oldValue) {
- self.trigger('change');
- }
- oldValue = text;
- }
- function autoFormat() {
- let totalLines = codemirror.lineCount();
- codemirror.autoFormatRange({
- line: 0,
- ch: 0
- }, {
- line: totalLines
- });
- codemirror.setSelection({
- line: 0,
- ch: 0
- });
- }
- }
- JsonInputView.prototype.getText = function () {
- return this.codemirror.getValue();
- };
- JsonInputView.prototype.setText = function (text) {
- return this.codemirror.setValue(text);
- };
- JsonInputView.prototype.highlightRemoval = function (diff) {
- this._highlight(diff, '#DD4444');
- };
- JsonInputView.prototype.highlightAddition = function (diff) {
- this._highlight(diff, '#4ba2ff');
- };
- JsonInputView.prototype.highlightChange = function (diff) {
- this._highlight(diff, '#E5E833');
- };
- JsonInputView.prototype._highlight = function (diff, color) {
- let pos = getStartAndEndPosOfDiff(this.getText(), diff);
- this.codemirror.markText(pos.start, pos.end, {
- css: 'background-color: ' + color
- });
- };
- JsonInputView.prototype.clearMarkers = function () {
- this.codemirror.getAllMarks().forEach(function (marker) {
- marker.clear();
- });
- };
- function getStartAndEndPosOfDiff(textValue, diff) {
- let result = parse(textValue);
- let pointers = result.pointers;
- let path = diff.path;
- let start = {
- line: pointers[path].key ? pointers[path].key.line : pointers[path].value.line,
- ch: pointers[path].key ? pointers[path].key.column : pointers[path].value.column
- };
- let end = {
- line: pointers[path].valueEnd.line,
- ch: pointers[path].valueEnd.column
- };
- return {
- start: start,
- end: end
- }
- }
- function onInputChange() {
- compareJson();
- }
- let leftInputView = null;
- let rightInputView = null;
- let errHandler = null;
- let diffHandler = null;
- function compareJson() {
- leftInputView.clearMarkers();
- rightInputView.clearMarkers();
- let leftText = leftInputView.getText(),
- rightText = rightInputView.getText();
- let leftJson, rightJson;
- try {
- if (leftText) {
- leftJson = JSON.parse(leftText);
- }
- errHandler && errHandler('left', true);
- } catch (e) {
- console.log('left ==>', e);
- }
- try {
- if (rightText) {
- rightJson = JSON.parse(rightText);
- }
- errHandler && errHandler('right', true);
- } catch (e) {
- console.log('right ==>', e);
- }
- if (!leftJson || !rightJson) {
- if (!leftJson && !rightJson) {
- errHandler && errHandler('left-right', false);
- } else if (!leftJson) {
- errHandler && errHandler('left', false);
- } else {
- errHandler && errHandler('right', false);
- }
- return;
- }
- let diffs = jsonpatch.compare(leftJson, rightJson);
- diffHandler && diffHandler(diffs);
- diffs.forEach(function (diff) {
- try {
- if (diff.op === 'remove') {
- leftInputView.highlightRemoval(diff);
- } else if (diff.op === 'add') {
- rightInputView.highlightAddition(diff);
- } else if (diff.op === 'replace') {
- rightInputView.highlightChange(diff);
- leftInputView.highlightChange(diff);
- }
- } catch (e) {
- console.warn('error while trying to highlight diff', e);
- }
- });
- }
- function init(left, right, errorHandler, dfHandler) {
- errHandler = errorHandler;
- diffHandler = dfHandler;
- BackboneEvents.mixin(JsonInputView.prototype);
- leftInputView = new JsonInputView(left, '');
- rightInputView = new JsonInputView(right, '');
- leftInputView.on('change', onInputChange);
- rightInputView.on('change', onInputChange);
- leftInputView.codemirror.on('scroll', function () {
- let scrollInfo = leftInputView.codemirror.getScrollInfo();
- rightInputView.codemirror.scrollTo(scrollInfo.left, scrollInfo.top);
- });
- rightInputView.codemirror.on('scroll', function () {
- let scrollInfo = rightInputView.codemirror.getScrollInfo();
- leftInputView.codemirror.scrollTo(scrollInfo.left, scrollInfo.top);
- });
- }
- return {
- init: init
- }
- })();
|