Commit 7af277f6 authored by Sean McGivern's avatar Sean McGivern Committed by Fatih Acet

Auto-highlight conflict when rich_text is called

parent d7721635
...@@ -21,7 +21,8 @@ module Gitlab ...@@ -21,7 +21,8 @@ module Gitlab
def lines def lines
@lines ||= Gitlab::Conflict::Parser.new.parse(merge_file_result[:data], @lines ||= Gitlab::Conflict::Parser.new.parse(merge_file_result[:data],
our_path: our_path, our_path: our_path,
their_path: their_path) their_path: their_path,
parent: self)
end end
def resolve!(resolution, index:, rugged:) def resolve!(resolution, index:, rugged:)
...@@ -57,27 +58,23 @@ module Gitlab ...@@ -57,27 +58,23 @@ module Gitlab
end.compact end.compact
end end
def highlighted_lines def highlight_lines!
return @highlighted_lines if @highlighted_lines
their_highlight = Gitlab::Highlight.highlight_lines(repository, their_ref, their_path) their_highlight = Gitlab::Highlight.highlight_lines(repository, their_ref, their_path)
our_highlight = Gitlab::Highlight.highlight_lines(repository, our_ref, our_path) our_highlight = Gitlab::Highlight.highlight_lines(repository, our_ref, our_path)
@highlighted_lines = lines.map do |line| lines.each do |line|
line = line.dup
if line.type == 'old' if line.type == 'old'
line.rich_text = their_highlight[line.old_line - 1] line.rich_text = their_highlight[line.old_line - 1]
else else
line.rich_text = our_highlight[line.new_line - 1] line.rich_text = our_highlight[line.new_line - 1]
end end
line
end end
end end
def sections def sections
return @sections if @sections return @sections if @sections
chunked_lines = highlighted_lines.chunk { |line| line.type.nil? } chunked_lines = lines.chunk { |line| line.type.nil? }
match_line = nil match_line = nil
@sections = chunked_lines.flat_map.with_index do |(no_conflict, lines), i| @sections = chunked_lines.flat_map.with_index do |(no_conflict, lines), i|
......
...@@ -7,7 +7,7 @@ module Gitlab ...@@ -7,7 +7,7 @@ module Gitlab
class MissingEndDelimiter < StandardError class MissingEndDelimiter < StandardError
end end
def parse(text, our_path:, their_path:) def parse(text, our_path:, their_path:, parent: nil)
return [] if text.blank? return [] if text.blank?
line_obj_index = 0 line_obj_index = 0
...@@ -36,9 +36,9 @@ module Gitlab ...@@ -36,9 +36,9 @@ module Gitlab
type = nil type = nil
elsif line[0] == '\\' elsif line[0] == '\\'
type = 'nonewline' type = 'nonewline'
lines << Gitlab::Diff::Line.new(full_line, type, line_obj_index, line_old, line_new) lines << Gitlab::Diff::Line.new(full_line, type, line_obj_index, line_old, line_new, parent: parent)
else else
lines << Gitlab::Diff::Line.new(full_line, type, line_obj_index, line_old, line_new) lines << Gitlab::Diff::Line.new(full_line, type, line_obj_index, line_old, line_new, parent: parent)
line_old += 1 if type != 'new' line_old += 1 if type != 'new'
line_new += 1 if type != 'old' line_new += 1 if type != 'old'
......
...@@ -2,12 +2,13 @@ module Gitlab ...@@ -2,12 +2,13 @@ module Gitlab
module Diff module Diff
class Line class Line
attr_reader :type, :index, :old_pos, :new_pos attr_reader :type, :index, :old_pos, :new_pos
attr_writer :rich_text
attr_accessor :text attr_accessor :text
attr_accessor :rich_text
def initialize(text, type, index, old_pos, new_pos) def initialize(text, type, index, old_pos, new_pos, parent: nil)
@text, @type, @index = text, type, index @text, @type, @index = text, type, index
@old_pos, @new_pos = old_pos, new_pos @old_pos, @new_pos = old_pos, new_pos
@parent = parent
end end
def self.init_from_hash(hash) def self.init_from_hash(hash)
...@@ -44,6 +45,12 @@ module Gitlab ...@@ -44,6 +45,12 @@ module Gitlab
type == 'old' type == 'old'
end end
def rich_text
@parent.highlight_lines! if @parent && !@rich_text
@rich_text
end
def meta? def meta?
type == 'match' || type == 'nonewline' type == 'match' || type == 'nonewline'
end end
......
...@@ -63,17 +63,23 @@ describe Gitlab::Conflict::File, lib: true do ...@@ -63,17 +63,23 @@ describe Gitlab::Conflict::File, lib: true do
end end
end end
describe '#highlighted_lines' do describe '#highlight_lines!' do
def html_to_text(html) def html_to_text(html)
CGI.unescapeHTML(ActionView::Base.full_sanitizer.sanitize(html)).delete("\n") CGI.unescapeHTML(ActionView::Base.full_sanitizer.sanitize(html)).delete("\n")
end end
it 'returns lines with rich_text' do it 'modifies the existing lines' do
expect(conflict_file.highlighted_lines).to all(have_attributes(rich_text: a_kind_of(String))) expect { conflict_file.highlight_lines! }.to change { conflict_file.lines.map(&:instance_variables) }
end end
it 'returns lines with rich_text matching the text content of the line' do it 'is called implicitly when rich_text is accessed on a line' do
conflict_file.highlighted_lines.each do |line| expect(conflict_file).to receive(:highlight_lines!).once.and_call_original
conflict_file.lines.each(&:rich_text)
end
it 'sets the rich_text of the lines matching the text content' do
conflict_file.lines.each do |line|
expect(line.text).to eq(html_to_text(line.rich_text)) expect(line.text).to eq(html_to_text(line.rich_text))
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment