Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-02-18 13:34:06 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-02-18 13:34:06 +0300
commit859a6fb938bb9ee2a317c46dfa4fcc1af49608f0 (patch)
treed7f2700abe6b4ffcb2dcfc80631b2d87d0609239 /lib/gitlab/diff/char_diff.rb
parent446d496a6d000c73a304be52587cd9bbc7493136 (diff)
Add latest changes from gitlab-org/gitlab@13-9-stable-eev13.9.0-rc42
Diffstat (limited to 'lib/gitlab/diff/char_diff.rb')
-rw-r--r--lib/gitlab/diff/char_diff.rb74
1 files changed, 74 insertions, 0 deletions
diff --git a/lib/gitlab/diff/char_diff.rb b/lib/gitlab/diff/char_diff.rb
new file mode 100644
index 00000000000..c8bb39e9f5d
--- /dev/null
+++ b/lib/gitlab/diff/char_diff.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Diff
+ class CharDiff
+ include Gitlab::Utils::StrongMemoize
+
+ def initialize(old_string, new_string)
+ @old_string = old_string.to_s
+ @new_string = new_string.to_s
+ @changes = []
+ end
+
+ def generate_diff
+ @changes = diff_match_patch.diff_main(@old_string, @new_string)
+ diff_match_patch.diff_cleanupSemantic(@changes)
+
+ @changes
+ end
+
+ def changed_ranges(offset: 0)
+ old_diffs = []
+ new_diffs = []
+ new_pointer = old_pointer = offset
+
+ generate_diff.each do |(action, content)|
+ content_size = content.size
+
+ if action == :equal
+ new_pointer += content_size
+ old_pointer += content_size
+ end
+
+ if action == :delete
+ old_diffs << (old_pointer..(old_pointer + content_size - 1))
+ old_pointer += content_size
+ end
+
+ if action == :insert
+ new_diffs << (new_pointer..(new_pointer + content_size - 1))
+ new_pointer += content_size
+ end
+ end
+
+ [old_diffs, new_diffs]
+ end
+
+ def to_html
+ @changes.map do |op, text|
+ %{<span class="#{html_class_names(op)}">#{ERB::Util.html_escape(text)}</span>}
+ end.join.html_safe
+ end
+
+ private
+
+ def diff_match_patch
+ strong_memoize(:diff_match_patch) { DiffMatchPatch.new }
+ end
+
+ def html_class_names(operation)
+ class_names = ['idiff']
+
+ case operation
+ when :insert
+ class_names << 'addition'
+ when :delete
+ class_names << 'deletion'
+ end
+
+ class_names.join(' ')
+ end
+ end
+ end
+end