Files
danbooru/app/helpers/wiki_page_versions_helper.rb
evazion a586916cb3 /wiki_page_versions: various usability improvements.
Changes to the /wiki_page_versions global listing:

* Add "diff" links that show you what changed in the given edit.
* Add "?" links that take you to the current version of the wiki.
* Add "»" links next to wiki page titles that take you to the wiki's full edit history.
* Add "»" links next to usernames that take you to the user's full edit history.
* Add a "Status" column that shows whether the wiki page was created,
  deleted, undeleted, or renamed.
* Link to /wiki_page_versions in sidebar, not /wiki_pages?order=time.
2019-08-18 17:08:35 -05:00

71 lines
2.2 KiB
Ruby

module WikiPageVersionsHelper
def wiki_page_version_status_diff(wiki_page_version)
cur = wiki_page_version
prev = wiki_page_version.previous
return "New" if prev.blank?
status = []
status += ["Renamed"] if cur.title != prev.title
status += ["Deleted"] if cur.is_deleted? && !prev.is_deleted?
status += ["Undeleted"] if !cur.is_deleted? && prev.is_deleted?
status.join(" ")
end
def wiki_page_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(/&/,'&amp;').gsub(/</,'&lt;').gsub(/>/,'&gt;')}
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, '</ins>')
end
hunk.reverse_each do |chg|
case chg.action
when '-'
oldstart = chg.old_position
output[chg.old_position] = '<br>' if chg.old_element.match(/^\r?\n$/)
when '+'
if chg.new_element.match(/^\r?\n$/)
output.insert(chg.old_position, '<br>')
else
output.insert(chg.old_position, "#{escape_html[chg.new_element]}")
end
end
end
if newchange.action == '+'
output.insert(newstart, '<ins>')
end
if hunk[0].action == '-'
output.insert((newstart == oldstart || newchange.action != '+') ? newstart+1 : newstart, '</del>')
output.insert(oldstart, '<del>')
end
end
output.join.gsub(/\r?\n/, '<br>').html_safe
end
end