summaryrefslogtreecommitdiff
path: root/lib/gitlab/diff/parallel_diff.rb
blob: 1c1fc148123ef436b0185b75a9f79ce443940a34 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
module Gitlab
  module Diff
    class ParallelDiff
      attr_accessor :diff_file

      def initialize(diff_file)
        @diff_file = diff_file
      end

      def parallelize
        lines = []
        skip_next = false

        highlighted_diff_lines = diff_file.highlighted_diff_lines
        highlighted_diff_lines.each do |line|
          full_line = line.text
          type = line.type
          line_code = diff_file.line_code(line)
          line_new = line.new_pos
          line_old = line.old_pos
          position = diff_file.position(line)

          next_line = diff_file.next_line(line.index)

          if next_line
            next_line = highlighted_diff_lines[next_line.index]
            full_next_line = next_line.text
            next_line_code = diff_file.line_code(next_line)
            next_type = next_line.type
            next_position = diff_file.position(next_line)
          end

          case type
          when 'match', nil
            # line in the right panel is the same as in the left one
            lines << {
              left: {
                type:       type,
                number:     line_old,
                text:       full_line,
                line_code:  line_code,
                position:   position
              },
              right: {
                type:       type,
                number:     line_new,
                text:       full_line,
                line_code:  line_code,
                position:   position
              }
            }
          when 'old'
            case next_type
            when 'new'
              # Left side has text removed, right side has text added
              lines << {
                left: {
                  type:       type,
                  number:     line_old,
                  text:       full_line,
                  line_code:  line_code,
                  position:   position
                },
                right: {
                  type:       next_type,
                  number:     line_new,
                  text:       full_next_line,
                  line_code:  next_line_code,
                  position:   next_position,
                }
              }
              skip_next = true
            when 'old', 'nonewline', nil
              # Left side has text removed, right side doesn't have any change
              # No next line code, no new line number, no new line text
              lines << {
                left: {
                  type:       type,
                  number:     line_old,
                  text:       full_line,
                  line_code:  line_code,
                  position:   position
                },
                right: {
                  type:       next_type,
                  number:     nil,
                  text:       "",
                  line_code:  nil,
                  position:   nil
                }
              }
            end
          when 'new'
            if skip_next
              # Change has been already included in previous line so no need to do it again
              skip_next = false
              next
            else
              # Change is only on the right side, left side has no change
              lines << {
                left: {
                  type:       nil,
                  number:     nil,
                  text:       "",
                  line_code:  line_code,
                  position:   position
                },
                right: {
                  type:       type,
                  number:     line_new,
                  text:       full_line,
                  line_code:  line_code,
                  position:   position
                }
              }
            end
          end
        end
        lines
      end
    end
  end
end