Whoops, forgot to add files
This commit is contained in:
parent
13f10efcf1
commit
5de8971ddf
|
|
@ -0,0 +1,75 @@
|
|||
module Gitlab
|
||||
module Diff
|
||||
class InlineDiff
|
||||
attr_accessor :lines
|
||||
|
||||
def initialize(lines)
|
||||
@lines = lines
|
||||
end
|
||||
|
||||
def inline_diffs
|
||||
inline_diffs = []
|
||||
|
||||
local_edit_indexes.each do |index|
|
||||
old_index = index
|
||||
new_index = index + 1
|
||||
old_line = @lines[old_index]
|
||||
new_line = @lines[new_index]
|
||||
|
||||
suffixless_old_line = old_line[1..-1]
|
||||
suffixless_new_line = new_line[1..-1]
|
||||
|
||||
# Skip inline diff if empty line was replaced with content
|
||||
next if suffixless_old_line == ""
|
||||
|
||||
# Add one, because this is based on the suffixless version
|
||||
lcp = longest_common_prefix(suffixless_old_line, suffixless_new_line) + 1
|
||||
lcs = longest_common_suffix(suffixless_old_line, suffixless_new_line)
|
||||
|
||||
old_diff_range = lcp..(old_line.length - lcs - 1)
|
||||
new_diff_range = lcp..(new_line.length - lcs - 1)
|
||||
|
||||
inline_diffs[old_index] = [old_diff_range] if old_diff_range.begin <= old_diff_range.end
|
||||
inline_diffs[new_index] = [new_diff_range] if new_diff_range.begin <= new_diff_range.end
|
||||
end
|
||||
|
||||
inline_diffs
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def local_edit_indexes
|
||||
line_prefixes = @lines.map { |line| line.match(/\A([+-])/) ? $1 : ' ' }
|
||||
joined_line_prefixes = " #{line_prefixes.join} "
|
||||
|
||||
offset = 0
|
||||
local_edit_indexes = []
|
||||
while index = joined_line_prefixes.index(" -+ ", offset)
|
||||
local_edit_indexes << index
|
||||
offset = index + 1
|
||||
end
|
||||
|
||||
local_edit_indexes
|
||||
end
|
||||
|
||||
def longest_common_prefix(a, b)
|
||||
max_length = [a.length, b.length].max
|
||||
|
||||
length = 0
|
||||
(0..max_length - 1).each do |pos|
|
||||
old_char = a[pos]
|
||||
new_char = b[pos]
|
||||
|
||||
break if old_char != new_char
|
||||
length += 1
|
||||
end
|
||||
|
||||
length
|
||||
end
|
||||
|
||||
def longest_common_suffix(a, b)
|
||||
longest_common_prefix(a.reverse, b.reverse)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
module Gitlab
|
||||
module Diff
|
||||
class InlineDiffMarker
|
||||
attr_accessor :raw_line, :rich_line
|
||||
|
||||
def initialize(raw_line, rich_line = raw_line)
|
||||
@raw_line = raw_line
|
||||
@rich_line = rich_line
|
||||
end
|
||||
|
||||
def mark(line_inline_diffs)
|
||||
offset = 0
|
||||
line_inline_diffs.each do |inline_diff_range|
|
||||
inline_diff_positions = position_mapping[inline_diff_range]
|
||||
marker_ranges = collapse_ranges(inline_diff_positions)
|
||||
|
||||
marker_ranges.each do |range|
|
||||
offset = insert_around_range(rich_line, range, "<span class='idiff'>", "</span>", offset)
|
||||
end
|
||||
end
|
||||
|
||||
rich_line
|
||||
end
|
||||
|
||||
def position_mapping
|
||||
@position_mapping ||= begin
|
||||
mapping = []
|
||||
raw_pos = 0
|
||||
rich_pos = 0
|
||||
(0..raw_line.length).each do |raw_pos|
|
||||
raw_char = raw_line[raw_pos]
|
||||
rich_char = rich_line[rich_pos]
|
||||
|
||||
while rich_char == '<'
|
||||
until rich_char == '>'
|
||||
rich_pos += 1
|
||||
rich_char = rich_line[rich_pos]
|
||||
end
|
||||
|
||||
rich_pos += 1
|
||||
rich_char = rich_line[rich_pos]
|
||||
end
|
||||
|
||||
mapping[raw_pos] = rich_pos
|
||||
|
||||
rich_pos += 1
|
||||
end
|
||||
|
||||
mapping
|
||||
end
|
||||
end
|
||||
|
||||
def collapse_ranges(positions)
|
||||
return [] if positions.empty?
|
||||
ranges = []
|
||||
|
||||
start = prev = positions[0]
|
||||
range = start..prev
|
||||
positions[1..-1].each do |pos|
|
||||
if pos == prev + 1
|
||||
range = start..pos
|
||||
prev = pos
|
||||
else
|
||||
ranges << range
|
||||
start = prev = pos
|
||||
range = start..prev
|
||||
end
|
||||
end
|
||||
ranges << range
|
||||
|
||||
ranges
|
||||
end
|
||||
|
||||
def insert_around_range(text, range, before, after, offset = 0)
|
||||
text.insert(offset + range.begin, before)
|
||||
offset += before.length
|
||||
|
||||
text.insert(offset + range.end + 1, after)
|
||||
offset += after.length
|
||||
|
||||
offset
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue