mirror of
https://github.com/abapGit/abapGit.git
synced 2025-05-01 12:20:51 +08:00
Code selection by column on DIFF screen (#3091)
* Code selection by column on DIFF screen Fix of #3089 Two ways to select a text: 1. Position the mouse at the start of the text, press mouse left button, keep pressed, drag to the end of the text, release the button 2. Position the mouse at the start of the text, press mouse left button, release the button, position the mouse to the end of the text, press shift key + mouse left button. Two ways to copy the selected text: 1. Press Ctrl + C or Ctrl + Ins 2. Mouse right button on the text to display the context menu and choose Copy SPLIT VIEW (code at the left is the LOCAL code and code at the right is the REMOTE code): - Text can be selected only at the left side, or only at the right side. - The dummy empty lines which show the place of lines which exist only at the other side are not copied. UNIFIED VIEW (LOCAL and REMOTE are mixed in the same column, "green plus" lines correspond to lines only in the LOCAL code, "red minus" lines correspond to lines only in the REMOTE code. - Only the lines from the REMOTE code are copied PATCH VIEW (split view + one extra column on the left) - Same features as the SPLIT VIEW * corrections lint javascript * merge latest abapgit changes * corrections lint javascript * JS refactor functions to prototyped fns (classes) * JS lint corrections + minor last minute changes * conform current common.js standards * LINT conform to common.js standards * unused lines removed
This commit is contained in:
parent
02204d07b4
commit
175f2fabec
|
@ -432,6 +432,58 @@ table.diff_tab td.code {
|
|||
table.diff_tab tbody tr:first-child td { padding-top: 0.5em; }
|
||||
table.diff_tab tbody tr:last-child td { padding-bottom: 0.5em; }
|
||||
|
||||
table.diff_tab td.mark, th.mark {
|
||||
width: 0.1%;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.diff_select_left td.diff_right,
|
||||
.diff_select_left td.diff_right *,
|
||||
.diff_select_left th.diff_right,
|
||||
.diff_select_left th.diff_right *,
|
||||
.diff_select_right td.diff_left,
|
||||
.diff_select_right td.diff_left *,
|
||||
.diff_select_right th.diff_left,
|
||||
.diff_select_right th.diff_left * {
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.diff_select_left td.diff_left,
|
||||
.diff_select_left td.diff_left *,
|
||||
.diff_select_left th.diff_left,
|
||||
.diff_select_left th.diff_left *,
|
||||
.diff_select_right td.diff_right,
|
||||
.diff_select_right td.diff_right *,
|
||||
.diff_select_right th.diff_right,
|
||||
.diff_select_right th.diff_right * {
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
td.diff_others::selection,
|
||||
td.diff_others *::selection,
|
||||
th.diff_others::selection,
|
||||
th.diff_others *::selection {
|
||||
background-color: transparent;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.diff_select_left td.diff_right::selection,
|
||||
.diff_select_left td.diff_right *::selection,
|
||||
.diff_select_left th.diff_right::selection,
|
||||
.diff_select_left th.diff_right *::selection,
|
||||
.diff_select_right td.diff_left::selection,
|
||||
.diff_select_right td.diff_left *::selection,
|
||||
.diff_select_right th.diff_left::selection,
|
||||
.diff_select_right th.diff_left *::selection {
|
||||
background-color: transparent;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
/* DEBUG INFO STYLES */
|
||||
div.debug_container {
|
||||
padding: 0.5em;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<RELID>MI</RELID>
|
||||
<OBJID>ZABAPGIT_CSS_COMMON</OBJID>
|
||||
<NAME>filename</NAME>
|
||||
<VALUE>~wwwtmp.css</VALUE>
|
||||
<VALUE>common.css</VALUE>
|
||||
</WWWPARAMS>
|
||||
<WWWPARAMS>
|
||||
<RELID>MI</RELID>
|
||||
|
|
|
@ -770,6 +770,133 @@ function addMarginBottom(){
|
|||
document.getElementsByTagName("body")[0].style.marginBottom = screen.height + "px";
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************
|
||||
* Diff page logic of column selection
|
||||
**********************************************************/
|
||||
|
||||
function DiffColumnSelection() {
|
||||
this.selectedColumnIdx = -1;
|
||||
this.lineNumColumnIdx = -1;
|
||||
//https://stackoverflow.com/questions/2749244/javascript-setinterval-and-this-solution
|
||||
document.addEventListener("mousedown", this.mousedownEventListener.bind(this));
|
||||
document.addEventListener("copy", this.copyEventListener.bind(this));
|
||||
}
|
||||
|
||||
DiffColumnSelection.prototype.mousedownEventListener = function(e) {
|
||||
// Select text in a column of an HTML table and copy to clipboard (in DIFF view)
|
||||
// (https://stackoverflow.com/questions/6619805/select-text-in-a-column-of-an-html-table)
|
||||
// Process mousedown event for all TD elements -> apply CSS class at TABLE level.
|
||||
// (https://stackoverflow.com/questions/40956717/how-to-addeventlistener-to-multiple-elements-in-a-single-line)
|
||||
var unifiedLineNumColumnIdx = 0;
|
||||
var unifiedCodeColumnIdx = 3;
|
||||
var splitLineNumLeftColumnIdx = 0;
|
||||
var splitCodeLeftColumnIdx = 2;
|
||||
var splitLineNumRightColumnIdx = 3;
|
||||
var splitCodeRightColumnIdx = 5;
|
||||
|
||||
if (e.button !== 0) return; // function is only valid for left button, not right button
|
||||
|
||||
var td = e.target;
|
||||
while (td != undefined && td.tagName != "TD" && td.tagName != "TBODY") td = td.parentElement;
|
||||
if (td == undefined) return;
|
||||
var table = td.parentElement.parentElement;
|
||||
|
||||
var patchColumnCount = 0;
|
||||
if (td.parentElement.cells[0].classList.contains("patch")) {
|
||||
patchColumnCount = 1;
|
||||
}
|
||||
|
||||
if (td.classList.contains("diff_left")) {
|
||||
table.classList.remove("diff_select_right");
|
||||
table.classList.add("diff_select_left");
|
||||
if ( window.getSelection() && this.selectedColumnIdx != splitCodeLeftColumnIdx + patchColumnCount ) {
|
||||
// De-select to avoid effect of dragging selection in case the right column was first selected
|
||||
if (document.body.createTextRange) { // All IE but Edge
|
||||
// document.getSelection().removeAllRanges() may trigger error
|
||||
// so use this code which is equivalent but does not fail
|
||||
// (https://stackoverflow.com/questions/22914075/javascript-error-800a025e-using-range-selector)
|
||||
range = document.body.createTextRange();
|
||||
range.collapse();
|
||||
range.select();
|
||||
} else {
|
||||
document.getSelection().removeAllRanges();
|
||||
}}
|
||||
this.selectedColumnIdx = splitCodeLeftColumnIdx + patchColumnCount;
|
||||
this.lineNumColumnIdx = splitLineNumLeftColumnIdx + patchColumnCount;
|
||||
|
||||
} else if (td.classList.contains("diff_right")) {
|
||||
table.classList.remove("diff_select_left");
|
||||
table.classList.add("diff_select_right");
|
||||
if ( window.getSelection() && this.selectedColumnIdx != splitCodeRightColumnIdx + patchColumnCount ) {
|
||||
if (document.body.createTextRange) { // All IE but Edge
|
||||
// document.getSelection().removeAllRanges() may trigger error
|
||||
// so use this code which is equivalent but does not fail
|
||||
// (https://stackoverflow.com/questions/22914075/javascript-error-800a025e-using-range-selector)
|
||||
var range = document.body.createTextRange();
|
||||
range.collapse();
|
||||
range.select();
|
||||
} else {
|
||||
document.getSelection().removeAllRanges();
|
||||
}}
|
||||
this.selectedColumnIdx = splitCodeRightColumnIdx + patchColumnCount;
|
||||
this.lineNumColumnIdx = splitLineNumRightColumnIdx + patchColumnCount;
|
||||
|
||||
} else if (td.classList.contains("diff_unified")) {
|
||||
this.selectedColumnIdx = unifiedCodeColumnIdx;
|
||||
this.lineNumColumnIdx = unifiedLineNumColumnIdx;
|
||||
|
||||
} else {
|
||||
this.selectedColumnIdx = -1;
|
||||
this.lineNumColumnIdx = -1;
|
||||
}
|
||||
};
|
||||
|
||||
DiffColumnSelection.prototype.copyEventListener = function(e) {
|
||||
// Select text in a column of an HTML table and copy to clipboard (in DIFF view)
|
||||
// (https://stackoverflow.com/questions/6619805/select-text-in-a-column-of-an-html-table)
|
||||
var td = e.target;
|
||||
while (td != undefined && td.tagName != "TD" && td.tagName != "TBODY") td = td.parentElement;
|
||||
if(td != undefined){
|
||||
// Use window.clipboardData instead of e.clipboardData
|
||||
// (https://stackoverflow.com/questions/23470958/ie-10-copy-paste-issue)
|
||||
var clipboardData = ( e.clipboardData == undefined ? window.clipboardData : e.clipboardData );
|
||||
var text = this.getSelectedText();
|
||||
clipboardData.setData("text", text);
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
DiffColumnSelection.prototype.getSelectedText = function() {
|
||||
// Select text in a column of an HTML table and copy to clipboard (in DIFF view)
|
||||
// (https://stackoverflow.com/questions/6619805/select-text-in-a-column-of-an-html-table)
|
||||
var sel = window.getSelection(),
|
||||
range = sel.getRangeAt(0),
|
||||
doc = range.cloneContents(),
|
||||
nodes = doc.querySelectorAll("tr"),
|
||||
text = "";
|
||||
if (nodes.length === 0) {
|
||||
text = doc.textContent;
|
||||
} else {
|
||||
var newline = "",
|
||||
realThis = this;
|
||||
[].forEach.call(nodes, function(tr, i) {
|
||||
var cellIdx = ( i==0 ? 0 : realThis.selectedColumnIdx );
|
||||
if (tr.cells.length > cellIdx) {
|
||||
var tdSelected = tr.cells[cellIdx];
|
||||
var tdLineNum = tr.cells[realThis.lineNumColumnIdx];
|
||||
// copy is interesting for remote code, don't copy lines which exist only locally
|
||||
if (i==0 || tdLineNum.getAttribute("line-num")!="") {
|
||||
text += newline + tdSelected.textContent;
|
||||
// special processing for TD tag which sometimes contains newline
|
||||
// (expl: /src/ui/zabapgit_js_common.w3mi.data.js) so don't add newline again in that case.
|
||||
var lastChar = tdSelected.textContent[ tdSelected.textContent.length - 1 ];
|
||||
if ( lastChar == "\n" ) newline = "";
|
||||
else newline = "\n";
|
||||
}}});}
|
||||
return text;
|
||||
};
|
||||
|
||||
/**********************************************************
|
||||
* Other functions
|
||||
**********************************************************/
|
||||
|
|
|
@ -669,9 +669,10 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_DIFF IMPLEMENTATION.
|
|||
ENDIF.
|
||||
IF mv_unified = abap_true.
|
||||
ro_html->add( '<th class="num"></th>' ).
|
||||
ro_html->add( '<th class="mark"></th>' ).
|
||||
ro_html->add( |<th>@@ { is_diff_line-new_num } @@ { lv_beacon }</th>| ).
|
||||
ELSE.
|
||||
ro_html->add( |<th colspan="3">@@ { is_diff_line-new_num } @@ { lv_beacon }</th>| ).
|
||||
ro_html->add( |<th colspan="6">@@ { is_diff_line-new_num } @@ { lv_beacon }</th>| ).
|
||||
ENDIF.
|
||||
|
||||
ro_html->add( '</tr>' ).
|
||||
|
@ -850,8 +851,9 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_DIFF IMPLEMENTATION.
|
|||
lv_mark = `+`.
|
||||
ENDIF.
|
||||
ENDIF.
|
||||
lv_new = |<td class="num" line-num="{ is_diff_line-new_num }"></td>|
|
||||
&& |<td class="code{ lv_bg }">{ lv_mark }{ is_diff_line-new }</td>|.
|
||||
lv_new = |<td class="num diff_others" line-num="{ is_diff_line-new_num }"></td>|
|
||||
&& |<td class="mark diff_others">{ lv_mark }</td>|
|
||||
&& |<td class="code{ lv_bg } diff_left">{ is_diff_line-new }</td>|.
|
||||
|
||||
IF lv_mark <> ` `.
|
||||
lv_patch_line_possible = abap_true.
|
||||
|
@ -869,8 +871,9 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_DIFF IMPLEMENTATION.
|
|||
lv_mark = `-`.
|
||||
ENDIF.
|
||||
ENDIF.
|
||||
lv_old = |<td class="num" line-num="{ is_diff_line-old_num }"></td>|
|
||||
&& |<td class="code{ lv_bg }">{ lv_mark }{ is_diff_line-old }</td>|.
|
||||
lv_old = |<td class="num diff_others" line-num="{ is_diff_line-old_num }"></td>|
|
||||
&& |<td class="mark diff_others">{ lv_mark }</td>|
|
||||
&& |<td class="code{ lv_bg } diff_right">{ is_diff_line-old }</td>|.
|
||||
|
||||
IF lv_mark <> ` `.
|
||||
lv_patch_line_possible = abap_true.
|
||||
|
@ -912,16 +915,18 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_DIFF IMPLEMENTATION.
|
|||
IF is_diff_line-result <> zif_abapgit_definitions=>c_diff-update.
|
||||
LOOP AT mt_delayed_lines ASSIGNING <ls_diff_line>.
|
||||
ro_html->add( '<tr>' ). "#EC NOTEXT
|
||||
ro_html->add( |<td class="num" line-num="{ <ls_diff_line>-old_num }"></td>|
|
||||
&& |<td class="num" line-num=""></td>|
|
||||
&& |<td class="code diff_del">-{ <ls_diff_line>-old }</td>| ).
|
||||
ro_html->add( |<td class="num diff_others" line-num="{ <ls_diff_line>-old_num }"></td>|
|
||||
&& |<td class="num diff_others" line-num=""></td>|
|
||||
&& |<td class="mark diff_others">-</td>|
|
||||
&& |<td class="code diff_del diff_unified">{ <ls_diff_line>-old }</td>| ).
|
||||
ro_html->add( '</tr>' ). "#EC NOTEXT
|
||||
ENDLOOP.
|
||||
LOOP AT mt_delayed_lines ASSIGNING <ls_diff_line>.
|
||||
ro_html->add( '<tr>' ). "#EC NOTEXT
|
||||
ro_html->add( |<td class="num" line-num=""></td>|
|
||||
&& |<td class="num" line-num="{ <ls_diff_line>-new_num }"></td>|
|
||||
&& |<td class="code diff_ins">+{ <ls_diff_line>-new }</td>| ).
|
||||
ro_html->add( |<td class="num diff_others" line-num=""></td>|
|
||||
&& |<td class="num diff_others" line-num="{ <ls_diff_line>-new_num }"></td>|
|
||||
&& |<td class="mark diff_others">+</td>|
|
||||
&& |<td class="code diff_ins diff_others">{ <ls_diff_line>-new }</td>| ).
|
||||
ro_html->add( '</tr>' ). "#EC NOTEXT
|
||||
ENDLOOP.
|
||||
CLEAR mt_delayed_lines.
|
||||
|
@ -932,17 +937,20 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_DIFF IMPLEMENTATION.
|
|||
WHEN zif_abapgit_definitions=>c_diff-update.
|
||||
APPEND is_diff_line TO mt_delayed_lines. " Delay output of subsequent updates
|
||||
WHEN zif_abapgit_definitions=>c_diff-insert.
|
||||
ro_html->add( |<td class="num" line-num=""></td>|
|
||||
&& |<td class="num" line-num="{ is_diff_line-new_num }"></td>|
|
||||
&& |<td class="code diff_ins">+{ is_diff_line-new }</td>| ).
|
||||
ro_html->add( |<td class="num diff_others" line-num=""></td>|
|
||||
&& |<td class="num diff_others" line-num="{ is_diff_line-new_num }"></td>|
|
||||
&& |<td class="mark diff_others">+</td>|
|
||||
&& |<td class="code diff_ins diff_others">{ is_diff_line-new }</td>| ).
|
||||
WHEN zif_abapgit_definitions=>c_diff-delete.
|
||||
ro_html->add( |<td class="num" line-num="{ is_diff_line-old_num }"></td>|
|
||||
&& |<td class="num" line-num=""></td>|
|
||||
&& |<td class="code diff_del">-{ is_diff_line-old }</td>| ).
|
||||
ro_html->add( |<td class="num diff_others" line-num="{ is_diff_line-old_num }"></td>|
|
||||
&& |<td class="num diff_others" line-num=""></td>|
|
||||
&& |<td class="mark diff_others">-</td>|
|
||||
&& |<td class="code diff_del diff_unified">{ is_diff_line-old }</td>| ).
|
||||
WHEN OTHERS. "none
|
||||
ro_html->add( |<td class="num" line-num="{ is_diff_line-old_num }"></td>|
|
||||
&& |<td class="num" line-num="{ is_diff_line-new_num }"></td>|
|
||||
&& |<td class="code"> { is_diff_line-old }</td>| ).
|
||||
ro_html->add( |<td class="num diff_others" line-num="{ is_diff_line-old_num }"></td>|
|
||||
&& |<td class="num diff_others" line-num="{ is_diff_line-new_num }"></td>|
|
||||
&& |<td class="mark diff_others"> </td>|
|
||||
&& |<td class="code diff_unified">{ is_diff_line-old }</td>| ).
|
||||
ENDCASE.
|
||||
ro_html->add( '</tr>' ). "#EC NOTEXT
|
||||
|
||||
|
@ -1000,6 +1008,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_DIFF IMPLEMENTATION.
|
|||
IF mv_unified = abap_true.
|
||||
ro_html->add( '<th class="num">old</th>' ). "#EC NOTEXT
|
||||
ro_html->add( '<th class="num">new</th>' ). "#EC NOTEXT
|
||||
ro_html->add( '<th class="mark"></th>' ). "#EC NOTEXT
|
||||
ro_html->add( '<th>code</th>' ). "#EC NOTEXT
|
||||
ELSE.
|
||||
|
||||
|
@ -1011,8 +1020,10 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_DIFF IMPLEMENTATION.
|
|||
ENDIF.
|
||||
|
||||
ro_html->add( '<th class="num"></th>' ). "#EC NOTEXT
|
||||
ro_html->add( '<th class="mark"></th>' ). "#EC NOTEXT
|
||||
ro_html->add( '<th>LOCAL</th>' ). "#EC NOTEXT
|
||||
ro_html->add( '<th class="num"></th>' ). "#EC NOTEXT
|
||||
ro_html->add( '<th class="mark"></th>' ). "#EC NOTEXT
|
||||
ro_html->add( '<th>REMOTE</th>' ). "#EC NOTEXT
|
||||
|
||||
ENDIF.
|
||||
|
@ -1048,6 +1059,9 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_DIFF IMPLEMENTATION.
|
|||
ro_html->add( ' hotkeyDescription: "Jump to file ..."' ).
|
||||
ro_html->add( '});' ).
|
||||
|
||||
" Feature for selecting ABAP code by column and copy to clipboard
|
||||
ro_html->add( 'var columnSelection = new DiffColumnSelection();' ).
|
||||
|
||||
ENDMETHOD.
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user