From 885fcd4e05ccaf38794685eb20915d4e09579cbe Mon Sep 17 00:00:00 2001 From: Kljh Date: Sat, 16 Aug 2014 17:31:15 +0100 Subject: [PATCH] =?UTF-8?q?Added=20keyboard=20shortcuts=20=C3=A0=20la=20Wi?= =?UTF-8?q?nMerge.=20Alt=20+=20Up=20or=20Down=20arrow=20:=20go=20to=20prev?= =?UTF-8?q?ious=20or=20next=20difference=20Alt=20+=20Left=20or=20Right=20a?= =?UTF-8?q?rrow=20:=20merge=20difference=20using=20right=20or=20left=20con?= =?UTF-8?q?tent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Shift, Ctr, Alt or Meta keys can be used indifferntly (to cope with browser's idiosyncratics). Event handler is now attached to text editor. This is clearly to review (does not capture all page events and too intrusive). New state "current_diff" has been added. Need to scroll the editor to center it on currently active state (scrollToChange function to add). --- lib/mergely.js | 101 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 10 deletions(-) diff --git a/lib/mergely.js b/lib/mergely.js index 1fe2c6d..1c064c6 100644 --- a/lib/mergely.js +++ b/lib/mergely.js @@ -386,11 +386,13 @@ 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'}, + current_diff: 0, // currently active difference, in 0 .. changes.length range. + fgcolor: {a:'#4ba3fa',c:'#a3a3a3',d:'#ff7f7f', // color for differences (soft color) + ca:'#4b73ff',cc:'#737373',cd:'#ff4f4f'}, // color for currently active difference (bright color) bgcolor: '#eee', vpcolor: 'rgba(0, 0, 200, 0.5)', lhs: function(setValue) { }, @@ -686,6 +688,74 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, { var setv = this.editor[this.id + '-rhs'].getDoc().setValue; this.settings.rhs(setv.bind(this.editor[this.id + '-rhs'].getDoc())); } + + // kljh: register WinMerge style key bindings + var self = this; + el.addEventListener("keydown", function(evt) { + if (evt.defaultPrevented) + ;//return; // Should do nothing if the key event was already consumed. + + if (!evt.shiftKey && !evt.altKey && !evt.ctrlKey && !evt.metaKey) + return; // if none of Shift, Alt, Ctrl or Meta key is used then do nothing + + var shift_key = 16, alt_key = 17, ctrlKey = 18, metaKey = 91; // 13, 27 ? + var up_arrow = 38, down_arrow = 40, left_arrow = 37, right_arrow = 39; + if (!evt.key) { + // use keyCode as key + evt.key = evt.which; + } + + switch (evt.key) { + case "ArrowDown": + case down_arrow: + self.settings.current_diff++; + self._changed(self.id + '-lhs', self.id + '-rhs'); + break; + case "ArrowUp": + case up_arrow: + self.settings.current_diff--; + self.settings.current_diff = Math.max(self.settings.current_diff, 0); + self._changed(self.id + '-lhs', self.id + '-rhs'); + break; + case "ArrowLeft": + case left_arrow: + // !! recalculating the changes !! + var editor_name1 = self.id + '-lhs'; + var editor_name2 = self.id + '-rhs'; + var lhs = self.editor[editor_name1].getValue(); + var rhs = self.editor[editor_name2].getValue(); + var d = new Mgly.diff(lhs, rhs, self.settings); + var changes = Mgly.DiffParser(d.normal_form()); + + var change = changes[self.settings.current_diff]; + self._merge_change(change, "rhs", "lhs"); + break; + case "ArrowRight": + case right_arrow: + // !! recalculating the changes !! + var editor_name1 = self.id + '-lhs'; + var editor_name2 = self.id + '-rhs'; + var lhs = self.editor[editor_name1].getValue(); + var rhs = self.editor[editor_name2].getValue(); + var d = new Mgly.diff(lhs, rhs, self.settings); + var changes = Mgly.DiffParser(d.normal_form()); + + var change = changes[self.settings.current_diff]; + self._merge_change(change, "lhs", "rhs"); + break; + case "Enter": + // Do something for "enter" or "return" key press. + break; + case "Escape": + // Do something for "esc" key press. + break; + default: + return; // Quit when this doesn't handle the key event. + } + + // Consume the event for suppressing "double action". + //event.preventDefault(); + }); }, _scrolling: function(editor_name) { @@ -1230,7 +1300,21 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, { }); var change = self.changes[cid]; - var line = {lhs: ed['lhs'].lineInfo(llt), rhs: ed['rhs'].lineInfo(rlt)}; + // kljh: not used + //var line = {lhs: ed['lhs'].lineInfo(llt), rhs: ed['rhs'].lineInfo(rlt)}; + + self._merge_change(change, side, oside); + return false; + }); + this.trace('change', 'markup buttons time', timer.stop()); + }, + _merge_change : function(change, side, oside) { + var editor_name1 = this.id + '-lhs'; + var editor_name2 = this.id + '-rhs'; + var led = this.editor[editor_name1]; + var red = this.editor[editor_name2]; + var ed = {lhs:led, rhs:red}; + var text = ed[side].getRange( CodeMirror.Pos(change[side + '-line-from'], 0), @@ -1271,9 +1355,6 @@ 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()); }, _draw_info: function(editor_name1, editor_name2) { var visible_page_height = jQuery(this.editor[editor_name1].getScrollerElement()).height(); @@ -1344,14 +1425,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.settings.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.settings.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)); @@ -1370,8 +1451,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.settings.current_diff==i?'c':'')+change['op']]; + ctx.lineWidth = (this.settings.current_diff==i) ? 1.5 : 1; var rectWidth = this.draw_lhs_width; var rectHeight = lhs_y_end - lhs_y_start - 1;