diff --git a/editor/editor.css b/editor/editor.css
index 0f08598..6b1b85b 100755
--- a/editor/editor.css
+++ b/editor/editor.css
@@ -27,7 +27,9 @@ body { margin: 0; }
.icon-swap { background-image: url(images/swap.png); }
.icon-arrow-right { background-image: url(images/arrow-right.png); }
.icon-arrow-right-v { background-image: url(images/arrow-right-v.png); }
+.icon-arrow-right-vv { background-image: url(images/arrow-right-vv.png); }
.icon-arrow-left-v { background-image: url(images/arrow-left-v.png); }
+.icon-arrow-left-vv { background-image: url(images/arrow-left-vv.png); }
.icon-arrow-up { background-image: url(images/arrow-up-v.png); }
.icon-arrow-down { background-image: url(images/arrow-down-v.png); }
.icon-x-mark { background-image: url(images/x-mark.png); }
diff --git a/editor/editor.js b/editor/editor.js
index 453abbf..41cf6c2 100755
--- a/editor/editor.js
+++ b/editor/editor.js
@@ -249,6 +249,9 @@ $(document).ready(function() {
handleFind(ed.find('#mergely-editor-lhs'));
}
else if (id == 'edit-left-merge-right') {
+ ed.mergely('mergeCurrentDiff', 'rhs');
+ }
+ else if (id == 'edit-left-merge-right-file') {
ed.mergely('merge', 'rhs');
}
else if ([
@@ -272,6 +275,9 @@ $(document).ready(function() {
handleFind(ed.find('#mergely-editor-rhs'));
}
else if (id == 'edit-right-merge-left') {
+ ed.mergely('mergeCurrentDiff', 'lhs');
+ }
+ else if (id == 'edit-right-merge-left-file') {
ed.mergely('merge', 'lhs');
}
else if (id == 'edit-right-clear') {
@@ -286,6 +292,12 @@ $(document).ready(function() {
else if (id == 'view-refresh') {
ed.mergely('update');
}
+ else if (id == 'view-change-next') {
+ ed.mergely('scrollToDiff', 'next');
+ }
+ else if (id == 'view-change-prev') {
+ ed.mergely('scrollToDiff', 'prev');
+ }
else if (id == 'view-clear') {
ed.mergely('unmarkup');
}
diff --git a/editor/editor.php b/editor/editor.php
index 9f78257..0786222 100755
--- a/editor/editor.php
+++ b/editor/editor.php
@@ -1,6 +1,6 @@
Redo
+
+
+
diff --git a/lib/mergely.js b/lib/mergely.js
index 9c153e1..38b5e74 100644
--- a/lib/mergely.js
+++ b/lib/mergely.js
@@ -386,11 +386,12 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
viewport: false,
ignorews: false,
fadein: 'fast',
- editor_width: '400px',
+ editor_width: '650px',
editor_height: '400px',
resize_timeout: 500,
change_timeout: 150,
- fgcolor: {a:'#4ba3fa',c:'#a3a3a3',d:'#ff7f7f'},
+ fgcolor: {a:'#4ba3fa',c:'#a3a3a3',d:'#ff7f7f', // color for differences (soft color)
+ ca:'#4b73ff',cc:'#434343',cd:'#ff4f4f'}, // color for currently active difference (bright color)
bgcolor: '#eee',
vpcolor: 'rgba(0, 0, 200, 0.5)',
lhs: function(setValue) { },
@@ -481,6 +482,26 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
unmarkup: function() {
this._clear();
},
+ scrollToDiff: function(direction) {
+ if (!this.changes.length) return;
+ if (direction == 'next') {
+ this._current_diff = Math.min(++this._current_diff, this.changes.length - 1);
+ }
+ else {
+ this._current_diff = Math.max(--this._current_diff, 0);
+ }
+ this._scroll_to_change(this.changes[this._current_diff]);
+ this._changed(this.id + '-lhs', this.id + '-rhs');
+ },
+ mergeCurrentDiff: function(side) {
+ if (!this.changes.length) return;
+ if (side == 'lhs' && !this.lhs_cmsettings.readOnly) {
+ this._merge_change(this.changes[this._current_diff], 'rhs', 'lhs');
+ }
+ else if (side == 'rhs' && !this.rhs_cmsettings.readOnly) {
+ this._merge_change(this.changes[this._current_diff], 'lhs', 'rhs');
+ }
+ },
scrollTo: function(side, num) {
var le = this.editor[this.id + '-lhs'];
var re = this.editor[this.id + '-rhs'];
@@ -605,7 +626,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
}
else {
// homebrew
- var style = 'opacity:0.4;width:10px;height:15px;background-color:#888;cursor:pointer;text-align:center;color:#eee;border:1px solid: #222;margin-right:5px;';
+ var style = 'opacity:0.4;width:10px;height:15px;background-color:#888;cursor:pointer;text-align:center;color:#eee;border:1px solid: #222;margin-right:5px;margin-top: -2px;';
merge_lhs_button = '
<
';
merge_rhs_button = '
>
';
}
@@ -688,7 +709,31 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
this.settings.rhs(setv.bind(this.editor[this.id + '-rhs'].getDoc()));
}
},
-
+
+ _scroll_to_change : function(change) {
+ if (!change) return;
+ var self = this;
+ var led = self.editor[self.id+'-lhs'];
+ var red = self.editor[self.id+'-rhs'];
+
+ var yref = led.getScrollerElement().offsetHeight * 1/2; // center between >0 and 1/2
+
+ // set cursors
+ led.setCursor(Math.max(change["lhs-line-from"],0), 0); // use led.getCursor().ch ?
+ red.setCursor(Math.max(change["rhs-line-from"],0), 0);
+
+ // using directly CodeMirror breaks canvas alignment
+ // var ly = led.charCoords({line: Math.max(change["lhs-line-from"],0), ch: 0}, "local").top;
+
+ // calculate scroll offset for current change. Warning: returns relative y position so we scroll to 0 first.
+ led.scrollTo(null, 0);
+ red.scrollTo(null, 0);
+ self._calculate_offsets(self.id+'-lhs', self.id+'-rhs', [change]);
+ led.scrollTo(null, Math.max(change["lhs-y-start"]-yref, 0));
+ red.scrollTo(null, Math.max(change["rhs-y-start"]-yref, 0));
+ // right pane should simply follows
+ },
+
_scrolling: function(editor_name) {
if (this._skipscroll[editor_name] === true) {
// scrolling one side causes the other to event - ignore it
@@ -845,6 +890,12 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
this.trace('change', 'diff time', timer.stop());
this.changes = Mgly.DiffParser(d.normal_form());
this.trace('change', 'parse time', timer.stop());
+ if (this._current_diff === undefined) {
+ // go to first difference on start-up
+ this._current_diff = 0;
+ this._scroll_to_change(this.changes[0]);
+ }
+ this.trace('change', 'scroll_to_change time', timer.stop());
this._calculate_offsets(editor_name1, editor_name2, this.changes);
this.trace('change', 'offsets time', timer.stop());
this._markup_changes(editor_name1, editor_name2, this.changes);
@@ -1230,8 +1281,17 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
}
});
var change = self.changes[cid];
+ self._merge_change(change, side, oside);
+ return false;
+ });
+ this.trace('change', 'markup buttons time', timer.stop());
+ },
+ _merge_change : function(change, side, oside) {
+ if (!change) return;
+ var led = this.editor[this.id+'-lhs'];
+ var red = this.editor[this.id+'-rhs'];
+ var ed = {lhs:led, rhs:red};
- var line = {lhs: ed['lhs'].lineInfo(llt), rhs: ed['rhs'].lineInfo(rlt)};
var text = ed[side].getRange(
CodeMirror.Pos(change[side + '-line-from'], 0),
@@ -1272,9 +1332,8 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
//reset
ed['lhs'].setValue(ed['lhs'].getValue());
ed['rhs'].setValue(ed['rhs'].getValue());
- return false;
- });
- this.trace('change', 'markup buttons time', timer.stop());
+
+ this._scroll_to_change(change)
},
_draw_info: function(editor_name1, editor_name2) {
var visible_page_height = jQuery(this.editor[editor_name1].getScrollerElement()).height();
@@ -1345,14 +1404,14 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
this.trace('draw', 'marker calculated', lhs_y_start, lhs_y_end, rhs_y_start, rhs_y_end);
ctx_lhs.beginPath();
- ctx_lhs.fillStyle = this.settings.fgcolor[change['op']];
+ ctx_lhs.fillStyle = this.settings.fgcolor[(this._current_diff==i?'c':'')+change['op']];
ctx_lhs.strokeStyle = '#000';
ctx_lhs.lineWidth = 0.5;
ctx_lhs.fillRect(1.5, lhs_y_start, 4.5, Math.max(lhs_y_end - lhs_y_start, 5));
ctx_lhs.strokeRect(1.5, lhs_y_start, 4.5, Math.max(lhs_y_end - lhs_y_start, 5));
ctx_rhs.beginPath();
- ctx_rhs.fillStyle = this.settings.fgcolor[change['op']];
+ ctx_rhs.fillStyle = this.settings.fgcolor[(this._current_diff==i?'c':'')+change['op']];
ctx_rhs.strokeStyle = '#000';
ctx_rhs.lineWidth = 0.5;
ctx_rhs.fillRect(1.5, rhs_y_start, 4.5, Math.max(rhs_y_end - rhs_y_start, 5));
@@ -1371,8 +1430,8 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
// draw left box
ctx.beginPath();
- ctx.strokeStyle = this.settings.fgcolor[change['op']];
- ctx.lineWidth = 1;
+ ctx.strokeStyle = this.settings.fgcolor[(this._current_diff==i?'c':'')+change['op']];
+ ctx.lineWidth = (this._current_diff==i) ? 1.5 : 1;
var rectWidth = this.draw_lhs_width;
var rectHeight = lhs_y_end - lhs_y_start - 1;