From 83f811fff5f6b2188c82f187f747122d2f7cd936 Mon Sep 17 00:00:00 2001 From: George Dewar Date: Fri, 21 Mar 2014 17:05:46 +1300 Subject: [PATCH] Refactor Parallel Diff feature and add scrollbars Also now removed lines relating to unused comments feature --- app/assets/stylesheets/sections/diff.scss | 25 +++- app/helpers/commits_helper.rb | 76 +++++++++++- app/models/diff_line.rb | 3 + .../projects/commits/_parallel_view.html.haml | 114 ++++++++---------- 4 files changed, 147 insertions(+), 71 deletions(-) create mode 100644 app/models/diff_line.rb diff --git a/app/assets/stylesheets/sections/diff.scss b/app/assets/stylesheets/sections/diff.scss index 813566c4def..eb272f20f40 100644 --- a/app/assets/stylesheets/sections/diff.scss +++ b/app/assets/stylesheets/sections/diff.scss @@ -62,6 +62,29 @@ font-size: 12px; } } + + .text-file-parallel div { + display: inline-block; + padding-bottom: 16px; + } + .diff-side { + overflow-x: scroll; + width: 508px; + height: 700px; + } + .diff-side.diff-side-left{ + overflow-y:hidden; + } + .diff-side table, td.diff-middle table { + height: 700px; + } + .diff-middle { + width: 114px; + vertical-align: top; + height: 700px; + overflow: hidden + } + .old_line, .new_line, .diff_line { margin: 0px; padding: 0px; @@ -125,8 +148,6 @@ } &.parallel { display: table-cell; - overflow: hidden; - width: 50%; } } } diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index 5e5f3f77a21..c6e4f574b67 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -105,8 +105,80 @@ module CommitsHelper branches.sort.map { |branch| link_to(branch, project_tree_path(project, branch)) }.join(", ").html_safe end - def get_old_file(project, commit, diff) - project.repository.blob_at(commit.parent_id, diff.old_path) if commit.parent_id + def parallel_diff_lines(project, commit, diff, file) + old_file = project.repository.blob_at(commit.parent_id, diff.old_path) if commit.parent_id + deleted_lines = {} + added_lines = {} + each_diff_line(diff, 0) do |line, type, line_code, line_new, line_old| + if type == "old" + deleted_lines[line_old] = { line_code: line_code, type: type, line: line } + elsif type == "new" + added_lines[line_new] = { line_code: line_code, type: type, line: line } + end + end + max_length = old_file ? old_file.sloc + added_lines.length : file.sloc + + offset1 = 0 + offset2 = 0 + old_lines = [] + new_lines = [] + + max_length.times do |line_index| + line_index1 = line_index - offset1 + line_index2 = line_index - offset2 + deleted_line = deleted_lines[line_index1 + 1] + added_line = added_lines[line_index2 + 1] + old_line = old_file.lines[line_index1] if old_file + new_line = file.lines[line_index2] + + if deleted_line && added_line + elsif deleted_line + new_line = nil + offset2 += 1 + elsif added_line + old_line = nil + offset1 += 1 + end + + old_lines[line_index] = DiffLine.new + new_lines[line_index] = DiffLine.new + + # old + if line_index == 0 && diff.new_file + old_lines[line_index].type = :file_created + old_lines[line_index].content = 'File was created' + elsif deleted_line + old_lines[line_index].type = :deleted + old_lines[line_index].content = old_line + old_lines[line_index].num = line_index1 + 1 + old_lines[line_index].code = deleted_line[:line_code] + elsif old_line + old_lines[line_index].type = :no_change + old_lines[line_index].content = old_line + old_lines[line_index].num = line_index1 + 1 + else + old_lines[line_index].type = :added + end + + # new + if line_index == 0 && diff.deleted_file + new_lines[line_index].type = :file_deleted + new_lines[line_index].content = "File was deleted" + elsif added_line + new_lines[line_index].type = :added + new_lines[line_index].num = line_index2 + 1 + new_lines[line_index].content = new_line + new_lines[line_index].code = added_line[:line_code] + elsif new_line + new_lines[line_index].type = :no_change + new_lines[line_index].num = line_index2 + 1 + new_lines[line_index].content = new_line + else + new_lines[line_index].type = :deleted + end + end + + return old_lines, new_lines end protected diff --git a/app/models/diff_line.rb b/app/models/diff_line.rb new file mode 100644 index 00000000000..ad37945874a --- /dev/null +++ b/app/models/diff_line.rb @@ -0,0 +1,3 @@ +class DiffLine + attr_accessor :type, :content, :num, :code +end diff --git a/app/views/projects/commits/_parallel_view.html.haml b/app/views/projects/commits/_parallel_view.html.haml index 3234e9da0ac..5b60ab80ba4 100644 --- a/app/views/projects/commits/_parallel_view.html.haml +++ b/app/views/projects/commits/_parallel_view.html.haml @@ -1,75 +1,55 @@ / Side-by-side diff view -- old_file = get_old_file(project, @commit, diff) -- deleted_lines = {} -- added_lines = {} -- each_diff_line(diff, index) do |line, type, line_code, line_new, line_old, raw_line| - - if type == "old" - - deleted_lines[line_old] = { line_code: line_code, type: type, line: line } - - elsif type == "new" - - added_lines[line_new] = { line_code: line_code, type: type, line: line } - -- max_length = old_file.sloc + added_lines.length if old_file -- max_length ||= file.sloc -- offset1 = 0 -- offset2 = 0 +- old_lines, new_lines = parallel_diff_lines(project, @commit, diff, file) +- num_lines = old_lines.length %div.text-file-parallel - %table{ style: "table-layout: fixed;" } - - max_length.times do |line_index| - - line_index1 = line_index - offset1 - - line_index2 = line_index - offset2 - - deleted_line = deleted_lines[line_index1 + 1] - - added_line = added_lines[line_index2 + 1] - - old_line = old_file.lines[line_index1] if old_file - - new_line = file.lines[line_index2] + %div.diff-side.diff-side-left + %table + - old_lines.each do |line| - - if deleted_line && added_line - - elsif deleted_line - - new_line = nil - - offset2 += 1 - - elsif added_line - - old_line = nil - - offset1 += 1 + %tr.line_holder.parallel + - if line.type == :file_created + %td.line_content.parallel= "File was created" + - elsif line.type == :deleted + %td.line_content{class: "parallel noteable_line old #{line.code}", "line_code" => line.code }= line.content + - else line.type == :no_change + %td.line_content.parallel= line.content - %tr.line_holder.parallel - - if line_index == 0 && diff.new_file - %td.line_content.parallel= "File was created" - %td.old_line= "" - - elsif deleted_line - %td.line_content{class: "parallel noteable_line old #{deleted_line[:line_code]}", "line_code" => deleted_line[:line_code] }= old_line - %td.old_line.old - = line_index1 + 1 - - if @comments_allowed - =# render "projects/notes/diff_note_link", line_code: deleted_line[:line_code] - - elsif old_line - %td.line_content.parallel= old_line - %td.old_line= line_index1 + 1 - - else - %td.line_content.parallel= "" - %td.old_line= "" + %div.diff-middle + %table + - num_lines.times do |index| + %tr + - if old_lines[index].type == :deleted + %td.old_line.old= old_lines[index].num + - else + %td.old_line= old_lines[index].num - %td.diff_line= "" + %td.diff_line="" - - if diff.deleted_file && line_index == 0 - %td.new_line= "" - %td.line_content.parallel= "File was deleted" - - elsif added_line - %td.new_line.new - = line_index2 + 1 - - if @comments_allowed - =# render "projects/notes/diff_note_link", line_code: added_line[:line_code] - %td.line_content{class: "parallel noteable_line new #{added_line[:line_code]}", "line_code" => added_line[:line_code] }= new_line - - elsif new_line - %td.new_line= line_index2 + 1 - %td.line_content.parallel= new_line - - else - %td.new_line= "" - %td.line_content.parallel= "" + - if new_lines[index].type == :added + %td.new_line.new= new_lines[index].num + - else + %td.new_line= new_lines[index].num - - if @reply_allowed - - comments1 = [] - - comments2 = [] - - comments1 = @line_notes.select { |n| n.line_code == deleted_line[:line_code] }.sort_by(&:created_at) if deleted_line - - comments2 = @line_notes.select { |n| n.line_code == added_line[:line_code] }.sort_by(&:created_at) if added_line - - unless comments1.empty? && comments2.empty? - = render "projects/notes/diff_notes_with_reply_parallel", notes1: comments1, notes2: comments2, line1: deleted_line, line2: added_line \ No newline at end of file + %div.diff-side.diff-side-right + %table + - new_lines.each do |line| + + %tr.line_holder.parallel + - if line.type == :file_deleted + %td.line_content.parallel= "File was deleted" + - elsif line.type == :added + %td.line_content{class: "parallel noteable_line new #{line.code}", "line_code" => line.code }= line.content + - else line.type == :no_change + %td.line_content.parallel= line.content + +:javascript + $('.diff-side-right').on('scroll', function(){ + $('.diff-side-left, .diff-middle').scrollTop($(this).scrollTop()); + $('.diff-side-left').scrollLeft($(this).scrollLeft()); + }); + + $('.diff-side-left').on('scroll', function(){ + $('.diff-side-right, .diff-middle').scrollTop($(this).scrollTop()); // might never be relevant + $('.diff-side-right').scrollLeft($(this).scrollLeft()); + });