2019-01-23 03:50:19 -05:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require 'gt_one_coercion'
|
|
|
|
|
|
|
|
module Blobs
|
|
|
|
class UnfoldPresenter < BlobPresenter
|
|
|
|
include Virtus.model
|
|
|
|
include Gitlab::Utils::StrongMemoize
|
|
|
|
|
|
|
|
attribute :full, Boolean, default: false
|
|
|
|
attribute :since, GtOneCoercion
|
2019-08-09 22:36:32 -04:00
|
|
|
attribute :to, Integer
|
2019-01-23 03:50:19 -05:00
|
|
|
attribute :bottom, Boolean
|
|
|
|
attribute :unfold, Boolean, default: true
|
|
|
|
attribute :offset, Integer
|
|
|
|
attribute :indent, Integer, default: 0
|
|
|
|
|
|
|
|
def initialize(blob, params)
|
2019-07-22 01:25:24 -04:00
|
|
|
# Load all blob data first as we need to ensure they're all loaded first
|
|
|
|
# so we can accurately show the rest of the diff when unfolding.
|
|
|
|
load_all_blob_data
|
|
|
|
|
2019-01-23 03:50:19 -05:00
|
|
|
@subject = blob
|
2019-08-08 20:13:09 -04:00
|
|
|
@all_lines = blob.data.lines
|
2019-01-23 03:50:19 -05:00
|
|
|
super(params)
|
|
|
|
|
2019-08-09 22:36:32 -04:00
|
|
|
self.attributes = prepare_attributes
|
2019-01-23 03:50:19 -05:00
|
|
|
end
|
|
|
|
|
2019-07-22 01:25:24 -04:00
|
|
|
# Returns an array of Gitlab::Diff::Line with match line added
|
2019-03-06 23:29:02 -05:00
|
|
|
def diff_lines
|
2019-08-08 20:13:09 -04:00
|
|
|
diff_lines = lines.map.with_index do |line, index|
|
|
|
|
full_line = limited_blob_lines[index].delete("\n")
|
2019-07-22 01:25:24 -04:00
|
|
|
|
2019-08-08 20:13:09 -04:00
|
|
|
Gitlab::Diff::Line.new(full_line, nil, nil, nil, nil, rich_text: line)
|
2019-03-06 23:29:02 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
add_match_line(diff_lines)
|
|
|
|
|
|
|
|
diff_lines
|
|
|
|
end
|
|
|
|
|
2019-01-23 03:50:19 -05:00
|
|
|
def lines
|
2019-08-09 22:36:32 -04:00
|
|
|
strong_memoize(:lines) do
|
|
|
|
limit(highlight.lines).map(&:html_safe)
|
|
|
|
end
|
2019-01-23 03:50:19 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def match_line_text
|
|
|
|
return '' if bottom?
|
|
|
|
|
|
|
|
lines_length = lines.length - 1
|
|
|
|
line = [since, lines_length].join(',')
|
|
|
|
"@@ -#{line}+#{line} @@"
|
|
|
|
end
|
2019-03-06 23:29:02 -05:00
|
|
|
|
|
|
|
private
|
|
|
|
|
2019-08-09 22:36:32 -04:00
|
|
|
def prepare_attributes
|
|
|
|
return attributes unless full? || to == -1
|
|
|
|
|
|
|
|
full_opts = {
|
|
|
|
since: 1,
|
|
|
|
to: all_lines_size,
|
|
|
|
bottom: false,
|
|
|
|
unfold: false,
|
|
|
|
offset: 0,
|
|
|
|
indent: 0
|
|
|
|
}
|
|
|
|
|
|
|
|
return full_opts if full?
|
|
|
|
|
|
|
|
full_opts.merge(attributes.slice(:since))
|
|
|
|
end
|
|
|
|
|
|
|
|
def all_lines_size
|
|
|
|
strong_memoize(:all_lines_size) do
|
|
|
|
@all_lines.size
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-03-06 23:29:02 -05:00
|
|
|
def add_match_line(diff_lines)
|
|
|
|
return unless unfold?
|
2019-08-09 22:36:32 -04:00
|
|
|
return if bottom? && to >= all_lines_size
|
2019-03-06 23:29:02 -05:00
|
|
|
|
2019-08-09 22:36:32 -04:00
|
|
|
if bottom? && to < all_lines_size
|
2019-03-06 23:29:02 -05:00
|
|
|
old_pos = to - offset
|
|
|
|
new_pos = to
|
|
|
|
elsif since != 1
|
|
|
|
old_pos = new_pos = since
|
|
|
|
end
|
|
|
|
|
|
|
|
# Match line is not needed when it reaches the top limit or bottom limit of the file.
|
|
|
|
return unless new_pos
|
|
|
|
|
|
|
|
match_line = Gitlab::Diff::Line.new(match_line_text, 'match', nil, old_pos, new_pos)
|
|
|
|
|
|
|
|
bottom? ? diff_lines.push(match_line) : diff_lines.unshift(match_line)
|
|
|
|
end
|
2019-08-08 20:13:09 -04:00
|
|
|
|
|
|
|
def limited_blob_lines
|
2019-08-09 22:36:32 -04:00
|
|
|
strong_memoize(:limited_blob_lines) do
|
|
|
|
limit(@all_lines)
|
|
|
|
end
|
2019-08-08 20:13:09 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def limit(lines)
|
|
|
|
return lines if full?
|
|
|
|
|
|
|
|
lines[since - 1..to - 1]
|
|
|
|
end
|
2019-01-23 03:50:19 -05:00
|
|
|
end
|
|
|
|
end
|