From 4ab90e5d6e7d77f5e8b4209e7d57df72069ae9e5 Mon Sep 17 00:00:00 2001 From: BrokenEagle Date: Tue, 7 Jan 2020 00:18:50 +0000 Subject: [PATCH] Move diff logic out of helper --- app/helpers/wiki_page_versions_helper.rb | 60 +++------------------- app/logical/diff_builder.rb | 57 ++++++++++++++++++++ app/views/wiki_page_versions/diff.html.erb | 5 +- 3 files changed, 68 insertions(+), 54 deletions(-) create mode 100644 app/logical/diff_builder.rb diff --git a/app/helpers/wiki_page_versions_helper.rb b/app/helpers/wiki_page_versions_helper.rb index 0f0d7e3f2..f68ab5c63 100644 --- a/app/helpers/wiki_page_versions_helper.rb +++ b/app/helpers/wiki_page_versions_helper.rb @@ -12,59 +12,13 @@ module WikiPageVersionsHelper status.join(" ") end - def wiki_page_diff(thispage, otherpage) + def wiki_other_names_diff(thispage, otherpage) + pattern = Regexp.new('\S+|\s+') + DiffBuilder.new("#{thispage.other_names}\n\n", "#{otherpage.other_names}\n\n", pattern).build + end + + def wiki_body_diff(thispage, otherpage) pattern = Regexp.new('(?:<.+?>)|(?:\w+)|(?:[ \t]+)|(?:\r?\n)|(?:.+?)') - other_names_pattern = Regexp.new('\S+|\s+') - - thisarr = thispage.body.scan(pattern) - otharr = otherpage.body.scan(pattern) - - if thispage.other_names.present? || otherpage.other_names.present? - thisarr = "#{thispage.other_names}\n\n".scan(other_names_pattern) + thisarr - otharr = "#{otherpage.other_names}\n\n".scan(other_names_pattern) + otharr - end - - cbo = Diff::LCS::ContextDiffCallbacks.new - diffs = thisarr.diff(otharr, cbo) - - escape_html = ->(str) {str.gsub(/&/, '&').gsub(//, '>')} - - output = thisarr - output.each { |q| q.replace(escape_html[q]) } - - diffs.reverse_each do |hunk| - newchange = hunk.max {|a, b| a.old_position <=> b.old_position} - newstart = newchange.old_position - oldstart = hunk.min {|a, b| a.old_position <=> b.old_position}.old_position - - if newchange.action == '+' - output.insert(newstart, '') - end - - hunk.reverse_each do |chg| - case chg.action - when '-' - oldstart = chg.old_position - output[chg.old_position] = '
' if chg.old_element.match(/^\r?\n$/) - when '+' - if chg.new_element.match(/^\r?\n$/) - output.insert(chg.old_position, '
') - else - output.insert(chg.old_position, (escape_html[chg.new_element]).to_s) - end - end - end - - if newchange.action == '+' - output.insert(newstart, '') - end - - if hunk[0].action == '-' - output.insert((newstart == oldstart || newchange.action != '+') ? newstart + 1 : newstart, '') - output.insert(oldstart, '') - end - end - - output.join.gsub(/\r?\n/, '
').html_safe + DiffBuilder.new(thispage.body, otherpage.body, pattern).build end end diff --git a/app/logical/diff_builder.rb b/app/logical/diff_builder.rb new file mode 100644 index 000000000..971f60cd9 --- /dev/null +++ b/app/logical/diff_builder.rb @@ -0,0 +1,57 @@ +class DiffBuilder + attr_reader :this_text, :that_text, :pattern + + def initialize(this_text, that_text, pattern) + @this_text = this_text + @that_text = that_text + @pattern = pattern + end + + def build + thisarr = this_text.scan(pattern) + otharr = that_text.scan(pattern) + + cbo = Diff::LCS::ContextDiffCallbacks.new + diffs = thisarr.diff(otharr, cbo) + + escape_html = ->(str) {str.gsub(/&/, '&').gsub(//, '>')} + + output = thisarr + output.each { |q| q.replace(escape_html[q]) } + + diffs.reverse_each do |hunk| + newchange = hunk.max {|a, b| a.old_position <=> b.old_position} + newstart = newchange.old_position + oldstart = hunk.min {|a, b| a.old_position <=> b.old_position}.old_position + + if newchange.action == '+' + output.insert(newstart, '
') + end + + hunk.reverse_each do |chg| + case chg.action + when '-' + oldstart = chg.old_position + output[chg.old_position] = '
' if chg.old_element.match(/^\r?\n$/) + when '+' + if chg.new_element.match(/^\r?\n$/) + output.insert(chg.old_position, '
') + else + output.insert(chg.old_position, (escape_html[chg.new_element]).to_s) + end + end + end + + if newchange.action == '+' + output.insert(newstart, '') + end + + if hunk[0].action == '-' + output.insert((newstart == oldstart || newchange.action != '+') ? newstart + 1 : newstart, '') + output.insert(oldstart, '') + end + end + + output.join.gsub(/\r?\n/, '
').html_safe + end +end diff --git a/app/views/wiki_page_versions/diff.html.erb b/app/views/wiki_page_versions/diff.html.erb index b60410d8c..3aeb38afc 100644 --- a/app/views/wiki_page_versions/diff.html.erb +++ b/app/views/wiki_page_versions/diff.html.erb @@ -7,7 +7,10 @@

Showing differences between <%= compact_time @thispage.updated_at %> (<%= link_to_user @thispage.updater %>) and <%= compact_time @otherpage.updated_at %> (<%= link_to_user @otherpage.updater %>)

- <%= wiki_page_diff(@thispage, @otherpage) %> + <%= wiki_other_names_diff(@thispage, @otherpage) %> +
+
+ <%= wiki_body_diff(@thispage, @otherpage) %>
<% else %>

The artist requested removal of this page.